Créer une amitié entre 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 non seulement de la création de produits logiciels eux-mêmes, mais également de la fourniture de leur infrastructure. En conséquence, de nombreux développeurs, de leur plein gré ou contre leur gré, ont dû apprendre un nouveau langage pour une utilisation ultérieure en complément des bons vieux scripts Bash. Cependant, Bash et Python proposent des approches différentes en matière d'écriture de code et possèdent certaines fonctionnalités, ce qui signifie que le portage de scripts Bash vers le « langage serpent » s'avère parfois être une tâche volumineuse et loin d'être 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 deux nouvelles bibliothèques créées par l'auteur de cet article - environnement intelligent и coquille de python - et conçu pour soulager les développeurs de la nécessité de prêter beaucoup d'attention aux subtilités du travail avec Python, laissant ainsi la place à des tâches plus intéressantes. Le domaine d'activité des bibliothèques concerne les variables d'environnement et le lancement d'utilitaires externes.

Toute personne intéressée, veuillez consulter le chat.

De nouveaux « vélos » ?

Il semblerait, pourquoi créer de nouveaux packages pour des opérations assez ordinaires ? Qu'est-ce qui vous empêche d'utiliser directement os.environ et subprocess.<method or class of your Choice> ?

Je fournirai des preuves en faveur de chacune des bibliothèques séparément.

bibliothèque smart-env

Avant d'écrire votre propre idée, il est utile d'aller en ligne et de rechercher des solutions toutes faites. Bien sûr, il y a un risque de ne pas trouver ce dont on a besoin, mais il s'agit plutôt d'un « événement d'assurance ». En règle générale, cette approche fonctionne et permet d'économiser beaucoup de temps et d'efforts.

Selon les résultats moteur de recherche ce qui suit a été révélé :

  • il existe des packages qui encapsulent les appels à os.environ, mais nécessitent en même temps un certain nombre d'actions distrayantes (création d'une instance d'une classe, paramètres spéciaux dans les appels, etc.) ;
  • Il existe de bons packages, qui sont cependant strictement liés à un écosystème spécifique (principalement des frameworks web comme Django) et ne sont donc pas du tout universels sans fichier ;
  • il existe de rares tentatives pour faire quelque chose de nouveau. Par exemple, ajouter une saisie et analysez explicitement les valeurs des variables en appelant des méthodes telles que
    get_<typename>(var_name)

    Ou ici une solution de plus, qui, cependant, ne prend pas en charge Python 2, désormais en disgrâce (qui, malgré RIP officiel, il existe encore des montagnes de code écrit et des écosystèmes entiers) ;

  • Il existe des créations d'élèves qui, pour une raison inconnue, se sont retrouvées dans le PyPI en amont et ne créent que des problèmes avec la dénomination des nouveaux packages (en particulier, le nom « smart-env » est une mesure nécessaire).

Et cette liste peut durer longtemps. Cependant, les points ci-dessus ont suffi à m'enthousiasmer à l'idée de créer quelque chose de pratique et d'universel.

Exigences définies avant d'écrire 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 du code par les tests

Finalement, tout cela s’est 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 sur l'exemple, pour travailler avec une nouvelle classe, il vous 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 s'y référant comme une variable de la classe ENV, ce qui, en fait, fait de cette classe un wrapper intuitif pour l'environnement système natif, tout en la transformant simultanément en un objet de configuration possible pour presque tous les systèmes ( une approche similaire, par exemple, est obtenue dans Django , seulement là, l'objet de configuration est le module/package de paramètres lui-même).

L'activation/désactivation du mode de prise en charge de la saisie automatique 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 sérialisé de type JSON ou même simplement une constante booléenne (définir explicitement 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 désormais, il n'est plus nécessaire de convertir explicitement les chaînes - la plupart des actions nécessaires sont déjà intégrées dans les profondeurs de la bibliothèque et n'attendent qu'un signal pour agir. 🙂 En général, la saisie fonctionne de manière transparente et prend en charge presque tous les types de données intégrés disponibles (les frozenset, les complexes et les octets n'ont pas été testés).

L'exigence de support de Python 2 a été mise en œuvre pratiquement sans sacrifices (l'abandon du typage et certains des « bonbons au sucre » des dernières versions de Python 3), notamment grâce aux six omniprésents (pour résoudre les problèmes d'utilisation des métaclasses ).

Mais il y a quelques restrictions :

  • Le support de Python 3 signifie 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 sur 3.4) ;
  • Dans Python 2.7, la bibliothèque ne prend pas en charge la désérialisation des littéraux définis. Description ici. Mais si quelqu'un veut le mettre en œuvre, il est le bienvenu :);

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

bibliothèque python-shell

Je vais maintenant vous parler de la deuxième bibliothèque (j'omettra la description des défauts des analogues existants - elle est similaire à celle décrite pour smart-env. Analogues - ici и ici).

En général, l'idée de mise en œuvre et ses exigences 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 de chaque appel de fonction sont ensuite transmis à l'appel de commande Bash correspondant ;
  4. Chaque commande est exécutée « ici et maintenant » au moment où elle est appelée, c'est-à-dire l'approche synchrone fonctionne ;
  5. il est possible d'accéder à la sortie d'une commande dans stdout, ainsi qu'à son code retour ;
  6. Si la commande n'est pas dans le système, une exception est levée.

Comme avec smart-env, il existe un support pour Python 2 (même si un peu plus de sang sacrificiel était nécessaire) et aucun 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 publié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, s'il peut être difficile de proposer une variété de nouvelles fonctionnalités dans smart-env, alors dans python-shell, il y a certainement autre chose à ajouter :

  • prise en charge des appels non bloquants ;
  • possibilité de communication interactive avec l'équipe (travail avec stdin) ;
  • ajout de nouvelles propriétés (par exemple, propriété pour recevoir la sortie de stderr) ;
  • implémentation d'un répertoire de commandes disponibles (à utiliser avec la fonction dir()) ;
  • etc.

références

  1. bibliothèque smart-env : Github и PyPI
  2. bibliothèque python-shell : Github и PyPI
  3. Canal télégramme 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/XNUMX/XNUMX. Les modifications incluent la prise en charge de la saisie semi-automatique des commandes et de la commande dir(Shell), l'exécution de commandes avec un identifiant Python non valide et des corrections de bugs.

Source: habr.com

Ajouter un commentaire