Come creare e distribuire un pacchetto Python

Cerca

In questo articolo analiziamo il processo di packaging di un progetto Python. Vediamo come aggiungere i file e la struttura necessari per creare il pacchetto, come compilare il pacchetto e come caricarlo sul Python Package Index (PyPI).

Requisiti

Come prima cosa assicuriamoci di aver installato l’ultima versione di PIP

				
					python3 -m pip install --upgrade pip
				
			

Lanciamo l’aggiornamento di build

				
					python3 -m pip install --upgrade build
				
			

E assicuriamoci che anche twine sia all’ultima versione

				
					python3 -m pip install --upgrade twine
				
			

Creazione del progetto

Questo tutorial utilizza un semplice progetto denominato example_package_YOUR_USERNAME_HERE. Il mio username è alessandro, quindi il pacchetto sarà example_package_alessandro; questo ci assicura di avere un nome di pacchetto univoco che non entri in conflitto con i pacchetti caricati da altre persone che seguono questo tutorial. Ti consiglio di seguire questo tutorial utilizzando questo progetto, prima di passare al packaging del tuo progetto reale.

Crea la seguente struttura di file in locale:

				
					packaging_tutorial/
└── src/
    └── example_package_YOUR_USERNAME_HERE/
        ├── __init__.py
        └── example.py
				
			

La directory contenente i file Python dovrebbe chiamarsi con il nome del progetto perché ciò semplifica la configurazione ed è di più facile interpretazione per gli utenti che installano il pacchetto.

È inoltre consigliata la creazione del file __init__.py perché l’esistenza di un file __init__.py consente agli utenti di importare la directory come un pacchetto normale, anche se (come nel caso di questo tutorial) __init__.py è vuoto.

example.py è un esempio di un modulo all’interno del pacchetto che potrebbe contenere la logica (funzioni, classi, costanti, ecc.) del pacchetto. Per questo esempio utilizzeremo qualcosa di molto semplice. Apri quindi il file example.py e inserisci il seguente contenuto:
				
					def add_one(number):
    return number + 1
				
			

Creazione dei package files

Ora aggiungiamo tutti i file necessari affinché il nostro progetto sia conforme e pronto per la sua distribuzione. Al termine, la struttura del progetto apparirà così:

				
					packaging_tutorial/
├── LICENSE
├── pyproject.toml
├── README.md
├── src/
│   └── example_package_YOUR_USERNAME_HERE/
│       ├── __init__.py
│       └── example.py
└── tests/
				
			

Creazione della test directory

tests/ è un placeholder per i file di test. Per il momento lo lasceremo semplicemente vuoto.

Scelta del backend di build

Strumenti come pip e build non convertono effettivamente i sorgenti in un pacchetto di distribuzione (come una wheel). Per svolgere questo lavoro dobbiamo affidarci ad un backend di build.

Esistono diversi backend, ognuno con caratteristiche diverse. In questo tutorial utilizziamo Hatchling di default, ma funzionerà in modo identico con Setuptools, Flit, PDM e tutti gli altri backend che supportano la tabella [project] per i metadati.

Il file pyproject.toml indica agli strumenti di frontend di build come pip e build quale backend utilizzare per il progetto. Di seguito sono riportati alcuni esempi di backend di build comuni
Hatchling
				
					[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
				
			
setuptools
				
					[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
				
			
Flit
				
					[build-system]
requires = ["flit_core>=3.4"]
build-backend = "flit_core.buildapi"
				
			
PDM
				
					[build-system]
requires = ["pdm-backend"]
build-backend = "pdm.backend"
				
			

La key requires è un elenco di pacchetti necessari per compilare il nostro progetto. Il frontend dovrebbe installarli automaticamente prima di compilare il progetto. Essendo che i frontend solitamente eseguono le build in ambienti isolati, omettere di specificare le dipendenze potrebbe causare errori in fase di compilazione. È pertanto necessario includere sempre il pacchetto del backend di build che si sta utilizzando, in quanto almeno quello è necessario che venga installato nell’ambiente isolato di compilazione.

La key build-backend è invece il nome dell’oggetto Python che il frontend utilizzerà per eseguire la build.

Configurazione dei metadata

Apriamo il file pyproject.toml e incolliamo il seguente contenuto cambiando opportunamente i dati relativi allo username. Questo ci assicura che il nome del package non andrà in conflitto con i packages caricati da altre persone che seguono questo tutorial.
				
					[project]
name = "example_package_YOUR_USERNAME_HERE"
version = "0.0.1"
authors = [
  { name="Example Author", email="author@example.com" },
]
description = "A small example package"
readme = "README.md"
requires-python = ">=3.8"
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]
[project.urls]
Homepage = "https://github.com/pypa/sampleproject"
Issues = "https://github.com/pypa/sampleproject/issues"
				
			

Creazione del file README.md

Apriamo il file README.md e inseriamo il seguente contenuto.
				
					# Example Package
This is a simple example package. You can use
[GitHub-flavored Markdown](https://guides.github.com/features/mastering-markdown/)
to write your content.
				
			

Creazione del file README.md

È importante che ogni pacchetto caricato sul Python Package Index includa una licenza in quanto indica agli utenti che installeranno e utilizzeranno il pacchetto i termini in base ai quali lo possono utilizzare. Per assistenza nella scelta di una licenza, un sito di riferimento è https://choosealicense.com/. Dopo aver scelto una licenza, apriamo LICENSE e inseriamo il testo della licenza.

Nel nostro esempio utiliziamo la licenza MIT:

				
					Copyright (c) 2018 The Python Packaging Authority
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
				
			

Generazione dei distribution archives

Non ci resta ora che costruire il nostro package. Per fare ciò, collochiamoci nella directory dove è contenuto il file pyproject.toml e lanciamo il seguente comando:
				
					python3 -m build
				
			

L’esecuzione di questo comando darà come output una cospiqua quantità di testo. Una volta completato troveremo una directory chiamata dist/ la quale conterrà due file.

				
					dist/
├── example_package_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl
└── example_package_YOUR_USERNAME_HERE-0.0.1.tar.gz
				
			

Upload del package su PyPI

Finalmente possiamo caricare il nostro pacchetto su PyPI. Però sono necessari alcuni passaggi preliminari. Vediamoli in dettaglio.

Registrazione account

La prima cosa da fare è registrare un account su TestPyPI. Seguiamo questo link e registriamo il nostro account https://test.pypi.org/account/register/

Generazione del token

Dopo aver registrato il nostro account su TestPyPI, dobbiamo generare il token che usiamo per caricare i nostri pacchetti. Seguiamo questo link e creiamo il token https://test.pypi.org/manage/account/#api-tokens

Nel mio account di esempio ho impostato un token in questo modo:

Creazione del file di configurazione di twine
Nella home del nostro user, creiamo il file .pypirc e incolliamo la seguente configurazione personalizzando la key password con il token che abbiamo appena creato.
				
					[testpypi]
  username = __token__
  password = pypi-[your-token]
				
			
Pubblicazione del pacchetto

Ora siamo davvero pronti! Pubblichiamo il nostro pacchetto con il seguente comando:

				
					python3 -m twine upload --repository testpypi dist/*
				
			

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.

Most Recent
Partners