Stvaranje prijateljstva između Pythona i Basha: knjižnice smart-env i python-shell

Dobar dan svima.

Danas je Python jedan od najčešće korištenih jezika u području stvaranja ne samo samih softverskih proizvoda, već i pružanja njihove infrastrukture. Kao rezultat toga, mnogi devopsi, bilo svojom voljom ili protiv nje, morali su naučiti novi jezik za kasniju upotrebu kao dodatak dobrim starim Bash skriptama. Međutim, Bash i Python ispovijedaju različite pristupe pisanju koda i imaju određene značajke, što znači da se prenošenje Bash skripti na "zmijski jezik" ponekad pokaže kao opsežan i daleko od trivijalnog zadatka.

Kako bi se olakšao život devopsima, stvorene su i nastavljaju se stvarati mnoge korisne biblioteke i uslužni programi u Pythonu. Ovaj članak opisuje dvije nove biblioteke koje je stvorio autor ovog posta - pametno okruženje и python-ljuska - i osmišljen kako bi devops oslobodio potrebe da obraćaju puno pozornosti na zamršenosti rada s Pythonom, ostavljajući mjesta za zanimljivije zadatke. Djelokrug aktivnosti knjižnica su varijable okruženja i pokretanje vanjskih pomoćnih programa.

Koga zanima neka pogleda kat.

Novi "bicikli"?

Čini se, zašto stvarati nove pakete za prilično obične operacije? Što vas sprječava da izravno koristite os.environ i subprocess.<method ili klasu po vašem izboru>?

Dokaz ću dati u korist svake od knjižnica posebno.

biblioteka smart-env

Prije nego što napišete vlastitu zamisao, korisno je otići na internet i potražiti gotova rješenja. Naravno, postoji rizik da ne pronađete ono što vam je potrebno, ali to je prije “osiguravajući slučaj”. U pravilu, ovaj pristup funkcionira i štedi puno vremena i truda.

Prema rezultatima traži otkriveno je sljedeće:

  • postoje paketi koji zapravo omotavaju pozive na os.environ, ali istovremeno zahtijevaju hrpu ometajućih radnji (stvaranje instance klase, posebni parametri u pozivima itd.);
  • Postoje dobri paketi, koji su, međutim, striktno vezani za određeni ekosustav (uglavnom web okviri poput Djanga) i stoga nisu uopće univerzalni bez datoteke;
  • rijetki su pokušaji da se učini nešto novo. Na primjer, dodati tipkanje i eksplicitno analizirati vrijednosti varijable pozivanjem metoda poput
    get_<typename>(var_name)

    Ili ovdje još jedno rješenje, koji međutim ne podržava danas osramoćeni Python 2 (koji, unatoč službeni RIP, još uvijek postoje brda pisanog koda i cijeli ekosustavi);

  • Postoje školsko-učenički obrti koji su iz nepoznatog razloga završili u uzvodnom PyPI-ju i samo stvaraju probleme s imenovanjem novih paketa (konkretno, naziv "smart-env" je nužna mjera).

I ovaj se popis može nastaviti dugo. Međutim, gore navedene točke bile su dovoljne da me potaknu na ideju da napravim nešto praktično i univerzalno.

Zahtjevi koji su postavljeni prije pisanja smart-env:

  • Najjednostavnija shema korištenja
  • Lako konfigurabilna podrška za tipkanje podataka
  • Python 2.7 kompatibilan
  • Dobra pokrivenost koda testovima

U konačnici se sve to realiziralo. Evo primjera korištenja:

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

Kao što možete vidjeti iz primjera, da biste radili s novom klasom, samo je trebate uvesti (ne morate stvoriti instancu - bez dodatne radnje). Pristup bilo kojoj varijabli okoline postiže se pozivanjem na nju kao varijablu klase ENV, što ovu klasu zapravo čini intuitivnim omotom za okolinu izvornog sustava, dok je istovremeno pretvara u mogući konfiguracijski objekt za gotovo svaki sustav ( sličan pristup, na primjer, postignut je u Djangu, samo što je tamo konfiguracijski objekt sam modul/paket postavki).

