18 pontos por darjeeling 2025-11-09 | 1 comentários | Compartilhar no WhatsApp

Resumo do gerenciamento de um monorepo Python com UV Workspaces

Este vídeo apresenta como resolver de forma elegante os problemas que surgem ao gerenciar vários aplicativos Python (monorepo) em um único repositório Git usando o recurso UV Workspaces.

1. Resumo do vídeo

Problemas

Ao desenvolver ao mesmo tempo uma ferramenta de CLI e um app FastAPI dentro de um único repositório, surgem problemas como estes:

  • Duplicação de código: é preciso copiar e colar funcionalidades usadas em comum pela CLI e pela API, como uma função de crawling de manchetes.
  • Gerenciamento complexo de ambientes: como cada app precisa de seu próprio ambiente virtual, podem ocorrer conflitos de versão entre dependências e desperdício de espaço em disco.

Solução: UV Workspaces

O UV Workspaces oferece dois recursos centrais para resolver esses problemas.

  1. Dependências compartilhadas e um único ambiente virtual

    • É possível definir dependências comuns no arquivo pyproject.toml localizado na raiz do projeto.
    • Ao executar o comando uv sync, o UV lê esse arquivo de configuração e cria na pasta raiz um único ambiente virtual (.venv) compartilhado por todo o repositório.
    • Com isso, todos os subprojetos (CLI, API etc.) passam a compartilhar o mesmo ambiente e as mesmas dependências, evitando conflitos de versão e facilitando a manutenção.
  2. Compartilhamento de código por meio de pacotes internos

    • O código comum duplicado, como a função fetch_headlines, pode ser separado em um "pacote interno" próprio, como core.
    • Pela configuração do workspace, esse pacote core passa a ser reconhecido como uma fonte local, e não do PyPI.
    • Assim, o app CLI e o app API podem reutilizar esse código comum com import, como em from core.news import fetch_headlines.

2. Como usar UV Workspaces

Etapa 1: configurar o workspace

Crie um arquivo pyproject.toml na pasta raiz do projeto e defina a seção [tool.uv.workspace] para informar onde estão os subprojetos.

[tool.uv.workspace]  
# Reconhece todas as subpastas dentro de "packages" como membros do workspace  
members = ["packages/*"]  

Etapa 2: gerenciar dependências

  • Dependências compartilhadas: dependências usadas em comum por todos os projetos, como python-dotenv, devem ser adicionadas ao pyproject.toml da raiz.
  • Dependências individuais: dependências usadas apenas por um app específico, como fastapi e uvicorn no app api, devem ser adicionadas ao pyproject.toml desse app (por exemplo, packages/api/pyproject.toml).
  • Ao executar uv sync na pasta raiz, o UV faz a varredura de todos os pyproject.toml e instala no ambiente virtual da raiz todas as dependências necessárias.

Etapa 3: compartilhar código com um pacote interno

  1. Crie um novo pacote (pasta) para o código compartilhado, como packages/core.
  2. Adicione esse pacote ao pyproject.toml da raiz como se fosse uma dependência comum.
  3. Adicione a seção [tool.uv.sources] ao pyproject.toml da raiz para configurar que o pacote core deve ser buscado dentro do workspace, e não no PyPI.
<!-- end list -->
[project]  
# 1. Adiciona o pacote interno como dependência  
dependencies = [  
    "core",  
    "python-dotenv"  
]  
  
# 2. Indica que 'core' é um pacote local do workspace  
[tool.uv.sources]  
core = { workspace = true }  
  1. Execute uv sync novamente para instalar o pacote core a partir da fonte local.
  2. Agora, em packages/api ou packages/cli, é possível importar o código comum com a sintaxe from core.news import ....

Etapa 4: executar os projetos

Para executar um projeto específico, use uv run --from <nome-do-pacote>.

# Executa o servidor API  
uv run --from packages/api uvicorn main:app --reload  
  
# Executa a ferramenta CLI  
uv run --from packages/cli python main.py  

3. Para quem é recomendado

  • Ao gerenciar, em um único repositório, vários scripts pequenos de automação, webhooks, APIs, CLIs etc.
  • É especialmente útil quando esses aplicativos compartilham lógica ou dependências em comum.
  • Por outro lado, pode não ser a melhor opção para gerenciar um script único, um pacote a ser distribuído de forma independente no PyPI ou apps totalmente sem relação entre si.

Link do vídeo original: https://www.youtube.com/watch?v=N_ypJwV8Q8I

1 comentários

 
pcj9024 2025-11-10

Parece bastante com o pnpm.