Ti spiego la procedura che ho seguito per pubblicare il mio primo package su PyPi (pysunsky) e tutte le mitiche sfide che ho dovuto superare

Come pubblicare un package in Python su PyPi

26-08-2020

Compro molti prodotti online, spesso compro anche dalla Cina, tutti voi ormai conoscete benissimo i principali store:

  • GearBest
  • Deal Extreme (noto anche come DX)
  • AliExpress
  • Wish
  • BangGood

e potrei ancora andare avanti, la lista ormai è davvero lunga. Gli store cinesi sono tantissimi e continuano ad aumentare.

Uno dei siti dal qualche ogni tanto compro, da ormai diversi anni, è Sunsky Online.

Adesso ti chiederai:

Perchè mi stai parlando di Sunsky?

Perchè questo store offre un servizio che in altri non ho ancora trovato. Quando effettui degli acquisti ti cumula dei “punti esperienza”, al secondo livello sblocchi la possibilità di accedere al loro catalogo ed alla lista dei tuoi ordini via API. Più sali di livello e più chiamate al giorno puoi fare.

Immagino che, essendo rivolto principalmente ai rivenditore che al cliente finale, molti dei loro utenti abbiano la necessità di sincronizzare i prodotti e gli ordini effettuati con un software gestionale.

Io ho sbloccato da un bel po' questa possibilità, però per richiedere le chiavi di accesso devi contattarli via Skype, ed ho sempre rimandato.

Poi qualche settimana fa', consultando la loro documentazione mi sono accorto che mettevano a disposizione anche un SDK in Java ed in PHP. E quindi mi sono detto, potrei scrivere io l'SDK in Python! E così è stato.. Mi hanno anche citato nella loro documentazione (in fondo alla pagina, all’appendice E)

Qui puoi trovare il link al mio repository GitHub.

Successivamente mi sono documentato su come pubblicare il package su PyPi, per metterlo a disposizione di chiunque ne dovesse avere bisogno.

Prepara il tuo progetto alla pubblicazione

Essenzialmente sono solo 2 i files che sono necessari per poter pubblicare il tuo package su PyPi:

  • setup.py
  • setup.cfg

Il primo (setup.py) è molto semplice. Visualizza su GitHub.

from setuptools import setup

setup()

Nel secondo invece andrai ad elencare tutte le proprietà e le dipendenze del tuo progetto. Visualizza su GitHub.

[metadata]
name = pysunsky
version = 1.0
description = Simple SDK for use the Open API's of sunsky-online.com
long_description = file: readme.rst
url = https://github.com/progressify/sunsky-python-api-service
license = MIT
author = Progressify
author_email = info@progressify.dev
keywords = sunsky, api, e-commerce, dropshipping
classifiers =
    Programming Language :: Python
    Programming Language :: Python :: 3
    Programming Language :: Python :: 3.7
install_requires =
    configparser
    requests
[options]
zip_safe = False
python_requires = >= 3.7
test_suite = tests
packages =
    pysunsky
[bdist_wheel]
universal=0

Come pubblicare packages su PyPi

Prima di cominciare devi registrarti su PyPi.

Una volta registrato devi aprire un terminale e posizionarti nella cartella del progetto. Io utilizzo PyCharm, quindi mi è bastato aprire la tab “Terminal” presente nella barra in basso.

Installa subito Twine, ti servirà:

pip install twine

Poi devi creare un file nella root del progetto con nome: .pypirc. Sostituisci progressify con il tuo username.

[distutils]
index-servers=pypi

[pypi]
repository = https://pypi.python.org/pypi
username = progressify

Ho lanciato questo comando per creare il pacchetto da distribuire: python setup.py sdist.

progressify@mbpro16 sunskyApi % python setup.py sdist
running sdist
running egg_info
creating pysunsky.egg-info
writing pysunsky.egg-info/PKG-INFO
writing dependency_links to pysunsky.egg-info/dependency_links.txt
writing top-level names to pysunsky.egg-info/top_level.txt
writing manifest file 'pysunsky.egg-info/SOURCES.txt'
reading manifest file 'pysunsky.egg-info/SOURCES.txt'
writing manifest file 'pysunsky.egg-info/SOURCES.txt'
running check
creating pysunsky-1.0
creating pysunsky-1.0/pysunsky
creating pysunsky-1.0/pysunsky.egg-info
copying files to pysunsky-1.0...
copying setup.cfg -> pysunsky-1.0
copying setup.py -> pysunsky-1.0
copying pysunsky/__init__.py -> pysunsky-1.0/pysunsky
copying pysunsky/api.py -> pysunsky-1.0/pysunsky
copying pysunsky.egg-info/PKG-INFO -> pysunsky-1.0/pysunsky.egg-info
copying pysunsky.egg-info/SOURCES.txt -> pysunsky-1.0/pysunsky.egg-info
copying pysunsky.egg-info/dependency_links.txt -> pysunsky-1.0/pysunsky.egg-info
copying pysunsky.egg-info/not-zip-safe -> pysunsky-1.0/pysunsky.egg-info
copying pysunsky.egg-info/top_level.txt -> pysunsky-1.0/pysunsky.egg-info
Writing pysunsky-1.0/setup.cfg
creating dist
Creating tar archive
removing 'pysunsky-1.0' (and everything under it)