Omogućivanje/onemogućavanje načina podrške za automatsko tipkanje postiže se pomoću dvije metode - enable_automatic_type_cast() i disable_automatic_type_cast(). To može biti zgodno ako varijabla okruženja sadrži serijalizirani objekt sličan JSON-u ili čak samo Booleovu konstantu (eksplicitno postavljanje varijable DEBUG u Djangu usporedbom varijable okruženja s "važećim" nizovima jedan je od najčešćih slučajeva). Ali sada nema potrebe eksplicitno pretvarati nizove - većina potrebnih radnji već je ugrađena u dubine biblioteke i samo čekaju signal za djelovanje. 🙂 Općenito, upisivanje radi transparentno i podržava gotovo sve dostupne ugrađene tipove podataka (zamrznuti, složeni i bajtovi nisu testirani).

Zahtjev za podrškom za Python 2 implementiran je gotovo bez ikakvih žrtava (napuštanje tipkanja i neki od "šećernih bombona" ​​najnovijih verzija Pythona 3), posebice zahvaljujući sveprisutnoj šestici (za rješavanje problema korištenja metaklasa ).

Ali postoje neka ograničenja:

  • Python 3 podrška podrazumijeva verziju 3.5 i više (njihova prisutnost u vašem projektu rezultat je ili lijenosti ili nedostatka potrebe za poboljšanjima, jer je teško pronaći objektivan razlog zašto ste još uvijek na 3.4);
  • U Pythonu 2.7 biblioteka ne podržava deserijalizaciju skupnih literala. Opis ovdje. Ali ako ga netko želi implementirati, dobrodošao je :);

Knjižnica također ima mehanizam iznimke u slučaju pogrešaka parsiranja. Ako niz nije mogao prepoznati niti jedan od dostupnih analizatora, vrijednost ostaje niz (radije, iz razloga pogodnosti i kompatibilnosti s prethodnim verzijama s uobičajenom logikom rada varijabli u Bashu).

biblioteka python-shell

Sada ću vam reći o drugoj biblioteci (izostavit ću opis nedostataka postojećih analoga - sličan je onome opisanom za smart-env. Analozi - ovdje и ovdje).

Općenito, ideja implementacije i zahtjevi za nju slični su onima opisanim za smart-env, kao što se može vidjeti iz primjera:

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 ova:

  1. Jedna klasa koja predstavlja Bash u svijetu Pythona;
  2. Svaka Bash naredba poziva se kao funkcija klase Shell;
  3. Parametri za svaki poziv funkcije zatim se prosljeđuju u odgovarajući poziv Bash naredbe;
  4. Svaka naredba se izvršava "ovdje i sada" u trenutku kada je pozvana, tj. sinkroni pristup funkcionira;
  5. moguće je pristupiti izlazu naredbe u stdout-u, kao i njenom povratnom kodu;
  6. Ako naredba nije u sustavu, izbacuje se iznimka.

Kao i kod smart-env-a, postoji podrška za Python 2 (iako je bilo potrebno malo više žrtve) i nema podrške za Python 3.0-3.4.

Planovi razvoja knjižnice

Sada možete koristiti biblioteke: obje su objavljene na službenom PyPI. Izvori su dostupni na Githubu (vidi dolje).

Obje će se knjižnice razvijati uzimajući u obzir povratne informacije zainteresiranih. I, ako je možda teško smisliti niz novih značajki u smart-env-u, onda u python-shellu definitivno postoji još nešto za dodati:

  • podrška za neblokirajuće pozive;
  • mogućnost interaktivne komunikacije s timom (rad sa stdin);
  • dodavanje novih svojstava (na primjer, svojstvo za primanje izlaza iz stderr-a);
  • implementacija direktorija dostupnih naredbi (za korištenje s funkcijom dir());
  • itd.

reference

  1. biblioteka smart-env: Github и PyPI
  2. biblioteka python-shell: Github и PyPI
  3. Telegram kanal ažuriranja knjižnice

UPD 23.02.2020. XNUMX. XNUMX.:
* Repozitoriji su premješteni, odgovarajuće veze su ažurirane
* Verzija python-shell==1.0.1 priprema se za izdavanje 29.02.2020. Promjene uključuju podršku za automatsko dovršavanje naredbi i naredbu dir(Shell), pokretanje naredbi s nevažećim Python identifikatorom i ispravke grešaka.

Izvor: www.habr.com

Dodajte komentar