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:

  1. Jediná trieda, ktorá predstavuje Bash vo svete Pythonu;
  2. Každý príkaz Bash sa volá ako funkcia triedy Shell;
  3. Parametre pre každé volanie funkcie sú potom odovzdané do zodpovedajúceho volania príkazu Bash;
  4. Každý príkaz sa vykoná „tu a teraz“ v momente jeho volania, t.j. synchrónny prístup funguje;
  5. je možné získať prístup k výstupu príkazu v stdout, ako aj k jeho návratovému kódu;
  6. 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());
  • atď

referencie

  1. knižnica smart-env: GitHub и PyPI
  2. knižnica python-shell: GitHub и PyPI
  3. Telegramový kanál aktualizácie knižnice

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.

Zdroj: hab.com

Pridať komentár