Stvaranje Python i Bash prijateljstva: smart-env i python-shell biblioteke

Dobar dan svima.

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

Kako bi se olakšao život devops-u, mnoge korisne biblioteke i uslužni programi u Pythonu su kreirani i nastavljaju se stvarati. Ovaj članak opisuje dvije nove biblioteke koje je kreirao autor ovog posta - smart-env и python-shell - i dizajniran da oslobodi devops potrebe da se posveti mnogo pažnje zamršenostima rada sa Pythonom, ostavljajući prostora za zanimljivije zadatke. Opseg aktivnosti biblioteka su varijable okruženja i pokretanje eksternih uslužnih programa.

Ko je zainteresovan neka vidi mačku.

Novi "bicikli"?

Čini se, zašto kreirati nove pakete za prilično uobičajene operacije? Šta vas sprečava da direktno koristite os.environ i subprocess.<metod ili klasa po vašem izboru>?

Ja ću dati dokaze u korist svake od biblioteka posebno.

smart-env biblioteka

Prije nego što napišete vlastitu ideju, 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 ovo je prije „događaj osiguranja“. U pravilu, ovaj pristup funkcionira i štedi mnogo vremena i truda.

Prema rezultatima pretraživanje otkriveno je sljedeće:

  • postoje paketi koji zapravo omotavaju pozive u os.environ, ali u isto vrijeme zahtijevaju gomilu ometajućih radnji (kreiranje instance klase, specijalni parametri u pozivima, itd.);
  • Postoje dobri paketi, koji su, međutim, striktno vezani za određeni ekosistem (uglavnom web okviri kao što je Django) i stoga nisu nimalo univerzalni bez datoteke;
  • retki su pokušaji da se uradi nešto novo. Na primjer, dodati kucanje i eksplicitno analizirati vrijednosti varijabli pozivanjem metoda poput
    get_<typename>(var_name)

    Ili ovde jos jedno resenje, koji, međutim, ne podržava sada osramoćeni Python 2 (koji, uprkos zvanični RIP, još uvijek postoje planine pisanog koda i cijeli ekosistemi);

  • Postoje zanati škola-učenici koji su, iz nepoznatog razloga, završili u uzvodnom PyPI-ju i samo stvaraju probleme s imenovanjem novih paketa (posebno, naziv “smart-env” je neophodna mjera).

I ova lista može se nastaviti dugo. Međutim, gore navedene tačke su bile dovoljne da me oduševi ideja da napravim nešto zgodno i univerzalno.

Zahtjevi koji su postavljeni prije pisanja smart-env:

  • Najjednostavnija shema upotrebe
  • Podrška za kucanje podataka koja se lako konfiguriše
  • Kompatibilan sa Python 2.7
  • Dobra pokrivenost koda testovima

Na kraju se sve ovo i realizovalo. Evo primjera upotrebe:

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 kreirati instancu - minus dodatnu radnju). Pristup bilo kojoj varijabli okruženja postiže se pozivanjem na nju kao varijablu klase ENV, što, u stvari, ovu klasu čini intuitivnim omotačem za prirodno okruženje sistema, dok je istovremeno pretvara u mogući konfiguracijski objekt za gotovo svaki sistem ( sličan pristup, na primjer, postiže se u Djangu, samo što je tu konfiguracijski objekt sam modul/paket postavki).

Omogućavanje/onemogućavanje režima podrške za automatsko kucanje postiže se pomoću dvije metode - enable_automatic_type_cast() i disable_automatic_type_cast(). Ovo 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 upoređivanjem varijable okruženja sa „važećim“ stringovima je jedan od najčešćih slučajeva). Ali sada nema potrebe za eksplicitnim pretvaranjem nizova - većina potrebnih radnji je već ugrađena u dubinu biblioteke i samo čeka signal za djelovanje. 🙂 Općenito, kucanje radi transparentno i podržava gotovo sve dostupne ugrađene tipove podataka (zamrznuti skup, složeni i bajtovi nisu testirani).

Zahtjev da se podrži Python 2 implementiran je bez ikakvih žrtava (napuštanje kucanja i nekih „šećera“ najnovijih verzija Pythona 3), posebno zahvaljujući sveprisutnoj šestorici (za rješavanje problema korištenja metaklasa ).

Ali postoje neka ograničenja:

  • Podrška za Python 3 znači verziju 3.5 i noviju (njihovo prisustvo u vašem projektu je rezultat ili lijenosti ili nedostatka potrebe za poboljšanjima, jer je teško doći do objektivnog razloga zašto ste još uvijek na 3.4);
  • U Pythonu 2.7, biblioteka ne podržava deserializaciju skupova literala. Opis ovdje. Ali ako neko želi da to implementira, dobrodošao je :);

Biblioteka također ima mehanizam izuzetaka u slučaju grešaka pri raščlanjivanju. Ako ni jedan od dostupnih analizatora ne može prepoznati niz, vrijednost ostaje string (radije, iz razloga pogodnosti i kompatibilnosti unazad sa uobičajenom logikom kako varijable rade u Bashu).

python-shell biblioteka

Sada ću vam reći o drugoj biblioteci (izostaviću opis nedostataka postojećih analoga - slična je onoj opisanoj za smart-env. Analogi - ovdje и ovdje).

Općenito, ideja implementacije i zahtjevi za nju slični su onima opisanima 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 Python svijetu;
  2. Svaka Bash naredba se poziva kao funkcija klase Shell;
  3. Parametri za svaki poziv funkcije se zatim prosljeđuju u odgovarajući poziv Bash komande;
  4. Svaka naredba se izvršava "ovdje i sada" u trenutku kada je pozvana, tj. sinhroni pristup funkcionira;
  5. moguće je pristupiti izlazu komande u stdout-u, kao i njenom povratnom kodu;
  6. Ako naredba nije u sistemu, izbacuje se izuzetak.

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

Planovi razvoja biblioteke

Sada možete koristiti biblioteke: obje su objavljene na službenom PyPI-ju. Izvori su dostupni na Githubu (pogledajte ispod).

Obje biblioteke će se razvijati uzimajući u obzir povratne informacije prikupljene od zainteresovanih. I, ako je možda teško smisliti razne nove funkcije u smart-env, onda u python-shell-u definitivno postoji nešto drugo za dodati:

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

reference

  1. smart-env biblioteka: GitHub и PyPI
  2. python-shell biblioteka: GitHub и PyPI
  3. Telegram kanal ažuriranja biblioteke

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

izvor: www.habr.com

Dodajte komentar