Vzpostavljanje prijateljstva med Pythonom in Bashom: knjižnici smart-env in python-shell

dober dan vsem

Danes je Python eden najpogosteje uporabljenih jezikov na področju ustvarjanja ne le samih programskih izdelkov, temveč tudi zagotavljanja njihove infrastrukture. Posledično so se številni devopsi, bodisi po svoji volji ali proti njej, morali naučiti novega jezika za kasnejšo uporabo kot dodatek k dobrim starim skriptom Bash. Vendar Bash in Python izpovedujeta različne pristope k pisanju kode in imata določene značilnosti, kar pomeni, da se prenos skriptov Bash v "kačji jezik" včasih izkaže za obsežno in daleč od trivialne naloge.

Da bi devopsom olajšali življenje, je bilo ustvarjenih in se še naprej ustvarja veliko uporabnih knjižnic in pripomočkov v Pythonu. Ta članek opisuje dve novi knjižnici, ki ju je ustvaril avtor te objave - smart-env и python-shell - in zasnovan tako, da razbremeni devops potrebe po posvečanju veliko pozornosti zapletenosti dela s Pythonom, kar pušča prostor za bolj zanimive naloge. Področje delovanja knjižnic so spremenljivke okolja in zagon zunanjih pripomočkov.

Kogar zanima naj si ogleda kat.

Nova "bicikla"?

Zdi se, zakaj ustvarjati nove pakete za dokaj običajne operacije? Kaj vam preprečuje neposredno uporabo os.environ in subprocess.<metoda ali razred po vaši izbiri>?

Podal bom dokaze v prid vsaki od knjižnic posebej.

knjižnica smart-env

Preden napišete lastno idejo, je koristno iti na splet in poiskati že pripravljene rešitve. Seveda obstaja tveganje, da ne boste našli tistega, kar potrebujete, vendar je to bolj "zavarovalni primer". Ta pristop praviloma deluje in prihrani veliko časa in truda.

Glede na rezultate iskanje se je pokazalo naslednje:

  • obstajajo paketi, ki dejansko zavijejo klice v os.environ, a hkrati zahtevajo kup motečih dejanj (ustvarjanje primerka razreda, posebni parametri v klicih itd.);
  • Obstajajo dobri paketi, ki pa so strogo vezani na določen ekosistem (predvsem spletna ogrodja, kot je Django) in zato brez datoteke sploh niso univerzalni;
  • redki so poskusi narediti nekaj novega. na primer dodajte tipkanje in eksplicitno razčleniti vrednosti spremenljivk s klicanjem metod, kot je
    get_<typename>(var_name)

    Ali tukaj še ena rešitev, ki pa ne podpira zdaj osramočenega Pythona 2 (ki kljub uradni RIP, obstajajo še gore napisane kode in celi ekosistemi);

  • obstajajo šolsko-študentske obrti, ki so iz neznanega razloga končale v zgornjem toku PyPI in povzročajo samo težave pri poimenovanju novih paketov (zlasti ime "smart-env" je nujen ukrep).

In ta seznam se lahko nadaljuje še dolgo. Vendar so bile zgornje točke dovolj, da sem se navdušil nad idejo, da naredim nekaj priročnega in univerzalnega.

Zahteve, ki so bile nastavljene pred pisanjem smart-env:

  • Najbolj preprosta shema uporabe
  • Enostavno nastavljiva podpora za tipkanje podatkov
  • Python 2.7 združljiv
  • Dobra pokritost kode s testi

Na koncu se je vse to uresničilo. Tukaj je primer uporabe:

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

Kot lahko vidite iz primera, ga morate za delo z novim razredom samo uvoziti (ni vam treba ustvariti primerka – brez dodatnih dejanj). Dostop do katere koli spremenljivke okolja je dosežen tako, da se nanjo nanaša kot na spremenljivko razreda ENV, zaradi česar je ta razred dejansko intuitiven ovoj za izvorno sistemsko okolje, hkrati pa ga spremeni v možen konfiguracijski objekt za skoraj vsak sistem ( podoben pristop je na primer dosežen v Djangu, le da je tam konfiguracijski objekt sam modul/paket nastavitev).

