Packaging and excluding files
Because a protected dist is a drop-in mirror of your source, it slots into your existing packaging with minimal changes.
Excluding files
obfy build protects everything under --src by default. Some files must
stay as plain source — framework files read as text or imported dynamically
(Django migrations, manage.py, entry points). Exclude them with --exclude,
which uses Python fnmatch patterns, can be repeated, and is matched against the
<src>/<path> of each file and its parent directories. Excluded .py files are
copied into the dist verbatim, so they still run.
obfy build --src ./app --out ./dist \
--exclude "*/migrations/*" \ # Django migrations, any app
--exclude "*/manage.py" \ # filename in any path
--exclude "app/settings.py" # one exact file
Pattern cheatsheet:
| Pattern | Matches |
|---|---|
"src/test.py" | one exact script |
"./test" | an exact path/dir |
"*/test.py" | that filename anywhere |
"*/test" | any such directory |
--exclude controls protection, not copyingEvery non-.py file under --src is always copied into the dist so the
output runs in place. --exclude only leaves matching .py files as plain
source. Point --src at your code package to avoid copying secrets like .env.
PyInstaller
Point an existing .spec at the protected tree and bundle it whole — a one-word
path change:
a = Analysis(
['dist/run.py'], # was: app/run.py — the same entrypoint, now protected
datas=[('./dist/', './')], # ship the mirror, incl. __obfy__/ + bundled runtime
...
)
Docker
Build the dist, then copy the mirror into your image instead of your source:
# Build stage produces ./dist via `obfy build`
COPY --from=build /app/dist /app
CMD ["python", "/app/run.py"]
If you keep the build key out of the image, supply it at run time via OBFY_KEY
(see Keys and licensing).