Alla fine del processo ho trovato una directory dist nel mio progetto, con al suo interno il file della release con estensione: tar.gz.

Non resta altro che pubblicarlo! (Ed è qui che ci serve Twine)

(myvenv) progressify@mbpro16 sunskyApi % twine upload -r pypi  dist/*             
Uploading distributions to https://upload.pypi.org/legacy/
Enter your username: progressify
Enter your password: 
Uploading pysunsky-1.0.tar.gz
100%|███████████████████████████████████████████████████████████████████| 7.09k/7.09k [00:03<00:00, 1.87kB/s]

View at:
https://pypi.org/project/pysunsky/1.0/

A questo link puoi ancora trovare la prima release: https://pypi.org/project/pysunsky/1.0/

Come puoi notare anche tu, la descrizione del progetto si vede malissimo! Ho fatto qualche ricerchina, ho capito che PyPi vuole la descrizione in formato reStructuredText, il MarkDown proprio non gli piace 😅.

Mi scocciavo di apprestarmi ad imparare una nuova sintassi, a quest’ora poi (erano le 9 di sera circa). Stavo per mollare, quando sotto consiglio di un amico (che saluto e ringrazio per avermi assistito ogni tanto, Salvatore, scopro che esistono dei convertitori online. STUPENDO!

Ti linko quello che ho usato io: https://cloudconvert.com/

Semplicissimo, carico il file MarkDown, scarico il file reStructuredText. Sostituisco nel setup.cfg il riferimento.

Impacchetto e provo a distribuire nuovamente.

Nel ricaricare il pacchetto ricevo questo errore:

(myvenv) progressify@mbpro16 sunskyApi % twine upload -r pypi  dist/*
Uploading distributions to https://upload.pypi.org/legacy/
Enter your username: progressify
Enter your password: 
Uploading pysunsky-1.0.tar.gz
100%|███████████████████████████████████████████████████████████████████| 6.22k/6.22k [00:01<00:00, 3.32kB/s]
NOTE: Try --verbose to see response content.
HTTPError: 400 Bad Request from https://upload.pypi.org/legacy/
The description failed to render in the default format of reStructuredText. 
See https://pypi.org/help/#description-content-type for more information.

A quanto pare, non gli piacciono le immagini, non so se è un limite di PyPi o se il convertitore mi ha giocato un brutto scherzo. Sinceramente non ci ho badato troppo, ho semplicemente cancellato dal file readme.rst le immagini con i badge.

Impacchetto e provo a distribuire nuovamente.

Poteva andare tutto liscio?

(myvenv) progressify@mbpro16 sunskyApi % twine upload -r pypi  dist/*
Uploading distributions to https://upload.pypi.org/legacy/
Enter your username: progressify
Enter your password: 
Uploading pysunsky-1.0.tar.gz
100%|███████████████████████████████████████████████████████████████████| 6.29k/6.29k [00:02<00:00, 2.79kB/s]
NOTE: Try --verbose to see response content.
HTTPError: 400 Bad Request from https://upload.pypi.org/legacy/
File already exists. See https://pypi.org/help/#file-name-reuse for more information.

Ed effettivamente ha ragione. Non puoi pubblicare un aggiornamento con lo stesso numero di versione. Che si fa in questi casi? Ho dovuto aumentare il numero di versione.

Impacchetto e provo a distribuire nuovamente.

E finalmente https://pypi.org/project/pysunsky/1.0.1/.

Antonio Porcelli @progressify

Antonio Porcelli

@progressify

Commenta l'articolo

Se non visualizzi il blocco dei commenti è perchè non hai accettato i cookies.
Cancella le preferenze del tuo browser per questo sito, aggiorna la pagina ed accetta i cookies.