Omogočanje/onemogočanje načina podpore za samodejno tipkanje je doseženo z uporabo dveh metod - enable_automatic_type_cast() in disable_automatic_type_cast(). To je lahko priročno, če spremenljivka okolja vsebuje serializiran objekt, podoben JSON-u, ali celo samo logično konstanto (izrecna nastavitev spremenljivke DEBUG v Djangu s primerjavo spremenljivke okolja z "veljavnimi" nizi je eden najpogostejših primerov). Toda zdaj ni več potrebe po izrecni pretvarjanju nizov - večina potrebnih dejanj je že vdelanih v globine knjižnice in samo čakajo na signal za ukrepanje. 🙂 Na splošno tipkanje deluje pregledno in podpira skoraj vse razpoložljive vgrajene vrste podatkov (zamrznjene, kompleksne in bajtne niso bile preizkušene).

Zahteva po podpori za Python 2 je bila izvedena tako rekoč brez žrtvovanja (opustitev tipkanja in nekaj "sladkornih bonbonov" najnovejših različic Pythona 3), zlasti po zaslugi vseprisotnih šest (za reševanje težav z uporabo metarazredov ).

Vendar obstaja nekaj omejitev:

  • Podpora za Python 3 pomeni različico 3.5 in višje (njihova prisotnost v vašem projektu je posledica lenobe ali pomanjkanja potrebe po izboljšavah, saj je težko najti objektiven razlog, zakaj ste še vedno na 3.4);
  • V Pythonu 2.7 knjižnica ne podpira deserializacije nastavljenih literalov. Opis tukaj. Če pa ga kdo želi uresničiti, pa vabljeni :);

Knjižnica ima tudi mehanizem izjem v primeru napak pri razčlenjevanju. Če niza ne more prepoznati noben od razpoložljivih analizatorjev, vrednost ostane niz (namesto zaradi priročnosti in združljivosti za nazaj z običajno logiko delovanja spremenljivk v Bashu).

knjižnica python-shell

Zdaj vam bom povedal o drugi knjižnici (izpustil bom opis pomanjkljivosti obstoječih analogov - podoben je opisanemu za smart-env. Analogi - tukaj и tukaj).

Na splošno so ideja o implementaciji in zahteve zanjo podobne tistim, ki so opisane za smart-env, kot je razvidno iz primera:

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

Ideja je sledeča:

  1. En sam razred, ki predstavlja Bash v svetu Python;
  2. Vsak ukaz Bash se kliče kot funkcija razreda Shell;
  3. Parametri za vsak klic funkcije se nato posredujejo v ustrezen klic ukaza Bash;
  4. Vsak ukaz se izvede "tukaj in zdaj" v trenutku, ko je klican, tj. sinhroni pristop deluje;
  5. možen je dostop do izhoda ukaza v stdoutu, pa tudi do njegove povratne kode;
  6. Če ukaza ni v sistemu, se sproži izjema.

Tako kot pri smart-env obstaja podpora za Python 2 (čeprav je bilo potrebno malo več žrtvene krvi) in ni podpore za Python 3.0-3.4.

Načrti razvoja knjižnice

Knjižnici lahko uporabljate zdaj: obe sta objavljeni na uradnem PyPI. Viri so na voljo na Githubu (glejte spodaj).

Obe knjižnici bosta razviti ob upoštevanju povratnih informacij zainteresiranih. In če je v smart-env morda težko priti do različnih novih funkcij, potem je v python-shell vsekakor treba dodati še nekaj:

  • podpora za klice brez blokiranja;
  • možnost interaktivne komunikacije z ekipo (delo s stdin);
  • dodajanje novih lastnosti (na primer lastnost za prejemanje izhodnih podatkov iz stderr);
  • implementacija imenika razpoložljivih ukazov (za uporabo s funkcijo dir());
  • itd

reference

  1. knjižnica smart-env: GitHub и PyPI
  2. knjižnica python-shell: GitHub и PyPI
  3. Telegram kanal posodobitve knjižnice

UPD 23.02.2020. XNUMX. XNUMX:
* Repozitoriji so bili premaknjeni, ustrezne povezave so posodobljene
* Različica python-shell==1.0.1 je v pripravi za izdajo 29.02.2020. februarja XNUMX. Spremembe vključujejo podporo za samodokončanje ukazov in ukaz dir(Shell), izvajanje ukazov z neveljavnim identifikatorjem Python in popravke napak.

Vir: www.habr.com

Dodaj komentar