{"id":"179fd22d-f6e8-4a59-a190-e9609b7f21a3","shortId":"4aenwe","kind":"skill","title":"pyapp","tagline":"Use when building standalone Python executables with PyApp, bundling Python runtimes, preparing air-gapped or multi-architecture binaries, patching PyApp defaults, or compiling single-binary assets.","description":"# PyApp Standalone Binaries\n\nEnable building self-contained, air-gapped, multi-architecture standalone executables for any Python application using **PyApp** and **uv**.\n\n---\n\n## Overview\n\nStandard `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.\n\nThis skill documents the **Bundle-Patch-Compile** workflow:\n\n1. **Bundle**: Download a standalone Python build, install dependencies into its `site-packages`, and repackage.\n2. **Patch**: Modify the PyApp source code to enforce custom install locations or isolation defaults.\n3. **Compile**: Compile the patched PyApp binary with the bundled distribution embedded.\n\n---\n\n## Architecture & Philosophy\n\n### The Packaged Distribution\n\nInstead of installing at runtime, we build a **hybrid distribution**:\n\n* A basic standalone Python distribution (e.g., from `python-build-standalone`).\n* Pre-populated `site-packages` via `uv pip install --target`.\n* This avoids running any package managers on first execution.\n\n---\n\n<workflow>\n\n## Configuration\n\n### 1. Standard Settings\n\nIn your `pyproject.toml`, configure the Hatch target or custom builder to use specific variables.\n\n<example>\n\n```toml\n[tool.hatch.build.targets.binary]\nscripts = [\"myapp\"]\npyapp-version = \"v0.29.0\"\n\n[tool.hatch.build.targets.binary.env]\nPYAPP_DISTRIBUTION_EMBED = \"1\"\nPYAPP_FULL_ISOLATION = \"1\"\nPYAPP_ALLOW_UPDATES = \"1\"\n```\n\n</example>\n\n---\n\n## Step-by-Step Workflow\n\n### Phase 1: Bundling (Prep the Runtime)\n\nTo enable fully offline operations, follow these steps using an automation script (see `scripts/bundler.py`):\n\n1. **Download Standalone Python**: Acquire a compatible `install_only_stripped` version for the Target Rust arch (e.g., `x86_64-unknown-linux-gnu`).\n2. **Install Deps Off-Target**: Use `uv pip install` with specific cross-compilation flags:\n    * `--target <extracted_python_site_packages>`\n    * `--python-platform <uv_supported_platform>`\n    * `--upgrade`\n3. **Repackage**: Compress the resulting layout back into a `.tar.gz`.\n\n### Phase 2: PyApp Patching (Enforce Paths)\n\nBy 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`:\n\n<example>\n\n```python\n# Conceptual example of patching src/app.rs\nimport re\ncontent = app_rs.read_text()\npattern = re.compile(r\"platform_dirs\\(\\)\\s*\\.data_local_dir\\(\\)...\")\nreplacement = \"std::path::PathBuf::from(\\\"~/.myapp\\\")\"\napp_rs.write_text(pattern.sub(replacement, content))\n```\n\n</example>\n\n### Phase 3: Compiling\n\nTo maintain maximum glibc backward-compatibility (e.g., supporting RHEL 7+ / manylinux2014 baseline):\n\n* Use **Zig** as the linker trigger: `cargo zigbuild --release --target <target>.2.17`\n\n</workflow>\n\n---\n\n## CI/CD Integration\n\nEnsure your GitHub Action includes:\n\n1. An upstream build step creating target-agnostic `.whl` files.\n2. A cross-target build matrix (`x86_64-linux-gnu`, `aarch64-linux-gnu`, `aarch64-apple-darwin`, etc.).\n3. Zig setup steps for robust glibc pin targeting.\n\n> [!TIP]\n> Always test inside a non-networked container:\n> `docker run --network none -v $(pwd):/app ubuntu:20.04 /app/myapp-binary --help`\n\n---\n\n## Provided Resources\n\n* **Bundler Template**: `scripts/bundler.py` (in this skill directory)\n* **CI Matrix Action Example**: `examples/release-action.yml` (in this skill directory)\n\n## Shared Styleguide Baseline\n\n* Use shared styleguides for generic language/framework rules to reduce duplication in this skill.\n* [General Principles](https://github.com/cofin/flow/blob/main/templates/styleguides/general.md)\n* [Python](https://github.com/cofin/flow/blob/main/templates/styleguides/languages/python.md)\n* [Docker](https://github.com/cofin/flow/blob/main/templates/styleguides/tools/docker.md)\n* Keep this skill focused on tool-specific workflows, edge cases, and integration details.\n\n<guardrails>\n## Guardrails\n\n* **Use non-root user in production images** -- When containerizing the resulting binary, ensure it runs as a non-privileged user to minimize security risks.\n* **Prefer multi-stage Docker builds** -- Separate the build environment (with Cargo and Zig) from the final runtime image to keep the production artifact small.\n* **Target specific glibc versions with Zig** -- Use `cargo zigbuild --target <arch>.2.17` to ensure compatibility with older Linux distributions (e.g., RHEL 7+).\n* **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.\n* **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.\n</guardrails>\n\n<validation>\n## Validation Checkpoint\n\n* [ ] Binary runs successfully in a network-isolated (`--network none`) environment\n* [ ] glibc compatibility is verified using `ldd --version` on the target platform\n* [ ] No root privileges are required to execute the binary\n* [ ] All required Python dependencies are included in the embedded `site-packages`\n* [ ] Binary size is within the expected range for the bundled distribution\n* [ ] Custom install paths (if patched) are correctly respected by the application\n</validation>","tags":["pyapp","flow","cofin","agent-skills","ai-agents","beads","claude-code","codex","cursor","developer-tools","gemini-cli","opencode"],"capabilities":["skill","source-cofin","skill-pyapp","topic-agent-skills","topic-ai-agents","topic-beads","topic-claude-code","topic-codex","topic-cursor","topic-developer-tools","topic-gemini-cli","topic-opencode","topic-plugin","topic-slash-commands","topic-spec-driven-development"],"categories":["flow"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cofin/flow/pyapp","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cofin/flow","source_repo":"https://github.com/cofin/flow","install_from":"skills.sh"}},"qualityScore":"0.455","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 11 github stars · SKILL.md body (5,457 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:07:38.703Z","embedding":null,"createdAt":"2026-04-23T13:04:00.810Z","updatedAt":"2026-05-18T19:07:38.703Z","lastSeenAt":"2026-05-18T19:07:38.703Z","tsv":"'/.myapp':331,368 '/app':464 '/app/myapp-binary':467 '/cofin/flow/blob/main/templates/styleguides/general.md)':507 '/cofin/flow/blob/main/templates/styleguides/languages/python.md)':511 '/cofin/flow/blob/main/templates/styleguides/tools/docker.md)':515 '1':101,191,220,224,228,235,254,408,615 '2':117,277,309,419 '2.17':400,592 '20.04':466 '3':132,298,375,440 '64':272,427 '7':387,602 'aarch64':432,436 'aarch64-apple-darwin':435 'aarch64-linux-gnu':431 'access':69,630 'acquir':258 'action':406,480 'agnost':416 'ahead':89 'air':15,40,72,608 'air-gap':14,39,71,607 'allow':226 'alway':450 'app_rs.read':352 'app_rs.write':369 'appl':437 'applic':50,724 'arch':269 'architectur':20,44,144 'artifact':580 'asset':30 'autom':250 'avoid':182 'back':304 'backward':382 'backward-compat':381 'baselin':389,489 'basic':160 'binari':21,29,33,138,543,619,635,660,690,703 'bootstrap':59 'build':4,35,107,155,168,342,411,424,562,565 'builder':203 'bundl':10,97,102,141,236,712 'bundle-patch-compil':96 'bundler':471 'cargo':341,396,568,589 'case':526 'checkpoint':659 'ci':478 'ci/cd':401 'code':123,338 'compat':260,383,595,672 'compil':26,99,133,134,291,376 'compress':300 'conceptu':344 'configur':190,197 'contain':38,457,624 'container':540 'content':351,373 'correct':720 'creat':413 'cross':290,422 'cross-compil':289 'cross-target':421 'custom':126,202,714 'darwin':438 'data':319,323,360 'default':24,131,315 'dep':279 'depend':88,109,605,694 'detail':529 'dir':358,362 'directori':477,486 'distribut':85,142,148,158,163,218,599,613,643,713 'docker':458,512,561 'document':94 'download':103,255 'duplic':499 'e.g':164,270,330,384,600,649 'edg':525 'emb':81,219,603,614 'embed':143,642,699 'enabl':34,241 'enforc':125,312 'ensur':403,544,594,617 'entir':83 'environ':61,78,566,670 'etc':439 'exampl':345,481 'examples/release-action.yml':482 'execut':7,46,189,656,688 'expect':708 'file':418,648 'final':573 'first':63,188,632 'flag':292 'focus':519 'folder':324 'follow':245 'full':222 'fulli':242,621 'gap':16,41,73,609 'general':503 'generic':494 'github':405 'github.com':506,510,514 'github.com/cofin/flow/blob/main/templates/styleguides/general.md)':505 'github.com/cofin/flow/blob/main/templates/styleguides/languages/python.md)':509 'github.com/cofin/flow/blob/main/templates/styleguides/tools/docker.md)':513 'glibc':380,446,584,671 'gnu':276,430,434 'guardrail':530 'hatch':199 'help':468 'hybrid':157 'imag':538,575 'import':349 'includ':407,696 'insid':452 'instal':58,108,127,151,179,261,278,286,715 'instead':149 'integr':402,528 'internet':68,629 'isol':77,130,223,329,667 'keep':516,577,654 'language/framework':495 'layout':303 'ldd':676 'linker':394 'linux':275,429,433,598 'linux-gnu':428 'local':322,361 'locat':128 'maintain':378 'manag':186,657 'manylinux2014':388 'matrix':425,479 'maximum':379 'minim':554 'modifi':119 'monitor':637 'multi':19,43,559 'multi-architectur':18,42 'multi-stag':558 'must':80 'myapp':211 'network':76,456,460,666,668 'network-isol':75,665 'non':455,533,550 'non-network':454 'non-privileg':549 'non-root':532 'none':461,669 'off-target':280 'offlin':243 'older':597 'oper':244 'overview':55 'packag':114,147,175,185,702 'patch':22,98,118,136,311,334,347,718 'path':313,365,716 'pathbuf':366 'pattern':354 'pattern.sub':371 'phase':234,308,374 'philosophi':145 'pin':447 'pip':178,285 'platform':296,357,681 'popul':172 'pre':171 'pre-popul':170 'prefer':557 'prep':237 'prepar':13 'principl':504 'privileg':551,684 'product':537,579 'provid':469 'pwd':463 'pyapp':1,9,23,31,52,57,121,137,213,217,221,225,310,316,336,612 'pyapp-vers':212 'pyc':650 'pycach':651 'pyproject.toml':196 'python':6,11,49,84,106,162,167,257,295,343,508,693 'python-build-standalon':166 'python-platform':294 'r':356 'rang':709 're':350 're.compile':355 'reduc':498 'releas':398 'repackag':116,299 'replac':363,372 'requir':67,327,628,686,692 'resourc':470 'respect':721 'result':302,542 'rhel':386,601 'risk':556 'robust':445 'root':534,683 'rule':496 'run':64,183,459,546,633,661 'runtim':12,153,239,574 'rust':268 'script':210,251 'scripts/bundler.py':253,473 'secur':555 'see':252 'self':37,623 'self-contain':36,622 'separ':563 'set':193,611 'setup':442 'share':487,491 'singl':28 'single-binari':27 'site':113,174,701 'site-packag':112,173,700 'size':636,639,704 'skill':93,476,485,502,518 'skill-pyapp' 'small':581 'sourc':122,337 'source-cofin' 'specif':206,288,523,583 'src/app.rs':348 'stage':560 'standalon':5,32,45,105,161,169,256 'standard':56,192,321 'std':364 'step':230,232,247,412,443 'step-by-step':229 'store':317 'strict':328 'strip':263,644 'styleguid':488,492 'success':662 'support':385 'symbol':646 'tar.gz':307 'target':180,200,267,282,293,399,415,423,448,582,591,680 'target-agnost':414 'templat':472 'test':451,652 'text':353,370 'time':91 'tip':449 'toml':208 'tool':522 'tool-specif':521 'tool.hatch.build.targets.binary':209 'tool.hatch.build.targets.binary.env':216 'topic-agent-skills' 'topic-ai-agents' 'topic-beads' 'topic-claude-code' 'topic-codex' 'topic-cursor' 'topic-developer-tools' 'topic-gemini-cli' 'topic-opencode' 'topic-plugin' 'topic-slash-commands' 'topic-spec-driven-development' 'trigger':395 'ubuntu':465 'unknown':274 'unknown-linux-gnu':273 'unnecessari':645 'updat':227 'upgrad':297 'upstream':410 'use':2,51,205,248,283,390,490,531,588,610,675 'user':318,535,552 'usual':66 'uv':54,177,284 'v':462 'v0.29.0':215 'valid':634,658 'variabl':207 'verifi':674 'version':214,264,585,677 'via':176 'whl':417 'within':706 'workflow':100,233,524 'x86':271,426 'zig':391,441,570,587 'zigbuild':397,590","prices":[{"id":"87267abf-8806-4aef-bbde-227f36883427","listingId":"179fd22d-f6e8-4a59-a190-e9609b7f21a3","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cofin","category":"flow","install_from":"skills.sh"},"createdAt":"2026-04-23T13:04:00.810Z"}],"sources":[{"listingId":"179fd22d-f6e8-4a59-a190-e9609b7f21a3","source":"github","sourceId":"cofin/flow/pyapp","sourceUrl":"https://github.com/cofin/flow/tree/main/skills/pyapp","isPrimary":false,"firstSeenAt":"2026-04-23T13:04:00.810Z","lastSeenAt":"2026-05-18T19:07:38.703Z"}],"details":{"listingId":"179fd22d-f6e8-4a59-a190-e9609b7f21a3","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cofin","slug":"pyapp","github":{"repo":"cofin/flow","stars":11,"topics":["agent-skills","ai-agents","beads","claude-code","codex","context-driven-development","cursor","developer-tools","gemini-cli","opencode","plugin","slash-commands","spec-driven-development","subagents","tdd","workflow"],"license":"apache-2.0","html_url":"https://github.com/cofin/flow","pushed_at":"2026-04-27T19:07:26Z","description":"Context-Driven Development toolkit for AI agents — spec-first planning, TDD workflow, and Beads integration.","skill_md_sha":"3e9342b1ec288b65cc64be3d5ee8d0dd9f55ca43","skill_md_path":"skills/pyapp/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cofin/flow/tree/main/skills/pyapp"},"layout":"multi","source":"github","category":"flow","frontmatter":{"name":"pyapp","description":"Use when building standalone Python executables with PyApp, bundling Python runtimes, preparing air-gapped or multi-architecture binaries, patching PyApp defaults, or compiling single-binary assets."},"skills_sh_url":"https://skills.sh/cofin/flow/pyapp"},"updatedAt":"2026-05-18T19:07:38.703Z"}}