Skip to main content

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 (pyfernet is already taken)
  • CLI / import: pyfernet / import pyfernet
  • Relative paths work: Path(__file__).parent / "train_config.json", open, spec_from_file_location via 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

# default: interactive passphrase prompt
pyfernet encrypt ./my_train -o train_payload.enc -e train.py

# non-interactive: environment variable (recommended)
export PYFERNET_PASSWORD='your-secret'
pyfernet encrypt ./my_train -o train_payload.enc -e train.py --password-env PYFERNET_PASSWORD

# non-interactive: CLI flag (shows in process list / shell history; temporary use only)
pyfernet encrypt ./my_train -o train_payload.enc -e train.py -p 'your-secret'

Run

# default: interactive passphrase prompt (runs encrypt-time -e)
pyfernet run train_payload.enc

# non-interactive: environment variable (recommended)
export PYFERNET_PASSWORD='your-secret'
pyfernet run train_payload.enc --password-env PYFERNET_PASSWORD

# non-interactive: CLI flag (not recommended; passphrase is visible)
pyfernet run train_payload.enc -p 'your-secret'

# override entry (must exist inside the package; no re-encrypt needed)
pyfernet run train_payload.enc -e other_entry.py
pyfernet run train_payload.enc --entry export_core.py

# forward args to the chosen entry (after --):
pyfernet run train_payload.enc -- --epochs 50 --batch 8
pyfernet run train_payload.enc -e test_core.py -- --help

run -e overrides the manifest default entry. The path is relative to the encrypted source root (same style as encrypt -e). Absolute paths and .. are rejected. Old .enc files work after upgrading pyfernet-payload on the client.

Passphrase priority: -p / --password > --password-env / PYFERNET_PASSWORD > interactive prompt.

Equivalent:

python -m pyfernet encrypt ./my_train -o train_payload.enc -e train.py
python -m pyfernet run train_payload.enc

Workflow

  1. Local: write training code → pyfernet encrypt → train_payload.enc
  2. SFTP: upload the ciphertext only (client already has pip install pyfernet-payload)
  3. SSH: pyfernet run train_payload.enc, enter passphrase
  4. Decrypt into memory → empty dir anchors + VFS hooks → start training; write weights to a normal disk path
  5. 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"])
# override entry without re-encrypting:
run_payload(
    "dist/train_payload.enc",
    "secret",
    argv=["other_entry.py"],
    entry_point="other_entry.py",
)

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/shm on Linux)
  • Process memory / debuggers can still see plaintext; a leaked passphrase decrypts the blob
  • By default only .py and 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.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyfernet-payload 0.2.5
File Size Uploaded Provenance Actions
pyfernet_payload-0.2.5.tar.gz 19.4 kB Without provenance Details for pyfernet_payload-0.2.5.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pyfernet-payload 0.2.5
File Interpreter ABI Platform Actions
pyfernet_payload-0.2.5-py3-none-any.whl Python 3 none any Details for pyfernet_payload-0.2.5-py3-none-any.whl

Total release size: 38.5 kB

Release files / pyfernet_payload-0.2.5.tar.gz

Download URL pyfernet_payload-0.2.5.tar.gz
Size 19.4 kB
Tags Source
SHA-256 checksum
How to use checksums
8241e59eb9f6a25ae241e6eb2cce2da67a0d97b2dedd4858cba4ad0804c0af1c
BLAKE2b-256 checksum
How to use checksums
a9503fd41bf3e752ab52f4b7e5d4b05164c2fee86fc6f419fd590f697c917e5d
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.5-py3-none-any.whl

Download URL pyfernet_payload-0.2.5-py3-none-any.whl
Size 19.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e83780eab823adf13ca135405b199222dcc029c13ccdfed6cffbaa288ff1596c
BLAKE2b-256 checksum
How to use checksums
165cedc5b983c7423f6b98a5c193c5d3377eb1ddbd265e419d4022497b424ea7
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.5

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.

Release history Release notifications | RSS feed

This release

0.2.5 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page