{"id":18708593,"url":"https://github.com/va1da5/python-application-bundle","last_synced_at":"2026-04-20T03:31:28.422Z","repository":{"id":106645823,"uuid":"450217331","full_name":"va1da5/python-application-bundle","owner":"va1da5","description":"Example of packaging Python application as an executable ZIP archive","archived":false,"fork":false,"pushed_at":"2022-01-21T18:15:44.000Z","size":18,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-28T07:31:33.359Z","etag":null,"topics":["bundle","fastapi","packaging","python","zip","zipapp"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/va1da5.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-20T18:43:14.000Z","updated_at":"2022-01-20T18:47:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"df8fbb30-f8b8-4fd1-8428-48228ad7747b","html_url":"https://github.com/va1da5/python-application-bundle","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/va1da5%2Fpython-application-bundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/va1da5%2Fpython-application-bundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/va1da5%2Fpython-application-bundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/va1da5%2Fpython-application-bundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/va1da5","download_url":"https://codeload.github.com/va1da5/python-application-bundle/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239571586,"owners_count":19661165,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bundle","fastapi","packaging","python","zip","zipapp"],"created_at":"2024-11-07T12:24:05.450Z","updated_at":"2025-11-09T10:30:24.423Z","avatar_url":"https://github.com/va1da5.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bundle Python Application Using Zip\n\nThis is a small proof-of-concept (PoC) setup for packaging application as a single Python executable ZIP archive.\n\nThe idea is that the archive includes all (*most*) of the dependencies of the application and could be easily distributed to other interested parties.\n\nA minimal [FastAPI](https://fastapi.tiangolo.com/) setup is used to simulate an application with a number of dependencies, like [Uvicorn server](https://www.uvicorn.org/).\n\nPython includes an awesome utility module [zipapp](https://docs.python.org/3/library/zipapp.html) for packaging the application, however this example uses [the standard zip command line utility](https://linux.die.net/man/1/zip) to bundle up the application. This is because the PoC uses a custom [`__main__.py`](__main__.py) file which updates `sys.path` list, because the dependencies are placed in a dedicated directory `./site-packages` that are not part of the standard locations where Python looks for modules.\n\n\n## Results\n\nThe archived Python code gets executed. However, there are issues with static assets that are later used by code. [There are ways to access the files from archived modules](https://stackoverflow.com/questions/6028000/how-to-read-a-static-file-from-inside-a-python-package), but libraries like [FastAPI](https://fastapi.tiangolo.com/) or [Django](https://www.djangoproject.com/) do not take such setup into account and the static file loading fails.\n\nThis is something to be aware and evaluate before developing application with intend to distribute it as an executable archive.\n\n**Possible solutions**:\n\n  - Write utility function which would extract contents of the archive into some temporary location and allow code to access files from there;\n  - Implement an abstraction layer that would take ZIP archive and simply emulate it as a directory within regular filesystem.\n\nThe possible solution are out of the scope for this PoC.\n\n## Application Packaging\n\n```bash\n# create a temporary locations for bundling the application\nmkdir -p .tmp/ build\n\n# copy the application code to the temporary location\ncp -r *.py public server .tmp/\n\n# install required dependencies to a dedicated directory\npip install -r requirements.txt --target .tmp/site-packages\n\n\n# bundle up the application with dependencies\ncd .tmp/\nzip -r9 ../build/server.pyz .\ncd ..\n\n# run the application\npython3 ./build/server.pyz\n\n# make archive executable on its own\nmv ./build/server.pyz ./build/server.pyz.tmp\necho '#!/usr/bin/env python3' \u003e ./build/server.pyz\ncat ./build/server.pyz.tmp \u003e\u003e ./build/server.pyz\nrm ./build/server.pyz.tmp\nchmod +x ./build/server.pyz\n\n# start the application\n./build/server.pyz\n\n\n# the service could also be started using standard Uvicorn command\n# Python path needs to be updated to point to the bundled application internals\nPYTHONPATH=\"./build/server.pyz/site-packages:./build/server.pyz\" python -m uvicorn server:app --host localhost --port 4000\n\n\n# most of the actions could be performed using Make utility\nmake\nUsage: make [build|clean|run|dev]\n        build           : creates the application bundle\n        clean           : removes all traces of build artifacts\n        run             : runs built application\n        dev             : runs the application in development mode\n\n```\n\n\n## References\n\n- [Python zipapp](https://docs.python.org/3/library/zipapp.html)\n- [Python's zipapp: Build Executable Zip Applications](https://realpython.com/python-zipapp/)\n- [An Overview of Packaging for Python](https://packaging.python.org/en/latest/overview/#bringing-your-own-python-executable)\n- [shiv - command line utility for building fully self-contained Python zipapps](https://github.com/linkedin/shiv)\n- [How to read a (static) file from inside a Python package?](https://stackoverflow.com/questions/6028000/how-to-read-a-static-file-from-inside-a-python-package)\n- [PyFilesystem2’s documentation](https://docs.pyfilesystem.org/en/latest/index.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fva1da5%2Fpython-application-bundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fva1da5%2Fpython-application-bundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fva1da5%2Fpython-application-bundle/lists"}