pyapp
Auto-activate for pyapp build config. Build air-gapped, multi-architecture standalone Python executables using PyApp and uv. Use when: bundling Python runtimes for network-isolated environments, patching PyApp defaults, or compiling single-binary assets. Not for PyInstaller, cx_F
What it does
PyApp Standalone Binaries
Enable building self-contained, air-gapped, multi-architecture standalone executables for any Python application using PyApp and uv.
Overview
Standard pyapp installation bootstraps the environment on first run, which usually requires internet access. For air-gapped or network-isolated environments, you must embed the entire Python distribution and its dependencies ahead of time.
This skill documents the Bundle-Patch-Compile workflow:
- Bundle: Download a standalone Python build, install dependencies into its
site-packages, and repackage. - Patch: Modify the PyApp source code to enforce custom install locations or isolation defaults.
- Compile: Compile the patched PyApp binary with the bundled distribution embedded.
Architecture & Philosophy
The Packaged Distribution
Instead of installing at runtime, we build a hybrid distribution:
- A basic standalone Python distribution (e.g., from
python-build-standalone). - Pre-populated
site-packagesviauv pip install --target. - This avoids running any package managers on first execution.
<workflow>
Configuration
1. Standard Settings
In your pyproject.toml, configure the Hatch target or custom builder to use specific variables.
[tool.hatch.build.targets.binary]
scripts = ["myapp"]
pyapp-version = "v0.29.0"
[tool.hatch.build.targets.binary.env]
PYAPP_DISTRIBUTION_EMBED = "1"
PYAPP_FULL_ISOLATION = "1"
PYAPP_ALLOW_UPDATES = "1"
</example>
Step-by-Step Workflow
Phase 1: Bundling (Prep the Runtime)
To enable fully offline operations, follow these steps using an automation script (see scripts/bundler.py):
- Download Standalone Python: Acquire a compatible
install_only_strippedversion for the Target Rust arch (e.g.,x86_64-unknown-linux-gnu). - Install Deps Off-Target: Use
uv pip installwith specific cross-compilation flags:--target <extracted_python_site_packages>--python-platform <uv_supported_platform>--upgrade
- Repackage: Compress the resulting layout back into a
.tar.gz.
Phase 2: PyApp Patching (Enforce Paths)
By default, PyApp stores user data in standard local data folders. If you require strict isolation (e.g., ~/.myapp), you can patch the PyApp source code just before cargo build:
# Conceptual example of patching src/app.rs
import re
content = app_rs.read_text()
pattern = re.compile(r"platform_dirs\(\)\s*\.data_local_dir\(\)...")
replacement = "std::path::PathBuf::from(\"~/.myapp\")"
app_rs.write_text(pattern.sub(replacement, content))
</example>
Phase 3: Compiling
To maintain maximum glibc backward-compatibility (e.g., supporting RHEL 7+ / manylinux2014 baseline):
- Use Zig as the linker trigger:
cargo zigbuild --release --target <target>.2.17
CI/CD Integration
Ensure your GitHub Action includes:
- An upstream build step creating target-agnostic
.whlfiles. - A cross-target build matrix (
x86_64-linux-gnu,aarch64-linux-gnu,aarch64-apple-darwin, etc.). - Zig setup steps for robust glibc pin targeting.
[!TIP] Always test inside a non-networked container:
docker run --network none -v $(pwd):/app ubuntu:20.04 /app/myapp-binary --help
Provided Resources
- Bundler Template:
scripts/bundler.py(in this skill directory) - CI Matrix Action Example:
examples/release-action.yml(in this skill directory)
Shared Styleguide Baseline
- Use shared styleguides for generic language/framework rules to reduce duplication in this skill.
- General Principles
- Python
- Docker
- Keep this skill focused on tool-specific workflows, edge cases, and integration details.
- Use non-root user in production images -- When containerizing the resulting binary, ensure it runs as a non-privileged user to minimize security risks.
- Prefer multi-stage Docker builds -- Separate the build environment (with Cargo and Zig) from the final runtime image to keep the production artifact small.
- Target specific glibc versions with Zig -- Use
cargo zigbuild --target <arch>.2.17to ensure compatibility with older Linux distributions (e.g., RHEL 7+). - Embed all dependencies for air-gapped use -- Set
PYAPP_DISTRIBUTION_EMBED = "1"to ensure the binary is fully self-contained and does not require internet access on first run. - Validate binary size -- Monitor the size of the embedded distribution; strip unnecessary symbols and files (e.g.,
.pyc,__pycache__, tests) to keep the executable manageable. </guardrails>
- Binary runs successfully in a network-isolated (
--network none) environment - glibc compatibility is verified using
ldd --versionon the target platform - No root privileges are required to execute the binary
- All required Python dependencies are included in the embedded
site-packages - Binary size is within the expected range for the bundled distribution
- Custom install paths (if patched) are correctly respected by the application
Capabilities
Install
Quality
deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 11 github stars · SKILL.md body (5,457 chars)