Bygg Python-paket: Guide från utveckling till PyPI
Mäster Python-paketering från kod till PyPI-distribution
Python-paketering har utvecklats betydligt, med moderna verktyg och standarder som gör det enklare än någonsin att distribuera din kod.
Den här guiden leder dig genom att bygga professionella Python-paket och publicera dem på PyPI. Om du är nybörjare i Python eller behöver en snabb referens, kolla in vår Python Cheatsheet för att komma igång med grunderna i Python.

Varför paketera din Python-kod?
Att paketera ditt Python-projekt erbjuder flera fördelar:
- Återanvändbarhet: Dela kod mellan flera projekt utan att kopiera och klistra in
- Distribution: Låt andra installera din kod med ett enkelt
pip install - Beroendehantering: Klart specificera och hantera beroenden
- Versionering: Följ upp utgåvor och bibehålla bakåtkompatibilitet
- Professionella standarder: Följ Python-communityns bästa praxis
- Dokumentation: Strukturen uppmuntrar till ordentlig dokumentation och testning
Modern Python-paketstruktur
Ett välorganiserat paket följer denna 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
Src-layout föredras nu framför flat layout eftersom det:
- Förhindrar oavsiktliga importer av icke-installerad kod under utveckling
- Gör testning mer tillförlitlig genom att tvinga installation
- Skiljer tydligt källkod från andra projektfiler
När du organiserar ditt pakets interna struktur, överväg att tillämpa principer för ren arkitektur för att göra din kod mer underhållbar och testbar. Vår guide om Python Design Patterns for Clean Architecture täcker SOLID-principer, beroendeinjektion och lagerarkitektur som fungerar utmärkt med Python-paket.
Filen pyproject.toml: Modern konfiguration
pyproject.toml (PEP 518, 621) är den moderna standarden för Python-projektkonfiguration, som ersätter den äldre setup.py:
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "mypackage"
version = "0.1.0"
description = "Ett fantastiskt Python-paket"
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
{name = "Ditt Namn", email = "du@example.com"}
]
keywords = ["exempel", "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/dittanvändarnamn/mypackage"
Documentation = "https://mypackage.readthedocs.io"
Repository = "https://github.com/dittanvändarnamn/mypackage"
Issues = "https://github.com/dittanvändarnamn/mypackage/issues"
[project.scripts]
mypackage-cli = "mypackage.cli:main"
[tool.setuptools.packages.find]
where = ["src"]
Viktiga konfigurationer
- build-system: Anger byggverktyg (setuptools, hatchling, poetry-core, flit-core)
- project: Grundläggande metadata och beroenden
- project.optional-dependencies: Extra beroenden för funktioner (dev, docs, testning)
- project.scripts: Kommandoradsentrypunkter
- tool.*: Verktygsspecifik konfiguration (black, pytest, mypy, etc.)
Val av byggverktyg
Setuptools (Standardval)
Det mest använda och kompatibla alternativet:
[build-system]
requires = ["setuptools>=68.0", "wheel"]
build-backend = "setuptools.build_meta"
Fördelar: Universell kompatibilitet, omfattande funktioner, stort ekosystem Nackdelar: Mer omfattande konfiguration, långsammare än nya alternativ
Hatchling (Modern & Snabb)
Lättvikts och prestandastarkt modernt verktyg:
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Fördelar: Snabba byggningar, enkel konfiguration, bra standarder Nackdelar: Färre plugins än setuptools
Poetry (Allt-i-ett)
Komplett beroende- och miljöhantering:
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
[tool.poetry]
name = "mypackage"
version = "0.1.0"
description = "Ett fantastiskt Python-paket"
authors = ["Ditt Namn <du@example.com>"]
[tool.poetry.dependencies]
python = "^3.8"
requests = "^2.28.0"
Fördelar: Beroendeupplösning, låsfiler, integrerad arbetsflöde Nackdelar: Annorlunda arbetsflöde, större verktygsyta
Flit (Minimalistisk)
Enkelt verktyg för enkla paket:
[build-system]
requires = ["flit_core >=3.2,<4"]
build-backend = "flit_core.buildapi"
Fördelar: Extremt enkelt, minimal konfiguration Nackdelar: Begränsade funktioner för komplexa paket
Bygg ditt paket
Installera byggverktyg
# Installera det moderna byggverktyget
pip install build
# Eller för Poetry
pip install poetry
# Eller för Hatchling
pip install hatch
Bygg distributionsfiler
Använd paketet build (fungerar med alla verktyg):
# Rensa tidigare byggningar
rm -rf dist/ build/ *.egg-info
# Bygg källfördelning och wheel
python -m build
# Detta skapar:
# dist/mypackage-0.1.0.tar.gz (källfördelning)
# dist/mypackage-0.1.0-py3-none-any.whl (wheel)
Använd Poetry:
poetry build
Använd Hatch:
hatch build
Förstå distributionsformat
Källfördelning (sdist) - .tar.gz
- Innehåller källkod och bygginstruktioner
- Användarens pip bygger den under installation
- Inkluderar tester, dokumentation och andra utvecklingsfiler
Wheel - .whl
- Förbyggd binärfördelning
- Snabb installation (inget byggsteg)
- Plattformspecifik eller ren Python
- Rekommenderat format för distribution
Publicera på PyPI
Metod 1: Manuell uppdatering med Twine (Traditionell)
# Installera twine
pip install twine
# Kontrollera paketet innan uppdatering
twine check dist/*
# Ladda upp till TestPyPI först (rekommenderas)
twine upload --repository testpypi dist/*
# Testa installation från TestPyPI
pip install --index-url https://test.pypi.org/simple/ mypackage
# Ladda upp till produktions-PyPI
twine upload dist/*
Konfigurera autentisering i ~/.pypirc:
[distutils]
index-servers =
pypi
testpypi
[pypi]
username = __token__
password = pypi-AgEIcHlwaS5vcmc...
[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-AgENdGVzdC5weXBpLm9yZw...
Metod 2: Betrodd publicering (Rekommenderas för CI/CD)
Betrodd publicering använder OpenID Connect (OIDC) för att autentisera från CI/CD-plattformar utan att lagra token.
Inställning i PyPI:
- Gå till dina PyPI-projektinställningar
- Navigera till avsnittet “Publishing”
- Lägg till en ny “pending publisher”
- Konfigurera:
- Ägare: Ditt GitHub-användarnamn/organisation
- Repository: Repositorynamn
- Arbetsflöde:
publish.yml - Miljö:
release(valfritt men rekommenderas)
GitHub Actions Arbetsflöde (.github/workflows/publish.yml):
name: Publicera till PyPI
on:
release:
types: [published]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Konfigurera Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Installera byggberoenden
run: |
python -m pip install --upgrade pip
pip install build
- name: Bygg paket
run: python -m build
- name: Lagra distributionspaket
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: Hämta distributionspaket
uses: actions/download-artifact@v3
with:
name: python-package-distributions
path: dist/
- name: Publicera till PyPI
uses: pypa/gh-action-pypi-publish@release/v1
Fördelar:
- Inga API-token att hantera eller säkra
- Automatisk autentisering via OIDC
- Förbättrad säkerhet genom miljöskyddsregler
- Revisionsspårning av alla publiceringar
Bäst praxis
1. Versionshantering
Använd semantisk versionering (SemVer): MAJOR.MINOR.PATCH
# Installera versionshöjningsverktyg
pip install bump2version
# Höj version
bump2version patch # 0.1.0 -> 0.1.1
bump2version minor # 0.1.1 -> 0.2.0
bump2version major # 0.2.0 -> 1.0.0
Konfigurera i .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. Inkludera väsentliga filer
README.md: Klar projektbeskrivning, installationsanvisningar, användningsexempel LICENSE: Välj lämplig licens (MIT, Apache 2.0, GPL, etc.) CHANGELOG.md: Dokumentera ändringar mellan versioner .gitignore: Exkludera byggprodukter, cache, virtuella miljöer
3. Komplett testning
# Installera testberoenden
pip install pytest pytest-cov
# Kör tester med täckningsrapportering
pytest --cov=mypackage tests/
# Generera täckningsrapport
pytest --cov=mypackage --cov-report=html tests/
Konfigurera i pyproject.toml:
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
addopts = "--strict-markers --cov=mypackage"
4. Kvalitetsverktyg för kod
# Formatering
black src/ tests/
# Lintning
flake8 src/ tests/
# Typkontroll
mypy src/
# Importsortering
isort src/ tests/
Integrera i 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
Använd Sphinx för dokumentation:
# Installera Sphinx
pip install sphinx sphinx-rtd-theme
# Initiera dokumentation
cd docs
sphinx-quickstart
# Bygg dokumentation
make html
Eller använd MkDocs för enklare Markdown-baserad dokumentation:
pip install mkdocs mkdocs-material
mkdocs new .
mkdocs serve
6. Kontinuerlig integration
Att testa dina Python-paket över olika plattformar och miljöer är avgörande för tillförlitlighet. För insikter om Python-prestanda i olika distributionsscenarier, se vår jämförelse av AWS Lambda-prestanda: JavaScript vs Python vs Golang, som utforskar hur Python presterar i serverlösa miljöer.
Komplett CI/CD-flöde (.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: Konfigurera Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Installera beroenden
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
- name: Kör tester
run: pytest --cov=mypackage --cov-report=xml
- name: Ladda upp täckning
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Konfigurera Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Installera beroenden
run: |
pip install black flake8 mypy
- name: Black-formateringskontroll
run: black --check src/ tests/
- name: Flake8
run: flake8 src/ tests/
- name: MyPy
run: mypy src/
Vanliga fallgropar och lösningar
Problem 1: Importeringsfel efter installation
Problem: Paketet installerat men importering misslyckas
Lösning: Se till att du har rätt paketstruktur med __init__.py-filer och korrekt pyproject.toml-konfiguration:
[tool.setuptools.packages.find]
where = ["src"]
include = ["mypackage*"]
Problem 2: Saknade beroenden
Problem: Paketet installerat men misslyckas vid körning på grund av saknade beroenden
Lösning: Ange alla körningsberoenden i pyproject.toml:
[project]
dependencies = [
"requests>=2.28.0",
"click>=8.1.0",
]
Problem 3: Versionskonflikter
Problem: Paketet fungerar i utveckling men misslyckas i produktion
Lösning: Använd virtuella miljöer och ange minimiversioner:
# Skapa isolerad miljö
python -m venv .venv
source .venv/bin/activate # På Windows: .venv\Scripts\activate
# Installera i redigeringsläge för utveckling
pip install -e ".[dev]"
Problem 4: Stort paketstorlek
Problem: Paketet tar för lång tid att ladda ner/installera
Lösning: Exkludera onödiga filer med MANIFEST.in:
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: Plattformspecifika problem
Problem: Paketet fungerar på ett operativsystem men misslyckas på ett annat
Lösning: Testa på flera plattformar med hjälp av CI/CD-matrisbyggnader (se CI-exempel ovan)
Publiceringschecklista
Innan du publicerar ditt paket till PyPI, verifiera:
- Alla tester går igenom över Python-versioner
- Koden är formaterad och lintad
- README.md är komplett med exempel
- LICENSE-fil är inkluderad
- Versionsnummer är uppdaterat
- CHANGELOG.md är uppdaterad
- Beroenden är korrekt angivna
- Paketet byggs utan fel (
python -m build) - Paketet testat på TestPyPI
- Dokumentationen är uppdaterad
- Git-repositoryn är märkt med version
- GitHub-release är skapad (för betrodd publicering)
Avancerade ämnen
Entry Points och CLI-verktyg
Skapa kommandoradsgränssnitt:
[project.scripts]
mypackage = "mypackage.cli:main"
Implementering i src/mypackage/cli.py:
import click
@click.command()
@click.option('--name', default='World', help='Namn att hälsa')
def main(name):
"""Exempel på enkelt CLI-verktyg"""
click.echo(f'Hello, {name}!')
if __name__ == '__main__':
main()
För ett verkligt exempel på att skapa Python-paket som interagerar med externa API:er, se vår guide om Integrering av Ollama med Python, som demonstrerar byggandet av Python-klienter med både REST-API och officiella biblioteksintegreringar.
Plugin-system
Aktivera plugin-upptäckt:
[project.entry-points."mypackage.plugins"]
plugin_a = "mypackage_plugin_a:PluginA"
C-extensioner
För prestandakritisk kod:
[tool.setuptools.ext-modules]
name = "mypackage._speedups"
sources = ["src/mypackage/_speedups.c"]
Namnrymdspaket
För distribuerade paket under en gemensam namnrymd:
[tool.setuptools.packages.find]
where = ["src"]
include = ["company.*"]
[tool.setuptools.package-data]
"company.mypackage" = ["py.typed"]
Användbara verktyg och resurser
Paketutvecklingsverktyg
- cookiecutter: Projektmallar för Python-paket
- tox: Testautomatisering över Python-versioner
- nox: Flexibel testautomatisering (tox-alternativ)
- pre-commit: Git-hook-ramverk för kodkvalitet
- commitizen: Standardisera commit-meddelanden och versionshantering
Dokumentationsplattformar
- Read the Docs: Gratis dokumentationsvärd
- GitHub Pages: Värd för MkDocs eller Sphinx-dokumentation
- pdoc: Enkel API-dokumentationsgenerator
Paketregister
- PyPI: Det officiella Python Package Index (pypi.org)
- TestPyPI: Testmiljö (test.pypi.org)
- Anaconda.org: Conda-paketdistribution
- GitHub Packages: Privat paketvärd
Övervakning och analys
- PyPI Stats: Nedladdningsstatistik för paket
- Libraries.io: Beroendeövervakning och varningar
- Snyk: Säkerhetsriskanalys
- Dependabot: Automatiserade beroendeuppdateringar
Slutsats
Modern Python-paketering har utvecklats för att vara utvecklarvänlig med standarder som pyproject.toml, kraftfulla byggsystem och säker publicering via Trusted Publishing. Genom att följa denna guide kan du skapa professionella, underhållbara Python-paket som effektivt tjänar dina användare.
Viktiga slutsatser:
- Använd pyproject.toml för alla nya projekt
- Välj rätt byggsystem för dina behov
- Implementera automatiserad testning och CI/CD
- Använd Trusted Publishing för säker, tokenfri distribution
- Följ semantisk versionering och underhåll changelogs
- Ge omfattande dokumentation och exempel
Python-paketeringsekosystemet fortsätter att förbättras med bättre verktyg, standarder och säkerhetsfunktioner. Håll dig uppdaterad med Python Enhancement Proposals (PEPs) och community-bäst praxis för att hålla dina paket moderna och underhållbara.
Användbara länkar
- 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