{"id":35077582,"url":"https://github.com/chingc/tutorial-uv","last_synced_at":"2026-04-04T06:07:34.417Z","repository":{"id":290118443,"uuid":"973420130","full_name":"chingc/tutorial-uv","owner":"chingc","description":"A quickstart and reference for uv to help you get up and running fast.","archived":false,"fork":false,"pushed_at":"2025-06-01T21:00:01.000Z","size":6,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-29T03:23:03.105Z","etag":null,"topics":["documentation","python","quickstart","readme","reference","tutorial","uv"],"latest_commit_sha":null,"homepage":"https://docs.astral.sh/uv","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chingc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-27T00:24:17.000Z","updated_at":"2025-06-01T21:00:05.000Z","dependencies_parsed_at":"2025-06-01T22:18:46.668Z","dependency_job_id":null,"html_url":"https://github.com/chingc/tutorial-uv","commit_stats":null,"previous_names":["chingc/tutorial-uv"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/chingc/tutorial-uv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chingc%2Ftutorial-uv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chingc%2Ftutorial-uv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chingc%2Ftutorial-uv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chingc%2Ftutorial-uv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chingc","download_url":"https://codeload.github.com/chingc/tutorial-uv/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chingc%2Ftutorial-uv/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31389407,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T04:26:24.776Z","status":"ssl_error","status_checked_at":"2026-04-04T04:23:34.147Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["documentation","python","quickstart","readme","reference","tutorial","uv"],"created_at":"2025-12-27T12:24:13.102Z","updated_at":"2026-04-04T06:07:34.412Z","avatar_url":"https://github.com/chingc.png","language":null,"readme":"# uv\n\nManaging Python environments doesn't have to be hard. A lot of the manual and error prone processes can be handled automatically with the right tool.\n\nThis tutorial introduces uv. An extremely fast and popular Python package and project manager. A single tool to replace `pip`, `pip-tools`, `pipx`, `poetry`, `pyenv`, `twine`, `virtualenv`, and more. It can even install and manage Python versions.\n\n## Install\n\nWith homebrew:\n\n```bash\n$ brew install uv\n```\n\nClick [here](https://docs.astral.sh/uv/getting-started/installation/) for other installation methods.\n\nTo verify the installation, run `uv` and you should see a help menu listing available commands.\n\n\u003e [!NOTE]\n\u003e Use homebrew to upgrade or uninstall uv.\n\n## Managing Python Versions\n\nPython does not need to be explicitly installed to use uv. By default, uv will automatically download Python versions when they are required. Even if a specific Python version is not requested, uv will download the latest version on demand.\n\nFor example, if there are no Python versions on your system, the following will install Python before creating a new virtual environment:\n\n```bash\n$ uv venv\n```\n\nIf Python is already installed on your system, uv will detect and use it without configuration. You can also install and manage specific Python versions.\n\n```bash\n# Install the latest version\n$ uv python install\n\n# Install a specific version\n$ uv python install 3.12\n\n# Install multiple versions\n$ uv python install 3.11 3.12\n\n# Install an alternative implementation\n$ uv python install pypy@3.11\n```\n\n\u003e [!NOTE]\n\u003e Python does not publish official distributable binaries. As such, uv uses distributions from the Astral [python-build-standalone](https://github.com/astral-sh/python-build-standalone) project. See the [Python distributions](https://docs.astral.sh/uv/concepts/python-versions/#managed-python-distributions) documentation for more details.\n\nTo reinstall uv-managed Python versions, use `--reinstall`:\n\n```bash\n$ uv python install --reinstall\n```\n\nThis will reinstall all previously installed Python versions. Improvements are constantly being added to the Python distributions, so reinstalling may resolve bugs even if the Python version does not change.\n\nTo uninstall uv-managed Python versions:\n\n```bash\n$ uv python uninstall 3.11\n```\n\nTo view available and installed Python versions:\n\n```bash\n$ uv python list\n```\n\nA specific Python version can be requested with the `--python` flag in most uv commands. For example, when creating a virtual environment:\n\n```bash\n$ uv venv --python 3.13.3\n```\n\nIf you have a specific Python version you'd like to use as the default, the `.python-version` file is helpful. It can be created with the `uv python pin` command:\n\n```bash\n# Created in the user configuration directory\n$ uv python pin --global 3.13.3\n\n# Created in the current working directory\n$ uv python pin pypy@3.11\n```\n\n## Running Scripts\n\nBefore we talk about Python projects, let's quickly go over scripts. A Python script is a file intended for standalone execution (e.g. `python \u003cscript\u003e.py`).\n\nIf your script has no dependencies, or depends on modules in the standard library, you can execute it with `uv run` with nothing more to think about:\n\n```python\n# example.py\nimport os\nprint(os.path.expanduser(\"~\"))\n```\n\n```bash\n$ uv run example.py\n/Users/python-enjoyer\n```\n\nNote that if you use `uv run` in a project (a directory with a `pyproject.toml`), it will install the current project before running the script. If your script does not depend on the project, use the `--no-project` flag to skip this:\n\n```bash\n$ uv run --no-project example.py\n```\n\n\u003e [!NOTE]\n\u003e The `--no-project` flag is part of uv and not the script, so it must be specified before the script name.\n\nIf your script has dependencies it's recommended to create a project or use Python's new format for inline metadata. Inline metadata allows dependencies for a script to be declared in the script itself.\n\n```bash\n# Initialize a script with inline metadata\n$ uv init --script example.py --python 3.12\n\n# Add dependencies to a script\n$ uv add --script example.py 'requests\u003c3' 'rich'\n```\n\n```python\n# example.py\n\n# /// script\n# requires-python = \"\u003e=3.12\"\n# dependencies = [\n#   \"requests\u003c3\",\n#   \"rich\",\n# ]\n# ///\n\nimport requests\nfrom rich.pretty import pprint\n\nresp = requests.get(\"https://peps.python.org/api/peps.json\")\ndata = resp.json()\npprint([(k, v[\"title\"]) for k, v in data.items()][:10])\n```\n\n\u003e [!IMPORTANT]\n\u003e Scripts that declare inline metadata are automatically executed in environments isolated from the project. Only the dependencies listed in the script are available. The `--no-project` flag is not required.\n\nA shebang can be added to make a script executable without using `uv run`:\n\n```bash\n#!/usr/bin/env -S uv run --script\nprint(\"Hello, world!\")\n```\n\nEnsure the script is executable (`chmod +x greet`) then run the script:\n\n```bash\n$ ./greet\nHello, world!\n```\n\n## Project Initialization\n\nYou can initialize a brand new project:\n\n```bash\n$ uv init example\n$ cd example\n```\n\nOr, initialize an existing project:\n\n```bash\n$ cd example\n$ uv init\n```\n\nThis will create the following files:\n\n```\n.\n├── .python-version\n├── README.md\n├── main.py\n└── pyproject.toml\n```\n\nThe `main.py` file contains a simple \"Hello world\" program. Try it with `uv run`:\n\n```bash\n$ uv run main.py\nHello from example!\n```\n\nYou'll notice the project structure will now look like this:\n\n```\n.\n├── .python-version\n├── .venv\n├── README.md\n├── main.py\n├── pyproject.toml\n└── uv.lock\n```\n\nExcept for `.venv`, all of this should be checked into version control.\n\n### .python-version\n\nThe project's default Python version. This file tells uv which Python version to use when creating the project's virtual environment.\n\n### .venv\n\nThe .venv folder contains your project's virtual environment, a Python environment that is isolated from the rest of your system. This is where uv will install your project's dependencies.\n\nNotice how uv created this for you automatically. Very nice!\n\n### README.md\n\nThe project's README file.\n\n### main.py\n\nContains a simple \"Hello world\" program.\n\n### pyproject.toml\n\nContains metadata about your project. Use this file to specify dependencies, as well as details about the project such as its description or license. You can edit this file manually, or use commands like `uv add` and `uv remove`.\n\nYou'll also use this file to specify uv configuration options in a `[tool.uv]` section.\n\n### uv.lock\n\nA cross-platform lockfile that contains exact information about your project's dependencies. It's a human-readable TOML file, but it's managed by uv and shouldn't be edited manually.\n\n## Project Dependencies\n\nAdd or remove dependencies with `uv add` and `uv remove`. This will update `pyproject.toml`, `uv.lock`, and the project environment.\n\n```bash\n# Add a dependency\n$ uv add requests\n\n# Specify a version constraint\n$ uv add 'requests==2.30.0'\n\n# To update a version constraint\n$ uv add 'requests==2.31.0'\n\n# Add a git dependency (--tag, --branch, or --rev can be used for version constraint)\n$ uv add git+https://github.com/psf/requests\n\n# Migrating from requirements.txt\n$ uv add -r requirements.txt -c constraints.txt\n\n# Remove a dependency\n$ uv remove requests\n```\n\nTo see the dependency tree for your project:\n\n```bash\n$ uv tree\n```\n\nUse `uv lock` to upgrade a package:\n\n```bash\n# Upgrade to the latest version\n$ uv lock --upgrade-package requests\n\n# Upgrade to a specific version\n$ uv lock --upgrade-package 'requests==2.32.3'\n\n# Upgrade all packages:\n$ uv lock --upgrade\n```\n\nVersion constraints are respected when upgrading.\n\n\u003e [!TIP]\n\u003e Instead of upgrading a package, update its version constraint.\n\n### \"It works on my machine.\"\n\n\u003e [!CAUTION]\n\u003e It's important to understand how we end up here.\n\nWhen considering if the lockfile is up-to-date, uv will check if it matches the project metadata. For example, if you add a dependency to your `pyproject.toml`, the lockfile will be considered outdated. Similarly, if you change the version constraints for a dependency such that the locked version is excluded by the constraint, the lockfile will be considered outdated. However, if you change the version constraints such that the existing locked version is still within the constraint, the lockfile will still be considered up-to-date.\n\nThe last case is important.\n\nThis means, if you have `requests\u003e=2.32.3` as a version constraint, uv will not consider the lockfile outdated when a new version is released. The lockfile needs to be explicitly updated if you want to upgrade the dependency.\n\nIf you have lots of developers and systems, you could easily be in a situation where some machines are running `2.32.3` and some machines are running a newer version.\n\n\u003e [!TIP]\n\u003e \"It works on my machine\" can be very difficult to troubleshoot. Use the `==` version constraint to avoid this problem and maintain consistency across all systems.\n\n## Project Commands\n\nUse `uv run` to run arbitrary scripts or commands in your project environment.\n\nPrior to every `uv run` invocation, uv will verify that the lockfile is up-to-date and the environment is up-to-date with the lockfile, keeping your project synced without the need for manual intervention. `uv run` guarantees your command is run in a consistent and locked environment.\n\nFor example, to use flask:\n\n```bash\n$ uv add flask\n$ uv run -- flask run -p 3000\n```\n\n\u003e [!NOTE]\n\u003e The `--` is shell syntax that separates the main command (`uv`) from the subcommand (`flask`). This is helpful if the subcommand has its own flags and arguments.\n\nOr, to run a script:\n\n```bash\n$ uv run example.py\n```\n\nTo run commands without `uv run` you need to manually sync and activate the environment:\n\n```bash\n$ uv sync\n$ source .venv/bin/activate\n$ flask run -p 3000\n$ python example.py\n```\n\nThis involves more steps, and activation can differ per shell and platform. It is error prone and should be avoided.\n\n## Using Tools\n\nMany Python packages provide applications that can be used as tools. You can use `uvx` to easily run tools without the need to install them:\n\n```bash\n$ uvx pycowsay hello from uv\n\n  -------------\n\u003c hello from uv \u003e\n  -------------\n   \\   ^__^\n    \\  (oo)\\_______\n       (__)\\       )\\/\\\n           ||----w |\n           ||     ||\n```\n\nTools are installed into temporary isolated environments when using `uvx`.\n\n\u003e [!NOTE]\n\u003e `uvx` is an alias for convenience. The above is equivalent to `uv tool run pycowsay hello from uv`.\n\nIf a tool is used often, it's useful to install it to a persistent environment and add it to the `PATH` instead of invoking `uvx` repeatedly.\n\n```bash\n# Install a tool\n$ uv tool install ruff\n\n# It should now be available\n$ ruff --version\n\n# Upgrade a tool\n$ uv tool upgrade ruff\n\n# Upgrade all tools\n$ uv tool upgrade --all\n\n# List tools\n$ uv tool list\n\n# Uninstall a tool\n$ uv tool uninstall ruff\n```\n\n## Caching\n\nuv uses aggressive caching to avoid re-downloading (and re-building) dependencies that have already been accessed in prior runs.\n\nIf you're running into issues you think is related to the cache, uv includes a few escape hatches:\n\n- To force uv to revalidate cached data for all dependencies, pass `--refresh` to any command (e.g. `uv sync --refresh`).\n- To force uv to revalidate cached data for a specific dependency, pass `--refresh-package` to any command (e.g. `uv sync --refresh-package flask`).\n- To force uv to ignore existing installed versions, pass `--reinstall` to any installation command (e.g. `uv sync --reinstall`).\n\nYou can also remove entries from the cache:\n\n- `uv cache clean` removes all cache entries from the cache directory, clearing it out entirely.\n- `uv cache clean ruff` removes all cache entries for the `ruff` package, useful for invalidating the cache for one or more set of packages.\n- `uv cache prune` removes all unused cache entries. For example, the cache directory may contain entries created in previous uv versions that are no longer necessary and can be safely removed.\n\n## Locking and Syncing\n\nLocking and syncing are important concepts that deserve clarification and reiteration.\n\nLocking is the process of resolving your project's dependencies (specified in `pyproject.toml`) into a lockfile. Syncing is the process of installing packages from the lockfile into the project environment.\n\nBoth are automatic in uv. For example, when `uv run` is used, the project is locked and synced before invoking the requested command. This ensures the project environment is always up-to-date.\n\nThe lockfile can be manually created or updated with `uv lock`. Likewise, the environment can be manually synced with `uv sync`.\n\n## GitHub Actions\n\nFor GitHub Actions, use the official [setup-uv](https://github.com/astral-sh/setup-uv) action. It installs uv, adds it to `PATH`, (optionally) persists the cache, and more, with support for all uv-supported platforms.\n\n```\n- uses: astral-sh/setup-uv@v6\n  with:\n    enable-cache: true\n```\n\nYou can now use uv on GitHub Actions as you would locally.\n\n\u003e [!NOTE]\n\u003e The action will warn if the workdir is empty, because this is usually the case when `actions/checkout` is configured to run after `setup-uv`.\n\nCheckout first, or you can ignore this by setting the `ignore-empty-workdir` input to `true`.\n\n```\n- uses: astral-sh/setup-uv@v6\n  with:\n    ignore-empty-workdir: true\n```\n\n\u003e [!TIP]\n\u003e You want to make each step of your GitHub Actions workflow as simple as possible to easily identify points of failure. This includes installation of dependencies.\n\nUse `uv sync` to install dependencies and `--locked` to ensure the lockfile is up-to-date. If the lockfile is missing or outdated, uv will exit with an error.\n\n```\n- name: Install dependencies\n  run: uv sync --locked\n```\n\nCheck out this sample workflow: [basic_uv.yml](https://github.com/chingc/tutorial-github-actions/blob/main/.github/workflows/basic_uv.yml)\n\n### Dependabot\n\nThe dependabot [package-ecosystem](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#package-ecosystem-) has support for uv.\n\nSome use cases are not yet fully supported. See [astral-sh/uv#2512](https://github.com/astral-sh/uv/issues/2512) for updates.\n\n## References\n\n- [uv](https://docs.astral.sh/uv/)\n- [uv: Guides](https://docs.astral.sh/uv/guides/)\n- [uv: Python versions](https://docs.astral.sh/uv/concepts/python-versions/)\n- [uv: Managing dependencies](https://docs.astral.sh/uv/concepts/projects/dependencies/)\n- [uv: Running commands in projects](https://docs.astral.sh/uv/concepts/projects/run/)\n- [uv: Tools](https://docs.astral.sh/uv/concepts/tools/)\n- [uv: Caching](https://docs.astral.sh/uv/concepts/cache/)\n- [uv: Locking and syncing](https://docs.astral.sh/uv/concepts/projects/sync/)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchingc%2Ftutorial-uv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchingc%2Ftutorial-uv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchingc%2Ftutorial-uv/lists"}