astral-sh / uv

An extremely fast Python package and project manager, written in Rust.
https://docs.astral.sh/uv
Apache License 2.0
19.86k stars 584 forks source link

Consider adding documentation on using `uv ...` to use a `.venv` in Jupyter notebooks #6329

Open prrao87 opened 3 weeks ago

prrao87 commented 3 weeks ago

Thank you for all the amazing updates!

I've successfully migrated my project workflows over to use uv python and uv run, and this works great. As a user who (sometimes) has to use Jupyter notebooks, I find it a little hard to understand how I can use uv to manage Python versions and virtual environments that are accessible from within the Jupyter notebook.

I did see that it's possible to use uv tool to achieve this in some form, but it's not clear to me how this would work. https://github.com/astral-sh/uv/issues/4994#issuecomment-2241813473

When I run the command uv tool run --from jupyter-core --with jupyter jupyter notebook, indeed it does open a Jupyter notebook, but it's not clear if I can open a new notebook that's able to use the local virtual environment in that directory or the dependencies specified in uv.lock.

Could there be a documentation section added that explains how users can access a uv virtual environment and/or uv.lock from within a Jupyter notebook?

baggiponte commented 3 weeks ago

Uhm, that's a good question. I think it might be a bit tough since exposing a venv to jupyter requires ipykernel in the venv and running a specific ipykernel command [to create the kernel].

But on twitter there was this reply and Charlie saying that "@konstin has wanted to do this forever".

prrao87 commented 3 weeks ago

That's exactly the tweet I wanted to see, thanks for pointing it out! I hope this feature is considered, as this is, for me, is the FINAL step in completely leaving pyenv, poetry and pip and forever using uv in all my workflows. I think this is true for > 90% of users, too. 😎

bluss commented 3 weeks ago

Mentioning this, because it hits pretty close to the issue..

I've worked on https://bluss.github.io/pyproject-local-kernel/ which basically is that support, using Uv (or Rye, or others) to define dependencies per notebook project. It's made specifically for JupyterLab (works same way in Jupyter Notebook).

By default when you run JupyterLab (or jupyter notebook), it runs a bundled ipykernel which has access to exactly the dependencies installed together with jupyter. You'll need to do something extra to change this.

If you run jupyterlab with pyproject-local-kernel:

uvx --with pyproject-local-kernel --from jupyterlab jupyter-lab

Then you have support for using uv projects to define notebook dependencies.

This is something that works for me/my team, we it's easy to check out notebooks from git and have separate directories (projects) with separate dependencies. There are other ways to do it:

(1) uvx has the same bug/problem with jupyterlab that was already gracefully fixed for uv run, which is that uvx dies on Ctrl-C and leaves jupyterlab running in the background. (now, of course fixed :sunglasses: )

prrao87 commented 3 weeks ago

Thanks @bluss for the ideas. Just in case anybody else stumbles across this thread, I did the following and it worked for me using Jupyter Lab:

# Start project which generates .venv
uv init
# Add a sample library
uv add requests
# Add ipykernel to work with notebooks
uv add ipykernel
# Install kernelspec for the current .venv
uv run ipython kernel install --user --name=uv_test
# Run Jupyter Lab and open a new notebook using the newly created kernel `uv_test`
uvx --from jupyter-core --with jupyter jupyter lab

Then, I test that my requests module import works in the notebook, and it does:

import requests

That's a lot of steps to keep in mind, so I hope that a) this is documented somewhere, as this isn't intuitive for a lot of people, and b) the idea from the tweet linked above is implemented and that uv handles a lot of this burden for the user. All in all, so happy we've finally reached this stage in Python packaging! 🎉

bluss commented 3 weeks ago

@prrao87 if you don't like to install pyproject-local-kernel (or others), the following kernelspec here might be fun to install - however I share this for fun and learning, and I would actually recommend installing a dedicated python package instead of hacking around with kernelspecs.. (That said: the python package could be one with just this exact kernelspec! The reason you want to use packages is for reproducible environments, uv style!)

