python-pypi-package-builder

Par github · awesome-copilot

Compétence de bout en bout pour construire, tester, linter, versionner et publier une bibliothèque Python de niveau production sur PyPI. Couvre les quatre backends de build (setuptools+setuptools_scm, hatchling, flit, poetry), le versionnage PEP 440, le versionnage sémantique, le versionnage dynamique par git-tag, la conception OOP/SOLID, les annotations de type (PEP 484/526/544/561), le Trusted Publishing (OIDC) et le flux de packaging PyPA complet. À utiliser pour : créer des packages Python, des SDK installables via pip, des outils CLI, des plugins de framework, la configuration de pyproject.toml, py.typed, setuptools_scm, semver, mypy, pre-commit, la CI/CD GitHub Actions ou la publication sur PyPI.

npx skills add https://github.com/github/awesome-copilot --skill python-pypi-package-builder

Skill de création de paquets Python PyPI

Un guide complet et éprouvé pour construire, tester, linter, versioner, typer et publier une bibliothèque Python de qualité production sur PyPI — du premier commit à la version prête pour la communauté.

Instruction pour agent IA : Lisez ce fichier entièrement avant d'écrire une seule ligne de code ou de créer un fichier quelconque. Chaque décision — mise en page, backend, stratégie de versioning, patterns, CI — possède une règle de décision ici. Suivez les arbres de décision dans l'ordre. Ce skill s'applique à tout type de paquet Python (utilitaire, SDK, CLI, plugin, bibliothèque de données). Ne sautez pas de sections.


Navigation rapide

Section de ce fichier Ce qu'elle couvre
1. Déclencheur du skill Quand charger ce skill
2. Décision sur le type de paquet Identifier ce que vous construisez
3. Décision sur la structure de dossiers src/ vs plat vs monorepo
4. Décision sur le backend de build setuptools / hatchling / flit / poetry
5. Flux d'empaquetage PyPA Le pipeline de publication canonique
6. Templates de structure de projet Mises en page complètes pour chaque option
7. Stratégie de versioning PEP 440, semver, dynamique vs statique
Fichier de référence Ce qu'il couvre
references/pyproject-toml.md Tous les quatre templates de backend, setuptools_scm, py.typed, configs d'outils
references/library-patterns.md OOP/SOLID, type hints, conception de classe principale, factory, protocols, CLI
references/testing-quality.md conftest.py, tests unitaires/backend/async, ruff/mypy/pre-commit
references/ci-publishing.md ci.yml, publish.yml, Trusted Publishing, TestPyPI, CHANGELOG, checklist de release
references/community-docs.md README, docstrings, CONTRIBUTING, SECURITY, anti-patterns, master checklist
references/architecture-patterns.md Système backend (plugin/strategy), couche de config, couche de transport, CLI, injection de backend
references/versioning-strategy.md PEP 440, SemVer, pre-release, setuptools_scm deep-dive, flit statique, moteur de décision
references/release-governance.md Stratégie de branche, protection de branche, OIDC, validation d'auteur de tag, prévention de tags invalides
references/tooling-ruff.md Setup Ruff uniquement (remplace black/isort), config mypy, pre-commit, asyncio_mode=auto

Script de scaffold : exécutez python skills/python-pypi-package-builder/scripts/scaffold.py --name your-package-name pour générer l'intégralité de la mise en page de répertoires, des fichiers stub, et pyproject.toml en une seule commande.


1. Déclencheur du skill

Chargez ce skill chaque fois que l'utilisateur souhaite :

  • Créer, faire du scaffold, ou publier un paquet ou une bibliothèque Python sur PyPI
  • Construire un SDK installable via pip, un utilitaire, un outil CLI, ou une extension de framework
  • Configurer pyproject.toml, linting, mypy, pre-commit, ou GitHub Actions pour un projet Python
  • Comprendre le versioning (setuptools_scm, PEP 440, semver, versioning statique)
  • Comprendre les specs PyPA : py.typed, MANIFEST.in, RECORD, classifiers
  • Publier sur PyPI en utilisant Trusted Publishing (OIDC) ou des tokens API
  • Refactoriser un paquet existant pour suivre les standards modernes d'empaquetage Python
  • Ajouter des type hints, protocols, ABCs, ou dataclasses à une bibliothèque Python
  • Appliquer des patterns de design OOP/SOLID à un paquet Python
  • Choisir entre les backends de build (setuptools, hatchling, flit, poetry)

