Dobrý deň všetkým.
V súčasnosti je Python jedným z najpoužívanejších jazykov v oblasti vytvárania nielen samotných softvérových produktov, ale aj zabezpečenia ich infraštruktúry. V dôsledku toho sa mnohým devopsovým odborníkom, či už proti svojej vôli alebo z vlastnej iniciatívy, muselo naučiť nový jazyk s cieľom doplniť svoje staré dobré Bash skripty. Avšak Bash a Python vyznávajú rôzne prístupy k písaniu kódu a majú určité špecifiká, takže portovanie Bash skriptov na „hadí jazyk“ niekedy predstavuje zložitú a rozhodne nie triviálnu úlohu.
Aby sa devopsovým odborníkom uľahčil život, bolo vytvorených a naďalej sa vytvára množstvo užitočných knižníc a utilít na Pythone. Tento článok popisuje dve nové knižnice, ktoré autor tohto príspevku vytvoril — a — a majú za cieľ zbaviť devopsových odborníkov potreby venovať veľa pozornosti nuansám práce s Python, pričom ponechávajú priestor na zaujímavejšie úlohy. Oblasť činnosti knižníc sa týka premenných prostredia a spúšťania externých utilít.
Tí, ktorých to zaujalo, prosím, pokračujte pod článkom.
Nové "bicykle"?
Zdalo by sa, prečo vytvárať nové balíky pre dosť bežné operácie? Čo bráni priamemu používaniu os.environ a subprocess.?
Dôkazy v prospech každej z knižníc uvediem osobitne.
Knižnica smart-env
Predtým, než napíšete vlastný výtvor, je dobré prehľadať Internet a hľadať hotové riešenia. Samozrejme, existuje riziko, že nenájdete to, čo potrebujete, ale to je skôr "poistná udalosť". Zvyčajne to funguje a šetrí množstvo času a síl.
Na základe bolo zistené nasledovné:
- existujú balíky, ktoré skutočne encapsulujú volania na os.environ, avšak vyžadujú množstvo rušivých akcií (vytvorenie inštancie triedy, špeciálne parametre vo volaniach atď.);
- existujú slušné balíky, ktoré sú však pevne previazané na určitý ekosystém (predovšetkým na webové rámce ako Django) a preto sú bez úprav úplne neuniverzálne;
- existujú ojedinelé pokusy vytvoriť niečo nové. Napríklad a jasne parsovať hodnoty premenných pomocou volania metód typu
get_(var_name)Alebo tu , ktoré však už nepodporuje aktuálne opustený Python 2 (na ktorom, napriek , stále zostáva množstvo napísaného kódu a celé ekosystémy);
- existujú školskostudentské projekty, úplne nezrozumiteľne sa dostávajúce do upstream PyPI a len vytvárajúce problémy s názvami nových balíkov (najmä názov „smart-env“ — nútené opatrenie).
A tento zoznam by sa dal dlhodobo predlžovať. Avšak aj na vyššie uvedených bodoch stačilo na to, aby sa zrodila myšlienka vytvoriť niečo pohodlné a univerzálne.
Požiadavky, ktoré boli stanovené pri písaní smart-env:
- Maximálne jednoduché schémy použitia
- Ľahko konfigurovateľná podpora typizácie dát
- Kompatibilita s Python 2.7
- Dobré pokrytie kódu testami
Nakoniec sa to všetko podarilo realizovať. Tu je príklad použitia:
from smart_env import ENV
print(ENV.HOME) # Rovná sa print(os.environ['HOME'])
# predpokladajme, že ste nastavili env premennú MYVAR na "True"
ENV.enable_automatic_type_cast()
my_var = ENV.MY_VAR # Rovná sa boolean True
ENV.NEW_VAR = 100 # Nastaví novú premennú prostredia
Ako je vidieť z príkladu, pre prácu s novou triedou stačí ju importovať (zbytočné akcie s vytváraním inštancií nie sú potrebné). Prístup k akejkoľvek premennej prostredia sa dosahuje odkazovaním na ňu ako na premennú triedy ENV, čo v podstate robí túto triedu intuitívne pochopiteľným obalom nativného systémového prostredia, pričom ju zároveň mení na možný variant konfiguračného objektu prakticky akejkoľvek sústavy (podobný prístup sa dá dosiahnuť napríklad v Django, len tam je konfiguračným objektom priamo modul/paket settings).
Zapínanie/vypínanie režimu podpory automatickej typizácie sa dosahuje použitím dvoch metód — enable_automatic_type_cast() a disable_automatic_type_cast(). To môže byť užitočné, ak v premennej prostredia leží serializovaný JSON-podobný objekt alebo dokonca len booleovská konštanta (explicitné nastavovanie premennej DEBUG v Django prostredníctvom porovnania premennej prostredia s „prijateľnými“ reťazcami — jeden z často sa vyskytujúcich prípadov). Ale teraz už nie je potrebné explicitne konvertovať reťazce — väčšina potrebných akcií je už zakotvená v hlbinách knižnice a len čaká na signál k akcii. 🙂 V celku typizácia funguje priehľadne a podporuje takmer všetky existujúce zabudované typy dát (neboli testované frozenset, complex a bytes).
Podpora pre Python 2 bola implementovaná prakticky bez obetí (zrieknutie sa typing a niektorých "cukríkov" posledných verzií Python 3), predovšetkým vďaka všadeprítomnému six (na riešenie problémov s používaním metaclassov).
Existujú však aj určité obmedzenia:
- Podpora Python 3 zahŕňa verziu 3.5 a novšie (ich prítomnosť vo vašom projekte je výsledkom buď lenivosti, alebo absencie potreby na vylepšenia, ťažko si predstaviť objektívny dôvod, prečo by ste ešte stále používali 3.4);
- V Python 2.7 knižnica nepodporuje deserializáciu literálov množín. Opis . Ale ak by sa niekto rozhodol realizovať to — vitajte:);
Knižnica tiež zavádza mechanizmus výnimiek pre prípad chýb pri parsovaní. Ak sa reťazec nepodarí rozoznať žiadnym z dostupných analyzátorov, hodnota zostáva reťazcová (skôr z dôvodov pohodlia a spätnej kompatibility so zvyčajnou logikou práce s premennými v Bash).
Knižnica python-shell
Teraz budem hovoriť o druhej knižnici (opis nedostatkov existujúcich alternatív vynechám — je podobný tomu, čo je opísané pre smart-env. Alternatívy — a ).
Celkovo je myšlienka implementácie a požiadavky na ňu podobné tým, ktoré sú opísané pre smart-env, čo je vidieť z príkladu:
from python_shell import Shell
Shell.ls('-l', '$HOME') # Rovná sa "ls -l $HOME"
command = Shell.whoami() # Rovná sa "whoami"
print(command.output) # vytlačí vaše aktuálne meno používateľa
print(command.command) # vytlačí "whoami"
print(command.return_code) # vytlačí "0"
print(command.arguments) # vytlačí ""
Shell.mkdir('-p', '\/tmp\/new_folder') # vytvorí novú složku
Myšlienka je nasledujúca:
- Jedna trieda, ktorá zosobňuje Bash vo svete Pythonu;
- Každý Bash príkaz sa volá ako funkcia triedy Shell;
- Parametre volania každej funkcie sa ďalej prenášajú do volania príslušného Bash príkazu;
- Každý príkaz sa vykonáva "tu a teraz" v momente jeho vyvolania, t.j. funguje synchronný prístup;
- existuje možnosť získať prístup k výstupu príkazu v stdout, ako aj kódu jeho návratu;
- Ak príkaz nie je v systéme — vyhodí sa výnimka.
Rovnako ako v prípade smart-env, je zabezpečená podpora Python 2 (pravda, obetovaných krvi bolo o niečo viac) a nepodporuje sa Python 3.0-3.4.
Plány na rozvoj knižníc
Knižnice je možné používať už teraz: obe sú zverejnené na oficiálnom PyPI. Zdrojové kódy sú dostupné na Github (pozri nižšie).
Obe knižnice sa budú rozvíjať s ohľadom na spätnú väzbu zozbieranú od zainteresovaných osôb. A ak v smart-env môže byť ťažké vymyslieť rôzne nové funkcie, v python-shell je určite ešte čo pridať:
- podpora neblokujúcich volaní;
- možnosť interaktívneho komunikovania s tímom (práca s stdin);
- pridanie nových vlastností (napríklad property na získanie výstupu zo stderr);
- realizácia katalógu dostupných príkazov (na použitie s funkciou dir());
- a pod.
Odkazy
- Knižnica smart-env: a
- Knižnica python-shell: a
- aktualizácií knižníc
UPD 23.02.2020:
* Repozitáre boli presunuté, príslušné odkazy aktualizované
* Verzia python-shell==1.0.1 sa pripravuje na vydanie 29.02.2020. Medzi zmenami je podpora automatického doplňovania príkazov a príkazu dir(Shell), spúšťanie príkazov s Python-neplatným identifikátorom, oprava chýb.
Zdroj: habr.com
