Python-Pakete erstellen: Leitfaden von der Entwicklung bis zu PyPI
Meistern Sie Python-Paketierung von Code bis zur PyPI-Veröffentlichung
Python-Paketierung hat sich erheblich weiterentwickelt, mit modernen Tools und Standards, die es einfacher denn je machen, Ihren Code zu verteilen.
Dieser Leitfaden führt Sie durch den Aufbau professioneller Python-Pakete und deren Veröffentlichung auf PyPI. Wenn Sie neu in Python sind oder eine schnelle Referenz benötigen, werfen Sie einen Blick auf unseren Python-Cheat-Sheet, um sich mit den Grundlagen von Python vertraut zu machen.

Warum Ihr Python-Code paketieren?
Das Paketieren Ihres Python-Projekts bietet mehrere Vorteile:
- Wiederverwendbarkeit: Teilen Sie Code über mehrere Projekte hinweg ohne Kopieren und Einfügen
- Verteilung: Ermöglichen Sie anderen, Ihren Code mit einem einfachen
pip installzu installieren - Abhängigkeitsmanagement: Klare Spezifikation und Verwaltung von Abhängigkeiten
- Versionierung: Verfolgen Sie Veröffentlichungen und halten Sie die Abwärtskompatibilität aufrecht
- Professionelle Standards: Folgen Sie den Best Practices der Python-Community
- Dokumentation: Die Struktur fördert eine ordnungsgemäße Dokumentation und Tests
Moderne Python-Paketstruktur
Ein gut organisiertes Paket folgt dieser Struktur:
my-package/
├── src/
│ └── mypackage/
│ ├── __init__.py
│ ├── core.py
│ └── utils.py
├── tests/
│ ├── __init__.py
│ └── test_core.py
├── docs/
│ └── index.md
├── .github/
│ └── workflows/
│ └── publish.yml
├── pyproject.toml
├── README.md
├── LICENSE
└── .gitignore
Die src-Layout wird jetzt der flachen Layout bevorzugt, weil sie:
- Verhindert versehentliche Importe von nicht installiertem Code während der Entwicklung
- Macht Tests zuverlässiger, indem die Installation erzwungen wird
- Trennt klar den Quellcode von anderen Projektdateien
Beim Organisieren der internen Struktur Ihres Pakets sollten Sie die Anwendung von Clean-Architecture-Prinzipien in Betracht ziehen, um Ihren Code wartbarer und testbarer zu machen. Unser Leitfaden zu Python-Design Patterns für Clean Architecture behandelt SOLID-Prinzipien, Dependency Injection und geschichtete Architekturmuster, die hervorragend mit Python-Paketen funktionieren.
Die pyproject.toml-Datei: Moderne Konfiguration
pyproject.toml (PEP 518, 621) ist der moderne Standard für die Python-Projektkonfiguration und ersetzt das veraltete setup.py:
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "mypackage"
version = "0.1.0"
description = "Ein fantastisches Python-Paket"
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
{name = "Ihr Name", email = "you@example.com"}
]
keywords = ["beispiel", "tutorial", "paket"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]
dependencies = [
"requests>=2.28.0",
"click>=8.1.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.4.0",
"black>=23.0.0",
"flake8>=6.0.0",
"mypy>=1.5.0",
]
docs = [
"sphinx>=7.0.0",
"sphinx-rtd-theme>=1.3.0",
]
[project.urls]
Homepage = "https://github.com/yourusername/mypackage"
Documentation = "https://mypackage.readthedocs.io"
Repository = "https://github.com/yourusername/mypackage"
Issues = "https://github.com/yourusername/mypackage/issues"
[project.scripts]
mypackage-cli = "mypackage.cli:main"
[tool.setuptools.packages.find]
where = ["src"]
Wichtige Konfigurationsabschnitte
- build-system: Gibt das Build-Backend an (setuptools, hatchling, poetry-core, flit-core)
- project: Kernmetadaten und Abhängigkeiten
- project.optional-dependencies: Zusätzliche Feature-Abhängigkeiten (dev, docs, testing)
- project.scripts: Command-Line-Einstiegspunkte
- tool.*: Tool-spezifische Konfiguration (black, pytest, mypy, etc.)
Auswahl eines Build-Backends
Setuptools (Standardwahl)
Die am weitesten verbreitete und kompatible Option:
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
Vorteile: Universelle Kompatibilität, umfangreiche Funktionen, großes Ökosystem Nachteile: Mehrere Konfiguration, langsamer als neuere Alternativen
Hatchling (Modern & Schnell)
Leichtgewichtiges und leistungsfähiges modernes Backend:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Vorteile: Schnelle Builds, einfache Konfiguration, gute Standardeinstellungen Nachteile: Weniger Plugins als setuptools
Poetry (All-in-One)
Vollständiges Abhängigkeits- und Umgebungsmanagement:
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.poetry]
name = "mypackage"
version = "0.1.0"
description = "Ein fantastisches Python-Paket"
authors = ["Ihr Name <you@example.com>"]
[tool.poetry.dependencies]
python = "^3.8"
requests = "^2.28.0"
Vorteile: Abhängigkeitsauflösung, Lock-Dateien, integrierter Workflow Nachteile: Unterschiedlicher Workflow, größere Tool-Oberfläche
Flit (Minimalistisch)
Einfaches Tool für einfache Pakete:
[build-system]
requires = ["flit_core >=3.2,<4"]
build-backend = "flit_core.buildapi"
Vorteile: Extrem einfach, minimale Konfiguration Nachteile: Begrenzte Funktionen für komplexe Pakete
Bauen Ihres Pakets
Installieren Sie Build-Tools
# Installieren Sie das moderne Build-Tool
pip install build
# Oder für Poetry
pip install poetry
# Oder für Hatchling
pip install hatch
Erstellen Sie Verteilungsdateien
Mit dem build-Paket (funktioniert mit jedem Backend):
# Löschen Sie vorherige Builds
rm -rf dist/ build/ *.egg-info
# Bauen Sie die Quellverteilung und das Wheel
python -m build
# Dies erstellt:
# dist/mypackage-0.1.0.tar.gz (Quellverteilung)
# dist/mypackage-0.1.0-py3-none-any.whl (Wheel)
Mit Poetry:
poetry build
Mit Hatch:
hatch build
Verständnis der Verteilungsformate
Quellverteilung (sdist) - .tar.gz
- Enthält Quellcode und Build-Anweisungen
- Der pip des Benutzers baut es während der Installation
- Enthält Tests, Dokumente und andere Entwicklungsdateien
Wheel - .whl
- Vorinstallierte Binärverteilung
- Schnelle Installation (kein Build-Schritt)
- Plattformspezifisch oder plattformunabhängig
- Empfohlenes Format für die Verteilung
Veröffentlichung auf PyPI
Methode 1: Manuelles Hochladen mit Twine (Traditionell)
# Installieren Sie twine
pip install twine
# Überprüfen Sie das Paket vor dem Hochladen
twine check dist/*
# Laden Sie zunächst auf TestPyPI hoch (empfohlen)
twine upload --repository testpypi dist/*
# Testen Sie die Installation von TestPyPI
pip install --index-url https://test.pypi.org/simple/ mypackage
# Laden Sie auf das Produktions-PyPI hoch
twine upload dist/*
Konfigurieren Sie die Anmeldeinformationen in ~/.pypirc:
[distutils]
index-servers =
pypi
testpypi
[pypi]
username = __token__
password = pypi-AgEIcHlwaS5vcmc...
[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-AgENdGVzdC5weXBpLm9yZw...
Methode 2: Vertrauenswürdige Veröffentlichung (Empfohlen für CI/CD)
Vertrauenswürdige Veröffentlichung verwendet OpenID Connect (OIDC) zur Authentifizierung von CI/CD-Plattformen ohne Speicherung von Tokens.
Setup in PyPI:
- Gehen Sie zu den Einstellungen Ihres PyPI-Projekts
- Navigieren Sie zum Abschnitt “Publishing”
- Fügen Sie einen neuen “pending publisher” hinzu
- Konfigurieren Sie:
- Owner: Ihr GitHub-Benutzername/Organisation
- Repository: Repository-Name
- Workflow:
publish.yml - Environment:
release(optional, aber empfohlen)
GitHub Actions Workflow (.github/workflows/publish.yml):
name: Publish to PyPI
on:
release:
types: [published]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Store distribution packages
uses: actions/upload-artifact@v3
with:
name: python-package-distributions
path: dist/
publish:
needs: build
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write
steps:
- name: Download distributions
uses: actions/download-artifact@v3
with:
name: python-package-distributions
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
Vorteile:
- Keine API-Tokens zu verwalten oder zu sichern
- Automatische Authentifizierung über OIDC
- Erhöhte Sicherheit durch Umgebungs-Schutzregeln
- Audit-Trail aller Veröffentlichungen
Beste Praktiken
1. Versionsmanagement
Verwenden Sie semantisches Versionieren (SemVer): MAJOR.MINOR.PATCH
# Installieren Sie das Versionserhöhungstool
pip install bump2version
# Version erhöhen
bump2version patch # 0.1.0 -> 0.1.1
bump2version minor # 0.1.1 -> 0.2.0
bump2version major # 0.2.0 -> 1.0.0
Konfigurieren Sie in .bumpversion.cfg:
[bumpversion]
current_version = 0.1.0
commit = True
tag = True
[bumpversion:file:pyproject.toml]
search = version = "{current_version}"
replace = version = "{new_version}"
[bumpversion:file:src/mypackage/__init__.py]
search = __version__ = "{current_version}"
replace = __version__ = "{new_version}"
2. Wichtige Dateien einbeziehen
README.md: Klare Projektbeschreibung, Installationsanleitung, Verwendungsbeispiele LICENSE: Wählen Sie eine geeignete Lizenz (MIT, Apache 2.0, GPL usw.) CHANGELOG.md: Dokumentieren Sie Änderungen zwischen den Versionen .gitignore: Ausschluss von Build-Artifacts, Caches, virtuellen Umgebungen
3. Umfassendes Testen
# Installieren Sie Testabhängigkeiten
pip install pytest pytest-cov
# Führen Sie Tests mit Abdeckung aus
pytest --cov=mypackage tests/
# Generieren Sie einen Abdeckungsbericht
pytest --cov=mypackage --cov-report=html tests/
Konfigurieren Sie in pyproject.toml:
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
addopts = "--strict-markers --cov=mypackage"
4. Code-Qualitätstools
# Formatierung
black src/ tests/
# Linting
flake8 src/ tests/
# Typüberprüfung
mypy src/
# Import-Sortierung
isort src/ tests/
Integrieren Sie in Pre-Commit-Hooks (.pre-commit-config.yaml):
repos:
- repo: https://github.com/psf/black
rev: 23.9.1
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 6.1.0
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.5.1
hooks:
- id: mypy
5. Dokumentation
Verwenden Sie Sphinx für die Dokumentation:
# Installieren Sie Sphinx
pip install sphinx sphinx-rtd-theme
# Initialisieren Sie die Dokumentation
cd docs
sphinx-quickstart
# Bauen Sie die Dokumentation
make html
Oder verwenden Sie MkDocs für einfachere Markdown-basierte Dokumentation:
pip install mkdocs mkdocs-material
mkdocs new .
mkdocs serve
6. Continuous Integration
Das Testen Ihrer Python-Pakete auf verschiedenen Plattformen und in verschiedenen Umgebungen ist entscheidend für die Zuverlässigkeit. Für Einblicke in die Python-Leistung in verschiedenen Bereitstellungsszenarien sehen Sie sich unseren Vergleich der AWS Lambda-Leistung: JavaScript vs Python vs Golang, der untersucht, wie sich Python in serverlosen Umgebungen verhält.
Vollständiger CI/CD-Workflow (.github/workflows/ci.yml):
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
- name: Python einrichten
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Abhängigkeiten installieren
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Tests ausführen
run: pytest --cov=mypackage --cov-report=xml
- name: Abdeckung hochladen
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Python einrichten
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Abhängigkeiten installieren
run: |
pip install black flake8 mypy
- name: Black-Formatierungsprüfung
run: black --check src/ tests/
- name: Flake8
run: flake8 src/ tests/
- name: MyPy
run: mypy src/
Häufige Fallstricke und Lösungen
Problem 1: Importfehler nach der Installation
Problem: Paket installiert, aber Importe scheitern
Lösung: Stellen Sie eine korrekte Paketstruktur mit __init__.py-Dateien und eine korrekte pyproject.toml-Konfiguration sicher:
[tool.setuptools.packages.find]
where = ["src"]
include = ["mypackage*"]
Problem 2: Fehlende Abhängigkeiten
Problem: Paket installiert, aber Laufzeitfehler aufgrund fehlender Abhängigkeiten
Lösung: Geben Sie alle Laufzeitabhängigkeiten in pyproject.toml an:
[project]
dependencies = [
"requests>=2.28.0",
"click>=8.1.0",
]
Problem 3: Versionskonflikte
Problem: Paket funktioniert in der Entwicklung, aber nicht in der Produktion
Lösung: Verwenden Sie virtuelle Umgebungen und geben Sie Mindestversionen an:
# Erstellen Sie eine isolierte Umgebung
python -m venv .venv
source .venv/bin/activate # Auf Windows: .venv\Scripts\activate
# Installieren Sie im Entwicklermodus
pip install -e ".[dev]"
Problem 4: Große Paketgröße
Problem: Paket benötigt zu lange zum Herunterladen/Installieren
Lösung: Schließen Sie unnötige Dateien mit MANIFEST.in aus:
include README.md
include LICENSE
include pyproject.toml
recursive-include src *.py
recursive-exclude * __pycache__
recursive-exclude * *.py[co]
recursive-exclude tests *
recursive-exclude docs *
Problem 5: Plattformspezifische Probleme
Problem: Paket funktioniert auf einem Betriebssystem, aber nicht auf einem anderen
Lösung: Testen Sie auf mehreren Plattformen mit CI/CD-Matrix-Builds (siehe CI-Beispiel oben)
Veröffentlichungs-Checkliste
Bevor Sie Ihr Paket auf PyPI veröffentlichen, überprüfen Sie:
- Alle Tests laufen auf verschiedenen Python-Versionen
- Code ist formatiert und gelint
- README.md ist vollständig mit Beispielen
- LICENSE-Datei ist enthalten
- Versionsnummer ist aktualisiert
- CHANGELOG.md ist aktualisiert
- Abhängigkeiten sind korrekt angegeben
- Paket baut ohne Fehler (
python -m build) - Paket auf TestPyPI getestet
- Dokumentation ist aktuell
- Git-Repository mit Version getaggt
- GitHub-Release erstellt (für vertrauenswürdige Veröffentlichung)
Fortgeschrittene Themen
Einstiegspunkte und CLI-Tools
Erstellen Sie Befehlszeilenschnittstellen:
[project.scripts]
mypackage = "mypackage.cli:main"
Implementierung in src/mypackage/cli.py:
import click
@click.command()
@click.option('--name', default='World', help='Name zum Begrüßen')
def main(name):
"""Beispiel für ein einfaches CLI-Tool"""
click.echo(f'Hallo, {name}!')
if __name__ == '__main__':
main()
Für ein Praxisbeispiel zur Erstellung von Python-Paketen, die mit externen APIs interagieren, sehen Sie sich unsere Anleitung zur Integration von Ollama mit Python, die die Erstellung von Python-Clients mit sowohl REST-API als auch offiziellen Bibliotheksintegrationen demonstriert.
Plugin-Systeme
Aktivieren Sie die Plugin-Erkennung:
[project.entry-points."mypackage.plugins"]
plugin_a = "mypackage_plugin_a:PluginA"
C-Erweiterungen
Für leistungskritischen Code:
[tool.setuptools.ext-modules]
name = "mypackage._speedups"
sources = ["src/mypackage/_speedups.c"]
Namensraum-Pakete
Für verteilte Pakete unter einem gemeinsamen Namensraum:
[tool.setuptools.packages.find]
where = ["src"]
include = ["company.*"]
[tool.setuptools.package-data]
"company.mypackage" = ["py.typed"]
Nützliche Tools und Ressourcen
Paketentwicklungs-Tools
- cookiecutter: Projektvorlagen für Python-Pakete
- tox: Testautomatisierung über Python-Versionen
- nox: Flexible Testautomatisierung (tox-Alternative)
- pre-commit: Git-Hook-Framework für Code-Qualität
- commitizen: Standardisieren Sie Commit-Nachrichten und Versionierung
Dokumentationsplattformen
- Read the Docs: Kostenlose Dokumentationshosting
- GitHub Pages: Hosten Sie MkDocs- oder Sphinx-Dokumentation
- pdoc: Einfacher API-Dokumentationsgenerator
Paketregistries
- PyPI: Der offizielle Python Package Index (pypi.org)
- TestPyPI: Testumgebung (test.pypi.org)
- Anaconda.org: Conda-Paketverteilung
- GitHub Packages: Private Pakethosting
Überwachung und Analysen
- PyPI Stats: Download-Statistiken für Pakete
- Libraries.io: Abhängigkeitsüberwachung und -warnungen
- Snyk: Sicherheitslücken-Scanning
- Dependabot: Automatisierte Abhängigkeitsaktualisierungen
Fazit
Moderne Python-Paketierung hat sich zu einer developerfreundlichen Lösung mit Standards wie pyproject.toml, leistungsfähigen Build-Backends und sicherer Veröffentlichung über Trusted Publishing entwickelt. Mit dieser Anleitung können Sie professionelle, wartbare Python-Pakete erstellen, die Ihre Benutzer effektiv bedienen.
Wichtige Erkenntnisse:
- Verwenden Sie pyproject.toml für alle neuen Projekte
- Wählen Sie das richtige Build-Backend für Ihre Bedürfnisse
- Implementieren Sie automatisiertes Testen und CI/CD
- Verwenden Sie Trusted Publishing für sichere, tokenfreie Bereitstellung
- Folgen Sie semantischem Versionieren und pflegen Sie Changelogs
- Bieten Sie umfassende Dokumentation und Beispiele
Das Python-Paketierungsumfeld verbessert sich kontinuierlich mit besserer Tooling, Standards und Sicherheitsmerkmalen. Bleiben Sie mit Python Enhancement Proposals (PEPs) und Community-Best Practices auf dem Laufenden, um Ihre Pakete modern und wartbar zu halten.
Nützliche Links
- Python Packaging User Guide
- PEP 518 - Specifying Build System Requirements
- PEP 621 - Storing project metadata in pyproject.toml
- PyPI Trusted Publishing Documentation
- Setuptools Documentation
- Poetry Documentation
- Hatch Documentation
- TestPyPI
- Python Packaging Authority GitHub
- Semantic Versioning
- Choose a License