https://bluss.github.io/pyproject-local-kernel/FAQ/#isnt-there-a-less-complicated-way-to-do-it

lacker commented 1 week ago

For others running into this thread, to get a uv environment working inside VSCode:

uv add ipykernel
uv run ipython kernel install --user --name=uv

Then - important step - restart VSCode. Then your jupyter notebooks will have a button at the upper right to select a kernel, choose "jupyter kernel", then "uv" will be one of the selections.

bluss commented 1 week ago

@lacker If you don't mind, I would suggest the following for VS Code and VSCodium specifically:

# Create a new notebook project
# and open the directory in code
uv init my-notebook
cd my-notebook
uv add ipykernel
code .

image

Run this in the notebook to verify that the expected virtualenv is being used.

import sys
sys.executable

It will respond with a path such as /home/user/my-notebook/.venv/bin/python or similar.

You can now run commands such as !uv add pandas etc in the notebook to add more dependencies to the project.

I prefer this way - without registering kernelspecs - because it's easier to work with, also collaboratively, and scales better to many notebook projects. Let me know what you think. Code also supports using pure python formats such as py:percent for jupyter notebooks, which are another nice way to improve collaborative work, using git etc, with jupyter.

lacker commented 1 week ago

In my situation I didn't want to open a new project just for this notebook, I had an existing (non-python) project that I wanted to run the notebook inside. But, I see that you can open from the venv directly rather than doing uv run ipython kernel install. You do have to restart VSCode to pick up the venv after you create the venv! (That's what I missed originally.) So, yeah I like your recommendation of opening from the venv better than creating the kernelspec.

araichev commented 3 days ago

So is there a way yet to run a Jupyter notebook within the UV project's virtual environment from the command line (and without VS Code)? I use Jupyter notebooks for data pipelines within my Python projects, and this is the one missing feature stopping me from switching from Poetry to UV.

zanieb commented 3 days ago

@araichev How do you do it with Poetry?

araichev commented 3 days ago

I don't actually do it with Poetry but with Poetry (to manage the project's dependencies) + Virtualenvwrapper (to manage project's virtual environment).

# At start of project
> mkdir PROJECT_DIR
> cd PROJECT_DIR
> mkvirtualenv -p3.11 PROJECT_VENV
> poetry add jupyter geopandas
> jupyter notebook

# Can now use GeoPandas inside notebook

# Revisiting project after start
> cd PROJECT_DIR
> workon PROJECT_VENV
> poetry add lets_plot
> jupyter notebook

# Can now use GeoPandas and Lets-Plot inside notebook

If UV could do this by itself without Virtualenvwrapper, then i'd be sold.

baggiponte commented 2 days ago

I don't actually do it with Poetry but with Poetry (to manage the project's dependencies) + Virtualenvwrapper (to manage project's virtual environment).

# At start of project
> mkdir PROJECT_DIR
> cd PROJECT_DIR
> mkvirtualenv -p3.11 PROJECT_VENV
> poetry add jupyter geopandas
> jupyter notebook

# Can now use GeoPandas inside notebook

# Revisiting project after start
> cd PROJECT_DIR
> workon PROJECT_VENV
> poetry add lets_plot
> jupyter notebook

# Can now use GeoPandas and Lets-Plot inside notebook

If UV could do this by itself without Virtualenvwrapper, then i'd be sold.

Yes, I do this everytime. EDIT: you don't need virtualenvwrapper, but neither you do with poetry. If you do poetry/uv add jupyter you should just run poetry/uv run jupyter to run the jupyter in the venv.

The thread is about something different: running jupyter without having it installed in the venv.

araichev commented 2 days ago

Oops, my bad. Thanks for the clarification @baggiponte . I wasn't able to get uv run jupyter notebook to work a few weeks ago, but today, after upgrading to UV version 0.4.8, it works. Hooray!