ProHoster > Blog > Administrácia > Vytváranie priateľstva Python a Bash: knižnice smart-env a python-shell
Vytváranie priateľstva Python a Bash: knižnice smart-env a python-shell
Pekný deň všetkým.
Dnes je Python jedným z najpoužívanejších jazykov v oblasti tvorby nielen samotných softvérových produktov, ale aj poskytovania ich infraštruktúry. V dôsledku toho sa mnoho devopov, či už z vlastnej vôle alebo proti nej, muselo naučiť nový jazyk na neskoršie použitie ako doplnok k starým dobrým Bash skriptom. Bash a Python však vyznávajú rôzne prístupy k písaniu kódu a majú určité vlastnosti, čo znamená, že portovanie skriptov Bash do „jazyka hada“ sa niekedy ukáže ako priestranná a ani zďaleka triviálna úloha.
Aby sa uľahčil život vývojárom, bolo vytvorených mnoho užitočných knižníc a nástrojov v Pythone, ktoré sa naďalej vytvárajú. Tento článok popisuje dve nové knižnice vytvorené autorom tohto príspevku - smart-env и python-shell - a navrhnuté tak, aby odbremenili devopov od potreby venovať veľkú pozornosť zložitosti práce s Pythonom a ponechali priestor pre zaujímavejšie úlohy. Náplňou činnosti knižníc sú premenné prostredia a spúšťanie externých utilít.
Kto má záujem, pozrite si kat.
Nové "bicykle"?
Zdalo by sa, prečo vytvárať nové balíčky pre celkom bežné operácie? Čo vám bráni priamo použiť os.environ a podproces.<metóda alebo trieda podľa vášho výberu>?
Dôkazy v prospech každej z knižníc poskytnem samostatne.
knižnica smart-env
Pred napísaním vlastného nápadu je užitočné ísť online a hľadať hotové riešenia. Samozrejme, existuje riziko, že nenájdete to, čo potrebujete, ale ide skôr o „poistnú udalosť“. Tento prístup spravidla funguje a šetrí veľa času a úsilia.
Podľa výsledkov vyhľadávanie bolo odhalené nasledovné:
existujú balíčky, ktoré v skutočnosti zabaľujú volania do os.environ, no zároveň vyžadujú množstvo rušivých akcií (vytvorenie inštancie triedy, špeciálne parametre vo volaniach atď.);
Existujú dobré balíky, ktoré sú však striktne viazané na konkrétny ekosystém (hlavne webové frameworky ako Django), a preto nie sú bez súboru vôbec univerzálne;
sú zriedkavé pokusy urobiť niečo nové. Napríklad, pridať písanie a explicitne analyzovať hodnoty premenných volaním metód ako
get_<typename>(var_name)
Alebo tu ešte jedno riešenie, ktorý však nepodporuje teraz zneuctený Python 2 (ktorý napriek oficiálny RIP, stále existujú hory písaného kódu a celé ekosystémy);
Existujú školopovinné remeslá, ktoré z nejakého neznámeho dôvodu skončili v upstream PyPI a spôsobujú len problémy s pomenovaním nových balíkov (najmä názov „smart-env“ je nevyhnutným opatrením).
A tento zoznam môže pokračovať ešte dlho. Vyššie uvedené body však stačili na to, aby ma nadchla myšlienka vytvoriť niečo pohodlné a univerzálne.
Požiadavky, ktoré boli nastavené pred napísaním smart-env:
Najjednoduchšia schéma použitia
Jednoducho konfigurovateľná podpora zadávania údajov
Kompatibilný s Python 2.7
Dobré pokrytie kódu testami
Nakoniec sa toto všetko podarilo zrealizovať. Tu je príklad použitia:
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
Ako vidíte z príkladu, ak chcete pracovať s novou triedou, stačí ju importovať (nemusíte vytvárať inštanciu - mínus extra akcia). Prístup ku ktorejkoľvek premennej prostredia sa dosiahne tak, že sa na ňu odkazuje ako na premennú triedy ENV, čo v skutočnosti robí z tejto triedy intuitívny obal pre natívne systémové prostredie a súčasne ju premieňa na možný konfiguračný objekt pre takmer akýkoľvek systém ( podobný prístup je dosiahnutý napríklad v Django , len tam je konfiguračným objektom samotný modul/balík nastavení).
Zapnutie/vypnutie režimu podpory automatického písania sa dosiahne pomocou dvoch metód – enable_automatic_type_cast() a disable_automatic_type_cast(). To môže byť výhodné, ak premenná prostredia obsahuje serializovaný objekt podobný JSON alebo dokonca len booleovskú konštantu (explicitné nastavenie premennej DEBUG v Django porovnaním premennej prostredia s „platnými“ reťazcami je jedným z najbežnejších prípadov). Teraz však už nie je potrebné vyslovene prevádzať reťazce – väčšina potrebných úkonov je už zakomponovaná v hlbinách knižnice a čaká sa len na signál, aby konali. 🙂 Vo všeobecnosti písanie funguje transparentne a podporuje takmer všetky dostupné vstavané dátové typy (netestovali sa zmrazené, komplexné a bajty).
Požiadavka na podporu Pythonu 2 bola implementovaná prakticky bez obetí (upustenie od písania a niektorých „cukrových cukríkov“ najnovších verzií Pythonu 3), najmä vďaka všadeprítomným šiestim (na vyriešenie problémov s používaním metatried ).
Existujú však určité obmedzenia:
Podpora Pythonu 3 znamená verziu 3.5 a vyššiu (ich prítomnosť vo vašom projekte je výsledkom lenivosti alebo nedostatku potreby vylepšení, pretože je ťažké prísť na objektívny dôvod, prečo ste stále na 3.4);
V Pythone 2.7 knižnica nepodporuje deserializáciu množín literálov. Popis tu. Ale ak by to chcel niekto zrealizovať, ste vítaní :);
Knižnica má tiež mechanizmus výnimiek v prípade chýb analýzy. Ak reťazec nedokázal rozpoznať žiadny z dostupných analyzátorov, hodnota zostane reťazcom (skôr z dôvodov pohodlia a spätnej kompatibility s obvyklou logikou fungovania premenných v Bash).
knižnica python-shell
Teraz vám poviem o druhej knižnici (vynechám popis nedostatkov existujúcich analógov - je podobný tomu, ktorý je popísaný pre analógy smart-env. - tu и tu).
Vo všeobecnosti sú myšlienka implementácie a požiadavky na ňu podobné tým, ktoré sú opísané pre smart-env, ako je možné vidieť z príkladu:
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
Myšlienka je takáto:
Jediná trieda, ktorá predstavuje Bash vo svete Pythonu;
Každý príkaz Bash sa volá ako funkcia triedy Shell;
Parametre pre každé volanie funkcie sú potom odovzdané do zodpovedajúceho volania príkazu Bash;
Každý príkaz sa vykoná „tu a teraz“ v momente jeho volania, t.j. synchrónny prístup funguje;
je možné získať prístup k výstupu príkazu v stdout, ako aj k jeho návratovému kódu;
Ak príkaz nie je v systéme, vyvolá sa výnimka.
Rovnako ako v prípade smart-env je tu podpora pre Python 2 (hoci bola potrebná trochu viac obetnej krvi) a žiadna podpora pre Python 3.0-3.4.
Plány rozvoja knižnice
Knižnice môžete použiť už teraz: obe sú zverejnené na oficiálnom PyPI. Zdroje sú dostupné na Github (pozri nižšie).
Obe knižnice sa budú rozvíjať s prihliadnutím na spätnú väzbu získanú od záujemcov. A ak môže byť ťažké prísť s rôznymi novými funkciami v smart-env, potom v python-shell je určite potrebné pridať niečo ďalšie:
podpora neblokujúcich hovorov;
možnosť interaktívnej komunikácie s tímom (práca so stdin);
pridanie nových vlastností (napríklad vlastnosť na príjem výstupu zo stderr);
implementácia adresára dostupných príkazov (na použitie s funkciou dir());
UPD 23.02.2020:
* Repozitáre boli presunuté, príslušné odkazy boli aktualizované
* Verzia python-shell==1.0.1 sa pripravuje na vydanie 29.02.2020. Zmeny zahŕňajú podporu automatického dopĺňania príkazov a príkazu dir(Shell), spúšťanie príkazov s neplatným identifikátorom Pythonu a opravy chýb.