Forener Python og Bash: bibliotekerne smart-env og python-shell

Goddag alle sammen.

I dag er Python et af de mest anvendte sprog inden for udvikling af ikke kun softwareprodukter, men også deres infrastruktur. Som følge heraf har mange DevOps, frivilligt eller ufrivilligt, måttet lære et nyt sprog som supplement til de gode gamle Bash-scripts. Men Bash og Python følger forskellige tilgange til kode skrivning og har sine egne egenskaber, hvilket gør overførslen af Bash-scripts til 'slangesproget' til en opgave, der nogle gange kan være kompleks og langt fra trivial.

For at gøre livet lettere for DevOps er der skabt og fortsat skabes mange nyttige biblioteker og værktøjer i Python. Denne artikel beskriver to nye biblioteker, skabt af forfatteren af dette indlæg — smart-env og python-shell — og de er designet til at befri DevOps fra at skulle bruge for meget tid på detaljerne i Python, hvilket efterlader plads til mere interessante opgaver. Bibliotekerne arbejder med miljøvariabler og udførelse af eksterne værktøjer.

Dem, der er interesseret, bedes klikke videre.

Nye 'cykler'?

Det kunne virke unødvendigt at skabe nye pakker til ret almindelige operationer. Hvad forhindrer os i at bruge os.environ og subprocess direkte.?

Beviser for hver af bibliotekerne vil jeg fremlægge separat.

Biblioteket smart-env

Før man skriver sit eget værk, er det nyttigt at søge på internettet for at finde færdige løsninger. Selvfølgelig er der risiko for ikke at finde det, man har brug for, men det er mere en 'forsikringsbegivenhed'. Som regel fungerer denne tilgang og sparer en masse tid og kræfter.

I følge resultaterne søgning der blev identificeret følgende:

  • der er pakker, der faktisk omslutter kald til os.environ, men samtidig kræver en masse distraherende handlinger (oprettelse af klasseinstanser, specielle parametre i kald osv.);
  • der er nogle gode pakker, der dog er stramt bundet til et bestemt økosystem (primært web-rammer som Django) og derfor ikke er helt alsidige uden nogle redskaber;
  • der er sjældne forsøg på at skabe noget nyt. For eksempel, tilføje typeangivelse og tydeligt parse værdierne af variabler ved at kalde metoder som
    get_(var_name)

    Eller her endnu en løsning, som dog ikke understøtter det nu forsømte Python 2 (hvor på trods af den officielle R.I.P., der stadig er store mængder af skrevet kode og hele økosystemer);

  • der er skole- og studieprojekter, som helt uforståeligt er endt op i upstream PyPI og kun skaber problemer med navngivning af nye pakker (især navnet «smart-env» — en nødforanstaltning).

Og denne liste kan fortsætte længe. Men de ovennævnte punkter var nok til at få idéen til at skabe noget praktisk og universelt.

Kravene, der blev stillet før skrivningen af smart-env:

  • Maksimalt enkel brugsschema
  • Let konfigurerbar understøttelse af datatyper
  • Kompatibilitet med Python 2.7
  • God testdækning af koden

I sidste ende lykkedes det at implementere alt dette. Her er et eksempel på brug:

from smart_env import ENV

print(ENV.HOME)  # Svarer til print(os.environ['HOME'])

# Antager at du har sat miljøvariabel MYVAR til "True"

ENV.enable_automatic_type_cast()

my_var = ENV.MY_VAR  # Svarer til boolean True

ENV.NEW_VAR = 100  # Sætter en ny miljøvariabel

Som det fremgår af eksemplet, er det tilstrækkeligt at importere den nye klasse for at arbejde med den (det er ikke nødvendigt at oprette en instans — minus en unødvendig handling). Adgangen til enhver miljøvariabel opnås ved at referere til den som en klassevariabel i ENV, hvilket faktiske gør denne klasse til et intuitivt forståeligt wrapper for det native systemmiljø, samtidig med at det gør det til en mulig variant af et konfigurationsobjekt for næsten ethvert system (en lignende tilgang opnås for eksempel i Django, hvor konfigurationsobjektet faktisk er modulet/pakken settings).

