Entry Points & Console Scripts
Entry points registram comandos CLI e hooks de plugin no momento da instalação. [project.scripts] cria comandos de console; [project.entry-points] habilita a descoberta de plugins.
Receita
[project.scripts]
myapp = "myapp.cli:main"
[project.entry-points."myapp.plugins"]
json = "myapp.plugins.json:JsonPlugin"Quando usar isso:
- Enviando uma CLI com seu pacote
- Construindo um sistema de plugins que outros pacotes estendem
- Registrando ferramentas descobertas por frameworks
Exemplo de Trabalho
[project]
name = "invoice-cli"
version = "0.1.0"
[project.scripts]
invoice = "invoice_cli.main:cli"
[project.entry-points."invoice.exporters"]
csv = "invoice_cli.exporters:CSVExporter"
pdf = "invoice_cli.exporters:PDFExporter"# src/invoice_cli/main.py
import click
from importlib.metadata import entry_points
@click.group()
def cli():
"""CLI de gerenciamento de faturas."""
pass
@cli.command()
@click.option("--format", default="csv")
def export(format: str):
eps = entry_points(group="invoice.exporters")
exporter = eps[format].load()
exporter().run()
def main():
cli()uv pip install -e .
invoice export --format csvO que isso demonstra:
project.scriptsinstala o comandoinvoiceno PATH- Grupos de entry points habilitam a descoberta de plugins via
importlib.metadata - Pacotes de terceiros podem adicionar exportadores registrando seus próprios entry points
clickoutyperlida com o parsing da CLI dentro demain
Mergulho Profundo
Tipos de Entry Points
| Tipo | Configuração | Resultado |
|---|---|---|
| Scripts de console | [project.scripts] | Executável em bin/ |
| Grupos de plugins | [project.entry-points."group"] | Descoberta via importlib |
| Scripts GUI | [project.gui-scripts] | Launcher GUI (raro) |
Armadilhas
- Entry point para não-chamável - a instalação é bem-sucedida, a execução falha. Correção: aponte para uma função, não para um módulo.
- Colisão de nome com CLI existente - sobrescreve comandos do usuário. Correção: nomes de comando únicos e com namespace.
- Carregar todos os plugins na importação - inicialização lenta. Correção: carregue os plugins de forma preguiçosa quando o subcomando for invocado.
- Falta de guarda
main()- ok para entry points, mas necessário parapython -m. Correção: adicioneif __name__ == "__main__"para execução de módulo. - Instalação editável não atualiza scripts - entry points desatualizados. Correção: reinstale após alterar a configuração do entry point.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
python -m myapp | Nenhuma instalação necessária | CLI global esperada |
| pipx | Instalação isolada de CLI | Combinação biblioteca + CLI |
| Wrapper de script shell | Deploy legado | Pacote multiplataforma |
FAQs
scripts vs entry-points?
scripts = comandos CLI. entry-points = grupos de descoberta de plugins.
Como testar entry points?
from importlib.metadata import entry_points; ep.load()() em pytest.
Terceiros podem adicionar plugins?
Sim. Eles registram entry points em seu pyproject.toml sob o nome do seu grupo.
Como o pipx usa entry points?
O pipx instala o pacote e expõe os console_scripts para um venv isolado no PATH.
Nomenclatura de script de console?
Use nomes curtos e únicos. invoice em vez de cli.
Entry points e uv?
uv respeita os entry points PEP 621 de forma idêntica ao pip.
Como listar entry points instalados?
importlib.metadata.entry_points(group="console_scripts").
Entry points dinâmicos?
Não é padrão. Plugins são registrados estaticamente em seus próprios pacotes.
Entry points legados do setuptools?
[project.entry-points] substitui [options.entry_points] em setup.cfg.
Múltiplos comandos CLI?
Múltiplas linhas em [project.scripts], uma por comando.
Relacionados
- Noções Básicas de CLI - Design de CLI
- Empacotamento e Distribuição de CLIs - Distribuição com pipx
- Noções Básicas de Empacotamento - construir e instalar
- Click - Framework de CLI
Versões das Pilhas: Esta página foi escrita para Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.