Run uv commands on Modal.com with GPU and direct file sync
Project description
modal-uv
Run uv commands on Modal.com with GPU support, direct file sync, async execution IDs, logs, abort, and persistent Modal volumes.
Installation
Option 1: Coding Agent (Recommended)
Paste this prompt to your coding agent (opencode, Claude Code, Gemini CLI, etc.):
Install modal-uv globally and set it up:
1. Run: pip install modal-uv
2. Run: modal-uv onboard
- This opens a browser for Modal OAuth authentication
- Complete the auth flow in the browser
- It also installs the use-modal-uv skill to detected coding agents
3. In the project repo, run: modal-uv init
- This creates modal-uv.yaml with defaults if missing
- It creates .modal-uv/ for generated state and adds it to .gitignore
4. Edit modal-uv.yaml to set app_name, gpu, and volume.name for this project
5. Run: modal-uv doctor
- This checks modal-uv health: auth state, volume existence, app deployment, daemon status
- Does not wake the container
Option 2: Manual Getting Started
pip install modal-uv
Authenticate with Modal (opens browser for OAuth):
modal-uv onboard
This also installs the use-modal-uv skill to detected coding agents (~/.config/opencode/, ~/.claude/, ~/.agents/).
In your project repo, initialize modal-uv files:
modal-uv init
This creates modal-uv.yaml with defaults (using the directory name as app_name) if missing, and creates .modal-uv/ for generated state with a .gitignore entry.
Edit modal-uv.yaml to configure your app:
app_name: "my-project"
gpu: "T4"
work_dir: "/tmp/work"
volumes:
- name: "modal-uv-cache"
mount_path: "/mnt/volume"
commit_interval_seconds: 30
env: {}
runtime:
scaledown_window_seconds: 300
image:
python_version: "3.12"
base_image: "python:3.12-slim"
sync:
ignore:
- "data/**"
- "*.ckpt"
Then run commands on Modal:
modal-uv run -- pytest
Repository Configuration
modal-uv.yaml at the repository root is discovered by walking up from the current directory, similar to git or uv.
Fields:
app_name: Modal app name (required)gpu: GPU type, such asT4,A10G,A100,H100, orL4work_dir: Working directory inside the Modal container (default:/root/work)volumes: Modal volumes to mount in the container; may be empty or omittedvolumes[].name: Modal volume namevolumes[].mount_path: Mount path in the container (default:/root/.cache)volumes[].commit_interval_seconds: Periodic Modal Volume commit interval while a command runs (default:30)env: Extra container environment variables merged over modal-uv defaultsruntime.scaledown_window_seconds: Modal worker scaledown window (default:300)runtime.exec: Optional shell executable formodal-uv exec; if omitted, the remote Worker uses$SHELL, then/bin/shimage.python_version: Python version (default:3.12)image.base_image: Base Docker image (default:python:3.12-slim)sync.ignore: gitignore-style patterns excluded from direct sync
Repo-Local State
modal-uv creates .modal-uv/ at the repo root for generated/runtime files and ensures the root .gitignore ignores it.
Examples of generated files:
.modal-uv/deployment.py.modal-uv/daemon.pid.modal-uv/daemon.sock.modal-uv/daemon.log
.modal-uv/ is not normally synced to the Modal work directory.
Sync And Deployment
modal-uv run and modal-uv exec scan local files, apply built-in ignores plus sync.ignore, ask the warm Modal container which files are missing or stale, upload only those files, spawn the execution, print the Modal function call ID, and return immediately.
The detached daemon lazily ensures the Modal app is deployed before running work. It generates .modal-uv/deployment.py and redeploys when the deployment fingerprint changes. The fingerprint includes the deployment template, Modal-relevant config values, and the repo pyproject.toml SHA256 when present.
During a running command, modal-uv periodically commits the Modal Volume every volume.commit_interval_seconds seconds, plus one final commit after the command exits. This persists outputs and checkpoints written under the mounted volume during long runs.
Ordinary source changes do not redeploy the app; they are handled by direct sync.
Modal authentication remains Modal's normal user-global authentication. modal-uv does not create repo-local auth files.
Commands
Run uv commands on Modal:
modal-uv run -- pytest
modal-uv run -- python -m lab
modal-uv run -- python train.py --epochs 10
Tail or abort a spawned execution:
modal-uv logs fc-...
modal-uv abort fc-...
Run shell-style commands in the synced Modal work directory:
modal-uv exec -- nvidia-smi
modal-uv exec -- 'ls -la && pwd'
Open Modal's native interactive shell through the passthrough command:
modal-uv modal -- shell
Show Modal app status:
modal-uv status
Check the configured Modal volume directly:
modal-uv modal -- volume ls modal-uv-cache
Initialize or align modal-uv files in the current directory:
modal-uv init
Run any Modal CLI command through the modal-uv environment:
modal-uv modal -- app list
modal-uv modal -- volume ls
Daemon helpers:
modal-uv daemon-status
modal-uv daemon-stop
Updates
Upgrade modal-uv and refresh the skill on all detected agents:
modal-uv update
Install the skill to a specific agent (opencode, claude, agents) or an explicit directory path:
modal-uv install-skill opencode
modal-uv install-skill /path/to/skills/dir
Detected agents are based on which config directories exist (~/.config/opencode/, ~/.claude/, ~/.agents/).
Use --config or -c to specify a custom config file:
modal-uv run --config path/to/modal-uv.yaml -- pytest
Checks
uv run ruff check .
uv run ruff format --check .
uv run pytest
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file modal_uv-0.2.2.tar.gz.
File metadata
- Download URL: modal_uv-0.2.2.tar.gz
- Upload date:
- Size: 135.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12fa3428b4aae47fc51af189d737610929704a15b17d35f53223449bb376d506
|
|
| MD5 |
40848443398fd6b40ae6dfe33135234f
|
|
| BLAKE2b-256 |
9f013e0219f5ec71e719d9f91b30e6a8a31c3392b055ed937e31a74f34d44a62
|
Provenance
The following attestation bundles were made for modal_uv-0.2.2.tar.gz:
Publisher:
release.yml on ofekby/modal-uv
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
modal_uv-0.2.2.tar.gz -
Subject digest:
12fa3428b4aae47fc51af189d737610929704a15b17d35f53223449bb376d506 - Sigstore transparency entry: 2132580023
- Sigstore integration time:
-
Permalink:
ofekby/modal-uv@18799ff2a2db2631939a943c697f5012b3b5f454 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ofekby
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@18799ff2a2db2631939a943c697f5012b3b5f454 -
Trigger Event:
push
-
Statement type:
File details
Details for the file modal_uv-0.2.2-py3-none-any.whl.
File metadata
- Download URL: modal_uv-0.2.2-py3-none-any.whl
- Upload date:
- Size: 25.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de337ff6fc5f6f65a5e756a372651a35c810176ced83181269eceae13348de76
|
|
| MD5 |
94d5d3a1a25fc37d6f139db6bab939b8
|
|
| BLAKE2b-256 |
6668ea04f65e4c57f4bfec5d1a80ea62f9174e3027aa23730591fae3cd1788de
|
Provenance
The following attestation bundles were made for modal_uv-0.2.2-py3-none-any.whl:
Publisher:
release.yml on ofekby/modal-uv
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
modal_uv-0.2.2-py3-none-any.whl -
Subject digest:
de337ff6fc5f6f65a5e756a372651a35c810176ced83181269eceae13348de76 - Sigstore transparency entry: 2132580173
- Sigstore integration time:
-
Permalink:
ofekby/modal-uv@18799ff2a2db2631939a943c697f5012b3b5f454 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ofekby
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@18799ff2a2db2631939a943c697f5012b3b5f454 -
Trigger Event:
push
-
Statement type: