This release adds support for generating lockfiles from Jupyter notebooks using inline metadata, as defined in PEP 723.
By default, notebooks remain unlocked. To lock a notebook, run juv lock /path/to/notebook.ipynb
,
which generates and embeds a lockfile in the notebook's metadata under the
"uv.lock"
key. The lockfile is respected and updated automatically when using
juv run
, uv add
, or uv remove
.
Additional commands:
juv export
: Outputs an alternative lockfile format (requirements.txt style) to stdout.uv tree
: Displays the dependency tree for a script.
Both commands work with notebooks, whether locked or unlocked.
This release is considered breaking due to the lockfile support, which
requires a minimum uv
0.5.18 and modifies execution.
- Add
--clear
flag tolock
to clear lockfile metadata (#69) - Add
export
command (#70) - Add
lock
command (#64) - Add
tree
command (#68) - Sync lockfile during
add
command (#65) - Sync lockfile during
remove
command (#66)
- Require at least one package for
add
andremove
(#73) - Support relative paths in the
run
command (#72)
This release adds juv remove
to remove packages from a notebook or script.
Dependencies are removed from the PEP-723 inline metadata. The command follows
uv's semantics. See the uv
docs for more information.
uvx juv init
uvx juv add Untitled.ipynb 'numpy>=1.0.0' 'polars' # adds 'numpy>=1.0.0' 'polars'
uvx juv remove Untitled.ipynb numpy # removes 'numpy>=1.0.0'
- Add
remove
command (#59)
- Force UTF-8 encoding when reading/writing text (#56)
- Use TemporaryDirectoryIgnoreErrors in replacement template (#57)
- Support windows with
juv run
(#54)
This release adds --pin
flag to juv add
to have package specifiers resolved to an exact version at the time of the command, and subsequently pinned in the notebook/script.
uvx juv init
uvx juv add Untitled.ipynb 'numpy>=1.0.0' 'polars' # adds 'numpy>=1' 'polars'
uvx juv add Untitled.ipynb numpy polars --pin # adds 'numpy==2.1.3' 'polars==1.13.1'
This same behavior can be achieved without juv for regular scripts with a unix pipe:
echo 'numpy\npolars' | uv pip compile --no-deps - | grep '==' | xargs uv add --script foo.py
But alternatively you can use juv add
for the same thing:
uv init --script foo.py
uvx juv add foo.py numpy polars --pin
uv
supports time-based dependency resolution via exclude-newer
,
allowing packages to be resolved as they existed at a specific moment in time.
This feature greatly enhances the reproducibility of one-off scripts and notebooks without needing a lockfile.
However, exclude-newer
requires a full RFC 3339 timestamp (e.g., 2020-03-05T00:00:00-05:00), which can be tedious to manage manually.
This release introduces juv stamp
, a command that provides a high-level,
ergonomic API for pinning and unpinning various relevant timestamps in both
standalone Python scripts and Jupyter notebooks:
# Stamp a notebook
juv init foo.ipynb
juv stamp foo.ipynb
# Stamp with a specific time
juv stamp foo.ipynb --time "2020-03-05T00:00:00-05:00"
juv stamp foo.ipynb --date 2022-01-03
# Use Git revisions
juv stamp foo.ipynb --rev e20c99
juv stamp foo.ipynb --latest
# Clear the pinned timestamp
juv stamp foo.ipynb --clear
# For Python scripts
uv init --script foo.py
uv add --script foo.py polars anywidget
uvx juv stamp foo.py
- Add
juv stamp
for time-based dependency resolution pinning (#50)
- Clear widgets metadata in
clear
(#49)
- Upgrade uv to v0.5.0 (#47)
- Add
--pager
flag forjuv cat
(#45)
- Refactor environment vars to also accept flags (#46)
- Add
--check
flag forjuv clear
(#44)
- Use managed temp dir for
JUPYTER_DATA_DIR
(#43)
- Change directories prior to running uv (#41)
This release adds some nice cli flags to juv add
for configuring various kinds of dependency sources:
Include "extra" dependency groups with --extra
:
juv add Untitled.ipynb --extra dev anywidget # adds `anywidget[dev]`
Treat a local source as editable with --editable
:
juv add Untitled.ipynb --editable ./path/to/packages
Add a git source at a specific revision (i.e., commit), tag, or branch:
juv add Untitled.ipynb git+https://github.com/encode/httpx --tag 0.27.0
juv add Untitled.ipynb git+https://github.com/encode/httpx --branch master
juv add Untitled.ipynb git+https://github.com/encode/httpx --rev 326b9431c761e1ef1e00b9f760d1f654c8db48c6
- Support
--editable
sources foradd
(#39) - Support
add --extra
(#38) - Support git sources with
add
(#40) - Add help information for command line flags (#40)
- Support forwarding flags to underlying Jupyter front end (#35)
- Replace
cat --format
withcat --script
(#33) - Include
id
metadata for markdown editing for better diffing (#34)
- Fix so that cells are diffed by longest (#32)
- Strip content for editor (#27)
- Allow specifying directories for
clear
(#22)
- Add
clear
command (#20)
- Add
--output-format
flag forversion
command (#18)
- Add new empty cell to new notebooks (#15)
- Add PyPI shield to README (#14)
- Switch to click CLI (#6)
- Add
--with
flag to init (#8) - Add
add
/init
commands (#2) - Add managed run mode via
JUV_RUN_MODE=managed
env (#9) - Make nicer CLI output text (#5)
- Use jupytext for creating notebooks (#1)
- Support Python 3.8 and test on ubuntu (#11)