Déclenchez aussi pour les phrases comme : "créer un SDK Python", "publier ma bibliothèque", "configurer PyPI CI", "créer un paquet pip", "comment publier sur PyPI", "aide pyproject.toml", "PEP 561 typed", "version setuptools_scm", "semver Python", "PEP 440", "git tag release", "Trusted Publishing".


2. Décision sur le type de paquet

Identifiez ce que l'utilisateur construit avant d'écrire du code. Chaque type possède des patterns distincts.

Tableau de décision

Type Pattern fondamental Point d'entrée Dépendances clés Paquets exemples
Bibliothèque utilitaire Module de fonctions pures + helpers API d'import uniquement Minimal arrow, humanize, boltons, more-itertools
Client API / SDK Classe avec méthodes, authentification, logique de retry API d'import uniquement httpx ou requests boto3, stripe-python, openai
Outil CLI Fonctions de commande + analyseur d'arguments [project.scripts] ou [project.entry-points] click ou typer black, ruff, httpie, rich
Plugin framework Classe de plugin, enregistrement de hook [project.entry-points."framework.plugin"] Dépendance de framework pytest-*, django-*, flask-*
Bibliothèque de traitement de données Classes + pipeline fonctionnel API d'import uniquement Optionnel : numpy, pandas pydantic, marshmallow, cerberus
Mixte / générique Combinaison des options ci-dessus Varie Varie Beaucoup de paquets réels

Règle de décision : Posez la question à l'utilisateur si ce n'est pas clair. Un paquet peut combiner des types (par ex., SDK avec un point d'entrée CLI) — utilisez le type principal pour les décisions structurelles et ajoutez les patterns de type secondaire par-dessus.

Pour les patterns d'implémentation de chaque type, voir references/library-patterns.md.

Règles de nommage de paquet

  • Nom PyPI : tout en minuscules, tirets — my-python-library
  • Nom d'import Python : underscores — my_python_library
  • Vérifier la disponibilité : https://pypi.org/search/ avant de commencer
  • Évitez de masquer les paquets populaires (vérifiez que pip install <name> échoue d'abord)

3. Décision sur la structure de dossiers

Arbre de décision

Le paquet a-t-il 5+ modules internes OU plusieurs contributeurs OU des sous-paquets complexes?
├── OUI → Utilisez la mise en page src/
│         Raison : empêche l'import accidentel de code non installé pendant le développement;
│         sépare la source des fichiers racine du projet ; recommandé par PyPA pour les grands projets.
│
├── NON → Est-ce un paquet à module unique et ciblé (par ex., un fichier + helpers)?
│         ├── OUI → Utilisez la mise en page plat
│         └── NON (complexité moyenne) → Utilisez la mise en page plat, migrez vers src/ s'il grandit
│
└── Est-ce plusieurs paquets associés sous un namespace (par ex., myorg.http, myorg.db)?
          └── OUI → Utilisez la mise en page namespace/monorepo

Résumé de règle rapide

Situation Utilisez
Nouveau projet, taille future inconnue Mise en page src/ (défaut le plus sûr)
Paquet à usage unique, 1–4 modules Mise en page plat
Grande bibliothèque, nombreux contributeurs Mise en page src/
Plusieurs paquets dans un repo Namespace / monorepo
Migration d'ancien projet plat Gardez plat ; migrez vers src/ à la prochaine version majeure

4. Décision sur le backend de build

Arbre de décision

L'utilisateur a-t-il besoin d'une version dérivée automatiquement des tags git?
├── OUI → Utilisez setuptools + setuptools_scm
│         (git tag v1.0.0 → c'EST votre workflow de release)
│
└── NON → L'utilisateur veut-il un outil tout-en-un (dépendances + build + publish)?
          ├── OUI → Utilisez poetry (v2+ supporte la table [project] standard)
          │
          └── NON → Le paquet est-il du Python pur sans extensions C?
                    ├── OUI, config minimale préférée → Utilisez flit
                    │   (config zéro, détecte auto la version depuis __version__)
                    │
                    └── OUI, moderne & rapide préféré → Utilisez hatchling
                        (config zéro, système de plugins, pas de setup.py requis)

Le paquet a-t-il des extensions C/Cython/Fortran?
└── OUI → DOIT utiliser setuptools (seul backend avec support complet des extensions natives)

Comparaison des backends

Backend Source de version Config Extensions C Meilleur pour
setuptools + setuptools_scm Tags git (automatique) pyproject.toml + shim setup.py optionnel Oui Projets avec releases par tag git ; toute complexité
hatchling Manuel ou plugin pyproject.toml uniquement Non Nouveaux projets pure-Python ; rapide, moderne
flit __version__ dans __init__.py pyproject.toml uniquement Non Paquets très simples, mono-module
poetry Champ pyproject.toml pyproject.toml uniquement Non Équipes voulant une gestion de dépendances intégrée

Pour tous les quatre templates pyproject.toml complets, voir references/pyproject-toml.md.


5. Flux d'empaquetage PyPA

C'est le flux canonique de bout en bout de code source à installation utilisateur. Chaque étape doit être comprise avant de publier.

1. ARBRE SOURCE
   Votre code en contrôle de version (git)
   └── pyproject.toml décrit les métadonnées + système de build

2. BUILD
   python -m build
   └── Produit deux artefacts dans dist/:
       ├── *.tar.gz   → source distribution (sdist)
       └── *.whl      → built distribution (wheel) — préféré par pip

3. VALIDER
   twine check dist/*
   └── Vérifie les métadonnées, rendu README, compatibilité PyPI

4. TESTER PUBLIER (première release seulement)
   twine upload --repository testpypi dist/*
   └── Vérifier: pip install --index-url https://test.pypi.org/simple/ your-package

5. PUBLIER
   twine upload dist/*          ← fallback manuel
   OU GitHub Actions publish.yml  ← recommandé (Trusted Publishing / OIDC)

6. INSTALLATION UTILISATEUR
   pip install your-package
   pip install "your-package[extra]"

Concepts clés PyPA

Concept Ce que cela signifie
sdist Source distribution — votre source + métadonnées ; utilisé quand aucun wheel n'est disponible
wheel (.whl) Binary pré-construit — pip l'extrait directement dans site-packages ; pas d'étape de build
PEP 517/518 Interface standard du système de build via la table [build-system] de pyproject.toml
PEP 621 Table [project] standard dans pyproject.toml ; tous les backends modernes la supportent
PEP 639 Clé license comme chaîne SPDX (par ex., "MIT", "Apache-2.0") — pas {text = "MIT"}
PEP 561 Fichier marqueur py.typed vide — indique à mypy/IDEs que ce paquet livre des informations de type

Pour le workflow CI complet et la configuration de publishing, voir references/ci-publishing.md.


6. Templates de structure de projet

A. Mise en page src/ (Défaut recommandé pour les nouveaux projets)

your-package/
├── src/
│   └── your_package/
│       ├── __init__.py           # API publique : __all__, __version__
│       ├── py.typed              # Marqueur PEP 561 — FICHIER VIDE
│       ├── core.py               # Implémentation principale
│       ├── client.py             # (Type client API) ou supprimer
│       ├── cli.py                # (Type CLI) commandes click/typer, ou supprimer
│       ├── config.py             # Settings / dataclass configuration
│       ├── exceptions.py         # Hiérarchie des exceptions custom
│       ├── models.py             # Data classes, modèles Pydantic, TypedDicts
│       ├── utils.py              # Helpers internes (préfixe _utils si privé)
│       ├── types.py              # Alias de type partagés et TypeVars
│       └── backends/             # (Pattern plugin) — supprimer si non nécessaire
│           ├── __init__.py       # Définition d'interface Protocol / ABC
│           ├── memory.py         # Implémentation par défaut sans dépendance
│           └── redis.py          # Implémentation optionnelle lourde
├── tests/
│   ├── __init__.py
│   ├── conftest.py               # Fixtures partagées
│   ├── unit/
│   │   ├── __init__.py
│   │   ├── test_core.py
│   │   ├── test_config.py
│   │   └── test_models.py
│   ├── integration/
│   │   ├── __init__.py
│   │   └── test_backends.py
│   └── e2e/                      # Optionnel : tests de bout en bout
│       └── __init__.py
├── docs/                         # Optionnel : mkdocs ou sphinx
├── scripts/
│   └── scaffold.py
├── .github/
│   ├── workflows/
│   │   ├── ci.yml
│   │   └── publish.yml
│   └── ISSUE_TEMPLATE/
│       ├── bug_report.md
│       └── feature_request.md
├── .pre-commit-config.yaml
├── pyproject.toml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── SECURITY.md
├── LICENSE
├── README.md
└── .gitignore

B. Mise en page plat (Paquets petits / ciblés)

your-package/
├── your_package/         # ← à la racine, pas dans src/
│   ├── __init__.py
│   ├── py.typed
│   └── ... (même structure interne)
├── tests/
└── ... (mêmes fichiers de haut niveau)

C. Mise en page namespace / monorepo (Plusieurs paquets associés)

your-org/
├── packages/
│   ├── your-org-core/
│   │   ├── src/your_org/core/
│   │   └── pyproject.toml
│   ├── your-org-http/
│   │   ├── src/your_org/http/
│   │   └── pyproject.toml
│   └── your-org-cli/
│       ├── src/your_org/cli/
│       └── pyproject.toml
├── .github/workflows/
└── README.md

Chaque sous-paquet a son propre pyproject.toml. Ils partagent le namespace your_org via les paquets namespace implicites PEP 420 (pas __init__.py à la racine du namespace).

Directives de module interne

Fichier Objectif Quand l'inclure
__init__.py Surface API publique ; ré-exports ; __version__ Toujours
py.typed Marqueur paquet typé PEP 561 (vide) Toujours
core.py Classe principale / logique principale Toujours
config.py Dataclass Settings ou modèle Pydantic Quand configurable
exceptions.py Hiérarchie d'exceptions (YourBaseError → spécifiques) Toujours
models.py Modèles de données / DTOs / TypedDicts Quand data-heavy
utils.py Helpers internes (pas part de l'API publique) Au besoin
types.py Définitions TypeVar, TypeAlias, Protocol partagées Quand typage complexe
cli.py Points d'entrée CLI (click/typer) Type CLI uniquement
backends/ Pattern plugin/strategy Quand implémentations échangeables
_compat.py Shims compatibilité version Python Quand compat 3.9–3.13 nécessaire

7. Stratégie de versioning

PEP 440 — Le standard

Forme canonique:  N[.N]+[{a|b|rc}N][.postN][.devN]

Exemples:
  1.0.0          Release stable
  1.0.0a1        Alpha (pre-release)
  1.0.0b2        Beta
  1.0.0rc1       Release candidate
  1.0.0.post1    Post-release (par ex., correction d'empaquetage uniquement)
  1.0.0.dev1     Snapshot de développement (pas pour PyPI)

Semantic Versioning (recommandé)

MAJOR.MINOR.PATCH

MAJOR: Breaking API change (supprimer/renommer fonction/classe/argument public)
MINOR: Nouvelle fonctionnalité, entièrement rétro-compatible
PATCH: Correction de bug, pas de changement d'API

Versioning dynamique avec setuptools_scm (recommandé pour workflows avec tags git)

# Comment ça fonctionne:
git tag v1.0.0          →  version installée = 1.0.0
git tag v1.1.0          →  version installée = 1.1.0
(commits après tag)     →  version = 1.1.0.post1  (suffixe supprimé pour PyPI)

# Dans le code — NE JAMAIS coder en dur quand vous utilisez setuptools_scm:
from importlib.metadata import version, PackageNotFoundError
try:
    __version__ = version("your-package")
except PackageNotFoundError:
    __version__ = "0.0.0-dev"    # Fallback pour checkouts dev non installés

Config pyproject.toml requise:

[tool.setuptools_scm]
version_scheme = "post-release"
local_scheme   = "no-local-version"   # Prévient +g<hash> de casser les uploads PyPI

Critique : définissez toujours fetch-depth: 0 à chaque étape de checkout CI. Sans l'historique git complet, setuptools_scm ne peut pas trouver les tags et la version de build tombe silencieusement à 0.0.0+dev.

Versioning statique (flit, hatchling manuel, poetry)

# your_package/__init__.py
__version__ = "1.0.0"    # Mettre à jour avant chaque release

Bonnes pratiques de spécificateur de version pour les dépendances

# Dans les dépendances [project]:
"httpx>=0.24"            # Version minimum — PRÉFÉRÉ pour les bibliothèques
"httpx>=0.24,<1.0"       # Limite supérieure seulement quand un breaking change connu existe
"httpx==0.27.0"          # Épingler exactement UNIQUEMENT dans les applications, PAS les bibliothèques

# JAMAIS faire ceci dans une bibliothèque — ça casse la résolution de dépendances pour les utilisateurs:
# "httpx~=0.24.0"        # Trop strict
# "httpx==0.27.*"        # Fragile

Version bump → flux de release

# 1. Mettre à jour CHANGELOG.md — déplacer les entrées [Unreleased] vers [x.y.z] - YYYY-MM-DD
# 2. Commiter le changelog
git add CHANGELOG.md
git commit -m "chore: prepare release vX.Y.Z"
# 3. Tagger et push — ceci déclenche publish.yml automatiquement
git tag vX.Y.Z
git push origin main --tags
# 4. Surveiller GitHub Actions → vérifier sur https://pypi.org/project/your-package/

Pour les templates pyproject.toml complets pour tous les quatre backends, voir references/pyproject-toml.md.


Où aller ensuite

Après avoir compris les décisions et la structure :

  1. Configurer pyproject.tomlreferences/pyproject-toml.md Tous les quatre templates de backend (setuptools+scm, hatchling, flit, poetry), configs d'outils complètes, setup py.typed, config de versioning.

  2. Écrire votre code de bibliothèquereferences/library-patterns.md Principes OOP/SOLID, type hints (PEP 484/526/544/561), conception de classe principale, fonctions factory, __init__.py, pattern plugin/backend, point d'entrée CLI.

  3. Ajouter tests et qualité de codereferences/testing-quality.md conftest.py, tests unitaires/backend/async, parametrize, setup ruff/mypy/pre-commit.

  4. Configurer CI/CD et publishreferences/ci-publishing.md ci.yml, publish.yml avec Trusted Publishing (OIDC, pas de tokens API), format CHANGELOG, checklist de release.

  5. Polir pour la communauté/OSSreferences/community-docs.md Sections README, format docstring, CONTRIBUTING, SECURITY, templates d'issues, tableau anti-patterns, et master checklist de release.

  6. Concevoir backends, config, transport, CLIreferences/architecture-patterns.md Système backend (pattern plugin/strategy), Settings dataclass, couche de transport HTTP, CLI avec click/typer, règles d'injection de backend.

  7. Choisir et implémenter une stratégie de versioningreferences/versioning-strategy.md Formes canoniques PEP 440, règles SemVer, identifiants pre-release, setuptools_scm deep-dive, versioning statique flit, moteur de décision (DEFAULT/BEGINNER/MINIMAL).

  8. Gouverner les releases et sécuriser le pipeline de publishreferences/release-governance.md Stratégie de branche, règles de protection de branche, setup OIDC Trusted Publishing, validation d'auteur de tag dans CI, mise en place du format de tag, publish.yml complet gouverné.

  9. Simplifier les outils avec Ruffreferences/tooling-ruff.md Setup Ruff uniquement remplaçant black/isort/flake8, config mypy, hooks pre-commit, asyncio_mode=auto (supprimer @pytest.mark.asyncio), guide de migration.

Skills similaires