Alliage de Python et Bash : bibliothèques smart-env et python-shell

Bonjour à 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, mais aussi de l'infrastructure qui les supporte. Par conséquent, de nombreux DevOps, qu'ils le veuillent ou non, ont dû apprendre un nouveau langage pour l'utiliser en complément des anciens bons scripts Bash. Cependant, Bash et Python ont des approches différentes en matière de codage et présentent certaines particularités, ce qui rend parfois le portage de scripts Bash vers le « langage serpent » une tâche complexe et loin d'être triviale.

Pour faciliter la vie des DevOps, de nombreuses bibliothèques et outils utiles en Python ont été et continuent d'être créés. Cet article décrit deux nouvelles bibliothèques développées par l'auteur de ce post — smart-env et python-shell — destinées à libérer le DevOps de la nécessité de se concentrer sur les subtilités du travail avec Python, laissant place à des tâches plus intéressantes. Le domaine d'application des bibliothèques concerne les variables d'environnement et l'exécution d'outils externes.

Ceux que cela intéresse, veuillez continuer à lire.

Des “vélos” nouveaux ?

On pourrait se demander pourquoi créer de nouveaux packages pour des opérations assez ordinaires ? Qu'est-ce qui empêche d'utiliser directement os.environ et subprocess. ?

Je fournirai des preuves pour chaque bibliothèque séparément.

La bibliothèque smart-env

Avant de créer sa propre solution, il est utile de faire des recherches en ligne pour trouver des solutions prêtes à l'emploi. Bien sûr, il y a le risque de ne pas trouver ce qui convient, mais c'est plutôt un « cas d'assurance ». En règle générale, cette approche fonctionne bien et permet d'économiser beaucoup de temps et d'efforts.

Selon les résultats de Recherche A donné les résultats suivants :

  • Il existe des packages qui enveloppent réellement les appels à os.environ, mais nécessitent beaucoup d'actions distrayantes (création d'une instance de classe, paramètres spéciaux dans les appels, etc.) ;
  • Il existe de bons packages qui, cependant, sont étroitement liés à un écosystème particulier (principalement des frameworks web comme Django) et ne sont donc pas du tout universels sans modification ;
  • Il y a de rares tentatives de faire quelque chose de nouveau. Par exemple, ajouter de la typage et analyser explicitement les valeurs des variables en appelant des méthodes de type
    get_(var_name)

    Ou encore une autre solution, qui ne prend cependant pas en charge le Python 2 désormais obsolète (sur lequel, malgré le fait que R.I.P. officiel, il reste encore des montagnes de code écrit et des écosystèmes entiers);

  • il y a des bricolages scolaires et étudiants, dont on ne sait pas vraiment pourquoi ils se trouvent dans le PyPI amont et qui ne font que créer des problèmes de nommage pour les nouveaux paquets (en particulier, le nom « smart-env » — une mesure contraignante).

Et cette liste pourrait continuer longtemps. Cependant, les points mentionnés ci-dessus suffisent pour susciter l'idée de créer quelque chose de pratique et universel.

Les exigences qui ont été posées lors de la rédaction de smart-env :

  • Une utilisation aussi simple que possible
  • Un support de typage des données facilement configurable
  • Compatibilité avec Python 2.7
  • Une bonne couverture du code par des tests

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

from smart_env import ENV

print(ENV.HOME)  # Équivalent à print(os.environ['HOME'])

# en supposant que vous ayez défini la variable d'environnement MYVAR à "True"

ENV.enable_automatic_type_cast()

my_var = ENV.MY_VAR  # Équivalent à True boolean

ENV.NEW_VAR = 100  # Définit une nouvelle variable d'environnement

Comme on peut le voir dans l'exemple, pour travailler avec la nouvelle classe, il suffit de l'importer (pas besoin de créer une instance — ce qui évite une action inutile). L'accès à toute variable d'environnement se fait par son nom comme s'il s'agissait d'une variable de classe ENV, ce qui, en fait, fait de cette classe un wrapper intuitif de l'environnement système natif, tout en la transformant en un candidat potentiel pour un objet de configuration dans presque tous les systèmes (une approche similaire est adoptée dans Django, où l'objet de configuration est directement le module/package settings).

L'activation/désactivation du mode de support pour la typage automatique se fait par l'utilisation 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 semblable à JSON sérialisé ou même simplement une constante booléenne (la déclaration explicite de la variable DEBUG dans Django, en comparant la variable d'environnement avec des 'chaînes' 'acceptables' — l'un des cas les plus courants). Mais maintenant, il n'est plus nécessaire de convertir explicitement les chaînes — la majorité 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, le typage fonctionne de manière transparente et prend en charge presque tous les types de données intégrés (les frozenset, complex et bytes n'ont pas été testés).

La prise en charge de Python 2 a été mise en œuvre presque sans sacrifices (abandon de typing et de quelques « confiseries » des dernières versions de Python 3), principalement grâce à l'omniprésent six (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 (le fait qu'elles soient présentes dans votre projet est soit le résultat de la paresse, soit de l'absence de nécessité d'améliorations, car il est difficile de trouver une raison objective pour laquelle vous restez encore sur 3.4) ;
  • Dans Python 2.7, la bibliothèque ne prend pas en charge la désérialisation des littéraux de ensembles. Description ici. Mais si quelqu'un souhaite mettre cela en œuvre — bienvenue :) ;

La bibliothèque adopte également un mécanisme d'exception pour les erreurs de parsing. Si une chaîne ne peut être reconnue par aucun des analyseurs disponibles, la valeur reste une chaîne (plutôt par souci de commodité et de rétrocompatibilité avec la logique de travail des variables dans Bash).

La bibliothèque python-shell

Je vais maintenant parler de la deuxième bibliothèque (je vais omettre la description des défauts des analogues existants — elle est similaire à celle décrite pour smart-env. Les analogues — ici et ici).

Dans l'ensemble, l'idée de mise en œuvre et les exigences à cet égard sont analogues à celles décrites pour smart-env, comme l'illustre l'exemple :

from python_shell import Shell

Shell.ls('-l', '$HOME')  # Équivalent à "ls -l $HOME"

command = Shell.whoami()  # Équivalent à "whoami"
print(command.output)  # affiche votre nom d'utilisateur actuel

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

Shell.mkdir('-p', '\/tmp\/new_folder')  # crée un nouveau dossier

L'idée est la suivante :

  1. Une seule classe, incarnant Bash dans le monde de Python ;
  2. Chaque commande Bash est appelée comme une fonction de la classe Shell ;
  3. Les paramètres de chaque appel de fonction sont ensuite passés à l'appel de la commande Bash correspondante ;
  4. Chaque commande est exécutée « ici et maintenant » au moment de son appel, c'est-à-dire qu'une approche synchrone est adoptée ;
  5. il est possible d'accéder à la sortie de la commande dans stdout, ainsi qu'à son code de retour ;
  6. Si la commande n'est pas présente sur le système — une exception est levée.

Comme dans le cas de smart-env, une prise en charge de Python 2 est assurée (il est vrai que cela a nécessité un peu plus de sacrifices) et il n'y a pas de prise en charge pour Python 3.0-3.4.

Plans de développement des bibliothèques

Les bibliothèques peuvent déjà être utilisées : les deux sont disponibles sur le PyPI officiel. Les sources sont accessibles sur Github (voir ci-dessous).

Les deux bibliothèques seront développées en tenant compte des retours recueillis auprès des personnes intéressées. Et, si dans smart-env, il peut être difficile d'imaginer une variété de nouvelles fonctionnalités, dans python-shell, il y a certainement encore des ajouts possibles :

  • support des appels non-bloquants ;
  • possibilité d'interaction en direct avec l'équipe (travail avec stdin) ;
  • ajout de nouvelles propriétés (comme property pour obtenir la sortie de stderr) ;
  • implémentation d'un répertoire des commandes disponibles (pour utilisation avec la fonction dir()) ;
  • etc.

Liens

  1. Bibliothèque smart-env : Github et PyPI
  2. Bibliothèque python-shell : Github et PyPI
  3. Canal Telegram mises à jour des bibliothèques

UPD 23.02.2020 :
* Les dépôts ont été transférés, les liens correspondants ont été mis à jour
* La version python-shell==1.0.1 est prévue pour le 29.02.2020. Parmi les changements — support de l'auto-complétion des commandes et de la commande dir(Shell), exécution de commandes avec un identifiant Python invalide, corrections de bugs.

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster