Colleghiamo Python e Bash: le librerie smart-env e python-shell

Buongiorno a tutti.

Oggi Python è uno dei linguaggi più utilizzati nel campo non solo dello sviluppo di prodotti software, ma anche della gestione della loro infrastruttura. Di conseguenza, molti devops, per scelta o costrizione, si sono trovati a dover imparare un nuovo linguaggio da utilizzare come complemento ai vecchi e affidabili script Bash. Tuttavia, Bash e Python seguono approcci diversi nella scrittura del codice e hanno caratteristiche specifiche, per cui il porting degli script Bash nel 'linguaggio serpente' può risultare un compito impegnativo e tutt'altro che banale.

Per semplificare la vita ai devops, sono state create e continuano a essere sviluppate molte librerie e utility utili in Python. Questo articolo descrive due nuove librerie, create dall'autore di questo post — smart-env e python-shell — pensate per liberare i devops dalla necessità di prestare troppa attenzione alle complessità del lavoro con Python, lasciando spazio a compiti più interessanti. L'ambito di applicazione delle librerie riguarda le variabili d'ambiente e l'esecuzione di utility esterne.

Chi fosse interessato, è pregato di continuare a leggere.

Nuove 'biciclette'?

Sembrerebbe inutile creare nuovi pacchetti per operazioni piuttosto comuni. Cosa impedisce di usare direttamente os.environ e subprocess.?

Fornirò le prove a sostegno di ciascuna libreria separatamente.

Libreria smart-env

Prima di scrivere la propria creazione, è utile cercare in Internet soluzioni pronte. Certo, c'è il rischio di non trovare ciò che serve, ma questo è più un 'caso assicurativo'. Di solito, questo approccio funziona e fa risparmiare un sacco di tempo e fatica.

In base ai risultati cerca è emerso quanto segue:

  • esistono pacchetti che effettivamente avvolgono le chiamate a os.environ, ma richiedono molte azioni distraenti (creazione di un'istanza di classe, parametri speciali nelle chiamate, ecc.);
  • ci sono buoni pacchetti, ma rigidamente legati a un certo ecosistema (principalmente ai framework web come Django), e quindi non sono affatto universali senza ritocchi;
  • ci sono rare tentativi di fare qualcosa di nuovo. Ad esempio, aggiungere tipizzazione e analizzare esplicitamente i valori delle variabili chiamando metodi del tipo
    get_(var_name)

    O ancora un'altra soluzione, che, però, non supporta l'ormai obsoleto Python 2 (su cui, nonostante il R.I.P. ufficiale.), ci sono ancora montagne di codice scritto e interi ecosistemi);

  • ci sono lavori scolastici e universitari, del tutto incomprensibili, che si sono ritrovati nello PyPI upstream e che creano solo problemi con la denominazione dei nuovi pacchetti (in particolare, il nome «smart-env» è una misura forzata).

E questo elenco potrebbe continuare a lungo. Tuttavia, i punti sopra citati sono stati sufficienti per accendere l'idea di creare qualcosa di comodo e universale.

Requisiti posti per la scrittura di smart-env:

  • Schema d'uso il più semplice possibile
  • Supporto per la tipizzazione dei dati facilmente configurabile
  • Compatibilità con Python 2.7
  • Buona copertura del codice con i test

Alla fine, tutto questo è stato realizzato. Ecco un esempio di utilizzo:

from smart_env import ENV

print(ENV.HOME)  # Equivalent a print(os.environ['HOME'])

# presupponendo di aver impostato la variabile d'ambiente MYVAR su "True"

ENV.enable_automatic_type_cast()

my_var = ENV.MY_VAR  # Equivalent a boolean True

ENV.NEW_VAR = 100  # Imposta una nuova variabile d'ambiente

