PyFernet (pyfernet-payload)
Pack a training source directory into a single .enc blob; on the client, decrypt and run from an in-memory VFS. Only an empty directory tree is created on disk (for Path(__file__) / chdir); .py / config contents are never written. Removed on exit.
- Zero third-party runtime deps (stdlib AES-128-CBC + Fernet-compatible format)
- PyPI name:
pyfernet-payload(pyfernetis already taken) - CLI / import:
pyfernet/import pyfernet - Relative paths work:
Path(__file__).parent / "train_config.json",open,spec_from_file_locationvia VFS hooks
Install
pip install pyfernet-payload
From a local clone:
# preferred on older pip / mirrors (no editable hook needed)
python3 -m pip install .
# or editable (dev); if this fails, upgrade pip first:
python3 -m pip install -U pip setuptools wheel
python3 -m pip install -e .
CLI
Encrypt
pyfernet encrypt ./my_train -o train_payload.enc -e train.py
# passphrase via prompt; or:
export PYFERNET_PASSWORD='your-secret'
pyfernet encrypt ./my_train -o train_payload.enc -e train.py --password-env PYFERNET_PASSWORD
Run
pyfernet run train_payload.enc
# forward args to the training entry (after --):
pyfernet run train_payload.enc -- --epochs 50 --batch 8
Equivalent:
python -m pyfernet encrypt ./my_train -o train_payload.enc -e train.py
python -m pyfernet run train_payload.enc
Workflow
- Local: write training code →
pyfernet encrypt→train_payload.enc - SFTP: upload the ciphertext only (client already has
pip install pyfernet-payload) - SSH:
pyfernet run train_payload.enc, enter passphrase - Decrypt into memory → empty dir anchors + VFS hooks → start training; write weights to a normal disk path
- On exit, remove empty dirs; durable disk still has only ciphertext
If the entry uses sibling dirs (e.g. train_detect_rtdetrv2/ + train_detect_cfg/ + train_detect_yolo/), encrypt the parent folder and set -e train_detect_rtdetrv2/train_insect.py.
Inference code, datasets, and weights can stay plaintext on the client.
IDE variable mode (optional)
With no CLI args, modules use the variables at the bottom of the file:
python -m pyfernet.encryptor # no args → SOURCE_DIR / OUTPUT_PATH / ENTRY_POINT
python -m pyfernet.loader # no args → PAYLOAD_PATH / TRAIN_ARGV
With args, they use the CLI, e.g. python -m pyfernet.encryptor ./src -o out.enc -e train.py.
Library API
from pyfernet import encrypt_directory, run_payload
encrypt_directory("examples/demo_train", "dist/train_payload.enc", "train.py", "secret")
run_payload("dist/train_payload.enc", "secret", argv=["train.py", "--epochs", "1"])
Payload format
PYFE1\0 + 16B salt + Fernet(token)
Fernet plaintext is a zip (sources + _pyfernet_manifest.json). The passphrase is stretched with PBKDF2-HMAC-SHA256 (390000 iterations).
Notes
- Source file bytes never hit disk; only empty directories exist briefly (often under
/dev/shmon Linux) - Process memory / debuggers can still see plaintext; a leaked passphrase decrypts the blob
- By default only
.pyand a few config suffixes are packed—do not put datasets or weights in the blob - The client still needs training deps installed (torch, ultralytics, etc.)
Publish to PyPI
See docs/PUBLISH.md (中文).
Layout
PyFernet/
pyproject.toml
README.md # English (PyPI)
README.zh-CN.md # Chinese
src/pyfernet/
cli.py
encryptor.py
loader.py
fernet_lite.py
examples/demo_train/
docs/PUBLISH.md
docs/PUBLISH.zh-CN.md
Metadata
Release files for pyfernet-payload 0.2.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pyfernet_payload-0.2.4.tar.gz | 18.0 kB | Without provenance | Details for pyfernet_payload-0.2.4.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pyfernet_payload-0.2.4-py3-none-any.whl | Python 3 | none | any | Details for pyfernet_payload-0.2.4-py3-none-any.whl |
Total release size: 36.1 kB
Release files / pyfernet_payload-0.2.4.tar.gz
| Download URL | pyfernet_payload-0.2.4.tar.gz |
|---|---|
| Size | 18.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
86aeacf798160c7808a99b9685a138372d7bec165bd73d93d6a95637187c7fab
|
|
BLAKE2b-256 checksum How to use checksums |
6a5430056300d9c9aa553e41a415cb46b282dce0d098970affa310dd8b2a241b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / pyfernet_payload-0.2.4-py3-none-any.whl
| Download URL | pyfernet_payload-0.2.4-py3-none-any.whl |
|---|---|
| Size | 18.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0bc1d4bf88426f1db1764a5dbee5e597f5b223e2130bcb09ec8586cf22b936c3
|
|
BLAKE2b-256 checksum How to use checksums |
09dec9e0bb0e5ee3bd7b2c3b00bc96277fcc508c63dba04bab1b62da36a2991a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Security for pyfernet-payload 0.2.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.