Dober dan vsem.
Danes je Python eden iz najbolj razširjenih jezikov na področju razvoja ne le programske opreme, temveč tudi zagotavljanja njihove infrastrukture. Zaradi tega se je mnogim DevOps-om, po njihovi volji ali ne, ukazalo, da se naučijo novega jezika, ki naj bi dopolnil stare dobre Bash skripte. Vendar se Bash in Python razlikujeta v pristopu k pisanju kode in imata določene posebnosti, zaradi česar je prenos Bash skriptov v „zmajev jezik“ včasih zahtevna in daleč od trivialne naloge.
Da bi poenostavili življenje DevOps-om, je bilo ustvarjenih in se še naprej ustvarja številne uporabne knjižnice in orodja v Pythonu. Ta članek opisuje dve novi knjižnici, ki ju je ustvaril avtor tega prispevka — in — in sta namenjeni zmanjšanju potrebe DevOps-a po posvečanju prevelike pozornosti podrobnostim dela s Pythonom, kar omogoča več prostora za zanimivejše naloge. Področje delovanja knjižnic so okoljske spremenljivke in zagon zunanjih orodij.
Kdor je zainteresiran, naj prebere naprej.
Nove 'kolesa'?
Zdi se, zakaj bi ustvarjali nove pakete za dovolj običajne operacije? Kaj preprečuje uporabo os.environ in subprocess neposredno. ?
Dokaze v podporo vsaki knjižnici bom navedel ločeno.
Knjižnica smart-env
Preden napišete svoje lastno tvorjenje, je koristno pobrskati po spletu in iskati rešitve. Seveda obstaja tveganje, da ne boste našli tistega, kar potrebujete, vendar je to bolj verjetno 'zavarovalni primer'. Na splošno pristop deluje in prihrani ogromno časa in truda.
Na osnovu rezultata je bilo ugotovljeno naslednje:
- so paketi, ki resnično obkrožajo klice k os.environ, vendar zahtevajo številne motilne akcije (ustvarjanje instance razreda, posebni parametri v klicih itd.);
- so dobri paketi, ki pa so močno vezani na določeno ekosistem (večinoma na spletne okvire, kot je Django) in zaradi tega brez prilagoditev sploh niso univerzalni;
- so redki poskusi, da bi naredili nekaj novega. Na primer, in jasno analizirati vrednosti spremenljivk z izvajanjem metod vrste
get_(var_name)Ali pa , ki pa ne podpira zdaj obsojenega Pythona 2 (na katerem, kljub , še vedno ostajajo gore napisanega kode in cela ekosistema);
- so tu še šolske in študentske kreacije, povsem nejasno zakaj so se znašle v upstream PyPI in ustvarjajo težave pri poimenovanju novih paketov (zlasti ime „smart-env“ — nujna rešitev).
In ta seznam bi se lahko dolgotrajno nadaljeval. Vendar pa je že to, kar je bilo navedeno zgoraj, zadostovalo, da smo se vznemirili z idejo, da ustvarimo nekaj uporabnega in univerzalnega.
Zahteve, ki jih je bilo treba izpolniti pri pisanju smart-env:
- Najbolj preprost način uporabe
- Enostavno konfigurabilna podpora za tipizacijo podatkov
- Združljivost s Pythonom 2.7
- Dobre pokritosti kode s testi
Na koncu je vse to uspelo uresničiti. Tukaj je primer uporabe:
from smart_env import ENV
print(ENV.HOME) # Enako print(os.environ['HOME'])
# domnevajmo, da ste nastavili okoljsko spremenljivko MYVAR na "True"
ENV.enable_automatic_type_cast()
my_var = ENV.MY_VAR # Enako boolean True
ENV.NEW_VAR = 100 # Nastavi novo okoljsko spremenljivko
Kot je razvidno iz primera, je za delo z novo razredom dovolj, da ga uvozite (ustvarjanje instance ni potrebno — minus nepotrebno dejanje). Dostop do katere koli okoljske spremenljivke se doseže z njenim naslovom kot do spremenljivke razreda ENV, kar dejansko ta razred naredi intuitivno razumljivo preobleko nativnega sistemskega okolja, obenem pa ga spremeni v možen konfiguracijski objekt praktično katere koli sistema (podoben pristop, na primer, dosežemo v Django, kjer je konfiguracijski objekt neposredno modul/paket settings).
Vklop/izklop načina podpore za avtomatsko tipizacijo se doseže z uporabo dveh metod — enable_automatic_type_cast() in disable_automatic_type_cast(). To lahko pride prav, če je v okoljski spremenljivki shranjen serializiran objekt, podoben JSON, ali preprosto booleanska konstanta (izrecno določanje spremenljivke DEBUG v Django s primerjavo okoljske spremenljivke z „dovoljenimi“ nizi — eden izmed pogostih primerov). Ampak zdaj ni potrebe po izrecnem pretvorbi nizov — večina potrebnih dejanj je že vgrajena v globine knjižnice in čaka na signal za dejanje. 🙂 Na splošno pa tipizacija deluje prozorno in podpira skoraj vse obstoječe vgrajene tipe podatkov (frozenset, complex in bytes niso bili preizkušeni).
Podpora za Python 2 je bila uresničena praktično brez žrtev (opustitev typing in nekaterih 'sladkarij' zadnjih različic Python 3), predvsem zahvaljujoč vsestranskemu six (za reševanje težav pri uporabi metaklas).
A vendar obstajajo tudi nekatere omejitve:
- Podpora za Python 3 predvideva različico 3.5 in višje (njena prisotnost v vašem projektu je rezultat bodisi lenobe bodisi pomanjkanja potrebe po izboljšavah, saj je težko najti objektiven razlog, zakaj ste še vedno na 3.4);
- V Python 2.7 knjižnica ne podpira deserializacije literala množic. Opis . Vendar, če se kdo želi uresničiti - dobrodošli;);
Knjižnica prav tako uporablja mehanizem izjem v primeru napak pri razčlenjevanju. Če niz ni mogoče prepoznati z nobenim od razpoložljivih analizatorjev, vrednost ostane nizovna (verjetno iz razloga uporabnosti in ohranitev združljivosti z običajno logiko delovanja spremenljivk v Bashu).
Knjižnica python-shell
Zdaj bom govoril o drugi knjižnici (opisa pomanjkljivosti obstoječih analogov ne bom podal - to je podobno tistemu, kar je bilo opisano za smart-env. Analogi - in ).
Na splošno so ideja in zahteve za izvajanje podobne tistim, ki so opisane za smart-env, kar je razvidno iz primera:
from python_shell import Shell
Shell.ls('-l', '$HOME') # Enakovredno "ls -l $HOME"
command = Shell.whoami() # Enakovredno "whoami"
print(command.output) # izpiše vaše trenutno uporabniško ime
print(command.command) # izpiše "whoami"
print(command.return_code) # izpiše "0"
print(command.arguments) # izpiše ""
Shell.mkdir('-p', 'tmp/new_folder') # ustvari novo mapo
Ideja je taka:
- Enotna klasa, ki predstavlja Bash v svetu Pythona;
- Vsaka Bash ukaz se pokliče kot funkcija razreda Shell;
- Parametri klica vsake funkcije se nato prenesejo v klic ustrezne Bash ukaza;
- Vsak ukaz se izvrši 'tukaj in zdaj' ob trenutnem klicu, tj. uporablja se sinhroniziran pristop;
- obstaja možnost dostopa do izhodnih podatkov ukaza v stdout, prav tako kot tudi do njegovega izhodnega kode;
- Če ukaz v sistemu ne obstaja - se sproži izjema.
Kot pri smart-env, je zagotovljena podpora za Python 2 (res pa je bilo potrebnih nekoliko več žrtev) in ni podpora za Python 3.0-3.4.
Načrti za razvoj knjižnic
Knjižnice se že zdaj lahko uporabljajo: obe sta objavljeni na uradnem PyPI. Izvorne kode so dostopne na Githubu (glej spodaj).
Obe knjižnice se bodo razvijale ob upoštevanju povratnih informacij, zbranih od zainteresiranih. In če je v smart-env morda težko smiselno razviti raznolikost novih funkcij, pa je v python-shell zagotovo še veliko prostora za dodatke:
- podpora za neblokirne klice;
- možnost interaktivne komunikacije s skupino (delo z stdin);
- dodajanje novih lastnosti (na primer, property za pridobivanje izhoda iz stderr);
- izvedba imenika dostopnih ukazov (za uporabo s funkcijo dir());
- itd.
Povezave
- Knjižnica smart-env: in
- Knjižnica python-shell: in
- posodobitve knjižnic
UPD 23.02.2020:
* Repozitoriji so bili preneseni, ustrezne povezave so posodobljene
* Različica python-shell==1.0.1 se pripravlja za izid 29.02.2020. Med spremembami je podpora za samodejno dopolnjevanje ukazov in ukaz dir(Shell), zagon ukazov s Python-neveljavnim identifikatorjem, odprava napak.
Izvor: habr.com
