Samenvoegen van Python en Bash: de bibliotheken smart-env en python-shell

Goedendag allemaal.

Tegenwoordig is Python een van de meest gebruikte talen voor het creƫren van niet alleen softwareproducten, maar ook voor de infrastructuur ervan. Dit heeft ervoor gezorgd dat veel DevOps, of ze willen of niet, een nieuwe taal moesten leren om deze als aanvulling op de goede oude Bash-scripts te gebruiken. Bash en Python benaderen het schrijven van code echter op verschillende manieren en hebben bepaalde kenmerken, waardoor het porteren van Bash-scripts naar de 'slangentaal' soms een complexe en verre van triviale taak is.

Om het leven van DevOps te vereenvoudigen, zijn er veel nuttige bibliotheken en hulpprogramma's in Python ontwikkeld en blijven deze ontstaan. Dit artikel beschrijft twee nieuwe bibliotheken die door de auteur van deze post zijn gemaakt — smart-env en python-shell — en die bedoeld zijn om DevOps te verlossen van de noodzaak om veel aandacht te besteden aan de subtiliteiten van werken met Python, zodat ze zich kunnen richten op interessantere taken. Het toepassingsgebied van de bibliotheken is omgevingsvariabelen en het starten van externe hulpprogramma's.

GeĆÆnteresseerden worden uitgenodigd om verder te lezen.

Nieuwe 'fietsen'?

Waarom zou je nieuwe pakketten maken voor vrij alledaagse operaties? Wat verhindert je om gewoon os.environ en subprocess. direct te gebruiken?

Bewijs ter ondersteuning van elke bibliotheek zal ik apart geven.

Bibliotheek smart-env

Voordat je je eigen creatie schrijft, is het nuttig om op internet te zoeken naar bestaande oplossingen. Natuurlijk is er een risico dat je niet vindt wat je zoekt, maar dat is meer een 'verzekeringsgeval'. In de meeste gevallen werkt deze aanpak en bespaart het veel tijd en moeite.

Volgens de resultaten van zoeken werd het volgende onthuld:

  • er zijn pakketten die daadwerkelijk aanroepen naar os.environ verpakken, maar die toch veel afleidende handelingen vereisen (het aanmaken van een klasse-exemplaar, speciale parameters bij aanroepen, enz.);
  • er zijn goede pakketten die echter stevig vastzitten aan een bepaalde ecosysteem (voornamelijk aan webframeworks zoals Django) en daardoor zonder aanpassingen helemaal niet universeel zijn;
  • er zijn zeldzame pogingen om iets nieuws te creĆ«ren. Bijvoorbeeld, type-annotaties toevoegen en waarden van variabelen expliciet parseren door methoden aan te roepen zoals
    get_(var_naam)

    Of hier is nog een oplossing, die echter de tegenwoordig afgestrafte Python 2 niet ondersteunt (waarop, ondanks de officiƫle R.I.P., er blijven bergen geschreven code en hele ecosystemen bestaan);

  • er zijn school- en studentenprojecten die eigenlijk geen zin hebben om in de upstream PyPI te verschijnen en alleen maar problemen creĆ«ren met de naamgeving van nieuwe pakketten (in het bijzonder, de naam 'smart-env' is een noodoplossing).

En deze lijst kan nog lang doorgaan. Maar de bovengenoemde punten zijn al voldoende om de idee op te doen om iets gebruiksvriendelijks en universeler te maken.

De eisen die gesteld werden aan het schrijven van smart-env:

  • Een maximaal eenvoudige gebruiksschema
  • Gemakkelijk configureerbare ondersteuning voor datatypen
  • Compatibiliteit met Python 2.7
  • Goede testdekking van de code

Uiteindelijk is het allemaal gelukt. Hier is een voorbeeld van het gebruik:

from smart_env import ENV

print(ENV.HOME)  # Gelijk aan print(os.environ['HOME'])

# uitgaande van dat je de omgevingsvariabele MYVAR hebt ingesteld op "True"

ENV.enable_automatic_type_cast()

my_var = ENV.MY_VAR  # Gelijk aan boolean True

ENV.NEW_VAR = 100  # Stelt een nieuwe omgevingsvariabele in

Zoals te zien is in het voorbeeld, is het voldoende om de nieuwe klasse te importeren (het is niet nodig om een instantie aan te maken — een overbodige actie). Toegang tot elke omgevingsvariabele wordt bereikt door deze als een klassevariabele van ENV aan te roepen, wat dat feitelijk deze klasse een intuĆÆtieve wrapper maakt van de native systeemomgeving, terwijl het tegelijkertijd een mogelijke variant van een configuratieobject voor bijna elk systeem vormt (een vergelijkbare benadering wordt bijvoorbeeld in Django toegepast, waar het configuratieobject direct de settings-module/-pakket is).

Het in- of uitschakelen van de ondersteuning voor automatische typering gebeurt door gebruik te maken van twee methoden — enable_automatic_type_cast() en disable_automatic_type_cast(). Dit kan handig zijn als er een geserialiseerd JSON-achtig object in de omgevingsvariabele ligt of zelfs gewoon een booleaanse constante (een veelvoorkomend geval is het expliciet instellen van de variabele DEBUG in Django door de omgevingsvariabele te vergelijken met 'toegestane' strings). Maar nu is het niet nodig om strings expliciet te converteren — het grootste deel van de noodzakelijke acties is al ingebouwd in de bibliotheek en wacht gewoon op een signaal om in actie te komen. šŸ™‚ Over het algemeen werkt typering transparant en ondersteunt het bijna alle aanwezige ingebouwde datatypy (frozenset, complex en bytes zijn niet getest).

De ondersteuning voor Python 2 is vrijwel zonder offers gerealiseerd (afzien van typing en enkele 'lekkernijen' uit de laatste versies van Python 3), voornamelijk dankzij de alomtegenwoordige six (om problemen met het gebruik van metaklassen op te lossen).

Maar er zijn ook enkele beperkingen:

  • De ondersteuning voor Python 3 houdt versie 3.5 en hoger in (de aanwezigheid ervan in uw project is het resultaat van ofwel luiheid ofwel het ontbreken van de noodzaak voor verbeteringen, want het is moeilijk om een objectieve reden te bedenken waarom u nog steeds op 3.4 zit);
  • In Python 2.7 ondersteunt de bibliotheek geen deserialisatie van set-literals. Beschrijving here. Maar als iemand het wil implementeren — welkom:);

De bibliotheek implementeert ook een exception-mechanisme voor parseerfouten. Als een string niet door een van de bestaande parsers kan worden herkend, blijft de waarde een string (meer uit overwegingen van gebruiksgemak en terugwaartse compatibiliteit met de gebruikelijke logica van variabelen in Bash).

Bibliotheek python-shell

Nu zal ik het hebben over de tweede bibliotheek (ik laat de beschrijving van de tekortkomingen van de bestaande analogieĆ«n achterwege — het lijkt op wat is beschreven voor smart-env. AnalogieĆ«n — here en here).

Over het algemeen zijn het idee van de implementatie en de eisen eraan vergelijkbaar met die van smart-env, zoals te zien is in het voorbeeld:

from python_shell import Shell

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

command = Shell.whoami()  # Gelijk aan "whoami"
print(command.output)  # print uw huidige gebruikersnaam

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

Shell.mkdir('-p', '\/tmp\/new_folder')  # maakt een nieuwe map aan

Het idee is als volgt:

  1. Een enkele klasse die Bash belichaamt in de wereld van Python;
  2. Elke Bash-opdracht wordt aangeroepen als een functie van de klasse Shell;
  3. De parameters van elke functieaanroep worden vervolgens doorgegeven aan de aanroep van de overeenkomstige Bash-opdracht;
  4. Elke opdracht wordt 'hier en nu' uitgevoerd op het moment van aanroep, dat wil zeggen werkt volgens een synchronische benadering;
  5. er is toegang tot de output van de opdracht in stdout, evenals de retourcode;
  6. Als de opdracht niet in het systeem aanwezig is, wordt er een uitzondering gegooid.

Net als bij smart-env is er ondersteuning voor Python 2 (er was wel iets meer offerbloed nodig) en is er geen ondersteuning voor Python 3.0-3.4.

Ontwikkelingsplannen voor bibliotheken

De bibliotheken kunnen nu al worden gebruikt: beide zijn gepubliceerd op de officiƫle PyPI. De broncode is beschikbaar op Github (zie hieronder).

Beide bibliotheken zullen zich ontwikkelen op basis van de feedback van geĆÆnteresseerden. En hoewel het misschien moeilijk is om diversiteit aan nieuwe functies te bedenken voor smart-env, zijn er zeker nog toevoegingen voor python-shell:

  • ondersteuning voor niet-blokkerende aanroepen;
  • de mogelijkheid voor interactieve communicatie met het team (werken met stdin);
  • toevoegen van nieuwe eigenschappen (bijvoorbeeld property om uitvoer uit stderr te krijgen);
  • implementatie van een catalogus van beschikbare commando's (voor gebruik met de functie dir());
  • enzovoorts.

Links

  1. Bibliotheek smart-env: Github en PyPI
  2. Bibliotheek python-shell: Github en PyPI
  3. Telegram-kanaal bibliotheekupdates

UPD 23.02.2020:
* Repositories zijn verplaatst, overeenkomstige links zijn bijgewerkt
* Versie python-shell==1.0.1 staat gepland voor uitgave op 29.02.2020. Onder wijzigingen — ondersteuning voor auto-complete van commando's en de commando dir(Shell), uitvoering van commando's met een Python-ongeldige identifier, bugfixes.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster