Nous nous faisons des amis Python et Bash: bibliothèques smart-env et python-shell

Bonne journée à tous.

Aujourd'hui, Python est l'un des langages les plus utilisés dans le domaine de la création non seulement de produits logiciels directs, mais également de la fourniture de leur infrastructure. En conséquence, de nombreux devops, par leur volonté ou contre, ont dû apprendre une nouvelle langue pour une utilisation ultérieure en complément des bons vieux scripts Bash. Cependant, Bash et Python professent des approches différentes pour écrire du code et ont certaines fonctionnalités, étant donné que le portage de scripts Bash vers le "langage de serpent" est parfois volumineux et loin d'être une tâche triviale.

Pour faciliter la vie des développeurs, de nombreuses bibliothèques et utilitaires utiles en Python ont été créés et continuent d'être créés. Cet article décrit immédiatement deux nouvelles bibliothèques créées par l'auteur de cet article - smart-envet python-shell - et conçu pour sauver les devops de la nécessité de prêter beaucoup d'attention aux subtilités de travailler avec Python, laissant de la place pour des tâches plus intéressantes. La portée de la bibliothèque est les variables d'environnement et le lancement d'utilitaires externes.

Qui sont intéressés, s'il vous plaît, sous le chat.

De nouveaux vélos?


Il semblerait, pourquoi créer de nouveaux packages pour des opérations assez banales? Qu'est-ce qui empêche l'utilisation directe d'os.environ et du sous-processus. <Méthode ou classe de votre choix>?

Je vais témoigner en faveur de chacune des bibliothèques séparément.

Bibliothèque Smart-env


Avant d'écrire votre propre idée, il est utile de surfer sur Internet et de rechercher des solutions toutes faites. Bien sûr, il y a un risque de ne pas trouver ce dont vous avez besoin, mais plutôt, c'est un "cas d'assurance". En règle générale, l'approche fonctionne et économise beaucoup de temps et d'efforts.

Selon les résultats de la recherche , les éléments suivants ont été révélés:

  • il existe des packages qui enveloppent vraiment les appels à os.environ, mais nécessitent en même temps un tas d'actions distrayantes (création d'une instance de la classe, paramètres spéciaux dans les appels, etc.);
  • il existe de bons packages qui sont cependant étroitement liés à un écosystème spécifique (principalement des frameworks web comme Django) et ne sont donc pas universels sans fichier;
  • il y a de rares tentatives pour faire quelque chose de nouveau. Par exemple, ajoutez du typage et analysez explicitement les valeurs des variables en appelant les méthodes du formulaire

    get_<typename>(var_name)

    Ou voici une autre solution qui, cependant, ne prend pas actuellement en charge Python 2 déshonoré (sur lequel, malgré le RIP officiel , il y a encore des montagnes de code écrit et des écosystèmes entiers);
  • il y a de l'artisanat pour les élèves, il n'est pas du tout clair pourquoi ils se sont retrouvés dans le PyPI en amont et ne créent que des problèmes pour nommer de nouveaux packages (en particulier, le nom "smart-env" est une mesure nécessaire).

Et la liste continue encore et encore. Cependant, les points ci-dessus étaient suffisants pour saisir l'idée de rendre quelque chose de pratique et universel.

Exigences pour smart-env:

  • Le schéma d'utilisation le plus simple
  • Prise en charge de la saisie de données facilement configurable
  • Compatible avec Python 2.7
  • Bonne couverture de test

Finalement, tout cela a été réalisé. Voici un exemple d'utilisation:

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

Comme vous pouvez le voir dans l'exemple, pour travailler avec la nouvelle classe, il suffit de l'importer (vous n'avez pas besoin de créer une instance - moins l'action supplémentaire). L'accès à n'importe quelle variable d'environnement est obtenu en se référant à elle comme une variable de classe ENV, ce qui, en fait, fait de cette classe un wrapper intuitif pour l'environnement système natif, en le transformant simultanément en une variante possible de l'objet de configuration de presque n'importe quel système (une approche similaire, par exemple, est réalisée dans Django , seulement là, l'objet de configuration est directement le module / package de paramètres).

L'activation / désactivation du mode de prise en charge automatique de la saisie est obtenue à l'aide de deux méthodes: enable_automatic_type_cast () et disable_automatic_type_cast (). Cela peut être pratique si la variable d'environnement contient un objet de type JSON sérialisé ou même juste une constante booléenne (la définition explicite de la variable DEBUG dans Django en comparant la variable d'environnement avec des chaînes «valides» est l'un des cas les plus courants). Mais maintenant, il n'est plus nécessaire de convertir explicitement les lignes - la plupart des actions nécessaires sont déjà intégrées dans les entrailles de la bibliothèque et n'attendent qu'un signal d'action. :) En général, la frappe fonctionne de manière transparente et prend en charge presque tous les types de données intégrés disponibles (frozenset, complex et octets n'ont pas été testés).

L'exigence de prise en charge de Python 2 a été mise en œuvre sans pratiquement aucun sacrifice (le refus de taper et certains bonbons de sucre des dernières versions de Python 3), en particulier, grâce aux six omniprésents (pour résoudre les problèmes d'utilisation des métaclasses).

Mais il y a quelques limitations:

  • La prise en charge de Python 3 implique la version 3.5 et supérieure (leur présence dans votre projet est le résultat soit de la paresse, soit du manque de besoin d'améliorations, car il est difficile de trouver une raison objective pour laquelle vous êtes toujours assis sur la 3.4);
  • Dans Python 2.7, la bibliothèque ne prend pas en charge la désérialisation des littéraux d'ensemble. Description ici . Mais, si quelqu'un veut mettre en œuvre - bienvenue :);

La bibliothèque professe également un mécanisme d'exception en cas d'erreurs d'analyse. Si une chaîne n'a pu être reconnue par aucun des analyseurs disponibles, la valeur reste chaîne (plutôt, pour des raisons de commodité et de compatibilité descendante avec la logique habituelle des variables dans Bash).

Bibliothèque shell Python


Maintenant, je vais parler de la deuxième bibliothèque (je vais omettre la description des lacunes des analogues disponibles - elle est similaire à celle décrite pour smart-env. Analogues - ici et ici ).

En général, l'idée d'implémentation et les exigences pour celle-ci sont similaires à celles décrites pour smart-env, comme le montre l'exemple:

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

L'idée est la suivante:

  1. Une classe unique qui représente Bash dans le monde Python;
  2. Chaque commande Bash est appelée en fonction de la classe Shell;
  3. Les paramètres d'appel de chaque fonction sont ensuite transmis à l'appel à la commande Bash correspondante;
  4. Chaque commande est exécutée "ici et maintenant" au moment de son appel, c'est-à-dire fonctionne approche synchrone;
  5. il est possible d'accéder à la commande exhaust dans stdout, ainsi qu'à son code retour;
  6. Si la commande est absente dans le système, une exception est levée.

Comme avec smart-env, le support de Python 2 est fourni (bien qu'il ait fallu un peu plus de sang sacrificiel) et il n'y a pas de support pour Python 3.0-3.4.

Plans de développement de la bibliothèque


Vous pouvez utiliser les bibliothèques maintenant: les deux sont présentées sur le PyPI officiel. Les sources sont disponibles sur Github (voir ci-dessous).

Les deux bibliothèques seront développées en tenant compte des commentaires recueillis auprès des personnes intéressées. Et, si dans smart-env il peut être difficile de proposer une variété de nouvelles fonctionnalités, alors il y a certainement autre chose à ajouter dans python-shell:

  • prise en charge des appels non bloquants;
  • la possibilité de communication interactive avec l'équipe (travail avec stdin);
  • ajouter de nouvelles propriétés (par exemple, une propriété pour obtenir l'échappement de stderr);
  • implémentation du catalogue des commandes disponibles (à utiliser avec la fonction dir ());
  • etc.

Références


  1. Bibliothèque Smart-env: Github et PyPI
  2. Bibliothèque Python-shell: github et pypi
  3. Canal de télégramme pour les mises à jour de la bibliothèque


UPD 23/02/2020:
* Les référentiels ont été déplacés, les liens correspondants ont été mis à jour
* La version python-shell == 1.0.1 est en cours de préparation pour une sortie le 29/02/2020. Parmi les modifications figurent la prise en charge de la saisie semi-automatique des commandes et de la commande dir (Shell), le lancement de commandes avec un identifiant Python non valide et des corrections de bogues.

UPD 03/01/2020:
* Publication sur la prochaine version.

All Articles