Come si può vedere dall'esempio, per lavorare con la nuova classe è sufficiente importarla (non è necessario creare un'istanza — un'azione superflua). L'accesso a qualsiasi variabile d'ambiente avviene tramite il riferimento a essa come variabile della classe ENV, il che rende questa classe un involucro intuitivo dell'ambiente di sistema nativo, trasformandolo parallelamente in una possibile variante di oggetto di configurazione per praticamente qualsiasi sistema (un approccio simile, ad esempio, viene raggiunto in Django, dove l'oggetto di configurazione è direttamente il modulo/pacchetto settings).

L'attivazione/disattivazione della modalità di supporto per la tipizzazione automatica è realizzata tramite due metodi — enable_automatic_type_cast() e disable_automatic_type_cast(). Questo può essere utile se nella variabile d'ambiente è contenuto un oggetto simile a JSON serializzato o anche solo una costante booleana (l'impostazione esplicita della variabile DEBUG in Django confrontando la variabile d'ambiente con stringhe 'ammissibili' è uno dei casi più comuni). Ma ora non c'è bisogno di convertire esplicitamente le stringhe — la maggior parte delle azioni necessarie è già integrata nelle profondità della libreria e aspetta solo un segnale per partire all'azione. 🙂 In generale, la tipizzazione funziona in modo trasparente e supporta quasi tutti i tipi di dati incorporati disponibili (non sono stati testati frozenset, complex e bytes).

Il requisito di supporto per Python 2 è stato implementato praticamente senza sacrifici (rinunciare a typing e alcune "delizie" delle ultime versioni di Python 3), in particolare grazie al sempre presente six (per risolvere i problemi di utilizzo dei metaclass).

Ma ci sono anche alcune limitazioni:

  • Il supporto per Python 3 implica la versione 3.5 e superiori (la loro presenza nel tuo progetto è il risultato di pigrizia o della mancanza di necessità di miglioramenti, poiché è difficile inventare una ragione obiettiva per cui sei ancora su 3.4);
  • In Python 2.7 la libreria non supporta la deserializzazione dei letterali dei set. Descrizione qui. Ma, se qualcuno desidera implementarlo, è il benvenuto:);

La libreria adotta anche un meccanismo di eccezioni nel caso di errori di parsing. Se una stringa non può essere riconosciuta da nessuno degli analizzatori disponibili, il valore rimane stringa (piuttosto per comodità e per mantenere la compatibilità con la logica lavorativa dei variabili in Bash).

Libreria python-shell

Ora parlerò della seconda libreria (ometterò la descrizione dei difetti degli analoghi esistenti — è simile a quanto descritto per smart-env. Gli analoghi — qui e qui).

In generale, l'idea di implementazione e i requisiti ad essa sono simili a quelli descritti per smart-env, come si può vedere dall'esempio:

from python_shell import Shell

Shell.ls('-l', '$HOME')  # Equivale a "ls -l $HOME"

command = Shell.whoami()  # Equivale a "whoami"
print(command.output)  # stampa il tuo nome utente attuale

print(command.command)  # stampa "whoami"
print(command.return_code)  # stampa "0"
print(command.arguments)  # stampa ""

Shell.mkdir('-p', '\/tmp\/new_folder')  # crea una nuova cartella

L'idea è questa:

  1. Una classe unica che incarna Bash nel mondo Python;
  2. Ogni comando Bash è chiamato come funzione della classe Shell;
  3. I parametri di chiamata di ciascuna funzione vengono quindi passati alla chiamata del corrispondente comando Bash;
  4. Ogni comando viene eseguito "qui e ora" al momento della sua chiamata, ovvero si utilizza un approccio sincrono;
  5. c'è la possibilità di accedere all'output del comando in stdout, così come al suo codice di ritorno;
  6. Se il comando non è presente nel sistema, viene sollevata un'eccezione.

Come nel caso di smart-env, è garantito il supporto per Python 2 (anche se è servito un po' più di sangue sacrificiali) e non c'è supporto per Python 3.0-3.4.

Piani di sviluppo delle librerie

Le librerie possono già essere utilizzate: entrambe sono state pubblicate su PyPI ufficiale. I sorgenti sono disponibili su Github (vedi sotto).

Entrambi i framework si svilupperanno tenendo conto del feedback raccolto dagli interessati. E se in smart-env può essere difficile immaginare un'ampia varietà di nuove funzionalità, in python-shell c'è sicuramente ancora molto da aggiungere:

  • supporto per chiamate non bloccanti;
  • possibilità di interazione diretta con il team (lavoro con stdin);
  • aggiunta di nuove proprietà (ad esempio, property per ottenere l'output da stderr);
  • realizzazione di un catalogo di comandi disponibili (da utilizzare con la funzione dir());
  • ecc.

Link

  1. Library smart-env: Github e PyPI
  2. Library python-shell: Github e PyPI
  3. Canale Telegram aggiornamenti delle librerie

UPD 23.02.2020:
* I repository sono stati trasferiti, i link corrispondenti sono stati aggiornati
* La versione python-shell==1.0.1 è in fase di rilascio il 29.02.2020. Tra le modifiche: supporto per l'autocompletamento dei comandi e il comando dir(Shell), esecuzione di comandi con identificatori non validi per Python, correzione di bug.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster