Optimierung der Python-Projektverteilung mit setuptools, wheel und PyPI
Olivia Novak
Dev Intern · Leapcell

Einleitung
die Entwicklung robuster Python-Anwendungen ist nur ein Teil der Reise; sie für andere zugänglich und einfach installierbar zu machen, ist ebenso entscheidend. Stellen Sie sich vor, Sie erstellen ein großartiges Dienstprogramm, nur damit die Benutzer mit manueller Abhängigkeitsverwaltung und komplexen Einrichtungsprozessen zu kämpfen haben. Hier kommen standardisierte Verpackung und Verteilung ins Spiel und verwandeln Ihr Projekt von einer Sammlung von Skripten in ein professionell einsetzbares Paket. Im riesigen Python-Ökosystem ist die Beherrschung der Verpackungskunst mit setuptools
, wheel
und der Verteilung über PyPI nicht nur eine Best Practice, sondern eine grundlegende Fähigkeit, die die nahtlose Weitergabe, Zusammenarbeit und breitere Akzeptanz Ihrer Arbeit ermöglicht. Dieser Artikel befasst sich mit den Feinheiten dieser Tools und führt Sie von einem Rohprojekt zu einem öffentlich verfügbaren und installierbaren Python-Paket.
Kernkonzepte vor Beginn
Bevor wir uns mit den praktischen Aspekten befassen, sollten wir ein gemeinsames Verständnis der wichtigsten beteiligten Akteure aufbauen:
setuptools
: Dies ist das Fundament der Python-Paketerstellung. Es ist eine Bibliothek, die die Fähigkeiten vondistutils
(der Standardverteilungsnutzlichkeit von Python) erweitert, um robuste Werkzeuge für die Definition, Erstellung und Installation von Python-Paketen bereitzustellen. Es kümmert sich um alles, von der Angabe von Metadaten und Abhängigkeiten bis zur Erstellung von Distributionsarchiven.wheel
: Ein Wheel (.whl
-Datei) ist ein vortagesfertiges Distributionsformat für Python. Im Gegensatz zu Quellverteilungen (sdist) enthalten Wheels kompilierte Bytecodes und sind bereit, direkt installiert zu werden, ohne Setup-Skripte ausführen oder Erweiterungen kompilieren zu müssen. Dies beschleunigt die Installation erheblich und vermeidet häufige umgebungsbezogene Probleme, was sie für viele zum bevorzugten Distributionsformat macht.- PyPI (Python Package Index): Ausgesprochen "Py-P-I", dies ist das offizielle Drittanbieter-Software-Repository für Python. Es ist ein riesiger öffentlicher Index, in den Python-Entwickler ihre Pakete hochladen und Benutzer sie mit Tools wie
pip
herunterladen und installieren können. Betrachten Sie es als den zentralen Marktplatz für Python-Software. pip
: Der Paketinstallateur für Python. Obwohl nicht direkt an der Verpackung beteiligt, istpip
das primäre Werkzeug, das Benutzer verwenden werden, um Ihre Pakete von PyPI oder anderen Quellen zu installieren. Es ist wichtig zu verstehen, wiepip
mit Ihrem verteilten Paket interagiert.
Verpackung und Verteilung Ihres Python-Projekts
Der Prozess der Verpackung und Verteilung Ihres Python-Projekts umfasst typischerweise die Definition von Projektmetadaten, die Erstellung von Distributionsarchiven und dann das Hochladen dieser Archive auf PyPI. Lassen Sie uns jeden Schritt mit praktischen Beispielen aufschlüsseln.
1. Projektstruktur
Eine gut organisierte Projektstruktur ist der erste Schritt. Betrachten Sie ein einfaches Projekt namens my_package
:
my_package_project/
├── my_package/
│ ├── __init__.py
│ └── main.py
├── tests/
│ ├── test_main.py
├── README.md
├── LICENSE
└── setup.py
Hier ist my_package/
das eigentliche Python-Paketverzeichnis, tests/
enthält Ihre Tests, README.md
bietet Projektdokumentation, LICENSE
gibt Lizenzinformationen an und setup.py
ist das Herzstück Ihrer Verpackungsbemühungen.
2. Definition von Projektmetadaten mit setup.py
Die Datei setup.py
ist der Ort, an dem Sie alle wesentlichen Informationen über Ihr Projekt mithilfe von setuptools.setup()
definieren. Erstellen wir ein einfaches setup.py
für unser my_package
:
# setup.py from setuptools import setup, find_packages setup( name='my_package', version='0.1.0', description='Ein einfaches Beispiel für ein Python-Paket', long_description=open('README.md').read(), long_description_content_type='text/markdown', author='Ihr Name', author_email='ihre.email@example.com', url='https://github.com/ihrbenutzername/my_package', packages=find_packages(), # Findet automatisch alle Pakete im Verzeichnis classifiers=[ 'Programming Language :: Python :: 3', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', ], python_requires='>=3.6', install_requires=[ # Listen Sie hier die Abhängigkeiten Ihres Projekts auf # 'requests>=2.20.0', # 'numpy', ], entry_points={ 'console_scripts': [ 'my-package-cli=my_package.main:cli_entry_point', ], }, )
Erklärung der Felder:
name
: Der Name Ihres Pakets. Dies ist das, was Benutzer zur Installation eingeben werden (z. B.pip install my_package
).version
: Die aktuelle Version Ihres Pakets (z. B.0.1.0
). Folgen Sie Semantic Versioning für Klarheit.description
: Eine kurze Zusammenfassung in einer Zeile.long_description
: Detaillierte Beschreibung, oft ausREADME.md
gelesen.long_description_content_type
: Gibt das Format vonlong_description
an (z. B.text/markdown
).author
,author_email
: Ihre Kontaktinformationen.url
: Homepage des Projekts oder GitHub-Repository.packages
: Dies ist entscheidend.find_packages()
erkennt automatisch alle Python-Pakete (Verzeichnisse mit__init__.py
) in Ihrem Projekt. Manuelles Auflisten ist ebenfalls eine Option.classifiers
: Kategorisiert Ihr Projekt auf PyPI und hilft Benutzern, es zu finden. Eine umfassende Liste finden Sie auf PyPI.python_requires
: Gibt die erforderliche Mindestversion von Python an.install_requires
: Listet die Laufzeitabhängigkeiten auf, die Ihr Paket benötigt.pip
installiert diese automatisch, wenn Ihr Paket installiert wird.entry_points
: Wenn Ihr Paket Kommandozeilen-Skripte bereitstellt, definieren Sie diese hier.my-package-cli
würde zu einem aufrufbaren Befehl werden, der die Funktioncli_entry_point
inmy_package.main
ausführt.
In my_package/main.py
könnten Sie haben:
# my_package/main.py def cli_entry_point(): print("Hallo von der my_package CLI!") if __name__ == '__main__': cli_entry_point()
3. Erstellung von Quell- und Wheel-Distributionen
Sobald setup.py
bereit ist, können Sie Ihre Distributionsarchive erstellen. Stellen Sie zuerst sicher, dass Sie build
installiert haben: pip install build
.
Navigieren Sie im Terminal in das Stammverzeichnis Ihres Projekts (my_package_project/
) und führen Sie aus:
python -m build
Dieser Befehl erstellt normalerweise zwei Arten von Distributionsdateien in einem neu erstellten Verzeichnis dist/
:
- Quellverteilung (sdist): Eine
.tar.gz
-Datei, die Ihren Quellcode undsetup.py
enthält. Dies ist für Benutzer, die von Grund auf neu erstellen möchten. - Wheel-Verteilung (bdist_wheel): Eine
.whl
-Datei. Dies ist ein vorkompiliertes, installationsbereites Paket, das plattformspezifisch ist (wenn es kompilierte Erweiterungen enthält) oder "reines Python" (plattformunabhängig).
Für unser einfaches my_package
sehen Sie möglicherweise Dateien wie:
dist/
├── my_package-0.1.0-py3-none-any.whl # Wheel
└── my_package-0.1.0.tar.gz # Quellverteilung
Der Wheel-Dateiname my_package-0.1.0-py3-none-any.whl
bezeichnet typischerweise: paketname-version-python_tag-abi_tag-plattform_tag.whl
. py3-none-any
zeigt an, dass er mit Python 3 kompatibel ist, keinen spezifischen ABI (Application Binary Interface) hat und plattformunabhängig ist.
4. Hochladen auf PyPI
Mit den fertigen Distributionen ist der letzte Schritt für die öffentliche Veröffentlichung das Hochladen dieser Archive auf PyPI.
a. Registrierung auf PyPI und TestPyPI
Zuerst benötigen Sie Konten für beide:
- PyPI (für Produktionspakete)
- TestPyPI (zum Testen Ihres Upload-Prozesses, ohne das Main-PyPI zu überladen)
b. Installation von twine
twine
ist ein sicheres Dienstprogramm, das für das Hochladen von Paketen auf PyPI empfohlen wird. Installieren Sie es:
pip install twine
c. Hochladen auf TestPyPI (Empfohlen!)
Testen Sie Ihren Upload-Prozess immer zuerst mit TestPyPI. Dies hilft, Probleme zu erkennen, ohne eine echte Veröffentlichung vorzunehmen.
twine upload --repository testpypi dist/*
Sie werden nach Ihrem TestPyPI-Benutzernamen und Passwort gefragt (das aus Sicherheitsgründen ein API-Token ist, das in Ihren TestPyPI-Konto-Einstellungen generiert wurde).
Nach einem erfolgreichen Upload können Sie Ihr Paket auf test.pypi.org/project/my_package
überprüfen. Sie können es sogar installieren:
pip install --index-url https://test.pypi.org/simple/ --no-deps my_package
Das Flag --no-deps
ist bei TestPyPI-Uploads oft nützlich, um die Installation potenziell fehlerhafter oder alter Abhängigkeiten von TestPyPI selbst zu vermeiden.
d. Hochladen auf das offizielle PyPI
Sobald Sie mit Ihrem TestPyPI-Upload zufrieden sind, können Sie zum offiziellen PyPI hochladen:
twine upload dist/*
Sie geben erneut Ihren PyPI-Benutzernamen und ein API-Token ein.
Herzlichen Glückwunsch! Ihr Paket ist jetzt auf PyPI verfügbar und kann von jedem mit pip install my_package
installiert werden.
Anwendungsszenarien
- Open-Source-Bibliotheken: Teilen Sie Ihren wiederverwendbaren Code mit der Welt und machen Sie ihn leicht auffindbar und installierbar.
- Interne Unternehmenswerkzeuge: Verteilen Sie proprietäre Dienstprogramme oder Module innerhalb Ihrer Organisation, ohne manuelle Installationsschritte.
- Komplexe Anwendungen: Selbst wenn Ihre primäre Verteilung nicht über PyPI erfolgt, hilft das Verständnis der Verpackung, Ihr Projekt für zuverlässige Abhängigkeitsverwaltung und mögliche zukünftige PyPI-Veröffentlichungen zu strukturieren.
- Abhängigkeitsverwaltung: Indem Sie
install_requires
ordnungsgemäß definieren, stellen Sie sicher, dass Benutzer alle notwendigen Komponenten ohne Rätselraten erhalten.
Fazit
Die Verpackung und Verteilung Ihrer Python-Projekte mit setuptools
, wheel
und PyPI ist eine unverzichtbare Fähigkeit für jeden ernsthaften Python-Entwickler. Sie verwandelt Ihren Rohcode in ein professionelles, leicht teilbares und installierbares Produkt. Indem Sie diese Schritte befolgen, können Sie sicherstellen, dass Ihre harte Arbeit ihr Publikum nahtlos erreicht und die breitere Akzeptanz und Zusammenarbeit innerhalb der Python-Community fördert. Beherrschen Sie diesen Workflow und schalten Sie das volle Potenzial Ihrer Python-Kreationen frei.