{"id":18933357,"url":"https://github.com/synap5e/onefile_python","last_synced_at":"2025-10-19T14:04:49.009Z","repository":{"id":150507252,"uuid":"451339845","full_name":"synap5e/onefile_python","owner":"synap5e","description":"Run python from a single exe","archived":false,"fork":false,"pushed_at":"2022-05-01T22:50:00.000Z","size":21,"stargazers_count":35,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T00:11:17.580Z","etag":null,"topics":["nim","nimble","python","reflective-dll","windows"],"latest_commit_sha":null,"homepage":"","language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/synap5e.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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-24T06:16:50.000Z","updated_at":"2025-03-18T12:58:23.000Z","dependencies_parsed_at":"2023-04-04T04:47:19.604Z","dependency_job_id":null,"html_url":"https://github.com/synap5e/onefile_python","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synap5e%2Fonefile_python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synap5e%2Fonefile_python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synap5e%2Fonefile_python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synap5e%2Fonefile_python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/synap5e","download_url":"https://codeload.github.com/synap5e/onefile_python/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249108941,"owners_count":21214089,"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":["nim","nimble","python","reflective-dll","windows"],"created_at":"2024-11-08T11:54:16.514Z","updated_at":"2025-10-19T14:04:48.957Z","avatar_url":"https://github.com/synap5e.png","language":"Nim","funding_links":[],"categories":[],"sub_categories":[],"readme":"# onefile_python\n\nRun python from a single exe (without needing to extract anything to disk).\n\nThis project uses reflective dll loading and either nim's `staticRead` to load the python runtime from the executable itself, or optionally downloads the embedded zip on launch (\"staged\" mode).\nCustom (python) import hooks are installed to support loading modules (both native python (.pyc) and extension modules (.pyd)) from the embedded standard library.\n\n## Building\n\nOr just download from from the [releases page](https://github.com/synap5e/onefile_python/releases).\n\n0. Set up nim\n\n### Zip embedded in file\n\n1. Download `python-3.10.1-embed-amd64.zip` to the project directory\n2. `nimble build`\n3. Run `onefile_python.exe`\n\n### Download zip on launch (\"staged\")\n\nPotentially useful if you want a smaller exe.\n\n1. `nimble build -d:staged`\n2. Run `onefile_python.exe`\n\n\n## Usage\n\n```\nonefile_python\n\nUsage:\n  onefile_python [options] [file] [arg ...]\n\nArguments:\n  [file]           Program; read from script file/URL ('-' or empty for interactive) (default: )\n  [arg ...]        Arguments passed to program in sys.argv[1:]\n\nOptions:\n  -h, --help\n  -V, --version\n  -c, --command=COMMAND      Program; passed in as string\n```\n`file` can be a http or https URL.\n\nFor staged version:\n```\n  -d, --download=DOWNLOAD    Download `python-3.10.1-embed-amd64.zip` from this url (default: https://www.python.org/ftp/python/3.10.1)\n\n```\n\nAlternatively specify the download URL in the app filename e.g. rename `onefile_python.exe` to `blabla(10.0.0.1)foobar.exe` to download python from `https://10.0.0.1/python-3.10.1-embed-amd64.zip`. `blabla` and `foobar` can be any string.\n\n\n## TODO\n\n- [ ] Build option for embedding a python file/module and running that on launch (instead of accepting file/interactive loop)\n- [ ] Support other versions of python than `3.10.1` (autodetect?)\n\n\n## Similar projects\n\n- [py2exe](https://www.py2exe.org/index.cgi/FrontPage)\n- [PyInstaller](https://pyinstaller.readthedocs.io/en/stable/index.html)\n\nBoth projects are better suited for bundling an application (and all its dependencies) to end users. They both support some form of dependency resolution so modules not required by the bundled don't get installed, while this project includes the entire standard library.\n\nPyInstaller supports single exe mode, but this just extracts the runtime to a temporary directory.\npy2exe supports a diskless/\"bundle\" mode.\n\nBoth these projects are *much* more complex than this one and support lots of extra features, but sometimes you don't need that...\n\nThis project is (maybe) better if you want a single exe that can run any python script, or just want an exe that gives a python REPL.\nBeing simpler, this project should be easier to hack on or learn from.\n\n\n## How it works\n\nThere's not much to it...\n\n0. Use nim's [staticRead](https://nim-lang.org/docs/system.html#staticRead%2Cstring) to include `python-*-embedded.zip` and `bootstrap.py` inside compiled exe itself OR download the zip from a URL.\n1. Use [zippy](https://github.com/guzba/zippy) to access the contents of the archive at runtime.\n2. Use [memlib](https://github.com/khchen/memlib) to perform reflective dll loading of the embedded `python*.dll`. Reflective dll loading allows for loading the dll from memory rather than from disk. Hook `LdrLoadDll` and `K32EnumProcessModules` so other code using the dll can find it. n.b. currently using a fork until https://github.com/khchen/memlib/pull/3 is merged.\n3. Call various functions in the (reflectively) loaded dll to partially initialize python. Configure python to not try to load anything from disk (not absolutely required, but prevents conflicts and means the exe doesn't run any code in the current directory)\n4. Use [nimpy](https://github.com/yglukhov/nimpy) to initialize a python extension exporting some nim functions that can read data out of the `python*.zip` standard library (contained within the `...-embedded.zip`).\n5. Run the embedded `bootsrap.py` code to install an import hook. This import hook uses the functions from (4) to support importing python modules. If a `.pyc` can be found that matches an import, a loader that returns the unmarshalled `.pyc` is provided. If a `.pyd` can be found, the returned loader reflectively loads the `.pyd` and calls the module's initialization routine.\n6. Now that python's standard library can be imported, finish initializing python.\n6. Reflectively load other `.dlls` inside the `...-embedded.zip`. This is required so extension modules that depend on these dlls work e.g. `ctypes` needs `_ctypes.pyd` which requires `libffi.dll`.\n7. Run python code / REPL\n\n## Is this a virus\n\nNo.\n\nIt uses reflective DLL loading, which is a technique some malware uses so that might upset particularly sensitive AVs.\nLike python itself, it could be used to run a malicious script.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynap5e%2Fonefile_python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsynap5e%2Fonefile_python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynap5e%2Fonefile_python/lists"}