uv — Gerenciador rápido de pacotes e projetos Python
Visão geral
uv é um único binário da Astral que cobre todo o fluxo de trabalho Python: projetos com um arquivo de trava multiplataforma (uv.lock), scripts de arquivo único com dependências inline, ferramentas de linha de comando (uvx), instalação de interpretadores Python e uma interface uv pip substituta. Ele baixa o próprio Python quando necessário, então a máquina precisa apenas do uv.
Instruções
Instalação
# Gerenciadores de pacotes
pipx install uv
brew install uv
winget install --id=astral-sh.uv -e
A Astral também publica um instalador autônomo para máquinas sem gerenciador de pacotes; a página de instalação em https://docs.astral.sh/uv/getting-started/installation/ tem o comando atual e os checksums.
uv --version
uv self update # apenas instalador autônomo; caso contrário, atualize com o gerenciador de pacotes
Para fixar uma versão, coloque a versão na URL do instalador: https://astral.sh/uv/0.12.21/install.sh.
Criar um projeto
uv init dispatch-api # aplicativo empacotado: src/dispatch_api/, backend uv_build, script de console
uv init --no-package cron-jobs # layout plano com main.py e sem sistema de build
uv init --lib geo-utils # biblioteca com marcador py.typed
uv init --bare --python 3.12 # apenas pyproject.toml, no diretório atual
uv init também escreve .python-version, README.md, .gitignore e inicializa o git. --bare escreve apenas pyproject.toml, o que o torna a escolha certa dentro de um repositório existente.
Gerenciar dependências
uv add 'httpx>=0.27' 'pydantic>=2.7,<3' # dependências de runtime
uv add --dev pytest ruff # grupo dev, não enviado para produção
uv add --group docs mkdocs # qualquer grupo de dependência nomeado
uv add --optional postgres 'psycopg[binary]' # extra: pip install dispatch-api[postgres]
uv add -r requirements.txt # importar um arquivo requirements existente
uv remove httpx
uv lock --upgrade-package pydantic # atualizar um pacote dentro de suas restrições
uv lock --upgrade # atualizar tudo
uv tree --outdated --depth 1 # o que tem uma versão mais nova
O primeiro uv add cria .venv/ e uv.lock. Cada alteração atualiza pyproject.toml, o arquivo de trava e o ambiente juntos.
Executar e sincronizar
uv run pytest # trava e sincroniza se necessário, depois executa dentro de .venv
uv run python -m dispatch_api
uv run --with rich python -c "import rich" # um pacote extra apenas para este comando
uv sync # instala tudo, incluindo o grupo dev
uv sync --locked # CI: falha se uv.lock não corresponder a pyproject.toml
uv sync --frozen --no-dev # produção: usa uv.lock como está, pula o grupo dev
uv sync --extra postgres
uv lock --check # sai com código diferente de zero quando o arquivo de trava está desatualizado
Nenhuma ativação é necessária; uv run encontra o ambiente do projeto por si só.
Scripts com dependências inline
uv init --script fetch-rates.py --python 3.12
uv add --script fetch-rates.py 'httpx<1' rich
uv run fetch-rates.py
uv lock --script fetch-rates.py # escreve fetch-rates.py.lock para execuções reproduzíveis
uv add --script mantém um bloco de metadados no topo do arquivo:
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "httpx<1",
# "rich>=15.0.0",
# ]
# ///
Adicione #!/usr/bin/env -S uv run --script como primeira linha e chmod +x no arquivo para executá-lo diretamente.
Ferramentas
uvx ruff check . # executa sem instalar; uvx = uv tool run
uvx [email protected] check . # versão exata
uvx --from 'markitdown[pdf]' markitdown q3-board-report.pdf # nome do comando difere do pacote
uv tool install ruff # instalação permanente e isolada no PATH
uv tool upgrade --all
uv tool list
uv tool uninstall ruff
As ferramentas instaladas vão para o diretório impresso por uv tool dir --bin; uv avisa quando esse diretório não está no PATH.
Versões do Python
uv python install 3.12 3.13
uv python list --only-installed
uv python pin 3.12 # escreve .python-version
uv run --python 3.13 pytest # execução única em outro interpretador
uv python upgrade 3.12 # versão de patch mais recente do 3.12
uv venv --python 3.12 # ambiente virtual simples em .venv
Requisições aceitam 3.12, 3.12.3, >=3.11,<3.13, [email protected] e 3.13t (free-threaded). uv baixa automaticamente um interpretador ausente; passe --no-python-downloads para proibir isso.
Interface compatível com pip
uv venv
uv pip install -r requirements.txt
uv pip compile requirements.in -o requirements.txt --universal
uv pip sync requirements.txt # remove qualquer coisa não listada
uv pip install --python .venv/bin/python 'rich>=13'
CI e Docker
name: ci
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.12.21"
enable-cache: true
- run: uv python install
- run: uv sync --locked --all-extras --dev
- run: uv run pytest
FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:0.12.21 /uv /uvx /bin/
WORKDIR /app
ENV UV_NO_DEV=1 UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
# Dependências primeiro, para que esta camada seja reutilizada até que uv.lock mude
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --locked --no-install-project
COPY . /app
RUN --mount=type=cache,target=/root/.cache/uv uv sync --locked
ENV PATH="/app/.venv/bin:$PATH"
CMD ["python", "-m", "dispatch_api"]
Adicione .venv ao .dockerignore; um ambiente do host não funciona dentro da imagem.
Exemplos
Exemplo 1: Migrar um serviço com requirements.txt para um projeto uv com trava
Solicitação: "Nosso repositório dispatch-api tem requirements.txt e requirements-dev.txt. Migre para uv com um arquivo de trava e faça os testes funcionarem."
cd dispatch-api
uv init --bare --python 3.12
uv python pin 3.12
uv add -r requirements.txt
sed '/^-r /d' requirements-dev.txt | uv add --dev -r -
uv run python -m pytest -q
uv run ruff check .
Resultado: pyproject.toml lista os cinco pacotes de runtime e um grupo dev, uv.lock trava 30 pacotes e as verificações passam. Saída resumida:
Initialized project `dispatch-api`
Pinned `.python-version` to `3.12`
+ uvicorn==0.34.0
+ pytest==8.3.4
+ ruff==0.8.6
1 passed, 1 warning in 0.12s
All checks passed!
Exemplo 2: Um script autossuficiente
Solicitação: "Escreva um script de relatório de uso de disco que eu possa copiar para qualquer servidor e executar sem configurar um ambiente."
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["rich>=13"]
# ///
import shutil
from rich.console import Console
from rich.table import Table
usage = shutil.disk_usage("/")
table = Table(title="Uso de disco")
table.add_column("Total GB")
table.add_column("Livre GB")
table.add_row(f"{usage.total / 1e9:.0f}", f"{usage.free / 1e9:.0f}")
Console().print(table)
chmod +x disk-report.py
./disk-report.py
Resultado: uv constrói um ambiente em cache com rich na primeira execução e imprime a tabela; execuções posteriores iniciam imediatamente.
Uso de disco
┏━━━━━━━━━━┳━━━━━━━━━┓
┃ Total GB ┃ Livre GB ┃
┡━━━━━━━━━━╇━━━━━━━━━┩
│ 3936 │ 2211 │
└──────────┴─────────┘
Diretrizes
- Faça commit de
uv.locke.python-version. Nunca editeuv.lockmanualmente; alterepyproject.tomlou useuv add,uv removeeuv lock. --lockedou--frozen:--lockedverifica o arquivo de trava e falha quando está desatualizado, o que é adequado para CI.--frozenpula a verificação e instala exatamente o que o arquivo diz.uv syncé exato,uv runnão é.uv syncremove pacotes que não estão no arquivo de trava, incluindo qualquer coisa adicionada comuv pip install.uv runapenas adiciona o que está faltando.uv pipescolhe seu alvo por descoberta: oVIRTUAL_ENVativo, depois.venvno diretório atual ou no pai mais próximo. Execute da pasta errada e ele instalará no ambiente de outra pessoa. Em scripts, passe--pythoncom o caminho do ambiente.- Projetos planos e pytest: com
--bareou--no-package, o próprio projeto não é instalado, entãouv run pytestpode falhar comModuleNotFoundError. Useuv run python -m pytest, ou definapythonpath = ["."]em[tool.pytest.ini_options]. uv initpadrão para layout empacotadosrc/. Passe--no-packagepara um projeto estilo script commain.py.- Comandos experimentais:
uv format,uv checkeuv auditimprimem um aviso de que podem mudar. Não construa pipelines neles ainda. - Índices privados: declare-os em
[[tool.uv.index]]e passe credenciais através de variáveis de ambiente nomeadas após o índice: para um índice chamadointernal,UV_INDEX_INTERNAL_USERNAMEeUV_INDEX_INTERNAL_PASSWORD. Nunca os commite. A estratégia padrãofirst-indexprotege contra confusão de dependências; eviteunsafe-best-match. - Cadeia de suprimentos:
uv run,uvxe scripts com metadados inline baixam e executam pacotes. Revise a lista de dependências de qualquer script de uma fonte não confiável antes de executá-lo. uv self updatefunciona apenas para instalações feitas com o instalador autônomo.- Cache CI: execute
uv cache prune --ciantes de salvar o cache para mantê-lo pequeno. - Quando NÃO usar: uv instala de índices de pacotes Python, git e caminhos locais. Ele não instala pacotes conda ou bibliotecas do sistema, então mantenha conda para stacks que dependem deles.