Creare amicizia tra Python e Bash: librerie smart-env e python-shell

Buona giornata a tutti

Oggi Python è uno dei linguaggi più utilizzati nel campo della creazione non solo dei prodotti software stessi, ma anche della fornitura della loro infrastruttura. Di conseguenza, molti devop, per loro volontà o contro di essa, hanno dovuto imparare un nuovo linguaggio da utilizzare successivamente come supplemento ai buoni vecchi script Bash. Tuttavia, Bash e Python professano approcci diversi alla scrittura del codice e hanno determinate caratteristiche, il che significa che il porting degli script Bash nel "linguaggio del serpente" a volte risulta essere un compito capiente e tutt'altro che banale.

Per rendere la vita più facile ai devops, sono state create e continuano a essere create molte librerie e utilità utili in Python. Questo articolo descrive due nuove librerie create dall'autore di questo post: ambiente intelligente и guscio di pitone - e progettato per alleviare i devops dalla necessità di prestare molta attenzione alle complessità del lavoro con Python, lasciando spazio a compiti più interessanti. L'ambito di attività delle biblioteche sono le variabili di ambiente e l'avvio di utilità esterne.

Chiunque sia interessato, veda il gatto.

Nuove "biciclette"?

Sembrerebbe, perché creare nuovi pacchetti per operazioni abbastanza ordinarie? Cosa ti impedisce di utilizzare os.environ e subprocess.<metodo o classe di tua scelta> direttamente?

Fornirò prove a favore di ciascuna delle biblioteche separatamente.

libreria smart-env

Prima di scrivere la tua idea, è utile andare online e cercare soluzioni già pronte. Certo, c'è il rischio di non trovare ciò di cui hai bisogno, ma questo è piuttosto un “evento assicurativo”. Di norma, questo approccio funziona e consente di risparmiare molto tempo e fatica.

Secondo i risultati ricerca è stato rivelato quanto segue:

  • ci sono pacchetti che effettivamente racchiudono le chiamate a os.environ, ma allo stesso tempo richiedono una serie di azioni che distraggono (creazione di un'istanza di una classe, parametri speciali nelle chiamate, ecc.);
  • Esistono buoni pacchetti, che però sono strettamente legati a un ecosistema specifico (principalmente framework web come Django) e quindi non sono affatto universali senza file;
  • ci sono rari tentativi di fare qualcosa di nuovo. Per esempio, aggiungi la digitazione e analizzare esplicitamente i valori delle variabili chiamando metodi come
    get_<typename>(var_name)

    O qui un'altra soluzione, che però non supporta l'ormai decaduto Python 2 (che, nonostante RIP ufficiale, esistono ancora montagne di codici scritti e interi ecosistemi);

  • Ci sono mestieri di studenti che, per qualche motivo sconosciuto, sono finiti nel PyPI upstream e creano solo problemi con la denominazione di nuovi pacchetti (in particolare, il nome “smart-env” è una misura necessaria).

E questo elenco potrebbe continuare a lungo. Tuttavia, i punti di cui sopra sono stati sufficienti per entusiasmarmi all’idea di creare qualcosa di conveniente e universale.

Requisiti impostati prima di scrivere smart-env:

  • Lo schema di utilizzo più semplice
  • Supporto per la digitazione dei dati facilmente configurabile
  • Compatibile con Python 2.7
  • Buona copertura del codice da parte dei test

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

from smart_env import ENV

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

# assuming you set env variable MYVAR to "True"

ENV.enable_automatic_type_cast()

my_var = ENV.MY_VAR  # Equals boolean True

ENV.NEW_VAR = 100  # Sets a new environment variable

Come puoi vedere dall'esempio, per lavorare con una nuova classe, devi solo importarla (non è necessario creare un'istanza, meno l'azione extra). L'accesso a qualsiasi variabile d'ambiente si ottiene facendo riferimento ad essa come una variabile della classe ENV, il che, di fatto, rende questa classe un wrapper intuitivo per l'ambiente di sistema nativo, trasformandola contemporaneamente in un possibile oggetto di configurazione per quasi tutti i sistemi ( un approccio simile, ad esempio, si ottiene in Django , solo che lì l'oggetto di configurazione è il modulo/pacchetto settings stesso).

L'abilitazione/disabilitazione della modalità di supporto della digitazione automatica si ottiene utilizzando due metodi: Enable_automatic_type_cast() e Disable_automatic_type_cast(). Questo può essere utile se la variabile d'ambiente contiene un oggetto serializzato simile a JSON o anche solo una costante booleana (impostare esplicitamente la variabile DEBUG in Django confrontando la variabile d'ambiente con stringhe "valide" è uno dei casi più comuni). Ma ora non è più necessario convertire esplicitamente le stringhe: la maggior parte delle azioni necessarie sono già integrate nelle profondità della libreria e aspettano solo un segnale per agire. 🙂 In generale, la digitazione funziona in modo trasparente e supporta quasi tutti i tipi di dati integrati disponibili (frozenset, complessi e byte non sono stati testati).

L'esigenza di supportare Python 2 è stata implementata praticamente senza sacrifici (l'abbandono della digitazione e di alcuni "zuccherini" delle ultime versioni di Python 3), in particolare grazie agli onnipresenti sei (per risolvere i problemi di utilizzo delle metaclassi ).

Ma ci sono alcune restrizioni:

  • Supporto Python 3 significa versione 3.5 e successive (la loro presenza nel tuo progetto è il risultato di pigrizia o mancanza di necessità di miglioramenti, poiché è difficile trovare una ragione oggettiva per cui sei ancora alla 3.4);
  • In Python 2.7, la libreria non supporta la deserializzazione dei valori letterali impostati. Descrizione qui. Ma se qualcuno vuole implementarlo, sei il benvenuto :);

La libreria dispone anche di un meccanismo di eccezione in caso di errori di analisi. Se la stringa non può essere riconosciuta da nessuno degli analizzatori disponibili, il valore rimane una stringa (piuttosto, per ragioni di comodità e compatibilità con la logica consueta di come funzionano le variabili in Bash).

libreria Python-Shell

Ora vi parlerò della seconda libreria (ometterò la descrizione delle carenze degli analoghi esistenti - è simile a quella descritta per smart-env. Analoghi - qui и qui).

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

from python_shell import Shell

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

command = Shell.whoami()  # Equals "whoami"
print(command.output)  # prints your current user name

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

Shell.mkdir('-p', '/tmp/new_folder')  # makes a new folder

L'idea è questa:

  1. Una singola classe che rappresenta Bash nel mondo Python;
  2. Ogni comando Bash viene chiamato in funzione della classe Shell;
  3. I parametri per ciascuna chiamata di funzione vengono quindi passati alla corrispondente chiamata al comando Bash;
  4. Ogni comando viene eseguito “qui e ora” nel momento in cui viene chiamato, cioè l'approccio sincrono funziona;
  5. è possibile accedere all'output di un comando in stdout, nonché al suo codice di ritorno;
  6. Se il comando non è nel sistema, viene generata un'eccezione.

Come con smart-env, c'è il supporto per Python 2 (sebbene fosse richiesto un po' più di sangue sacrificale) e nessun supporto per Python 3.0-3.4.

Piani di sviluppo della biblioteca

Ora puoi utilizzare le librerie: entrambe sono pubblicate sul PyPI ufficiale. I sorgenti sono disponibili su Github (vedi sotto).

Entrambe le librerie saranno sviluppate tenendo conto del feedback raccolto dagli interessati. E, se può essere difficile trovare una varietà di nuove funzionalità in smart-env, allora in python-shell c'è sicuramente qualcos'altro da aggiungere:

  • supporto per chiamate non bloccanti;
  • possibilità di comunicazione interattiva con il team (lavorare con stdin);
  • aggiunta di nuove proprietà (ad esempio, proprietà per ricevere l'output da stderr);
  • implementazione di una directory di comandi disponibili (da utilizzare con la funzione dir());
  • eccetera

riferimenti

  1. libreria smart-env: Github и PyPI
  2. libreria Python Shell: Github и PyPI
  3. Canale Telegram aggiornamenti della biblioteca

UPD 23.02.2020:
* I repository sono stati spostati, i collegamenti corrispondenti sono stati aggiornati
* La versione python-shell==1.0.1 è in preparazione per il rilascio il 29.02.2020/XNUMX/XNUMX. Le modifiche includono il supporto per il completamento automatico dei comandi e il comando dir(Shell), l'esecuzione di comandi con un identificatore Python non valido e correzioni di bug.

Fonte: habr.com

Aggiungi un commento