Gör Python och Bash Friendship: smart-env och python-shell-bibliotek

Goddag allihop.

Idag är Python ett av de mest använda språken inom området för att skapa inte bara mjukvaruprodukter själva, utan också tillhandahålla deras infrastruktur. Som ett resultat var många devops, vare sig de ville eller mot den, tvungna att lära sig ett nytt språk för senare användning som ett komplement till de gamla goda Bash-skripten. Men Bash och Python bekänner sig till olika tillvägagångssätt för att skriva kod och har vissa funktioner, vilket innebär att portering av Bash-skript till "ormspråket" ibland visar sig vara en rymlig och långt ifrån trivial uppgift.

För att göra livet lättare för devops har många användbara bibliotek och verktyg i Python skapats och fortsätter att skapas. Den här artikeln beskriver två nya bibliotek skapade av författaren till det här inlägget - smart-env и python-skal - och designad för att befria devops från behovet av att ägna mycket uppmärksamhet åt krångligheterna med att arbeta med Python, vilket ger utrymme för mer intressanta uppgifter. Bibliotekens verksamhetsområde är miljövariabler och lansering av externa verktyg.

Alla som är intresserade, se katt.

Nya "cyklar"?

Det verkar, varför skapa nya paket för ganska vanlig verksamhet? Vad hindrar dig från att använda os.environ och subprocess.<metod eller klass efter eget val> direkt?

Jag kommer att tillhandahålla bevis till förmån för vart och ett av biblioteken separat.

smart-env-bibliotek

Innan du skriver din egen idé är det nyttigt att gå online och leta efter färdiga lösningar. Visst finns det en risk att man inte hittar det man behöver, utan det här är snarare ett ”försäkringsfall”. Som regel fungerar detta tillvägagångssätt och sparar mycket tid och ansträngning.

Enligt resultaten Sök följande avslöjades:

  • det finns paket som faktiskt lindar anrop till os.environ, men som samtidigt kräver en massa distraherande åtgärder (skapa en instans av en klass, speciella parametrar i anrop, etc.);
  • Det finns bra paket, som dock är strikt knutna till ett specifikt ekosystem (främst webbramverk som Django) och därför inte alls är universella utan en fil;
  • det finns sällsynta försök att göra något nytt. Till exempel, lägg till skrivning och explicit analysera variabelvärden genom att anropa metoder som
    get_<typename>(var_name)

    Eller här ännu en lösning, som dock inte stöder den nu skamfilade Python 2 (som trots officiella RIP, det finns fortfarande berg av skriven kod och hela ekosystem);

  • det finns skol-elevhantverk som av okänd anledning hamnade i uppströms PyPI och bara skapar problem med namngivningen av nya paket (särskilt namnet "smart-env" är en nödvändig åtgärd).

Och den här listan kan fortsätta under lång tid. Ovanstående punkter var dock tillräckligt för att få mig upphetsad över idén om att göra något bekvämt och universellt.

Krav som ställdes innan du skrev smart-env:

  • Det enklaste användningsschemat
  • Lätt konfigurerbart stöd för dataskrivning
  • Python 2.7-kompatibel
  • Bra kodtäckning genom tester

Till slut förverkligades allt detta. Här är ett exempel på användning:

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

Som du kan se i exemplet, för att arbeta med en ny klass, behöver du bara importera den (du behöver inte skapa en instans - minus den extra åtgärden). Tillgång till vilken miljövariabel som helst uppnås genom att hänvisa till den som en variabel i ENV-klassen, vilket i själva verket gör den här klassen till ett intuitivt omslag för den inbyggda systemmiljön, samtidigt som den omvandlas till ett möjligt konfigurationsobjekt för nästan alla system ( ett liknande tillvägagångssätt, till exempel, uppnås i Django , bara där är konfigurationsobjektet själva inställningsmodulen/paketet).

Aktivering/inaktivering av det automatiska skrivstödsläget uppnås med två metoder - enable_automatic_type_cast() och disable_automatic_type_cast(). Detta kan vara praktiskt om miljövariabeln innehåller ett serialiserat JSON-liknande objekt eller till och med bara en boolesk konstant (att explicit ställa in DEBUG-variabeln i Django genom att jämföra miljövariabeln med "giltiga" strängar är ett av de vanligaste fallen). Men nu finns det inget behov av att explicit konvertera strängar - de flesta av de nödvändiga åtgärderna är redan inbäddade i bibliotekets djup och väntar bara på en signal att agera. 🙂 I allmänhet fungerar skrivning transparent och stöder nästan alla tillgängliga inbyggda datatyper (fryst uppsättning, komplex och bytes testades inte).

Kravet på att stödja Python 2 implementerades med praktiskt taget inga uppoffringar (övergivandet av att skriva och några av "sockergodisarna" i de senaste versionerna av Python 3), i synnerhet tack vare de allestädes närvarande sex (för att lösa problemen med att använda metaklasser ).

Men det finns några begränsningar:

  • Python 3-stöd betyder version 3.5 och högre (deras närvaro i ditt projekt är resultatet av antingen lathet eller brist på behov av förbättringar, eftersom det är svårt att komma på en objektiv anledning till varför du fortfarande är på 3.4);
  • I Python 2.7 stöder inte biblioteket deserialisering av uppsättningsliteraler. Beskrivning här. Men om någon vill genomföra det så är ni välkomna :);

Biblioteket har också en undantagsmekanism i händelse av analysfel. Om strängen inte kunde kännas igen av någon av de tillgängliga analysatorerna förblir värdet en sträng (snarare av bekvämlighetsskäl och bakåtkompatibilitet med den vanliga logiken för hur variabler fungerar i Bash).

python-shell-bibliotek

Nu ska jag berätta om det andra biblioteket (jag kommer att utelämna beskrivningen av bristerna hos de befintliga analogerna - det liknar det som beskrivs för smart-env. Analogs - här и här).

Generellt sett liknar idén med implementering och kraven för den de som beskrivs för smart-env, som kan ses från exemplet:

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

Tanken är denna:

  1. En enda klass som representerar Bash i Python-världen;
  2. Varje Bash-kommando anropas som en funktion av Shell-klassen;
  3. Parametrarna för varje funktionsanrop skickas sedan till motsvarande Bash-kommandoanrop;
  4. Varje kommando exekveras "här och nu" i det ögonblick det anropas, dvs. det synkrona tillvägagångssättet fungerar;
  5. det är möjligt att komma åt utdata från ett kommando i stdout, såväl som dess returkod;
  6. Om kommandot inte finns i systemet skapas ett undantag.

Precis som med smart-env finns det stöd för Python 2 (även om det krävdes lite mer offerblod) och inget stöd för Python 3.0-3.4.

Bibliotekets utvecklingsplaner

Du kan använda biblioteken nu: båda är upplagda på den officiella PyPI. Källor finns tillgängliga på Github (se nedan).

Båda biblioteken kommer att utvecklas med hänsyn till feedback från intresserade. Och om det kan vara svårt att komma med en mängd nya funktioner i smart-env, så finns det definitivt något annat att lägga till i python-shell:

  • stöd för icke-blockerande samtal;
  • möjlighet till interaktiv kommunikation med teamet (att arbeta med stdin);
  • lägga till nya egenskaper (till exempel egendom för att ta emot utdata från stderr);
  • implementering av en katalog med tillgängliga kommandon (för användning med dir()-funktionen);
  • etc.

referenser

  1. smart-env bibliotek: Github и PyPI
  2. python-shell bibliotek: Github и PyPI
  3. Telegram kanal biblioteksuppdateringar

UPD23.02.2020:
* Förråd har flyttats, motsvarande länkar har uppdaterats
* Version python-shell==1.0.1 förbereds för release den 29.02.2020/XNUMX/XNUMX. Ändringar inkluderar stöd för kommandot autocomplete och dir(Shell)-kommandot, körkommandon med en ogiltig Python-identifierare och buggfixar.

Källa: will.com

Lägg en kommentar