Vytvoření přátelství mezi Python a Bash: knihovny smart-env a python-shell

Dobrý den všem.

Python je dnes jedním z nejpoužívanějších jazyků v oblasti tvorby nejen samotných softwarových produktů, ale i poskytování jejich infrastruktury. V důsledku toho se mnoho devopů, ať už ze své vůle nebo proti ní, muselo naučit nový jazyk pro pozdější použití jako doplněk ke starým dobrým Bash skriptům. Bash a Python však vyznávají různé přístupy k psaní kódu a mají určité vlastnosti, což znamená, že portování Bash skriptů do „hadího jazyka“ se někdy ukazuje jako prostorný a zdaleka ne triviální úkol.

Aby se vývojářům usnadnil život, bylo vytvořeno mnoho užitečných knihoven a utilit v Pythonu a stále se vytváří. Tento článek popisuje dvě nové knihovny vytvořené autorem tohoto příspěvku - smart-env и python-shell - a navrženo tak, aby zbavilo devopy nutnosti věnovat velkou pozornost složitosti práce s Pythonem a ponechalo prostor pro zajímavější úkoly. Předmětem činnosti knihoven jsou proměnné prostředí a spouštění externích utilit.

Kdo má zájem, podívejte se na kočku.

Nová "kola"?

Zdálo by se, proč vytvářet nové balíčky pro docela běžné operace? Co vám brání používat os.environ a subprocess.<metodu nebo třídu dle vašeho výběru> přímo?

Důkazy poskytnu ve prospěch každé z knihoven zvlášť.

knihovna smart-env

Než napíšete svůj vlastní nápad, je užitečné jít online a hledat hotová řešení. Samozřejmě existuje riziko, že nenajdete, co potřebujete, ale jedná se spíše o „pojistnou událost“. Tento přístup zpravidla funguje a ušetří spoustu času a úsilí.

Podle výsledků vyhledávač bylo odhaleno následující:

  • existují balíčky, které ve skutečnosti zabalují volání do os.environ, ale zároveň vyžadují spoustu rušivých akcí (vytvoření instance třídy, speciální parametry ve voláních atd.);
  • Existují dobré balíčky, které jsou však striktně vázány na konkrétní ekosystém (hlavně webové frameworky jako Django), a proto nejsou bez souboru vůbec univerzální;
  • jsou vzácné pokusy udělat něco nového. Například, přidat psaní a explicitně analyzovat hodnoty proměnných voláním metod jako
    get_<typename>(var_name)

    Nebo tady ještě jedno řešení, který však nepodporuje nyní hanobený Python 2 (který navzdory oficiální RIP, stále existují hory psaného kódu a celé ekosystémy);

  • Existují žákovská řemesla, která z nějakého neznámého důvodu skončila v upstreamu PyPI a pouze dělají problémy s pojmenováním nových balíčků (zejména název „smart-env“ je nezbytným opatřením).

A tento seznam může pokračovat ještě dlouho. Výše uvedené body však stačily k tomu, aby mě nadchla myšlenka vytvořit něco pohodlného a univerzálního.

Požadavky, které byly nastaveny před zápisem smart-env:

  • Nejjednodušší schéma použití
  • Snadno konfigurovatelná podpora psaní dat
  • Kompatibilní s Python 2.7
  • Dobré pokrytí kódu testy

To vše se nakonec podařilo zrealizovat. Zde je příklad použití:

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

Jak můžete vidět z příkladu, pro práci s novou třídou ji stačí importovat (nemusíte vytvářet instanci – mínus akce navíc). Přístupu k jakékoli proměnné prostředí je dosaženo tím, že se na ni odkazuje jako na proměnnou třídy ENV, což ve skutečnosti činí tuto třídu intuitivním obalem pro nativní systémové prostředí a zároveň ji mění v možný konfigurační objekt pro téměř jakýkoli systém ( podobného přístupu je například dosaženo v Django , pouze tam je konfiguračním objektem samotný modul nastavení/balíček).

Zapnutí/vypnutí režimu podpory automatického psaní je dosaženo pomocí dvou metod – enable_automatic_type_cast() a disable_automatic_type_cast(). To může být výhodné, pokud proměnná prostředí obsahuje serializovaný objekt podobný JSON nebo dokonce jen booleovskou konstantu (explicitní nastavení proměnné DEBUG v Django porovnáním proměnné prostředí s „platnými“ řetězci je jedním z nejběžnějších případů). Nyní ale není potřeba vyloženě převádět řetězce – většina potřebných akcí je již zapuštěna do hlubin knihovny a jen čeká na signál k akci. 🙂 Obecně platí, že psaní funguje transparentně a podporuje téměř všechny dostupné vestavěné datové typy (netestováno zmrazené, komplexní a bajty).

Požadavek na podporu Pythonu 2 byl implementován prakticky bez obětí (opuštění psaní a některé „cukrové bonbóny“ nejnovějších verzí Pythonu 3), zejména díky všudypřítomné šestce (pro vyřešení problémů s používáním metatříd ).

Ale existují určitá omezení:

  • Podpora Pythonu 3 znamená verzi 3.5 a vyšší (jejich přítomnost ve vašem projektu je výsledkem lenosti nebo nedostatku potřeby vylepšení, protože je těžké přijít na objektivní důvod, proč jste stále na 3.4);
  • V Pythonu 2.7 knihovna nepodporuje deserializaci množinových literálů. Popis zde. Ale pokud by to chtěl někdo realizovat, jste vítáni :);

Knihovna má také mechanismus výjimek pro případ chyb analýzy. Pokud řetězec nemohl být rozpoznán žádným z dostupných analyzátorů, hodnota zůstane řetězcem (spíše z důvodů pohodlí a zpětné kompatibility s obvyklou logikou fungování proměnných v Bash).

python-shell knihovna

Nyní vám povím o druhé knihovně (vynechám popis nedostatků stávajících analogů - je podobný tomu popsanému pro analogy smart-env. - zde и zde).

Obecně platí, že myšlenka implementace a požadavky na ni jsou podobné těm popsaným pro smart-env, jak je vidět z příkladu:

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

Myšlenka je tato:

  1. Jediná třída, která reprezentuje Bash ve světě Pythonu;
  2. Každý příkaz Bash je volán jako funkce třídy Shell;
  3. Parametry pro každé volání funkce jsou pak předány do odpovídajícího volání příkazu Bash;
  4. Každý příkaz se provádí „tady a teď“ v okamžiku, kdy je volán, tzn. synchronní přístup funguje;
  5. je možné přistupovat k výstupu příkazu ve stdout, stejně jako k jeho návratovému kódu;
  6. Pokud příkaz není v systému, je vyvolána výjimka.

Stejně jako u smart-env je zde podpora pro Python 2 (i když bylo zapotřebí trochu více obětní krve) a žádná podpora pro Python 3.0-3.4.

Plány rozvoje knihoven

Knihovny můžete nyní používat: obě jsou zveřejněny na oficiálním PyPI. Zdroje jsou dostupné na Github (viz níže).

Obě knihovny budou rozvíjeny s ohledem na zpětnou vazbu shromážděnou od zájemců. A pokud může být obtížné přijít s řadou nových funkcí v smart-env, pak v python-shell je určitě ještě něco, co lze přidat:

  • podpora neblokujících hovorů;
  • možnost interaktivní komunikace s týmem (práce se stdin);
  • přidání nových vlastností (například vlastnost pro příjem výstupu ze stderr);
  • implementace adresáře dostupných příkazů (pro použití s ​​funkcí dir());
  • atd.

reference

  1. knihovna smart-env: GitHub и PyPI
  2. knihovna python-shell: GitHub и PyPI
  3. Telegramový kanál aktualizace knihovny

UPD23.02.2020:
* Úložiště byla přesunuta, odpovídající odkazy byly aktualizovány
* Verze python-shell==1.0.1 se připravuje na vydání 29.02.2020. Změny zahrnují podporu automatického dokončování příkazů a příkazu dir(Shell), spouštění příkazů s neplatným identifikátorem Pythonu a opravy chyb.

Zdroj: www.habr.com

Přidat komentář