Packaging Python : Création et Publication de Packages
Introduction
Bienvenue dans cette leçon dédiée au packaging Python, une compétence essentielle pour tout développeur souhaitant partager son code, le rendre réutilisable et faciliter sa distribution. Dans le cadre de notre cours sur le développement avancé avec Python, comprendre comment empaqueter (package) votre code n'est pas seulement une question de commodité, c'est une pierre angulaire de l'ingénierie logicielle collaborative et de la gestion de projets robustes.
Vous avez probablement déjà utilisé pip install pour installer des bibliothèques tierces. Mais vous êtes-vous déjà demandé comment ces bibliothèques ont été créées et mises à disposition ? C'est précisément ce que nous allons explorer. Nous allons apprendre à transformer votre code Python en un package installable, à le tester localement, puis à le publier sur le Python Package Index (PyPI), rendant ainsi votre travail accessible à la communauté mondiale.
À la fin de cette leçon, vous aurez une compréhension solide des concepts clés, des outils nécessaires et des étapes pratiques pour créer et publier vos propres packages Python.
Pourquoi Packager Votre Code Python ?
Le packaging n'est pas une simple formalité, il offre de nombreux avantages cruciaux :
- Réutilisabilité et Modularité : Transforme un ensemble de modules en une unité autonome et installable, favorisant la réutilisation dans différents projets.
- Distribution Facile : Permet à d'autres développeurs (ou à vous-même) d'installer votre bibliothèque avec une simple commande
pip install, sans avoir à copier-coller des fichiers ou à gérer manuellement les dépendances. - Gestion des Dépendances : Un package peut déclarer ses propres dépendances, assurant que toutes les bibliothèques nécessaires sont installées automatiquement lors de son installation.
- Versionnement : Facilite le suivi des modifications et la publication de nouvelles versions, permettant aux utilisateurs de choisir la version stable ou de migrer vers de nouvelles fonctionnalités.
- Visibilité et Collaboration : Publier sur PyPI rend votre travail visible par une vaste communauté de développeurs Python, ouvrant la porte à la collaboration et aux contributions.
- Environnements Stables : Permet de créer des environnements de développement et de déploiement cohérents et reproductibles.
Comprendre l'Écosystème du Packaging Python
Avant de plonger dans la pratique, il est crucial de comprendre les éléments fondamentaux qui composent l'écosystème du packaging Python.
Module vs Package
- Module : Un simple fichier
.pycontenant du code Python (fonctions, classes, variables). - Package : Un répertoire qui contient plusieurs modules et un fichier spécial
__init__.py(même vide). Un package permet d'organiser les modules en une structure hiérarchique et de les importer comme des sous-modules.
Un package distribuable (souvent appelé "distribution package" ou "distribution") est un ensemble de fichiers nécessaires pour installer un package Python (ou plusieurs packages et leurs ressources associées). C'est ce que nous allons créer.
PyPI (Python Package Index) et pip
- PyPI : C'est le dépôt officiel de paquets Python. C'est l'endroit où la plupart des paquets Python open-source sont hébergés et où
pipva chercher les paquets par défaut. Pensez-y comme l'App Store de Python. - pip : Le gestionnaire de paquets par excellence pour Python.
pipest utilisé pour installer, désinstaller et gérer les paquets Python. Lorsque vous exécutezpip install nom_du_paquet,pipse connecte à PyPI (ou à un autre index de paquets configuré) pour télécharger et installer le paquet.
Distributions : sdist et wheel
Lors de la construction d'un package, deux types de distributions sont généralement créés :
sdist(Source Distribution) : C'est une archive (généralement.tar.gzou.zip) qui contient le code source de votre package tel quel, ainsi que les métadonnées nécessaires pour le construire. Quand un utilisateur installe unsdist, son système doit le construire localement. Cela nécessite que l'utilisateur ait les outils de build appropriés (compilateurs C, etc. si votre package a des extensions compilées).wheel(Built Distribution) : C'est une archive pré-construite (fichier.whl) qui ne nécessite aucune étape de compilation lors de l'installation. Les wheels sont des distributions binaires, ce qui signifie qu'elles sont spécifiques à une plateforme (par exemple,my_package-1.0-cp39-cp39-linux_x86_64.whlpour Python 3.9 sur Linux 64-bit). Les wheels sont beaucoup plus rapides à installer car aucune compilation n'est nécessaire. C'est le format de distribution préféré et recommandé aujourd'hui.
Outils de Construction et de Publication
setuptools: La bibliothèque la plus ancienne et la plus couramment utilisée pour construire des packages Python. Elle gère la déclaration des métadonnées, les dépendances, et la création des distributions (sdistetwheel). Historiquement, elle s'appuyait sur un fichiersetup.py.build: Un outil moderne et standardisé (PEP 517/518) pour construire des distributions. Il est recommandé de l'utiliser à la place de l'ancienpython setup.py sdist bdist_wheel.buildtravaille en arrière-plan avec l'outil de build défini danspyproject.toml(souventsetuptools).twine: Un utilitaire sécurisé et recommandé pour uploader vos distributions (.sdistet.wheel) sur PyPI (ou TestPyPI). Il gère l'authentification et l'envoi des fichiers de manière fiable.
Environnements Virtuels (venv, virtualenv)
Il est impératif d'utiliser des environnements virtuels lors du développement et du test de vos packages.
- Un environnement virtuel crée un espace isolé pour vos projets Python, avec sa propre installation de l'interpréteur Python et de ses paquets.
- Cela évite les conflits de dépendances entre différents projets et garantit que les paquets que vous développez sont testés par rapport aux versions exactes de leurs dépendances.
- Comment l'utiliser :
- Créer :
python -m venv .venv(pour Python 3.3+) - Activer :
- Linux/macOS :
source .venv/bin/activate - Windows (CMD) :
.venv\Scripts\activate.bat - Windows (PowerShell) :
.venv\Scripts\Activate.ps1
- Linux/macOS :
- Désactiver :
deactivate
- Créer :
La Structure d'un Projet Packagable
Une bonne organisation de votre projet est fondamentale pour un packaging réussi. La structure recommandée suit une approche appelée "src-layout".
Organisation src/ (Recommandée)
Dans cette approche, le code source réel de votre package est placé dans un sous-répertoire nommé src/. Cela sépare clairement le code de votre package des fichiers de configuration, des tests, de la documentation, etc.
my_package/
├── src/
│ └── my_package/
│ ├── __init__.py
│ └── my_module.py
├── tests/
│ └── test_my_module.py
├── pyproject.toml
├── README.md
├── LICENSE
└── .gitignore
Explication des composants :
my_package/: Le répertoire racine de votre projet.src/: Contient le code source principal de votre package.src/my_package/: C'est le vrai package Python qui sera installé. Le nom de ce répertoire doit correspondre au nom de votre package que les utilisateurs importeront (ex:import my_package).src/my_package/__init__.py: Rend le répertoiremy_packageun package Python. Il peut être vide ou contenir des initialisations (par exemple, définir la version du package).src/my_package/my_module.py: Un exemple de module dans votre package.tests/: Répertoire pour vos tests unitaires et d'intégration. Il est séparé du code source installable.pyproject.toml: Le fichier de configuration moderne pour le packaging Python. Il déclare les dépendances de build et les métadonnées du package.README.md: Un fichier Markdown décrivant votre projet, son installation, son utilisation et d'autres informations importantes. C'est ce qui apparaît sur PyPI.LICENSE: Un fichier texte spécifiant la licence sous laquelle votre code est distribué (par exemple, MIT, Apache 2.0, GPL). Indispensable pour l'open-source..gitignore: Pour ignorer les fichiers et répertoires non pertinents pour le contrôle de version (ex:__pycache__,.venv,.pytest_cache, les distributions construitesdist/).
Fichiers Essentiels
pyproject.toml: Le fichier le plus important pour la configuration moderne.README.md: Description du projet.LICENSE: Informations sur la licence.- Fichiers de code Python :
.pyavec une structure de package valide.
Le Cœur de la Configuration : pyproject.toml (L'Approche Moderne)
pyproject.toml est le fichier de configuration standardisé pour les projets Python (introduit par la PEP 518, étendu par la PEP 621). Il est conçu pour être l'unique point d'entrée pour la configuration de votre projet, remplaçant progressivement setup.py et setup.cfg pour de nombreuses tâches.
Historique et Avantages
Historiquement, setup.py était le fichier central pour la configuration des packages. Cependant, il s'agissait d'un script Python, ce qui posait des problèmes de sécurité et de performances. pyproject.toml, un fichier TOML statique, résout ces problèmes en fournissant :
- Déclaration des dépendances de build : Permet aux outils de savoir comment construire votre package avant même d'installer quoi que ce soit.
- Configuration déclarative : Facilite la lecture et la validation.
- Indépendance de l'outil de build : Peut être utilisé avec différents "backends" de build (setuptools, Poetry, Hatch).
Structure et Sections Clés
Le fichier pyproject.toml est divisé en sections, dont les plus importantes pour le packaging sont :
[build-system]: Déclare le backend de build utilisé (par exemple,setuptoolsviasetuptools.build_meta) et ses dépendances. C'est ce qui permet àbuildde savoir comment construire votre package.[project]: Contient toutes les métadonnées du package (nom, version, description, auteurs, licence, dépendances d'exécution, etc.) selon la PEP 621.[tool.<outil_spécifique>]: Des sections spécifiques pour la configuration d'outils tiers (par exemple,[tool.setuptools]pour des options avancées de setuptools,[tool.pytest]pour pytest,[tool.black]pour Black).
Exemple Détaillé de pyproject.toml
Voici un exemple pour notre package imaginaire my_package, utilisant setuptools comme backend de build.
# pyproject.toml
[build-system]
requires = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "my-package-prof" # Nom du package tel qu'il apparaîtra sur PyPI
version = "0.1.0" # Version du package (SemVer recommandée)
authors = [
{ name="Votre Nom", email="votre.email@example.com" },
]
description = "Un package Python simple pour démontrer le packaging."
readme = "README.md" # Chemin vers le fichier README
requires-python = ">=3.8" # Version minimale de Python requise
classifiers = [ # Catégories pour classifier votre package sur PyPI
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Development Status :: 3 - Alpha", # Alpha, Beta, Production/Stable
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries :: Python Modules"
]
keywords = ["example", "packaging", "python"]
dependencies = [ # Dépendances d'exécution du package
"requests~=2.28", # Exemple : requests version 2.28.x
"numpy>=1.22" # Exemple : numpy version 1.22 ou plus
]
[project.urls]
"Homepage" = "https://github.com/votre_utilisateur/my_package_prof"
"Bug Tracker" = "https://github.com/votre_utilisateur/my_package_prof/issues"
"Documentation" = "https://my-package-prof.readthedocs.io/en/latest/"
[project.optional-dependencies] # Dépendances optionnelles (ex: pour le développement, tests)
dev = [
"pytest>=7.0",
"twine",
"build"
]
docs = [
"sphinx",
"sphinx-rtd-theme"
]
[tool.setuptools]
# Indique à setuptools de trouver les packages dans le répertoire 'src'
package-dir = {"" = "src"}
# Inclure les données non-code, comme les fichiers de données, les templates.
# Si vous avez des fichiers dans 'src/my_package/data/', vous pouvez les inclure ici.
# include-package-data = true # Nécessite aussi un MANIFEST.in souvent, ou package_data dans setup.py
packages = ["my_package"] # Explicitement lister les packages à inclure. Alternative à find:
# packages = ["my_package"] # ou setuptools.find_packages(where="src")
Explication du bloc de code pyproject.toml :
[build-system]:requires: Liste des paquets nécessaires pour construire votre projet.setuptoolsest l'outil principal pour la construction, etwheelest nécessaire pour créer les distributionswheel.build-backend: Spécifie quel module Python sera utilisé pour le backend de build.setuptools.build_metaest le standard poursetuptools.
[project]: Contient toutes les métadonnées essentielles pour PyPI.name: Le nom que les utilisateurs utiliseront pour installer votre package (ex:pip install my-package-prof). Il est recommandé d'utiliser des tirets dans le nom du package pour PyPI, mais le nom d'importation dans le code doit utiliser des underscores (ex:import my_package).version: La version du package. Suivre la versioning sémantique (SemVer :MAJEUR.MINEUR.PATCH) est une excellente pratique.authors,description,readme,requires-python,classifiers,keywords: Métadonnées pour PyPI qui aident les utilisateurs à trouver et comprendre votre package.dependencies: Une liste des dépendances de votre package au moment de l'exécution.piples installera automatiquement.
[project.urls]: Liens supplémentaires qui apparaîtront sur la page PyPI de votre package.[project.optional-dependencies]: Permet de spécifier des dépendances qui ne sont nécessaires que pour certaines fonctionnalités (ex:pip install my-package-prof[dev]pour les développeurs, oumy-package-prof[docs]pour la génération de documentation).[tool.setuptools]: Une section spécifique pour configurersetuptoolslorsque vous l'utilisez comme backend de build.package-dir = {"" = "src"}: Indique àsetuptoolsque les paquets Python (ceux qui contiennent__init__.py) se trouvent dans le sous-répertoiresrc/. C'est essentiel pour lesrc-layout.packages = ["my_package"]: Indique explicitement quel package (répertoire) à inclure. Pour des projets plus complexes avec plusieurs sous-packages, vous pouvez utilisersetuptools.find_packages(where="src")dans unsetup.pyminimal, ou laissersetuptoolstrouver les packages automatiquement avecpackage-dir.
Configuration Traditionnelle : setup.py et setup.cfg
Bien que pyproject.toml soit l'approche moderne, de nombreux projets existants utilisent encore setup.py (et parfois setup.cfg). Il est important de comprendre leur rôle.
Rôle et Interconnexion
setup.py: Traditionnellement, ce script Python contenait toutes les informations de packaging. Il était exécuté directement parpython setup.py installoupython setup.py sdist. Avecpyproject.tomlet l'outilbuild,setup.pyest souvent minimal, servant principalement de "point d'entrée" poursetuptoolssi certaines configurations ne peuvent être exprimées statiquement danspyproject.toml.setup.cfg: Un fichier de configuration statique (INI-like) quesetuptoolspeut lire. Il permet de déplacer une partie des métadonnées desetup.pyvers un format déclaratif, facilitant l'intégration avec d'autres outils. Il est complémentaire àpyproject.tomlou peut être utilisé avec unsetup.pyminimal.
Exemple de setup.py Minimal avec pyproject.toml
Si vous utilisez pyproject.toml pour toutes vos métadonnées, votre setup.py peut être très simple :
# setup.py
import setuptools
# setuptools lira la configuration depuis pyproject.toml
# et potentiellement setup.cfg
setuptools.setup()
Explication du bloc de code setup.py :
Ce setup.py est minimal. Il appelle simplement setuptools.setup(). Lorsque setuptools est exécuté (par exemple via l'outil build), il va automatiquement chercher et lire les métadonnées de votre package dans pyproject.toml (et/ou setup.cfg s'il existe). C'est la configuration recommandée si vous migrez vers pyproject.toml.
Note : Si vous n'utilisez pas pyproject.toml pour les métadonnées (ce qui est déconseillé pour les nouveaux projets), votre setup.py contiendrait directement toutes les informations, comme ceci :
# setup.py (Exemple d'approche ancienne, non recommandée pour les nouveaux projets)
from setuptools import setup, find_packages
setup(
name="my-package-prof-legacy",
version="0.1.0",
author="Votre Nom",
author_email="votre.email@example.com",
description="Un package Python simple (legacy setup.py).",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
url="https://github.com/votre_utilisateur/my_package_prof",
packages=find_packages(where="src"), # Important si vous utilisez src-layout
package_dir={"": "src"},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires='>=3.8',
install_requires=[
"requests~=2.28",
"numpy>=1.22"
],
# etc.
)
Inclusion de Fichiers Non-Code : MANIFEST.in
Par défaut, setuptools n'inclut que les fichiers Python dans votre distribution (sauf si vous avez configuré package_data ou include_package_data). Si votre package contient des fichiers non-Python nécessaires à son fonctionnement (fichiers de données, images, templates, fichiers de configuration, etc.), vous devez les déclarer.
Le fichier MANIFEST.in est un ensemble d'instructions qui dit à setuptools (lors de la création d'un sdist) quels fichiers inclure ou exclure.
Quand l'utiliser
Utilisez MANIFEST.in lorsque :
- Vous avez des fichiers non-code dans votre package qui doivent être distribués.
- Vous avez des fichiers non-code dans des sous-répertoires que
setuptoolsne détecterait pas automatiquement.
Syntaxe de Base
Le MANIFEST.in utilise une syntaxe simple basée sur des mots-clés :
include <pattern>: Inclut les fichiers correspondant au modèle.exclude <pattern>: Exclut les fichiers correspondant au modèle.recursive-include <dir> <pattern>: Inclut récursivement les fichiers correspondant au modèle dans le répertoire et ses sous-répertoires.recursive-exclude <dir> <pattern>: Exclut récursivement les fichiers.graft <dir>: Inclut récursivement tous les fichiers dans le répertoire spécifié.prune <dir>: Exclut récursivement tous les fichiers dans le répertoire spécifié.
Exemple de MANIFEST.in :
Supposons que votre package src/my_package contient un sous-répertoire data avec des fichiers CSV :
my_package/
├── src/
│ └── my_package/
│ ├── __init__.py
│ ├── my_module.py
│ └── data/
│ └── config.json
│ └── important.csv
├── MANIFEST.in
├── pyproject.toml
└── ...
Votre MANIFEST.in pourrait ressembler à ceci :
# MANIFEST.in
include README.md LICENSE
# Inclure tous les fichiers dans le répertoire data du package
recursive-include src/my_package/data *
Note : Pour que MANIFEST.in soit pris en compte, vous devez également configurer setuptools pour inclure les données du package. Dans pyproject.toml, cela peut être géré en spécifiant include-package-data = true sous [tool.setuptools]. Cependant, la meilleure approche est souvent de spécifier les package_data ou data_files directement dans la section [project] de pyproject.toml (PEP 621), ce qui est plus moderne et déclaratif.
# pyproject.toml (avec package-data pour inclure des fichiers dans les paquets)
[project]
# ... (autres métadonnées)
[project.urls]
# ...
[tool.setuptools]
package-dir = {"" = "src"}
packages = ["my_package"]
include-package-data = false # Désactiver si vous utilisez package-data ci-dessous
[tool.setuptools.package-data]
my_package = ["data/*.json", "data/*.csv"] # Inclut tous les .json et .csv dans my_package/data/
En utilisant [tool.setuptools.package-data], MANIFEST.in devient moins souvent nécessaire pour les fichiers dans le package. MANIFEST.in reste utile pour inclure des fichiers hors du package mais dans le répertoire racine du projet (comme README.md, LICENSE ou des scripts).
Construire Votre Package : Les Distributions
Une fois que votre projet est structuré et configuré, l'étape suivante consiste à construire les distributions sdist et wheel.
Installation des Outils de Build
Assurez-vous d'avoir les outils nécessaires installés dans votre environnement virtuel :
# Activez votre environnement virtuel si ce n'est pas déjà fait
# source .venv/bin/activate (Linux/macOS) ou .venv\Scripts\activate.bat (Windows)
pip install build twine
build: L'outil recommandé pour créer les distributions.twine: L'outil pour uploader les distributions sur PyPI.
Génération de sdist et wheel
Naviguez vers le répertoire racine de votre projet (là où se trouve pyproject.toml) et exécutez la commande build :
python -m build
Explication du bloc de code python -m build :
python -m build: Exécute le modulebuilden tant que script. Cet outil lira votrepyproject.toml(et/ousetup.pysi nécessaire), utilisera le backend de build spécifié (setuptoolsdans notre cas) pour construire lesdistet lewheel.
Après l'exécution, un nouveau répertoire nommé dist/ sera créé dans la racine de votre projet. Ce répertoire contiendra vos fichiers de distribution :
my_package/
├── dist/
│ ├── my_package_prof-0.1.0-py3-none-any.whl # Le wheel
│ └── my_package_prof-0.1.0.tar.gz # Le sdist
├── src/
│ └── my_package/
│ ├── __init__.py
│ └── my_module.py
├── pyproject.toml
├── README.md
├── LICENSE
└── ...
Vérification des Distributions
Il est fortement recommandé de vérifier le contenu de vos distributions avant de les publier. Vous pouvez utiliser twine check pour cela :
twine check dist/*
Cette commande vérifiera la validité de vos fichiers de distribution, notamment que votre README.md est bien rendu et qu'il n'y a pas d'erreurs de métadonnées qui pourraient causer des problèmes sur PyPI.
Tester Votre Package Localement
Avant de publier, il est crucial de tester l'installation et le fonctionnement de votre package comme le ferait un utilisateur.
Installation en Mode Éditable (pour le Développement)
Pendant que vous développez votre package, vous pouvez l'installer en mode "editable" (-e ou --editable). Cela crée un lien symbolique vers votre code source, de sorte que les modifications que vous apportez à votre code sont instantanément reflétées sans avoir besoin de réinstaller le package à chaque fois.
# Assurez-vous d'être dans votre environnement virtuel et dans la racine du projet
pip install -e .
Explication du bloc de code pip install -e . :
pip install -e .: Installe le package situé dans le répertoire courant (.) en mode éditable. Cela permet de développer le package et de le tester sans avoir à le re-builder et re-installer à chaque changement de code.
Après l'installation, vous devriez pouvoir importer votre package depuis n'importe quel endroit de votre environnement virtuel :
# python
import my_package_prof
print(my_package_prof.__version__) # Si vous avez défini __version__ dans __init__.py
# Vous pouvez aussi appeler des fonctions de my_module
# from my_package_prof import my_module
# my_module.some_function()
Installation depuis le Fichier .whl (pour le Test Final)
Pour un test plus réaliste de ce que les utilisateurs installeront, désinstallez votre package éditable, puis installez-le à partir du fichier .whl que vous avez créé :
pip uninstall my-package-prof -y # Désinstalle la version éditable
pip install dist/my_package_prof-0.1.0-py3-none-any.whl
Explication du bloc de code pip install dist/my_package_prof-0.1.0-py3-none-any.whl :
- Ceci simule exactement ce qui se passe lorsqu'un utilisateur télécharge votre
wheeldepuis PyPI et l'installe. Cela garantit que toutes les dépendances sont correctement installées et que le package fonctionne tel quel, sans lien vers le code source local.
Publier Votre Package
Une fois que vous avez construit et testé votre package, l'étape finale est la publication. Il est fortement recommandé de publier d'abord sur TestPyPI pour vous familiariser avec le processus sans risquer de "polluer" le PyPI officiel.
Créer Vos Comptes (TestPyPI, PyPI)
- TestPyPI : Créez un compte sur test.pypi.org/account/register/. Utilisez un nom d'utilisateur et un mot de passe différents de PyPI officiel.
- PyPI : Créez un compte sur pypi.org/account/register/.
Pour des raisons de sécurité, nous utiliserons des jetons d'API (API tokens) plutôt que votre mot de passe pour uploader avec twine.
- Allez sur votre profil PyPI (ou TestPyPI).
- Sélectionnez "Add API token".
- Donnez un nom au jeton (ex:
my-package-upload). - Laissez "Scope" à "Entire account" (ou limitez-le à un projet spécifique une fois votre projet créé sur PyPI).
- Copiez le jeton immédiatement ! Il ne sera affiché qu'une seule fois.
Publier sur TestPyPI
Maintenant, utilisons twine pour uploader vos distributions sur TestPyPI.
# Assurez-vous d'être dans l'environnement virtuel et dans le répertoire racine du projet
twine upload --repository testpypi dist/*
Explication du bloc de code twine upload --repository testpypi dist/* :
twine upload: La commande pour uploader les packages.--repository testpypi: Indique àtwined'utiliser l'URL de TestPyPI. Si omis,twineuploaderait vers PyPI par défaut.dist/*: Spécifie que tous les fichiers (sdist et wheel) dans le répertoiredist/doivent être uploadés.
twine vous demandera votre nom d'utilisateur et votre mot de passe.
- Nom d'utilisateur :
__token__(c'est une convention pour indiquer que vous utilisez un jeton d'API). - Mot de passe : Collez le jeton d'API que vous avez copié précédemment.
Si tout se passe bien, twine affichera un message de succès et vous pourrez visiter la page de votre package sur TestPyPI (ex: test.pypi.org/project/my-package-prof/). Testez l'installation :
pip install --index-url https://test.pypi.org/simple/ --no-deps my-package-prof
Note sur my_package_prof: Remplacez my_package_prof par le nom réel de votre package tel que défini dans pyproject.toml.
Publier sur PyPI
Une fois que vous avez confirmé que votre package fonctionne correctement sur TestPyPI, vous pouvez le publier sur PyPI. Le processus est identique, il suffit de retirer l'option --repository testpypi.
# Assurez-vous d'être dans l'environnement virtuel et dans le répertoire racine du projet
twine upload dist/*
De la même manière, twine vous demandera le nom d'utilisateur (__token__) et le jeton d'API de PyPI. Une fois l'upload réussi, votre package sera disponible sur pypi.org/project/votre-package-nom/ et pourra être installé par n'importe qui avec pip install votre-package-nom.
Bonnes Pratiques et Conseils Avancés
Gestion des Versions (SemVer)
- Adoptez le versioning sémantique (SemVer) :
MAJEUR.MINEUR.PATCH(ex:1.2.3).- MAJEUR : Incrémenté pour les changements incompatibles avec les versions précédentes.
- MINEUR : Incrémenté pour l'ajout de fonctionnalités compatibles.
- PATCH : Incrémenté pour les corrections de bugs compatibles.
- Utilisez des suffixes pour les versions de pré-publication (ex:
1.0.0b1pour une bêta,1.0.0rc1pour un release candidate,1.0.0.dev0pour le développement).
Licences
- Toujours inclure un fichier
LICENSEdans votre dépôt. - Choisissez une licence appropriée (MIT pour permissive, Apache 2.0 pour permissive avec brevets, GPL pour copyleft).
MITest un excellent choix pour les bibliothèques open source. - Déclarez la licence dans votre
pyproject.tomlvialicense = { file = "LICENSE" }et dans lesclassifiers.
Documentation
- Fournissez une documentation claire et complète.
- Le
README.mdest le point de départ. - Envisagez d'utiliser Sphinx pour une documentation plus structurée, hébergée par exemple sur Read the Docs.
Tests et CI/CD
- Écrivez des tests unitaires et d'intégration pour votre code (avec
pytest,unittest). - Intégrez un système d'intégration continue/déploiement continu (CI/CD) comme GitHub Actions, GitLab CI/CD ou Jenkins pour automatiser les tests, la construction et la publication de votre package à chaque modification.
Choix de l'Outil de Build
setuptools: Le choix par défaut, très flexible, mais sa configuration peut devenir complexe. Le combopyproject.toml+setuptools(backendsetuptools.build_meta) est la voie moderne.Poetry: Un gestionnaire de dépendances et de packages tout-en-un qui simplifie considérablement le packaging, la gestion des dépendances, et la publication. Excellent pour les nouveaux projets.Hatch: Un autre gestionnaire de projets moderne et flexible, similaire à Poetry, mais axé sur l'extensibilité et la configuration plus fine.
Pour cette leçon, nous nous sommes concentrés sur setuptools via pyproject.toml car c'est le standard de facto et le plus répandu, mais n'hésitez pas à explorer Poetry ou Hatch pour vos futurs projets.
Conclusion et Prochaines Étapes
Félicitations ! Vous avez parcouru le chemin complet de la création à la publication d'un package Python. Vous avez appris :
- L'importance du packaging pour la réutilisabilité et la distribution.
- Les composants clés de l'écosystème Python (PyPI, pip, sdist, wheel, setuptools, build, twine).
- La structure recommandée d'un projet Python (
src-layout). - Comment configurer votre package avec le moderne
pyproject.toml. - Les étapes pour construire vos distributions.
- Comment tester votre package localement.
- Le processus de publication sur TestPyPI et PyPI.
- De bonnes pratiques pour un packaging de qualité.
Le packaging est une compétence fondamentale pour tout développeur Python avancé. Il vous permet de contribuer à la communauté, de rationaliser vos propres projets et de collaborer plus efficacement.
Pour aller plus loin :
- Expérimentez avec les dépendances optionnelles.
- Mettez en place des tests CI/CD pour automatiser votre workflow.
- Explorez Poetry ou Hatch pour voir comment ils simplifient le processus.
- Consultez la documentation officielle de Python sur le packaging : packaging.python.org.
Maintenant, mettez ces connaissances en pratique et partagez vos créations avec le monde !