Fer Python i Bash Friendship: biblioteques smart-env i python-shell

Bon dia a tothom.

Avui dia, Python és un dels llenguatges més utilitzats en l'àmbit de la creació no només de productes de programari en si, sinó també de proporcionar la seva infraestructura. Com a resultat, molts devops, ja sigui per la seva voluntat o en contra, van haver d'aprendre un nou idioma per utilitzar-lo posteriorment com a complement dels bons scripts de Bash antics. Tanmateix, Bash i Python professen diferents enfocaments per escriure codi i tenen certes característiques, el que significa que portar els scripts Bash al "llenguatge de la serp" de vegades resulta ser una tasca àmplia i lluny de ser trivial.

Per facilitar la vida als devops, s'han creat i es continuen creant moltes biblioteques i utilitats útils a Python. Aquest article descriu dues biblioteques noves creades per l'autor d'aquesta publicació: smart-env и python-shell - i dissenyat per alleujar els devots de la necessitat de prestar molta atenció a les complexitats de treballar amb Python, deixant espai per a tasques més interessants. L'àmbit d'activitat de les biblioteques són les variables d'entorn i el llançament d'utilitats externes.

Tothom interessat, si us plau, vegeu cat.

Noves "bicicletes"?

Sembla, per què crear nous paquets per a operacions bastant normals? Què us impedeix utilitzar os.environ i subprocess.<mètode o classe que trieu> directament?

Aportaré proves a favor de cadascuna de les biblioteques per separat.

biblioteca smart-env

Abans d'escriure la teva pròpia idea, és útil connectar-te a Internet i buscar solucions ja fetes. Per descomptat, hi ha el risc de no trobar el que necessites, però això és més aviat un "esdeveniment d'assegurança". Com a regla general, aquest enfocament funciona i estalvia molt de temps i esforç.

Segons els resultats buscar es va revelar el següent:

  • hi ha paquets que en realitat embolcallen les trucades a os.environ, però al mateix temps requereixen un munt d'accions distraents (creació d'una instància d'una classe, paràmetres especials a les trucades, etc.);
  • Hi ha bons paquets, que, però, estan estrictament lligats a un ecosistema específic (principalment marcs web com Django) i per tant no són gens universals sense un fitxer;
  • hi ha pocs intents de fer alguna cosa nova. Per exemple, afegir mecanografia i analitzar explícitament els valors de les variables cridant mètodes com
    get_<typename>(var_name)

    O aquí una solució més, que, però, no admet l'ara deshonrat Python 2 (que, malgrat RIP oficial, encara hi ha muntanyes de codi escrit i ecosistemes sencers);

  • Hi ha manualitats d'alumnes de l'escola que, per algun motiu desconegut, van acabar al PyPI aigües amunt i només creen problemes amb la denominació de nous paquets (en particular, el nom "smart-env" és una mesura necessària).

I aquesta llista pot durar molt de temps. Tanmateix, els punts anteriors van ser suficients per entusiasmar-me amb la idea de fer alguna cosa convenient i universal.

Requisits que es van establir abans d'escriure smart-env:

  • L'esquema d'ús més senzill
  • Suport d'escriptura de dades fàcilment configurable
  • Compatible amb Python 2.7
  • Bona cobertura de codi per proves

Al final, tot això es va adonar. Aquí teniu un exemple d'ús:

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

