Python apps

Creare una app Python è un’operazione indispensabile per potere distribuire o riutilizzare il codice in più progetti.

È una operazione relativamente facile ma con un sacco di varianti e di possibilità, quindi è opportuno scegliere la strategia corretta per evitare mal di testa inutili.

Anzitutto chiariamo che la descrizione del pacchetto è contenuta nel file di configurazione che storicamente è sempre stato setup.py la cui indiscussa leadership è ora messa in discussione in favore del nuovo file di configurazione pyproject.toml.

setup.py vs. pyproject.toml

Il primo può contenere codice Python il secondo no. setup.py contiene tutte le informazioni come argomenti di un singolo comando setup, il secondo contiene varie sezioni ed è generalmente abbastanza flessibile da permettere di informare l’istanza di Python che lo legge di quali strumenti sono necessari per potere creare il pacchetto (sdit o wheele) cosa che prima non era possibile senza setuptools (quindi setupttools -che non è un pacchetto della libreria di sistema- era una scelta obbligata anche solo per decidere di non usarlo…

Come spiegato nella pagina dedicata a Poetry, che usa questo formato, stiamo passando ad usare anche noi pyproject.toml che semplifica un po” la creazione dei pacchetti.

Il punto principale della semplificazione è nella dichiarazione di quantio deve finire nel pacchetto sia per quanto riguarda i moduli Pyhton sia per quanto riguarda i file non python (es.: css, html, js, …).

Non mi addentro in questo campo in quanto il cookiecutter che utilizzeremo si occupa già di tutto quanto necessario. Un pacchetto che sia preparato con Poetry e quindi pyptoject.toml è utilizzabile anche con pip ma purtroppo non è al momento caricabile con l’opzione -e editable.

requirements.txt

Ricordo che il file requirements.txt non c’entra nulla con il setup.py: requirements.txt è un modo -a mio avviso molto grezzo- di creare un ambiente virtuale. Dico che è grezzo in quanto non mantiene memoria di cone i pacchetti sono arrivati nel virtalenv e quindi non sa quando diventano obsoleti e possono essere eliminati. Inoltre non ha alcun meccanismo che garantisca che lo sviluppatore si sia ricordato di registrare la dipendenza.

namespaced app

Python offre la possibilità di generare pacchetti con namespace, ovvero pacchetti che codividono lo stesso namespace (thx per noi, in precedenza jmb). Questo permette di creare pacchetti differenti ma con una ragionevole fiducia di non andare incontro a conflitti di nomi (dal punto di vista Python, attenzione però alle label di Django!!). As esempio l’import:

from thx import core

non andrà in conflitto con altri pacchetti e se per caso vorremo importare nello stesso modulo django.core sarà banale fare un rename locale:

from thx import core as thx_core

I namespaced packages sono raccomandati all’interno di Thux e il namespace da usare al moemnto (2020) è thx che è inteso per app con Python 3.6+

generazione pacchetto Python per app

Per creare una app Python:

cookiecutter hg+ssh://git@hg.thux.dev/tools/cookiecutter/namespaced_app

I parametri che vengono chiesti sono:

namespace

(es.: jmb, thx - default)

app_name

il nome del pacchetto (senza namespace)

pkg_name

es: jmb.core, thx.api

version

(default: 0.1)

description

la descrizione in pyproject.toml

Al solito possono essere passati come riga di comando:

cookiecutter /misc/src/hg/thunder/skel/namespaced_app namespace=thx app_name=bingo pkg_name=thx-bingo

Setup

Lavorate sempre in un virtualenv che potete creare a scelta:

  • con mkvirtualenv di virtualwrapper

  • con pyenv virtualenv

  • con python -m venv

  • poetry crea un virtualenv di default in ~/.poetry/virtualenvs, ma poi non si aggiorna correttamente pip…

è importante che poi aggiorniate pip all’ultima versione altrimenti avrete problemi ad installare pacchetti thx=*

Il setup consigliato è tramite poetry:

poetry install --no-root

ma può anche essere fatto con pip:

pip install .

La creazione del pacchetto avverrà con:

poetry build

Per metterlo disponibile a tutti, se avete i permessi:

jmb-prepare -u

Dipendenza da altri pacchetti in sviluppo

Spesso, quando si comincia a creare pacchetti, ci troviamo nella necessità di sviluppare dei pacchetti in parallelo ed abbiamo la necessità che entrambe i repository vengano installati nel virtualenv in modalità development o edit, ovvero non installati in site-packages. Questo si ottiene con una semplice modifica del sys.path, che python fa per noi con l’opzione -e di pip, o --dev di Poetry. Purtoppo nessuna delle due è ottimale:

  • pip non sa farlo in presenza di file pyproject.toml

  • Poetry lo fa scrive e «in duro» nel file pyproject.toml la posizione fisica, in modo tale che chiunque voglia farlo si trova a dovere posizionare le cartelle nel medesimo modo.

Un’escamotage è di impostare noi il PYTHONPATH in modo che passi prima dal pacchetto in sviluppo. Possiamo fare questo nel file bin/activate. Sarebbe possibile farlo anche nel file .env e sarebbe più leggibile ma poi rimarrebbe anche dopo l’uscita dall’environment.