Execute scripts Python independentes com o Hatch#

O Python suporta metadata inline para scripts (um recurso adicionado em 2024). Isso torna possível executar scripts independentes com dependências e versões do Python gerenciadas automaticamente.

Muitas ferramentas suportam esse workflow, incluindo PDM, Hatch e uv. Neste tutorial, focamos no Hatch e no UV. O mesmo formato de metadata também pode ser usado com outras ferramentas.

Como criar um script reproduzível#

Às vezes você quer compartilhar ou executar um único script sem criar um pacote Python completo. Para isso, você pode usar metadata inline de script. Esse formato permite especificar dependências e versões do Python no topo do seu script em um bloco de comentários.

Quando você adiciona metadata no topo de um script, o Hatch (ou PDM ouuv) usará essa metadata para:

  • Criar um virtual environment Python isolado para esse script.

  • Instalar as dependências listadas no script nesse environment.

  • Usar a versão do Python exigida que você especificar na metadata.

Essa abordagem é útil para workflows que você quer tornar reproduzíveis, mas que não precisam se tornar pacote Pythons completos.

Por que usar o Hatch para scripts?#

Metadata inline ajuda você a tornar scripts reproduzíveis. Qualquer pessoa pode executar seu script sem criar manualmente um novo environment ou adivinhar quais dependências ele precisa. O Hatch cuidade instalar as dependências e usar a versão correta do Python.

Como adicionar metadata inline ao seu script#

Você usará o Hatch neste exemplo, mas também pode usar o uv se essa for sua ferramenta preferida.

Primeiro, crie um novo arquivo chamado script.py com o bloco abaixo no topo. O bloco de metadata começa com # /// script e termina com # ///. Tudo entre eles deve ser metadata TOML escrita como comentários.

No exemplo abaixo, o script requer Python 3.11 ou mais recente, e o NumPy é declarado como dependência.

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "numpy",
# ]
# ///

import numpy as np

temperatures_c = np.array([12.4, 13.1, 14.8, 15.2, 16.0, 14.4, 13.7])
mean_temp = np.mean(temperatures_c)
anomalies = temperatures_c - mean_temp

print(f"Mean temperature: {mean_temp:.2f} C")
print("Temperature anomalies:", np.round(anomalies, 2))

Executar o script com o Hatch#

Abra seu terminal e mude para o diretório onde script.py está. Em seguida, execute:

hatch run script.py

Na primeira execução, o Hatch criará um environment e instalará as dependências. Nas execuções seguintes, o Hatch reutilizará esse environment para que a inicialização seja mais rápida.

Nota

O nome do environment é baseado no caminho do script. Se você mover o script para um novo local, o Hatch o tratará como um novo script environment.

Opcional: configurar o comportamento do script environment#

Você pode controlar o comportamento específico do Hatch para scripts no mesmo bloco de metadata. Por exemplo, para usar pip em vez de uv como instalador:

# /// script
# requires-python = ">=3.11"
# dependencies = ["numpy"]
#
# [tool.hatch]
# installer = "pip"
# ///

Executar o mesmo script com uv

Se você preferir o uv, pode executar o mesmo script com metadata inline com:

uv run script.py

O mesmo bloco de metadata # /// script funciona com uv, incluindo requires-python e dependencies.

Para mais informações sobre como usar o uv para executar scripts, consulte o guia: Executando scripts com uv.

Quando usar scripts vs. pacotes#

Você pode estar se perguntando quando usar scripts em vez de criar um pacote.

Isso depende do seu caso de uso. Scripts costumam ser úteis quando:

  • Você tem uma tarefa pequena ou um workflow específico que não é generalizável.

  • Seu workflow ainda está evoluindo, mas você quer executá-lo em um environment reproduzível.

  • Você quer dependências reproduzíveis rapidamente.

  • Você está compartilhando um único arquivo com colaboradores.

Crie um pacote completo quando:

  • Você está construindo modules reutilizáveis para vários projetos.

  • Você precisa de testes, documentação, releases e manutenção de longo prazo.

  • Sua base de código está crescendo além de um ou dois scripts.