Com podeu veure a l'exemple, per treballar amb una classe nova, només heu d'importar-la (no cal que creeu una instància, menys l'acció addicional). L'accés a qualsevol variable d'entorn s'aconsegueix referint-se a ella com una variable de la classe ENV, la qual cosa, de fet, fa d'aquesta classe un embolcall intuïtiu per a l'entorn del sistema natiu, alhora que la converteix en un possible objecte de configuració per a gairebé qualsevol sistema ( un enfocament similar, per exemple, s'aconsegueix a Django, només allà l'objecte de configuració és el mòdul/paquet de configuració en si).

L'habilitació/desactivació del mode de suport d'escriptura automàtica s'aconsegueix mitjançant dos mètodes: enable_automatic_type_cast() i disable_automatic_type_cast(). Això pot ser convenient si la variable d'entorn conté un objecte serialitzat semblant a JSON o fins i tot només una constant booleana (un dels casos més habituals és establir explícitament la variable DEBUG a Django comparant la variable d'entorn amb cadenes "vàlides"). Però ara no cal convertir les cadenes de manera explícita: la majoria de les accions necessàries ja estan incrustades a les profunditats de la biblioteca i només esperen un senyal per actuar. 🙂 En general, l'escriptura funciona de manera transparent i admet gairebé tots els tipus de dades integrades disponibles (no s'han provat el conjunt congelat, el complex i els bytes).

El requisit de donar suport a Python 2 es va implementar pràcticament sense sacrificis (l'abandonament de la mecanografia i alguns dels "caramels" de les últimes versions de Python 3), en particular, gràcies als sis omnipresents (per resoldre els problemes de l'ús de metaclasses). ).

Però hi ha algunes restriccions:

  • El suport de Python 3 significa la versió 3.5 i superior (la seva presència al vostre projecte és fruit de la mandra o de la manca de necessitat de millores, ja que és difícil trobar una raó objectiva per la qual encara esteu a la 3.4);
  • A Python 2.7, la biblioteca no admet la deserialització de literals conjunts. Descripció aquí. Però si algú el vol implementar, és benvingut :);

La biblioteca també té un mecanisme d'excepció en cas d'errors d'anàlisi. Si cap dels analitzadors disponibles no pot reconèixer la cadena, el valor continua sent una cadena (més aviat, per raons de comoditat i compatibilitat amb la lògica habitual de com funcionen les variables a Bash).

biblioteca python-shell

Ara us parlaré de la segona biblioteca (ometré la descripció de les deficiències dels anàlegs existents; és similar a la descrita per a smart-env. Analogues - aquí и aquí).

En general, la idea d'implementació i els seus requisits són similars als descrits per a smart-env, com es pot veure a l'exemple:

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

La idea és aquesta:

  1. Una única classe que representa Bash al món Python;
  2. Cada comanda Bash es crida com a funció de la classe Shell;
  3. Els paràmetres de cada trucada de funció es passen a la trucada d'ordres Bash corresponent;
  4. Cada comanda s'executa "aquí i ara" en el moment en què es crida, és a dir. l'enfocament sincrònic funciona;
  5. és possible accedir a la sortida d'una ordre a stdout, així com al seu codi de retorn;
  6. Si l'ordre no es troba al sistema, es llança una excepció.

Igual que amb smart-env, hi ha suport per a Python 2 (tot i que es necessitava una mica més de sang de sacrifici) i no hi ha suport per a Python 3.0-3.4.

Plans de desenvolupament de la biblioteca

Ja podeu utilitzar les biblioteques: totes dues es publiquen al PyPI oficial. Les fonts estan disponibles a Github (vegeu més avall).

Ambdues biblioteques es desenvoluparan tenint en compte els comentaris recollits dels interessats. I, si pot ser difícil crear una varietat de funcions noves a smart-env, aleshores a python-shell definitivament hi ha alguna cosa més a afegir:

  • suport per a trucades sense bloqueig;
  • possibilitat de comunicació interactiva amb l'equip (treballant amb stdin);
  • afegint propietats noves (per exemple, propietat per rebre la sortida de stderr);
  • implementació d'un directori d'ordres disponibles (per utilitzar amb la funció dir());
  • etcètera

Referències

  1. biblioteca smart-env: Github и PyPI
  2. biblioteca python-shell: Github и PyPI
  3. Canal de Telegram actualitzacions de la biblioteca

Actualització 23.02.2020/XNUMX/XNUMX:
* S'han mogut els repositoris, s'han actualitzat els enllaços corresponents
* La versió python-shell==1.0.1 s'està preparant per al llançament el 29.02.2020/XNUMX/XNUMX. Els canvis inclouen suport per a l'autocompletar ordres i l'ordre dir(Shell), executar ordres amb un identificador de Python no vàlid i correccions d'errors.

Font: www.habr.com

Afegeix comentari