{"id":16418199,"url":"https://github.com/facundobatista/pyempaq","last_synced_at":"2025-08-23T09:06:23.395Z","repository":{"id":37005767,"uuid":"386437775","full_name":"facundobatista/pyempaq","owner":"facundobatista","description":"A simple but powerful Python packer to run any project with any virtualenv dependencies anywhwere.","archived":false,"fork":false,"pushed_at":"2025-08-16T13:20:52.000Z","size":2771,"stargazers_count":47,"open_issues_count":9,"forks_count":9,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-08-23T09:02:34.460Z","etag":null,"topics":["distribution","packaging","python","virtualenv"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/facundobatista.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2021-07-15T22:16:17.000Z","updated_at":"2025-08-16T13:20:49.000Z","dependencies_parsed_at":"2023-02-16T15:00:59.061Z","dependency_job_id":"f4b2e7ed-c929-44a0-9a6f-eade39c45f48","html_url":"https://github.com/facundobatista/pyempaq","commit_stats":{"total_commits":105,"total_committers":3,"mean_commits":35.0,"dds":"0.32380952380952377","last_synced_commit":"1070aa57cb4e2eb8d1d6538c832943cd277b0e7c"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/facundobatista/pyempaq","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/facundobatista%2Fpyempaq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/facundobatista%2Fpyempaq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/facundobatista%2Fpyempaq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/facundobatista%2Fpyempaq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/facundobatista","download_url":"https://codeload.github.com/facundobatista/pyempaq/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/facundobatista%2Fpyempaq/sbom","scorecard":{"id":391182,"data":{"date":"2025-08-11","repo":{"name":"github.com/facundobatista/pyempaq","commit":"e1238bb4d26a09459590503a58b2b6a453822905"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.9,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/tests.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":5,"reason":"6 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/3 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yaml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/facundobatista/pyempaq/tests.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yaml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/facundobatista/pyempaq/tests.yaml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/tests.yaml:31","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 0.6 not signed: https://api.github.com/repos/facundobatista/pyempaq/releases/135471004","Warn: release artifact 0.5 not signed: https://api.github.com/repos/facundobatista/pyempaq/releases/120523433","Warn: release artifact 0.4.0 not signed: https://api.github.com/repos/facundobatista/pyempaq/releases/113233113","Warn: release artifact 0.3.1 not signed: https://api.github.com/repos/facundobatista/pyempaq/releases/100211378","Warn: release artifact 0.3.0 not signed: https://api.github.com/repos/facundobatista/pyempaq/releases/100134731","Warn: release artifact 0.6 does not have provenance: https://api.github.com/repos/facundobatista/pyempaq/releases/135471004","Warn: release artifact 0.5 does not have provenance: https://api.github.com/repos/facundobatista/pyempaq/releases/120523433","Warn: release artifact 0.4.0 does not have provenance: https://api.github.com/repos/facundobatista/pyempaq/releases/113233113","Warn: release artifact 0.3.1 does not have provenance: https://api.github.com/repos/facundobatista/pyempaq/releases/100211378","Warn: release artifact 0.3.0 does not have provenance: https://api.github.com/repos/facundobatista/pyempaq/releases/100134731"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T17:51:15.213Z","repository_id":37005767,"created_at":"2025-08-18T17:51:15.213Z","updated_at":"2025-08-18T17:51:15.213Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271746301,"owners_count":24813556,"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","status":"online","status_checked_at":"2025-08-23T02:00:09.327Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["distribution","packaging","python","virtualenv"],"created_at":"2024-10-11T07:13:31.663Z","updated_at":"2025-08-23T09:06:23.326Z","avatar_url":"https://github.com/facundobatista.png","language":"Python","funding_links":[],"categories":["Zipapps"],"sub_categories":[],"readme":"# PyEmpaq\n\nA simple but powerful Python packer to run any project with any virtualenv dependencies anywhwere.\n\nWith PyEmpaq you can convert any Python project (see limitations below) into a single `.pyz` file with all the project's content packed inside. \n\nPacking is super simple, see this demo:\n\n![pack-demo](https://github.com/facundobatista/pyempaq/blob/main/resources/demo_pack.gif?raw=True)\n\nThat single file is everything that needs to be distributed. When the final user executes it, the original project will be expanded, its dependencies installed in a virtualenv, and then executed. Note that no special permissions or privileges are required, as everything happens in the user environment.\n\nSee that in action:\n\n![run-demo](https://github.com/facundobatista/pyempaq/blob/main/resources/demo_run.gif?raw=True)\n\nBoth the packaging and the execution are fully multiplatorm. This means that you can pack a project in Linux, Windows, Mac or whatever, and it will run ok in Linux, Windows, Mac or whatever. The only requirement is Python to be already installed.\n\nYou can try yourself some packed with PyEmpaq examples, very easy, just download any of these files and run it with Python:\n\n- [in a terminal](https://github.com/facundobatista/pyempaq/blob/main/examples/simple-command-line.pyz?raw=True): a very small pure terminal example (this, of course, needs to be run in a terminal)\n- [a game](https://github.com/facundobatista/pyempaq/blob/main/examples/arcade-game.pyz?raw=True): a simple game using the [Python Arcade](https://api.arcade.academy/en/latest/) library (actually, it's the [example #6 from their tutorial](https://api.arcade.academy/en/latest/examples/platform_tutorial/step_06.html))\n- [desktop app](https://github.com/facundobatista/pyempaq/blob/main/examples/desktop-qt-app.pyz?raw=True): a full-fledged desktop application using PyQt5 (this [Encuentro app](https://encuentro.taniquetil.com.ar/))\n\n![logo](https://github.com/facundobatista/pyempaq/blob/main/resources/logo-256.png?raw=True)\n\n\nYou can install `pyempaq` directly from PyPI; see [instructions below](https://github.com/facundobatista/pyempaq#how-to-install-pyempaq).\n\nPyEmpaq is security friendly, there is nothing obscure or secretly shipped when you distribute your project with it: anybody can just open the `pyz` file (it's just a ZIP) and inspect it.\n\nIt's also safe regarding licenses when distributing your packed software. Unlike packing mechanisms that rely on putting inside a big blob, with PyEmpaq you don't have to worry about the licenses of your software dependencies (and the dependencies' dependencies) in regard to distributing them.\n\n\n### Limitations:\n\nThere are some limitations:\n\n- Only Python \u003e= 3.7 is supported\n\n- Only Linux, Windows and Mac is supported\n\n- Only pip-installable dependencies are supported (from PyPI or whatever).\n\n- Only dependencies that are pure Python or provide wheels are supported.\n\nAll this means that the most majority of the projects could be packed and run by PyEmpaq. If you have any ideas on how to overcome any of these limitations, let's talk!\n\n\n### How Does this Work?\n\nThere are two phases: packing and execution. \n\nThe **packing phase** is executed by the project developer, only once, before distribution. It's a simple step where the developer runs PyEmpaq indicating all needed info, and PyEmpaq will produce a single `\u003cprojectname\u003e.pyz` file. That's all, and that only file is what is needed for distribution.\n\nIn this packing phase, PyEmpaq builds the indicated packed file, putting inside:\n\n- the payload project, with all the indicated modules and binary files\n\n- an *unpacker* script from PyEmpaq, which will be run during the execution phase\n\n- few more stuff: some needed infrastructure details for the `.pyz` to run correctly\n\nAfter packing, the developer will distribute the packed file, final users will download/receive/get it, and execute it.\n\nIn the **execution phase** all that needs to be done by the final user is to run it using Python, which can be done from the command line (e.g. `python3 supergame.pyz`) or by doing double click from the file explorer in those systems that relate the `.pyz` extension to Python (e.g. Windows).\n\nIn this execution phase, the *unpacker* script put by PyEmpaq inside the packed file will be run, running the following steps:\n\n- check if the needed setup exists from a previous run; if yes, it will just run the payload project with almost no extra work; otherwise...\n\n- create a directory in the user data dir (or the indicated one, see below), and expand the `.pyz` file there\n\n- create a virtualenv in that new directory, and install all the payload's project dependencies\n\n- run the payload's project inside that virtualenv\n\nThe verification that the unpacker does to see if has a reusable setup from the past is based on the `.pyz` timestamp; if it changed (a new file was distributed), a new setup will be created and used.\n\nThe environment variable `PYEMPAQ_UNPACK_BASE_PATH` can be used to specify in which base directory PyEmpaq will unpack the different projects. If indicated, the path must exist and be a directory.\n\nPyEmpaq transparently returns the payload's exit code except when it must exit before the execution of the payload. In that case, it uses special codes equal or above 64, meaning:\n\n- `64`: `unpack-restrictions` are not met on the final user's system.\n- `65`: the indicated `PYEMPAQ_UNPACK_BASE_PATH` does not exist\n- `66`: the indicated `PYEMPAQ_UNPACK_BASE_PATH` is not a directory\n- `67`: the indicated `PYEMPAQ_ACTION` is not valid\n\n\n### Special Actions\n\nWhen running the packed project, some special actions can be indicated through the environment variable `PYEMPAQ_ACTION`. Note that if it is specified, the special action will take place and the packed program itself will **not** be run.\n\nCurrent special actions:\n\n- `info`: Show information about installations of the given project\n\n- `uninstall`: Remove all installations of the given project\n\n\n## Command Line Options\n\nThere is one mandatory parameter:\n\n- `source`: it needs to point the configuration file or to the directory where the configuration will be located (it will be searched by its default name `pyempaq.yaml`).\n\nExamples:\n\n- `pyempaq .`\n\n- `pyempaq /data/project/`\n\n- `pyempaq ~/repo/proj/config.yaml`\n\nYou can control verbosity by adding these command line parameters to control logging levels:\n\n- `-v, --verbose` - Show detailed information, typically of interest only when diagnosing problems.\n- `-q, --quiet` - Only events of WARNING level and above will be tracked.\n\nAll that said, there is an special option `-V, --version` (new in v0.3) that if used will just print the version and exit.\n\n\u003e **Note**\n\u003e In the **execution phase**, if you have an environment variable `PYEMPAQ_DEBUG=1` it will show the Pyempaq log lines during the execution.\n\n\n## The Configuration File\n\nAll the information that PyEmpaq needs to pack a project comes from a configuration file, which the developer would normally have in the project itself.\n\nThe following is the structure of the `pyempaq.yaml` configuration file:\n\n- `name` [mandatory]: the name of the project.\n\n- `basedir` [optional]: the project's base directory; if not included it defaults to where the configuration file is located.\n\n- `exec` [mandatory]: the section where is defined the information to execute the project once unpacked; it holds different subkeys (some subkeys are marked with †: ONE of those keys must be present, but only ONE):\n\n    - `script` [†]: the filepath of the python script to run; when unpacking PyEmpaq will do `python3 SCRIPT`.\n\n    - `module` [†]: the name of the module to invoke; when unpacking PyEmpaq will do `python3 -m MODULE`.\n\n    - `entrypoint` [†]: freeform, as a list of strings; when unpacking PyEmpaq will only insert the proper python3 at the beginning: `python3 STR1 STR2 ...`.\n\n    - `default-args` [optional]: the default arguments to be passed to the script/module/entrypoint (if not overridden when the distributed `.pyz` is executed).\n\n- `requirements` [optional]: a list of filepaths pointing to the requirement files with pip-installable dependencies.\n\n- `dependencies` [optional]: a list of strings to directly specify packages to be installed by `pip` without needing to have a requirement file.\n\n- `include` [optional, new in v0.3]: a list of strings, each one specifying a pattern to decide what files and directories to include in the pack (see below); if not included it defaults to `[\"./**\"]` which means all the files and directories in the project.\n\n- `exclude` [optional, new in v0.3]: a list of strings, each one specifying a pattern to decide what files and directories to exclude from the pack (see below).\n\n- `unpack-restrictions` [optional, new in v0.3]: a section to specify different restrictions to be verified/enforced during unpack.\n\n    - `minimum-python-version` [optional, new in v0.3]: a string specifying the minimum version possible to run correctly.\n\nAll specified filepaths must exist inside the project and must be relative (to the project's base directory), with the exception of `basedir` itself which can be absolute or relative (to the configuration file location).\n\nBoth `include` and `exclude` options use pattern matching according to the rules used by the Unix shell, using `*`, `?`, and character ranges expressed with `[]`. Also `**` will match any files and zero or more directories. For more information or subtleties check the [`glob.glob`](https://docs.python.org/dev/library/glob.html#glob.glob) documentation.\n\nNote that the final user may ignore/bypass any unpack restrictions using the `PYEMPAQ_IGNORE_RESTRICTIONS` environment variable with a value of comma-separated names of which restrictions to ignore.\n\nThe following are examples of different configuration files (which were the ones used to build the packed examples mentioned before):\n\n- [the terminal script](https://github.com/facundobatista/pyempaq/blob/main/examples/pyempaq-script.yaml?raw=True)\n\n- [the simple game](https://github.com/facundobatista/pyempaq/blob/main/examples/pyempaq-game.yaml?raw=True)\n\n- [the full desktop app](https://github.com/facundobatista/pyempaq/blob/main/examples/pyempaq-desktop-app.yaml?raw=True)\n\n\n## Context of the Project Being Run\n\nWhen the packed script/module/whatever is run in the unpacking phase, it will be executed inside the virtualenv with the needed requirements/dependencies (freshly created and installed or reused from a previous run).\n\nAlso, the following environment variable will be set:\n\n- `PYEMPAQ_PYZ_PATH`: the absolute path to the `.pyz` run by the user\n\n\n## How to Install PyEmpaq\n\nDirectly from PyPI:\n\n    pip install --user --upgrade --ignore-installed pyempaq\n\nIt's handy to install it using `pipx`, if you have it:\n\n    pipx install pyempaq\n\nIf you have `fades` you don't even need to install pyempaq, just run it:\n\n    fades -d pyempaq -x pyempaq\n\nIn the future there will be more ways to install it. Please open an issue if you desire an installation method (extra points if you specify how), thanks!\n\n\n## Try Packing an Example Project\n\nPyEmpaq sources come with a small example project if you want to play a little packing it. Just a couple of dir/files under `examples/srcproject`:\n\n- a `src` and `media`, with stuff to be imported and accessed.\n\n- a `pyempaq.yaml` with the configuration for PyEmpaq.\n\n- a `ep.py` file which is the project's entrypoint; all it does is to inform it started, import the internal module, access the media files, and use the declared dependency, reporting every step.\n\n- a `secrets.txt` file that must not be included in the packed file.\n\nThis explores most of the needs of any project. You can try this example, and surely after you will be ready to actually pack any other project you want.\n\nSo, let's pack the example source project. As you're working with the PyEmpaq project itself (as you're packing its example), you don't really need to have it installed yet. In that case, if you have `fades` installed is super easy:\n\n    fades -r requirements.txt -m pyempaq examples/srcproject/\n\nOtherwise, you would need to create and use a virtual environment:\n\n    python3 -m venv env\n    source env/bin/activate\n    pip install -r requirements\n    python3 -m pyempaq examples/srcproject/\n\nAfter running that command, you will see a `pyempaq-example.pyz` file. That is the **whole project encoded in a single file**.\n\nAt this point you may move that `pyempaq-example.pyz` to another directory, or to another machine, even that other machine having another operating system.\n\nThen, try it:\n\n    python3 pyempaq-example.pyz\n\nYou should see the project's reportings that we mentioned above (**note**: these lines will be surrounded by debug ones that will be hidden by default in the future):\n\n    Hello world\n    Code access ok .../pyempaq/projectname-20210722013526/orig/src/foo.py\n    Media access ok\n    Module requests imported .../pyempaq/projectname-20210722013526/venv/lib/python3.8/site-packages/requests/__init__.py\n\nThis shows that what you've run actually started, accessed the internal modules and other files, and imported correctly a custom-installed dependency.\n\n\n## How PyEmpaq Relates to Other Similar Tools?\n\nThere are other tools that are similar in their work. The more known are [Shiv](https://pypi.org/project/shiv/) and [Pex](https://pypi.org/project/pex/).\n\n**Shiv** would create a fully self-contained Python zip app with all their dependencies included, which means that it ships not only your project but also the dependencies! this makes the resulting .pyz NOT multiplatform (unless your project and ALL your dependencies are pure Python...).\n\nOn the other hand, PyEmpaq will create the virtualenv and install the needed dependencies the first time the .pyz is executed in the destination machine. This allows for example to pack a fully graphical desktop program that works with Qt, like the example shown above).\n\nA side detail of this is that we normally include dependencies in our programs, and those dependencies have sub-dependencies, etc. How sure are you that the whole set of dependencies and sub dependencies have a license that allows you to distribute them? Shiv will distribute them, PyEmpaq will not!\n\n**Pex** looks like it also includes the dependencies in the resulting file, but goes an extra mile pointing to the Python that was used to build the thing. So for example I built a .pex with Py3.10 and moved the file to a machine that has only 3.9, and it didn’t work, and both were Ubuntus! No multiplatform at all, no even mention to pack in Linux (once!) and run in Windows (or everywhere), as PyEmpaq allows to do.\n\nThese both tools are \"ahead of time\" dense (larger size) archives that include application code and dependencies for a single target platform. Hermetic and deterministic installation. Something that you would also get if you [snap](https://ubuntu.com/core/services/guide/snaps-intro) your project. \n\nOn the other hand PyEmpaq is a sparse (smaller size) archive. It only includes the application code and at first-run will create and install the rest into a virtualenv. A bit like using pipx to install an application, except without needing to teach the end-user about pipx. It’s self installing. Non-hermetic and non-deterministic installation, but may not matter in practice.\n\n\n## How to Contribute to the Project?\n\nPlease check [the how to contribute](https://github.com/facundobatista/pyempaq/blob/main/CONTRIBUTING.md) instructions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffacundobatista%2Fpyempaq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffacundobatista%2Fpyempaq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffacundobatista%2Fpyempaq/lists"}