Aktivering/deaktivering af understøttelse af automatisk typetildeling opnås ved brug af de to metoder — enable_automatic_type_cast() og disable_automatic_type_cast(). Dette kan være praktisk, hvis miljøvariablen indeholder et serialiseret JSON-lignende objekt eller endda blot en boolesk konstant (den eksplicitte angivelse af variablen DEBUG i Django ved at sammenligne miljøvariablen med "tilladte" strenge er et af de ofte forekommende tilfælde). Men nu er der ikke behov for eksplicit at konvertere strenge — størstedelen af de nødvendige handlinger er allerede indlejret i dybderne af biblioteket og venter kun på et aktiveringssignal. 🙂 Generelt fungerer typetildelingen transparent og understøtter næsten alle eksisterende indbyggede datatyper (frozenset, complex og bytes er ikke blevet testet).

Kravet om støtte til Python 2 er blevet implementeret næsten uden ofre (forsagelse af typing og nogle 'søde godbidder' fra de seneste versioner af Python 3), især takket være det allestedsnærværende six (til løsning af problemer med brugen af metaklasser).

Men der er også nogle begrænsninger:

  • Støtte til Python 3 indebærer version 3.5 og højere (tilstedeværelsen af dem i dit projekt er enten et resultat af dovenskab eller mangel på behov for forbedringer, da det er svært at finde en objektiv grund til, at du stadig bruger 3.4);
  • I Python 2.7 understøtter biblioteket ikke deserialisering af mængdelitteraler. Beskrivelse her. Men hvis nogen ønsker at implementere det — velkommen:);

Biblioteket anvender også en undtagelsesmekanisme, hvis der opstår fejl under parsing. Hvis strengen ikke kunne genkendes af nogen af de tilgængelige analyseværktøjer, forbliver værdien en streng (mere af hensyn til bekvemmelighed og bagudkompatibilitet med den sædvanlige logik for variable i Bash).

Biblioteket python-shell

Nu vil jeg fortælle om det andet bibliotek (jeg springer beskrivelsen af manglerne ved de eksisterende alternativer over — det ligner det, der er beskrevet for smart-env. Alternativerne — her og her).

Generelt er idéen om implementation og kravene til den ensartede med dem, der er beskrevet for smart-env, hvilket fremgår af eksemplet:

from python_shell import Shell

Shell.ls('-l', '$HOME')  # Svaret "ls -l $HOME"

command = Shell.whoami()  # Svaret "whoami"
print(command.output)  # udskriver dit nuværende brugernavn

print(command.command)  # udskriver "whoami"
print(command.return_code)  # udskriver "0"
print(command.arguments)  # udskriver ""

Shell.mkdir('-p', '\/tmp\/new_folder')  # opretter en ny mappe

Idéen er:

  1. En enkelt klasse, der personificerer Bash i Python-verdenen;
  2. Hver Bash-kommando kaldes som en funktion i klassen Shell;
  3. Parametrene til at kalde hver funktion videregives derefter til kaldet af den tilsvarende Bash-kommando;
  4. Hver kommando udføres 'her og nu' i det øjeblik, den kaldes, dvs. der anvendes en synkron tilgang;
  5. der er mulighed for at få adgang til uddata fra kommandoen i stdout samt dens returkode;
  6. Hvis kommandoen ikke findes på systemet — kastes der en undtagelse.

Som i tilfælde af smart-env er der sikret støtte til Python 2 (dog krævede det lidt flere ofre) og der er ikke støtte til Python 3.0-3.4.

Planer for udvikling af biblioteker

Bibliotekerne kan allerede bruges: begge er offentliggjort på den officielle PyPI. Kildekoderne er tilgængelige på Github (se nedenfor).

Begge biblioteker vil blive udviklet med hensyn til feedback indsamlet fra interesserede. Og hvis det i smart-env måske er svært at finde på nye funktioner, så er der bestemt stadig meget at tilføje i python-shell:

  • understøttelse af ikke-blokerende kald;
  • mulighed for interaktiv kommunikation med teamet (arbejde med stdin);
  • tilføjelse af nye egenskaber (f.eks. property til at få output fra stderr);
  • implementering af et katalog over tilgængelige kommandoer (til brug med funktionen dir());
  • osv.

Links

  1. Biblioteket smart-env: Github og PyPI
  2. Biblioteket python-shell: Github og PyPI
  3. Telegram-kanal opdateringer af bibliotekerne

UPD 23.02.2020:
* Repositories er blevet flyttet, de tilsvarende links er opdateret
* Version python-shell==1.0.1 er klar til udgivelse den 29.02.2020. Ændringerne omfatter understøttelse af autocompletion af kommandoer og kommandoen dir(Shell), kørsel af kommandoer med et ikke-Python-validt ID, rettelse af fejl.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster