-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Suggestion: uv bundle
, uv build --release
or similar to create a contained executable a la pyinstaller, py2exe
#5802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
uv bundle
or similar to create a contained executable a la pyinstaller, py2exeuv bundle
, uv build --release
or similar to create a contained executable a la pyinstaller, py2exe
Some relevant links that I'm adding to keep track of them for myself as much as anyone else:
|
To add… despite its popularity, |
Python to Rust transpilation would be pretty cool and there’s at least one project out there working on this: Imagine writing idiomatic Python, transpiling it to Rust and compiling a native executable. My mind would be blown. I don’t know how one could gracefully handle dependencies though. A lot of Python libs incorporate C extensions. Dealing with those would be extremely difficult, but there’s a DARPA program called TRACTOR working on that. |
An equivalent of (somewhat related: #5653) |
I want to give a mention to Nuitka which is serving me well. It's as straightforward as running
which spits out an executable. It's not really the right tool to be including with uv, it is essentially an alternate Python interpreter which compiles Python to C. But it's very easy to add and has worked well for me. And my experience with the developers has been very good. They were quick to add support for Rye when I encountered bugs - Nuitka/Nuitka#2933 |
@my1e5 why do you say that Nuitka would be unsuitable for inclusion with uv? |
@matterhorn103, I guess what I mean is that Nuitka is perhaps quite an opinionated way of packaging your Python code into an executable - as it is essentially an alternate Python interpreter which compiles Python to C. Whereas tools like Pyinstaller are more like a bundler - taking the Python interpreter, Python files and dependencies and packaging them into an executable. This is definitely more straightforward than the Nuitka approach, but it does make the Pyinstaller executable very easy to un-package and see the underlying source code (see https://github.com/extremecoders-re/pyinstxtractor). Which might be a caveat needed when including certain 'executable creators' within uv - you need to make users aware that their exe can easily be un-packaged. In terms of licensing, Nuitka is MIT licensed. But it does also have a commercial tier - which may or may not complicate matters if Astral were to want to bundle it with uv, I don't know. |
I think this is a duplicate of #2799, though there's more discussion here. |
Also want to call out pex, a tool for generating .pex files (Python EXecutable) which are self-contained zipped executable Python environments containing sources, requirements, and dependencies. |
I am interested in a solution like this. I think the bundler should be somewhat coupled with Example $ uv init --script foo.py
$ uv add requests --script foo.py
$ uv run foo.py
Hello from foo.py! Then you could make an executable which is composed of
$ uv bundle foo.py -o foo --include-uv --include-python --include-dependencies
$ ./foo
Hello from foo.py! This above would be a self contained binary (roughly 30MB as uv is ~12MB and python ~17MB). If downloading stuff on the fly is ok, the bootstrap code would just download uv, then uv would download python, install dependencies and run all during 1st execution. It should also be possible to create binaries cross platform since uv supports install/sync with $ uv bundle foo.py -o foo.exe --python-platform windows In a 2nd iteration, it would be nice to be have installers such as to create .dmg (mac) or an .exe windows installer file. |
what if the command was |
I love this idea and @jbvsmo proposal for CLI usage. I am a bit confused on the best choice for the bundling "backend" though, I see different options on the table and I'm not sure, how would you choose one over the other? Should maybe This feature would be great also for bundling pyspark apps (thinking about pex support mentioned by @martimlobao here) |
I think the bootstrap option mentioned by @jbvsmo is almost achievable with the existing uv options. You could do the following: Within your project folder have a script (written in the scrippting language supported by your operating system) that does the following:
Step 1 could of course be skipped, if the uv executable is already recognized within the specified subdir. And step 3-5 are basically what happens when you run uvx. So maybe this is actually a 2 line script. The great thing is that this script would be project independent! So someone just would need to write a script for each operating system and you could throw these scripts in your project folder. Then you just need to distribute this project folder and have people execute the script corresponding to their operating system. This process could then of course be wrapped further by an installer, but seems relatively straight forward to at least address the cases of "Please provide an exe". PS: If instead of creating a shell script to run the steps above, you use the darkmagic of cosmopolitan you could even create a single binary that dropped into a python package project anywhere makes it run by "double-clicking" the file. |
For me as a short term solution it would be enough to have For example I have done a program (as module) using PySide6.
With this solution I could distribute on Windows the files with "Inno Setup", adding |
As much as I like Pyinstaller (to me it's best of current options), one other thing that it suffers from is that anti-virus vendors are always flagging generic Pyinstaller binaries as malware. This is (at least in part, I think) because Pyinstaller uses the same bootloader binary for all built applications, thus if someone bundles malware with Pyinstaller version X, all other users who bundle legitimate applications using Pyinstaller X can get flagged as malware too. I've seen this hit AV software across both Windows and Linux over the years. Not sure I have any ideas on how Astral could improve that issue, but wanted to bring it up as a current (very annoying) real world challenge. |
It's not exactly the same thing, but I've suggested a relatively simple feature to Basically it would let |
Thanks for your request and for commenting here. For me the final tool would be a third party tool, part of uv (for Windows, uv.exe, uvx.exe and the new one, let's call it And that third tool should be Maybe we could get a simple tool and a complex one with all the hooks for the different packages. Maybe could also have different license models to allow Astral to capitalize the investment. But should be continued as a natural evolution of uv. But as a you say a wrapper of uvx would do it. Let's wait and see. |
Unfortunately https://github.com/indygreg/PyOxidizer only support Python up to 3.10 as specified in the latest stable documentation, except that it looks promising. Latest commit is two months old but you say it is not maintained again? |
I would also be interested in more direct support for using uv as an "installer" for python CLI tools. I've been using uv in novel ways for this purpose already. I recently wrote a bit about these approaches. Leaving the link here in case folks find it interesting or helpful: |
It will be useful if uv add |
It's worth noting that it looks like PyOxidizer has been taken over ty Astral-sh - in the form of python-build-standalone. So, this issue can likely be closed. |
No, we don't own PyOxidizer — we're just maintaining the standalone Python distributions. These ideas are separate. |
Interesting. That's not how I interpreted the blog post
But, it does explain why the releases seem to only contain python distributions. |
Yes we are the owners of |
This is a bit off topic, but I had a related discussion on discord about this topic and thought I would share A solution to MY problem that could be relevant to others. I feel that My problem statement: create a zipped folder with standalone python, standalone packages and their dependencies that I can distribute to other users ("download, unzip and run"). Non-goals: a single executable -- for me a folder containing lots of subdirectories/files is fine but an obvious "entry point" is desirable. Obviously the result will be OS and CPU type specific. Steps I followed:
The reason I like this solution is multifold (1) uses standard package installation methods (2) everything (?) is local to the folder (3) no e.g. pyinstaller-hooks-contrib to maintain. Are there downsides to this approach? Probably, but in my quick testing did not run across any issues -- it "just worked". This is contrast to my prior experiences with nuitka and pyinstaller which work perfectly for projects with pure python dependencies, but can require more "handholding" when that is not the case. Finally back to the topic of this post -- this would be very nice if supported by uv directly in some form. p.s. thanks to @geofft for their help |
The creator of the standalone python (Gregor Szorc) did it for his tool PyOxidizer. A rust substitute of pyinstaller or Nuitka. I am repeating when I can that Astral should take it and finish it. Gregor (indygreg) has no time and his work was really good. Just unfinished. But he did one of the biggest changes in python. The standalone python. Do not let his work disappear. |
@jdegenstein it sounds like you want to do |
(@jromal -- incase you haven't seen, we did assume stewardship of python-build-standalone: https://github.com/astral-sh/python-build-standalone) |
Since I originally created this issue it's been very popular, and it's also seen many comments offering suggestions. Naturally it is always a bit presumptuous to attempt to speak on behalf of a diverse and anonymous group, so maybe I'll be contradicted here, but I reckon that the vast majority of those who have voted for this issue or chimed in are united in hoping for something defined not by its technical implementation but by key behaviour – something that is:
This is essentially about being able to take a Python program on our machines and give it to non-programmers, right? It could be achieved with a variety of technical solutions, as shown by the slew of existing tools, and by people's contributions in this thread. I kind of want to clarify that while many people have been advocating for a wide variety of things, this issue as originally written wasn't advocating for a particular technical solution or requesting anything beyond that listed above. Going by past form, no doubt any (In the original post I suggested that maybe it would use |
@matterhorn103 FWIW, this is exactly my use case. I'm building a an "app" for non-programmers. I use uv with hatch to build the distributions. I have a custom hatch build script that kicks off pyinstaller to build the "executable". In my case, I'm using the "one_dir" option because along with the exectuable I have to ship various data files that are needed. One thing I ran into is that running pyinstaller standalone from the command line worked great. My custom build script that issued the same command line arguments was failing to find all the dependencies because of uv's build isolation. I had to set
and then it all worked well. Here's the snippets of relevant code. hatch_build.py
pyproject.toml
This should get you what want I think. |
@dbrtly Yes, that is correct -- in my experience with developing apps for new python users or python beginners as soon as the phrase "virtual environment" is uttered about half of the potential users will just give up (again my stated goal for my users is "download (my app), unzip and run"). Single executables are nice, as are installation wizards, but that introduces another layer of OS specific considerations that are not worth it for me (yet). |
It seems that you gave to draw the line somewhere and make an assumption about pre-requisites on the target machine: git? Is user local admin? Is the user sophisticated enough to use a cli tool at all? Is pyinstaller available? Is uv available? You could go a long way with something like this:
Am curious about what specific features you can see potential for uv to improve on for this user experience. |
I posted some ideas over in #11746 about what I think a
From my comment:
|
Summary of some of the ideas mentioned. The command names are flexible but I'm just using these for now to tell them apart 🙂
|
@chrisrodrigue I have done this for a proof-of-concept and, whilst clunky, it definitely does work. In fact, by repackaging its output into something like an RPM/DEB/Choco/pick-your-favourite-OS-package-manager -- or a self-extracting executable -- you end up with a passable (though non-optimised) |
Interesting, thanks @paveldikov. An open question I have about venvs… how can one install packages from one venv into another? AFAIK, there is no way to do this because you need wheels to do real installation into a venv. You could add the source environment to PATH and make new venvs with
These reasons are why I advocate for using wheels with layouts. However, venvs may be better for bundles since they compress better. The checksum of the bundle executable should be good enough for attestation. |
I tried running First, you will want
To grab wheels in lieu of
To grab the interpreter in lieu of
Configuring this I feel like a |
Sorry -- it's It will give you a known-good relocatable python site. You can then manipulate that as you please, e.g. by further relocating it to sit inside of a relocatable venv. And then manipulate p.s. and on posix, re-point the venv's |
To anyone who was looking into this option: I put together a recipe repository for bundling uv workspaces by compiling their dependencies using If you check it out, please let me know about any edge cases it does not accommodate! |
Nice. I'm using something similar in production. Hopefully pex would support uv.lock directly someday. |
Great ideas guys. I went with something similar on my project. |
Uh oh!
There was an error while loading. Please reload this page.
I regularly use pyinstaller for a project, and the frequency of questions about it - or the task more generally of "compiling" an executable for distribution - around the web indicates to me that it's widely popular.
It would be incredibly cool if uv offered a
uv bundle
command (or whatever name) that essentially did what pyinstaller does and bundles together everything to afford an executable that contains the dependencies and interpreter and can be distributed to users as-is. And I think this falls into the realm of what things a "Cargo for Python" might be expected to be able to do.I assume that pyinstaller, py2exe etc. are complex projects and implementing such functionality would be not trivial in the slightest, so I would have thought it would be a case of using
pyinstaller
itself in the background like the way that build backends are used.Presumably there will one day be a
uv build
command but I assume that will be similar torye build
in that it will create an sdist or wheel. Maybe there could be auv build --executable
option, oruv build --release
(by analogy tocargo build --release
)?The text was updated successfully, but these errors were encountered: