Facendo Python e Bash Friendship: bibliotecas smart-env e python-shell

Bo día a todos.

Hoxe, Python é unha das linguaxes máis utilizadas no ámbito da creación non só de produtos de software en si, senón tamén de proporcionar a súa infraestrutura. Como resultado, moitos devops, xa fose pola súa vontade ou en contra, tiveron que aprender un novo idioma para o seu uso posterior como complemento dos bos e vellos guións de Bash. Non obstante, Bash e Python profesan enfoques diferentes para escribir código e teñen certas características, o que significa que levar os scripts de Bash á "linguaxe da serpe" ás veces resulta ser unha tarefa ampla e lonxe de ser trivial.

Para facilitarlles a vida aos devops, creáronse e seguen creándose moitas bibliotecas e utilidades útiles en Python. Este artigo describe dúas novas bibliotecas creadas polo autor desta publicación: intelixente-env и python-shell - e deseñado para aliviar os devops da necesidade de prestar moita atención ás complexidades de traballar con Python, deixando espazo para tarefas máis interesantes. O ámbito de actividade das bibliotecas son as variables de ambiente e o lanzamento de utilidades externas.

Quen estea interesado, consulte cat.

Novas "bicicletas"?

Parece que, por que crear novos paquetes para operacións bastante comúns? Que lle impide usar os.environ e subprocess.<método ou clase que elixa> directamente?

Aportarei probas a favor de cada unha das bibliotecas por separado.

biblioteca smart-env

Antes de escribir a túa propia idea, é útil conectarte en liña e buscar solucións preparadas. Por suposto, existe o risco de non atopar o que necesitas, pero este é máis ben un "evento de seguro". Como regra xeral, este enfoque funciona e aforra moito tempo e esforzo.

Segundo os resultados buscar revelouse o seguinte:

  • hai paquetes que realmente envolven as chamadas a os.environ, pero ao mesmo tempo requiren unha serie de accións que distraen (crear unha instancia dunha clase, parámetros especiais nas chamadas, etc.);
  • Hai bos paquetes, que, porén, están estritamente ligados a un ecosistema específico (principalmente marcos web como Django) e polo tanto non son para nada universais sen un ficheiro;
  • hai raros intentos de facer algo novo. Por exemplo, engadir dixitación e analizar explícitamente os valores das variables chamando a métodos como
    get_<typename>(var_name)

    Ou aquí unha solución máis, que, con todo, non admite o agora deshonrado Python 2 (que, a pesar de RIP oficial, aínda hai montañas de código escrito e ecosistemas enteiros);

  • hai manualidades de estudantes escolares que, por algún motivo descoñecido, acabaron en PyPI ascendente e só crean problemas coa denominación de novos paquetes (en particular, o nome "smart-env" é unha medida necesaria).

E esta lista pode continuar por moito tempo. Non obstante, os puntos anteriores foron suficientes para entusiasmarme coa idea de facer algo cómodo e universal.

Requisitos que se estableceron antes de escribir smart-env:

  • O esquema de uso máis sinxelo
  • Soporte de escritura de datos facilmente configurable
  • Compatible con Python 2.7
  • Boa cobertura de código mediante probas

En definitiva, todo isto deuse conta. Aquí tes un exemplo de uso:

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

Como podes ver no exemplo, para traballar cunha nova clase, só tes que importala (non necesitas crear unha instancia, menos a acción extra). O acceso a calquera variable de ambiente conséguese referíndose a ela como unha variable da clase ENV, o que, de feito, fai desta clase un envoltorio intuitivo para o entorno do sistema nativo, ao tempo que a converte nun posible obxecto de configuración para case calquera sistema ( un enfoque similar, por exemplo, conséguese en Django , só alí o obxecto de configuración é o propio módulo/paquete de configuración).

A activación/desactivación do modo de soporte de escritura automática conséguese mediante dous métodos: enable_automatic_type_cast() e disable_automatic_type_cast(). Isto pode ser conveniente se a variable de ambiente contén un obxecto tipo JSON serializado ou mesmo só unha constante booleana (un dos casos máis comúns é establecer explícitamente a variable DEBUG en Django comparando a variable de ambiente con cadeas "válidas"). Pero agora non hai necesidade de converter as cadeas de xeito explícito: a maioría das accións necesarias xa están incrustadas nas profundidades da biblioteca e só esperan un sinal para actuar. 🙂 En xeral, a escritura funciona de forma transparente e admite case todos os tipos de datos integrados dispoñibles (non se probaron os conxuntos conxelados, os complexos e os bytes).

O requisito para admitir Python 2 implementouse practicamente sen sacrificios (o abandono da mecanografía e algúns dos "doces de azucre" das últimas versións de Python 3), en particular, grazas ao ubicuo seis (para resolver os problemas de uso de metaclases). ).

Pero hai algunhas restricións:

  • O soporte de Python 3 significa a versión 3.5 ou superior (a súa presenza no teu proxecto é o resultado da preguiza ou da falta de necesidade de melloras, xa que é difícil atopar unha razón obxectiva pola que aínda estás na 3.4);
  • En Python 2.7, a biblioteca non admite a deserialización de literais de conxunto. Descrición aquí. Pero se alguén quere implementala, benvido é :);

A biblioteca tamén ten un mecanismo de excepción en caso de erros de análise. Se a cadea non pode ser recoñecida por ningún dos analizadores dispoñibles, o valor segue a ser unha cadea (máis ben, por razóns de conveniencia e compatibilidade cara atrás coa lóxica habitual de como funcionan as variables en Bash).

biblioteca python-shell

Agora falarei sobre a segunda biblioteca (omitirei a descrición das deficiencias dos análogos existentes - é semellante ao descrito para smart-env. Análogos - aquí и aquí).

En xeral, a idea de implementación e os requisitos para ela son similares aos descritos para smart-env, como se pode ver no exemplo:

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

A idea é esta:

  1. Unha única clase que representa a Bash no mundo de Python;
  2. Cada comando Bash chámase como unha función da clase Shell;
  3. Os parámetros para cada chamada de función pásanse despois á chamada de comando Bash correspondente;
  4. Cada comando execútase "aquí e agora" no momento en que se chama, é dicir. o enfoque sincrónico funciona;
  5. é posible acceder á saída dun comando en stdout, así como ao seu código de retorno;
  6. Se o comando non está no sistema, lánzase unha excepción.

Do mesmo xeito que con smart-env, hai soporte para Python 2 (aínda que foi necesario un pouco máis de sacrificio de sangue) e non hai soporte para Python 3.0-3.4.

Plans de desenvolvemento da biblioteca

Xa podes usar as bibliotecas: ambas están publicadas no PyPI oficial. As fontes están dispoñibles en Github (ver máis abaixo).

Ambas bibliotecas desenvolveranse tendo en conta os comentarios recollidos dos interesados. E, se pode ser difícil crear unha variedade de funcións novas en smart-env, entón en python-shell definitivamente hai algo máis que engadir:

  • soporte para chamadas sen bloqueo;
  • posibilidade de comunicación interactiva co equipo (traballando con stdin);
  • engadindo novas propiedades (por exemplo, propiedade para recibir saída de stderr);
  • implementación dun directorio de comandos dispoñibles (para usar coa función dir());
  • etc

referencias

  1. biblioteca smart-env: Github и PyPI
  2. biblioteca python-shell: Github и PyPI
  3. Canle de telegrama actualizacións da biblioteca

Actualización 23.02.2020/XNUMX/XNUMX:
* Movéronse os repositorios, actualizáronse as ligazóns correspondentes
* A versión python-shell==1.0.1 estase preparando para a súa publicación o 29.02.2020/XNUMX/XNUMX. Os cambios inclúen soporte para o autocompletado de comandos e o comando dir(Shell), a execución de comandos cun identificador de Python non válido e correccións de erros.

Fonte: www.habr.com

Engadir un comentario