Skip to content
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

Add uv instructions #558

Open
TimMonko opened this issue Feb 3, 2025 · 9 comments
Open

Add uv instructions #558

TimMonko opened this issue Feb 3, 2025 · 9 comments
Labels
content Ideas for new or improved content

Comments

@TimMonko
Copy link
Contributor

TimMonko commented Feb 3, 2025

📚 New content request

Cross-posted in napari/napari#7573

With the recent increase in the popularity of uv, napari should make a concerted effort to offer installation instructions with uv. There are a multitude of ways to access napari with uv, but these have inconsistent behavior (at least on Windows). I'll detail especially why this needs documentated, but the usage pattern either results in surprising errors or differences from typical pip/conda usage. Despite this, uv is so incredibly fast and easy that I have found it much easier to recommend for colleagues to keep their napari up to date and they much prefer its speed (despite each time I have to figure something out different on each computer).

uv sync / uv lock / uv add

These are intended for using with projects, which is a very useful part of uv, but doesn't seem to work great out of the box with napari

  1. Without a uv lock file, this can be quite problematic. For example, on Windows: uv sync --extra all results in solving the wrong pyqt-qt5 which is an extreme pain to fix. message: error: Distribution pyqt5-qt5==5.15.16 @ registry+https://pypi.org/simple` can't be installed because it doesn't have a source distribution or wheel for the current platformCan be fixed byuv pip` installing in the
  2. Without a python pin, uv sync will by default attempt to use Py 3.13, which breaks. Also at least on Windows, 3.12 gives me a hassle, whereas 3.11 is fine.

uv pip

  1. This seems to be the easiest pattern to get up and working in an environment. But uv's documentation implies that this is not the preferred way for users to interact with uv for project management. It seems that for example uv pip install -e .[all] works very smoothly when just then using napari in the command line with that venvs parent. BUT this does not work well with the usual mamba activate env type pattern which is useful across projects. Ultimately, because of how fast uv is, there is likely a movement towards per-project installs, but this is not the pattern that will have been used by many napari users for a while.

uv run

  1. uv run napari will not succeed because there is no Qt install. Not solved with uv run napari --extra all or any equivalent. Error message tells user best guess is that napari was installed with pip (incorrect), so does not provide solution

uv tool install

  1. uv tool install napari[all] --upgrade -> uvx napari or uv tool run napari works. Closest functionality to a simple pip environment, BUT has the caveats of being a separated environment.
  2. uv tool install -e .[all] is a very handy way to quickly test a napari branch and use in editable mode, but has the problem of being a global tool, so not really useful for environment management

unclear what napari in the command line does after using uv. Does it use some root uv version of napari? is it only with uv added to path? I actually haven't figured this out yet myself

@psobolewskiPhD
Copy link
Member

In general I'm supportive.
I do think it's important to split this into user facing vs. contributor/dev facing.
For users, this would be a just a doc update in the installation guide:

  • Adding mention of uv pip where we currently use just pip would be fine.
  • We don't cover pipx anywhere, but we could consider adding uv tool install? My understanding is that like pipx it's an install in an isolated environment that is added to your path. (I think uvx does the same, but doesn't persist the env, so it's a one time run, not sure useful for napari.)
    Not sure how useful that is, but I guess as a viewer it would work -- does uv install pip so plugins would be installable via the GUI?

For contributors:

  • we could consider adding the project meta stuff to the napari/napari repo to make the project workflow work -- and the document it obviously. I don't have a strong opinion on this. An upside of this, if I understand it correctly, is we could check-in the lock files and use them instead of the existing constraints files. They'd work on CI and when locally developing when using uv.

In general, I'm of two minds about mamba, micromamba, uv, pixi. If you're already aware of them, then it's great to have the instructions. But otherwise, most intro Python things still use pip or conda, so then these "newfangled" "fancy" things cause cognitive load. Someone will have conda from one tutorial or plugin and uv from another and pixi from a workshop. Bleh.
I've already seen a situation where a user had 3 conda installs and 3 envs active at the same time!
Turns out they followed instructions to install anaconda, then later miniconda, and then a workshop wanted miniforge.
🤯

@Czaki
Copy link
Contributor

Czaki commented Feb 3, 2025

The uv tool run --with pyqt5 napari is working

@psobolewskiPhD
Copy link
Member

psobolewskiPhD commented Feb 3, 2025

@Czaki thanks! it's actually documented here:
https://docs.astral.sh/uv/guides/tools/#installing-tools

Thinking about it more based on the uv docs, I don't think we should encourage this tool pattern in our docs (so leave it to advanced uv users), because it's not installing any of the other optional dependencies. As we put more in all and optional this makes uv tool run --with pyqt5 napari less and less good.
Fine for a quick test or whatever, for a savvy person, but would be confusing for a new person.
We'd need to go with the napari-core route and then napari for napari[all].

to be clear, uv pip handles the optional dependencies just fine so we can definitely mention that.

@TimMonko
Copy link
Contributor Author

TimMonko commented Feb 4, 2025

In general, I'm of two minds about mamba, micromamba, uv, pixi. If you're already aware of them, then it's great to have the instructions. But otherwise, most intro Python things still use pip or conda, so then these "newfangled" "fancy" things cause cognitive load.

I think this is a very important point. Fortunately, most of the conda-variants still use conda so they are compatible. Like, if I set up someone an environment with mamba I tell them it's conda and so far everything works as expected 😉

But, for me, users (some that DESPISE the command line / code) that I've switched to uv from mamba find it so much easier and intuitive to upgrade. The problem is basically ... do I do the uv tool install version of napari (which is good because its system wide) or try to set up a base uv venv with napari in it (not ideal, and harder to write instructions for).

Fortunately, to answer one question, yes, napari installed as a tool does work with the plugin-manager, so it's basically just a super fast way to get someone set up with a pip-equivalent napari install

Thinking about it more based on the uv docs, I don't think we should encourage this tool pattern in our docs (so leave it to advanced uv users), because it's not installing any of the other optional dependencies.

I tend to agree with this, and hope it's the case. BUT, that uv tool install version I mentioned above is helpful in the case of 'I just want napari and I don't care about Python'. But, it's faster to set up and tear down than the bundled app, in case someone needs to be outside of that (or... they do need to do a little Python begrudgingly)

@psobolewskiPhD
Copy link
Member

psobolewskiPhD commented Feb 4, 2025

Yeah if you're setting up someone, then do what works for you since you will support them.
But when there are written instructions, that's where it can be overwhelming or result in people having multiple ways to do the same thing and just being confused eventually, even if things work now.

Anyhow bundle has the advantage of no pre-reqs. With uv tool you still need uv and the CLI.
That's why I think that having uv runnable examples (technically not a uv specific thing) is better than uv tool, but good that it works.

Edit: FYI as of conda 23.10, conda is mamba.

@TimMonko
Copy link
Contributor Author

TimMonko commented Feb 4, 2025

As an updated way for us to integrate this with a typical conda environment (I haven't tried this before, but maybe it's what I'll use with others going forward)

conda create -n uv-env  python=3.12
conda activate uv-env
pip install uv
uv pip install napari[all]

Note: pip install uv is not required if it's installed system wide. However, the python seems to be required to be installed with conda, it cannot be installed with uv

This is the speed of uv with a clean installation (I think these weren't cached)

(uv-env) C:\Users\timmo>uv pip install napari[all]
Using Python 3.12.8 environment at: mambaforge\envs\uv-env
Resolved 128 packages in 190ms
Installed 127 packages in 6.36s

Also to me one of the advantages of the tool install is that it only requires one CLI input of uvx napari and thus results in avoiding the common mistake of not activating the environment first

@jni
Copy link
Member

jni commented Feb 4, 2025

Edit: FYI as of conda 23.10, conda is mamba.

That's a bit of an exaggeration — as of that version, conda uses the libmamba solver by default, which mamba (a totally different package) used from the beginning.

This is the speed of uv with a clean installation (I think these weren't cached)

That's insane @TimMonko! Can you please verify about the cache thing?

Anyway, I totally know all the arguments in favour (these new tools are way faster and have made some nice new design decisions that they could do because they were not hamstrung by backwards compatibility) and against (mixing tools is an issue and indeed most folks will come from the most common tutorials, which are pip and conda based).

My proposed solution is that we keep pip and conda front and centre and we add an "advanced installation paths" page (name TBD) where we can go crazy with folks' preferred tools.

@psobolewskiPhD
Copy link
Member

psobolewskiPhD commented Feb 4, 2025

I hadn't thought of using uv in a conda env, I guess since it's a pip replacement it should work -- and it does.
Still, it seems a bit of an odd pattern to recommend?
Actually, i see uv is on conda-forge, so you could do a more elegant:
conda create -n uv-env python=3.12 uv

Anyhow, based on the uv docs, I'm not sure that's a pattern we should be recommending.
You can install python with uv:
https://docs.astral.sh/uv/guides/install-python/#getting-started

So I think if we opt to recommend uv we should follow their best practices and have the user install python with uv and use uv envs.

Edit: we have tabs for the user install instructions, so could add a from PyPI with uv tab.

(Re: mamba, my understanding is that mamba and conda are in fact now identical and mamba has been deprecated.)

@TimMonko
Copy link
Contributor Author

TimMonko commented Feb 4, 2025

That's insane @TimMonko! Can you please verify about the cache thing?

Reinstalling all packages, but I think this uses the cache (it 'refreshes' the cache, whatever that means) - takes about 4.7 seconds (with an IRL stopwatch, since some things overlap)

(uv-env) C:\Users\timmo>uv pip install napari[all] --reinstall
Using Python 3.12.8 environment at: mambaforge\envs\uv-env
Resolved 128 packages in 181ms
Prepared 128 packages in 15ms
Uninstalled 128 packages in 1.72s
Installed 128 packages in 1.80s

Without using the cache, it preps the whole env in ~38s.

(uv-env) C:\Users\timmo>uv pip install napari[all] --reinstall --no-cache
Using Python 3.12.8 environment at: mambaforge\envs\uv-env
Resolved 128 packages in 722ms
Prepared 128 packages in 37.20s
Uninstalled 128 packages in 1.79s
Installed 128 packages in 1.75s

Compared to pip with everything cached pip install napari[all] took 3m12s.

And then pip with no cache pip install napari[all] --no-cache-dir takes about 32s to install the packages (similar to uv) and then 2m45s to build (surprisingly similar times between pip cache and no cache lol)

So most of the time spent with uv is downloading (if no cache), otherwise environment builds super fast. Whereas with pip most of the time is spent building.

Mamba was 36s to find packages, 32s to download, and 39s to simultaneous extract packages (+7s from download), then 16s to build. HAHA I knew mamba/conda got much faster recently, but didn't realize it was much faster than pip...

For comparison these were all done in a different mamba=1.4.2 environment made with mamba create -n ___ python=3.12, so that it was the most direct comparison between all the tools. Theoretically, if download time was negligible (or packages already cached) installs would be uv~3s, pip~3m and mamba~50s. In other words, creating a uv env for each project actually seems feasible for every install, since it even uses a cached python -- so takes about 5s to build once computer is all set up. The disadvantage is the .venv does live locally in each project, but this can easily be deleted and then uv sync used again to set that project up. Nice for reproducibility, I suppose

Anyhow, based on the uv docs, I'm not sure that's a pattern we should be recommending. You can install python with uv: https://docs.astral.sh/uv/guides/install-python/#getting-started

So I think if we opt to recommend uv we should follow their best practices and have the user install python with uv and use uv envs.

I think you are right on this, which was my hope in getting this discussed. The uv python installs are fast and super easy to manage. You can also switch python version on-the-fly within a uv environment. So takes just a few seconds to rebuild an environment for testing something (tox-uv is also super fast for this reason too, I think @Czaki has more knowledge on this)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
content Ideas for new or improved content
Projects
None yet
Development

No branches or pull requests

4 participants