paint-brush
3 problèmes majeurs de Python et comment les résoudrepar@dave01
3,578 lectures
3,578 lectures

3 problèmes majeurs de Python et comment les résoudre

par David Finson18m2023/01/21
Read on Terminal Reader

Trop long; Pour lire

La gestion d'environnements de développement complexes a souvent posé des défis à mesure que les projets se développaient. La solution est l'utilisation de la conteneurisation, qui est une méthode de conditionnement d'une application et de ses dépendances dans une unité autonome qui peut être facilement déployée et exécutée sur n'importe quelle plate-forme. Je vais montrer comment configurer et utiliser un environnement de développement conteneurisé à l'aide de Docker et Docker Compose.
featured image - 3 problèmes majeurs de Python et comment les résoudre
David Finson HackerNoon profile picture

Bien que travailler avec Python ait, le plus souvent, été une expérience fantastique pour moi, la gestion d'environnements de développement complexes a souvent posé des défis à mesure que les projets se développaient.

Pour ne citer que quelques exemples, voici 3 problèmes majeurs avec Python que j'ai rencontrés :

1. Les applications qui dépendent de variables d'environnement peuvent avoir besoin que ces variables soient définies avant que l'application puisse s'exécuter.

2. Les applications qui utilisent des certificats d'authentification pour la communication entre différents services peuvent nécessiter la génération de ces certificats localement avant d'exécuter l'application.

3. Des conflits de version de dépendance peuvent survenir entre différents microservices au sein d'un même projet.

Les choses peuvent devenir particulièrement difficiles lorsque vous travaillez avec plusieurs microservices qui dépendent les uns des autres et, franchement, en tant que développeur, je ne veux pas vraiment gérer tous ces frais généraux juste pour être opérationnel. Cela est particulièrement vrai si je suis juste en train d'intégrer un nouveau projet.

Une solution courante utilisée lors du développement d'applications Python consiste à utiliser des environnements virtuels Python , qui sont des environnements isolés contenant une installation Python et les packages requis. Cependant, la gestion de plusieurs environnements virtuels et d'autres configurations liées à l'environnement peut toujours être fastidieuse et fastidieuse, car l'environnement virtuel ne fournit une isolation qu'au niveau de l'interpréteur Python. Cela signifie que d'autres configurations liées à l'environnement, telles que les variables d'environnement et l'allocation de port, sont toujours partagées globalement pour tous les composants du projet.

La solution que je vais démontrer dans cet article est l'utilisation de la conteneurisation, qui est une méthode de conditionnement d'une application et de ses dépendances dans une unité autonome qui peut être facilement déployée et exécutée sur n'importe quelle plate-forme. Docker est une plate-forme populaire pour le développement, le déploiement et l'exécution d'applications conteneurisées, et Docker Compose est un outil qui facilite la définition et l'exécution d'applications Docker multi-conteneurs à l'aide d'un seul fichier YAML (généralement nommé

 docker-compose.yml
). Bien qu'il existe des solutions alternatives telles que minikube , par souci de simplicité, je m'en tiendrai à l'utilisation de Docker et Docker Compose dans cet exemple.

Je vais montrer comment configurer et utiliser un environnement de développement conteneurisé à l'aide de Docker et Docker Compose. Je discuterai également de certains des défis liés à l'utilisation d'un environnement de développement conteneurisé et de la manière de les surmonter en configurant Docker et Docker Compose pour répondre aux exigences clés suivantes pour un environnement de développement efficace :

1. Exécuter - Exécution de scénarios de bout en bout qui simulent l'exécution sur l'environnement de production cible.

2. Déployer - Apporter des modifications au code et le redéployer rapidement, comme avec une pile d'exécution d'application non conteneurisée.

3. Débogage - Définition de points d'arrêt et utilisation d'un débogueur pour parcourir le code, comme avec une pile d'exécution d'application non conteneurisée, afin d'identifier et de corriger les erreurs.

Configuration du projet

Pour illustrer cela par un exemple, je définirai une application Python simple qui utilise le framework Web Python léger, Flask , pour créer une API RESTful pour interroger des informations sur les auteurs et leurs publications. L'API a un point de terminaison unique,

 /authors/{author_id}
, qui peut être utilisé pour récupérer des informations sur un auteur particulier en spécifiant son ID en tant que paramètre de chemin. L'application utilise ensuite le module de requêtes pour envoyer des requêtes HTTP à un service de publication distinct, qui est censé fournir une liste des publications de cet auteur. Pour garder le code concis, toutes les données seront générées aléatoirement à la volée à l'aide de la bibliothèque Faker .

Pour commencer, je vais initialiser puis ouvrir un répertoire vide pour le projet. Ensuite, je vais créer deux sous-répertoires : Le premier s'appellera

 authors_service
, et le deuxième
 posts_service
. Dans chacun de ces répertoires, je vais créer 3 fichiers :

1.

 app.py
: Le point d'entrée principal de l'application Flask, qui définit l'application, configure les routes et spécifie les fonctions à appeler lorsqu'une demande est faite à ces routes.

2.

 requirements.txt
: Un fichier texte brut qui spécifie les packages Python requis pour que l'application s'exécute.

3.

 Dockerfile
: Un fichier texte contenant des instructions pour créer une image Docker, qui, comme mentionné ci-dessus, est un package léger, autonome et exécutable qui comprend tout le nécessaire pour exécuter l'application, y compris le code, un runtime, des bibliothèques, des variables d'environnement, et à peu près n'importe quoi d'autre.

Dans chaque

 app.py
fichier, je vais implémenter un microservice Flask avec la logique souhaitée.

Pour

 authors_service
, les
 app.py
le fichier se présente comme suit :

 import os import flask import requests from faker import Faker app = flask.Flask(__name__) @app.route( "/authors/<string:author_id>" , methods=[ "GET" ] )
def get_author_by_id ( author_id: str ):
 author = {        "id" : author_id,        "name" : Faker().name(),        "email" : Faker().email(),        "posts" : _get_authors_posts(author_id) }    return flask.jsonify(author) def _get_authors_posts ( author_id: str ):
 response = requests.get(        f' {os.environ[ "POSTS_SERVICE_URL" ]} / {author_id} '
 )    return response.json() if __name__ == "__main__" : app.run( host=os.environ[ 'SERVICE_HOST' ], port= int (os.environ[ 'SERVICE_PORT' ]) )


Ce code configure une application Flask et définit une route pour gérer les requêtes GET vers le point de terminaison

 /authors/{author_id}
. Lorsque ce point de terminaison est accessible, il génère des données fictives pour un auteur avec l'ID fourni et récupère une liste de publications pour cet auteur à partir du service de publication séparé. Il exécute ensuite l'application Flask, en écoutant le nom d'hôte et le port spécifiés dans les variables d'environnement correspondantes.

Notez que la logique ci-dessus dépend de la
 flask
,
 requests
et
 Faker
paquets. Pour tenir compte de cela, je vais les ajouter au service des auteurs
 requirements.txt
dossier, comme suit :

 flask == 2 . 2 . 2
requests == 2 . 28 . 1
Faker == 15 . 3 . 4

Notez qu'il n'existe aucune exigence spécifique de gestion des versions de package pour les dépendances référencées tout au long de ce guide. Les versions utilisées étaient les dernières disponibles au moment de la rédaction.

Pour le

 posts_service
,
 app.py
se présente comme suit :

 import os import uuid from random import randint import flask from faker import Faker app = flask.Flask(__name__) @app.route( '/posts/<string:author_id>' , methods=[ 'GET' ] )
def get_posts_by_author_id ( author_id: str ):
 posts = [ {            "id:" : str (uuid.uuid4()),            "author_id" : author_id,            "title" : Faker().sentence(),            "body" : Faker().paragraph() }        for _ in range (randint( 1 , 5 )) ]    return flask.jsonify(posts) if __name__ == '__main__' : app.run( host=os.environ[ 'SERVICE_HOST' ], port= int (os.environ[ 'SERVICE_PORT' ]) )


Dans ce code, lorsqu'un client (c'est-à-dire

 authors_service
) envoie une requête GET à la route
 /posts/{author_id}
, la fonction
 get_posts_by_author_id
est appelé avec le spécifié
 author_id
comme paramètre. La fonction génère des données fictives pour entre 1 et 5 publications écrites par l'auteur à l'aide de la bibliothèque Faker et renvoie la liste des publications sous forme de réponse JSON au client.

Je devrai également ajouter les packages flask et Faker aux messages du service

 requirements.txt
dossier, comme suit :

 flask == 2 . 2 . 2
Faker == 15 . 3 . 4

Avant de conteneuriser ces services, considérons un exemple de la raison pour laquelle je voudrais les empaqueter et les exécuter isolément les uns des autres en premier lieu.

Les deux services utilisent les variables d'environnement

 SERVICE_HOST
et
 SERVICE_PORT
pour définir le socket sur lequel le serveur Flask sera lancé. Tandis que
 SERVICE_HOST
n'est pas un problème (plusieurs services peuvent écouter sur le même hôte),
 SERVICE_PORT
peut causer des problèmes. Si je devais installer toutes les dépendances dans un environnement Python local et exécuter les deux services, le premier service à démarrer utiliserait le port spécifié, provoquant le blocage du second service car il ne pouvait pas utiliser le même port. Une solution simple consiste à utiliser des variables d'environnement distinctes (par exemple,
 AUTHORS_SERVICE_PORT
et
 POSTS_SERVICE_PORT
) au lieu. Cependant, modifier le code source pour s'adapter aux contraintes environnementales peut devenir complexe lors d'un passage à l'échelle.

La conteneurisation permet d'éviter de tels problèmes en configurant l'environnement pour qu'il soit adapté à l'application, plutôt que l'inverse . Dans ce cas, je peux régler le

 SERVICE_PORT
variable d'environnement à une valeur différente pour chaque service, et chaque service pourra utiliser son propre port sans interférence d'autres services.

Pour conteneuriser les services, je vais créer un nouveau fichier nommé
 Dockerfile
dans le répertoire de chaque service. Le contenu de ce fichier (pour les deux services) est le suivant :

 FROM python: 3.8
RUN mkdir /app WORKDIR /app COPY requi rements.txt /app/
RUN pip install -r requi rements.txt
COPY . /app/ CMD [ "python" , "app.py" ]

Cette

 Dockerfile
se construit à partir d'une image parent Python 3.8 et configure un répertoire pour l'application dans le conteneur. Il copie alors le
 requirements.txt
fichier de la machine hôte vers le conteneur et installe les dépendances répertoriées dans ce fichier. Enfin, il copie le reste du code d'application de la machine hôte vers le conteneur et exécute le script d'application principal au démarrage du conteneur.

Ensuite, je vais créer un fichier nommé

 docker-compose.yml
dans le répertoire racine du projet. Comme brièvement mentionné ci-dessus, ce fichier est utilisé pour définir et exécuter des applications Docker multi-conteneurs. Dans le
 docker-compose.yml
fichier, je peux définir les services qui composent l'application, spécifier les dépendances entre eux et configurer la manière dont ils doivent être construits et exécutés. Dans ce cas, il se présente comme suit :

 ---
# Specify the version of the Docker Compose file format
version: '3.9'
services:
  # Define the authors_service service
  authors_service:
    # This service relies on, and is therefor dependent on, the below `posts_service` service
    depends_on:
      - posts_service
    # Specify the path to the Dockerfile for this service
    build:
      context: ./authors_service
      dockerfile: Dockerfile
    # Define environment variables for this service
    environment:
      - SERVICE_HOST=0.0.0.0
      - PYTHONPATH=/app
      - SERVICE_PORT=5000
      - POSTS_SERVICE_URL=http://posts_service:6000/posts
    # Map port 5000 on the host machine to port 5000 on the container
    ports:
      - "5000:5000"
    # Mount the authors_service source code directory on the host to the working directory on the container
    volumes:
      - ./authors_service:/app
  # Define the posts_service service
  posts_service:
    # Specify the path to the Dockerfile for this service
    build:
      context: ./posts_service
      dockerfile: Dockerfile
    # Define environment variables for this service
    environment:
      - PYTHONPATH=/app
      - SERVICE_HOST=0.0.0.0
      - SERVICE_PORT=6000
    # Mount the posts_service source code directory on the host to the working directory on the container
    volumes:
      - ./posts_service:/app


Lancer l'application

Les conteneurs peuvent être démarrés avec le

 docker-compose up
commande. La première fois que cela est exécuté, les images docker seront automatiquement construites.

Cela satisfait la première exigence de base ci-dessus de "Exécuter".

Redéploiement

Notez que dans le

 docker-compose.yml
fichier, les montages de volume sont utilisés pour partager les répertoires de code source pour le
 authors_service
et
 posts_service
services entre la machine hôte et les conteneurs. Cela permet de modifier le code sur la machine hôte avec les modifications automatiquement reflétées dans les conteneurs (et vice versa).

Par exemple, la ligne suivante monte le

 ./authors_service
répertoire sur la machine hôte vers le
 /app
répertoire dans le
 authors_service
récipient:

 volumes: - . /authors_service:/ app

Les modifications apportées sur la machine hôte sont immédiatement disponibles sur le conteneur, et les modifications apportées dans le conteneur sont immédiatement conservées dans le répertoire de code source de la machine hôte. Cela permet de redéployer rapidement les modifications en redémarrant le conteneur concerné sans reconstruire l'image, satisfaisant ainsi la deuxième exigence principale de "Déployer".

Débogage

C'est là que ça s'implique un peu plus. Les débogueurs en Python utilisent les outils de débogage fournis par l'interpréteur pour interrompre l'exécution d'un programme et inspecter son état à certains moments. Cela inclut la définition d'une fonction de trace avec

 sys.settrace()
à chaque ligne de code et en vérifiant les points d'arrêt, ainsi qu'en utilisant des fonctionnalités telles que la pile d'appels et l'inspection des variables. Le débogage d'un interpréteur Python s'exécutant dans un conteneur peut potentiellement ajouter de la complexité par rapport au débogage d'un interpréteur Python s'exécutant sur une machine hôte. En effet, l'environnement de conteneur est isolé de la machine hôte.

Pour surmonter cela, l'une des deux pistes générales suivantes peut être suivie : le code peut être débogué à partir du conteneur lui-même, ou il peut être débogué à l'aide d'un serveur de débogage distant.

Tout d'abord, j'utiliserai VSCode comme éditeur de choix pour montrer comment procéder. Ensuite, j'expliquerai comment travailler de manière similaire avec JetBrains PyCharm .

Débogage du code depuis le conteneur lui-même

Pour développer et déboguer du code à partir d'un conteneur Docker en cours d'exécution à l'aide de VSCode, je vais :

1. Assurez-vous que l' extension Docker pour VSCode est installée et activée.

2. Assurez-vous que le conteneur auquel je souhaite me connecter est opérationnel.

3. Ouvrez la vue de l'explorateur de l'extension Docker en cliquant sur l'icône Docker dans la barre latérale gauche.

4. Dans la vue de l'explorateur, développez la section "Running Containers" et sélectionnez le conteneur auquel je souhaite me connecter.

5. Faites un clic droit sur le conteneur et sélectionnez l'option "Attach Visual Studio Code" dans le menu contextuel.

Cela attachera Visual Studio Code au conteneur sélectionné et ouvrira une nouvelle fenêtre VSCode dans le conteneur. Dans cette nouvelle fenêtre, je peux écrire, exécuter et déboguer du code comme je le ferais normalement sur un environnement local.

Afin d'éviter d'avoir à installer des extensions VSCode telles que Python à chaque redémarrage du conteneur, je peux monter un volume à l'intérieur du conteneur qui stocke les extensions VSCode. Ainsi, lorsque le conteneur sera redémarré, les extensions seront toujours disponibles car elles sont stockées sur la machine hôte. Pour ce faire, en utilisant docker compose dans ce projet de démonstration, le

 docker-compose.yml
fichier peut être modifié comme suit :

 ---
# Specify the version of the Docker Compose file format
version: '3.9'
services:
  # Define the authors_service service
  authors_service:
    ...
    # Mount the authors_service source code directory on the host to the working directory on the container
    volumes:
      - ./authors_service:/app
      # Mount the vscode extension directory on the host to the vscode extension directory on the container
      - /path/to/host/extensions:/root/.vscode/extensions
  # Define the posts_service service
  posts_service:
    ...

Notez que les extensions VSCode se trouvent généralement sur

 ~/.vscode/extensions
sur Linux et macOS, ou
 %USERPROFILE%\.vscode\extensions
sur Windows.

Utiliser un serveur de débogage Python distant

La méthode de débogage ci-dessus fonctionne bien pour les scripts autonomes ou pour l'écriture, l'exécution et le débogage de tests. Cependant, le débogage d'un flux logique impliquant plusieurs services s'exécutant dans différents conteneurs est plus complexe.

Lorsqu'un conteneur est démarré, le service qu'il contient est généralement lancé immédiatement. Dans ce cas, les serveurs Flask sur les deux services sont déjà en cours d'exécution au moment où VSCode est attaché, donc cliquer sur "Exécuter et déboguer" et lancer une autre instance du serveur Flask n'est pas pratique car cela entraînerait l'exécution de plusieurs instances du même service. sur le même conteneur et en concurrence les uns avec les autres, ce qui n'est généralement pas un flux de débogage fiable.

Cela m'amène à l'option numéro deux ; à l'aide d'un serveur de débogage Python distant. Un serveur de débogage Python distant est un interpréteur Python qui s'exécute sur un hôte distant et est configuré pour accepter les connexions d'un débogueur. Cela permet d'utiliser un débogueur qui s'exécute localement pour examiner et contrôler un processus Python qui s'exécute sur un environnement distant.

Il est important de noter que le terme "distant" ne fait pas nécessairement référence à une machine physiquement distante ou même à un environnement local mais isolé tel qu'un conteneur Docker exécuté sur une machine hôte. Un serveur de débogage distant Python peut également être utile pour déboguer un processus Python qui s'exécute dans le même environnement que le débogueur. Dans ce contexte, j'utiliserai un serveur de débogage distant qui s'exécute dans le même conteneur que le processus que je débogue. La principale différence entre cette méthode et la première option de débogage que nous avons couverte est que je vais m'attacher à un processus préexistant au lieu d'en créer un nouveau chaque fois que je veux exécuter et déboguer le code.

Pour commencer, la première étape consiste à ajouter le package debugpy au

 requirements.txt
fichiers pour les deux services. debugpy est un débogueur Python open source de haut niveau qui peut être utilisé pour déboguer des programmes Python localement ou à distance. Je vais ajouter la ligne suivante aux deux
 requirements.txt
des dossiers:

 debugpy == 1 . 6 . 4

Maintenant, je dois reconstruire les images afin d'installer debugpy sur les images Docker pour chaque service. je vais lancer le

 docker-compose build
commande pour le faire. Alors je vais courir
 docker-compose up
pour lancer les conteneurs.

Ensuite, je vais attacher VSCode au conteneur en cours d'exécution contenant le processus que je veux déboguer, comme je l'ai fait ci-dessus.

Afin d'attacher un débogueur à l'application Python en cours d'exécution, je dois ajouter l'extrait suivant au code au point à partir duquel je souhaite commencer le débogage :

 import debugpy; debugpy.listen( 5678 )

Cet extrait importe le module de débogage et appelle le

 listen
, qui démarre un serveur de débogage qui écoute les connexions d'un débogueur sur le numéro de port spécifié (dans ce cas, 5678).

Si je voulais déboguer le

 authors_service
, je pourrais placer l'extrait ci-dessus juste avant le
 get_author_by_id
déclaration de fonction dans le
 app.py
fichier - comme suit :

 import os import flask import requests from faker import Faker app = flask.Flask(__name__) import debugpy; debugpy.listen( 5678 ) @app.route( "/authors/<string:author_id>" , methods=[ "GET" ] )
def get_author_by_id ( author_id: str ):
...

Cela démarrerait un serveur de débogage au démarrage de l'application en tant que

 app.py
le script est exécuté.

L'étape suivante consiste à créer une configuration de lancement VSCode pour déboguer l'application. Dans le répertoire racine du service dont je suis attaché au conteneur (et sur lequel j'exécute la fenêtre VSCode), je vais créer un dossier nommé

 .vscode
. Ensuite, dans ce dossier, je vais créer un fichier nommé
 launch.json
, avec le contenu suivant :

 {    "version" : "0.2.0" ,    "configurations" : [ {            "name" : "Python: Remote Attach" ,            "type" : "python" ,            "request" : "attach" ,            "connect" : {                "host" : "localhost" ,                "port" : 5678
 } } ] }

Cette configuration spécifie que VSCode doit s'attacher à un débogueur Python s'exécutant sur la machine locale (c'est-à-dire le conteneur actuel) sur le port 5678 - qui, surtout, était le port spécifié lors de l'appel du

 debugpy.listen
fonction ci-dessus.

Je vais ensuite enregistrer toutes les modifications. Dans la vue de l'explorateur de l'extension Docker, je clique avec le bouton droit sur le conteneur auquel je suis actuellement attaché et je sélectionne "Redémarrer le conteneur" dans le menu contextuel (effectué sur l'instance locale de VSCode). Après avoir redémarré le conteneur, la fenêtre VSCode dans le conteneur affichera une boîte de dialogue me demandant si je veux recharger la fenêtre - la bonne réponse est oui.

Il ne reste plus qu'à le voir en action !Pour commencer le débogage, dans l'instance VSCode exécutée sur le conteneur, j'ouvre le script que je veux déboguer et j'appuie sur F5 pour démarrer le débogueur. Le débogueur s'attachera au script et mettra l'exécution en pause à la ligne où le

 debugpy.listen
fonction est appelée. Les commandes du débogueur dans l'onglet Débogage peuvent désormais être utilisées pour parcourir le code, définir des points d'arrêt et inspecter des variables.

Cela répond à l'exigence de "débogage" ci-dessus.

Développement et débogage à distance avec Jetbrains Pycharm IDE

Selon la documentation officielle , il existe deux façons de procéder lors de l'utilisation de PyCharm : un interpréteur peut être récupéré à partir d'une image Docker à l'aide de la fonctionnalité d'interpréteur à distance et/ou d'une configuration de serveur de débogage à distance. Notez que ces deux options ne sont pas mutuellement exclusives. Personnellement, je compte principalement sur la fonctionnalité d'interpréteur à distance pour le développement et j'utilise une configuration de serveur de débogage à distance si et quand cela est nécessaire.



Mise en place d'un interprète à distance

Pour configurer un interprète à distance sur PyCharm, je vais :

1. Cliquez sur le menu contextuel de l'onglet Interprètes dans le coin inférieur droit de la fenêtre de l'IDE.

2. Cliquez sur Add new interpreter , puis sélectionnez On docker compose... dans le menu contextuel.

3. Dans la fenêtre contextuelle suivante, sélectionnez le fichier de composition Docker approprié, puis sélectionnez le service approprié dans la liste déroulante. PyCharm va maintenant tenter de se connecter à l'image Docker et récupérer les interpréteurs Python disponibles.

4. Dans la fenêtre suivante, sélectionnez l'interpréteur python que je souhaite utiliser (par exemple

 /usr/local/bin/python
). Une fois l'interpréteur sélectionné, cliquez sur "Créer".

PyCharm indexera ensuite le nouvel interpréteur, après quoi je pourrai exécuter ou déboguer le code comme d'habitude - PyCharm orchestrera la composition de docker dans les coulisses pour moi chaque fois que je le souhaite.

Mise en place d'une configuration de serveur de débogage à distance

Afin de mettre en place une configuration de serveur de débogage à distance, je dois d'abord ajouter deux dépendances au

 requirements.txt
fichier(s) : pydevd et pydevd_pycharm . Leur fonction est similaire au package de débogage présenté ci-dessus, mais, comme son nom l'indique, pydevd_pycharm est spécialement conçu pour le débogage avec PyCharm. Dans le cadre de ce projet de démonstration, j'ajouterai les deux lignes suivantes aux deux
 requirements.txt
des dossiers:

 pydevd ~= 2 . 9 . 1
pydevd -pycharm== 223 . 8214 . 17

Une fois que cela est fait et que les images docker ont été reconstruites, je peux alors intégrer l'extrait de code suivant dans le code pour démarrer un serveur de débogage pydevd_pycharm au point du code à partir duquel je souhaite commencer le débogage :

 import pydevd_pycharm; pydevd_pycharm.settrace( 'host.docker.internal' , 5678 )

Notez que contrairement à debugpy, ici j'ai spécifié une adresse de nom d'hôte avec la valeur "host.docker.internal", qui est un nom DNS qui se résout en l'adresse IP interne de la machine hôte à partir d'un conteneur Docker. C'est parce que je n'exécute pas PyCharm sur le conteneur ; à la place, je configure effectivement le serveur de débogage pour qu'il écoute sur le port 5678 de la machine hôte .

Cette option existe également avec debugpy, mais comme dans ce cas j'exécutais une instance de VSCode sur le conteneur lui-même, cela simplifiait les choses en laissant simplement l'adresse du nom d'hôte par défaut sur "localhost" (c'est-à-dire l'interface de bouclage du conteneur lui-même, pas le ordinateur hôte).

La dernière étape consiste à configurer une configuration d'exécution que PyCharm peut utiliser pour se connecter au serveur de débogage distant.

Pour ce faire, je vais :

1. Ouvrez la boîte de dialogue Exécuter/Déboguer la configuration en sélectionnant Exécuter > Modifier les configurations dans le menu principal.

2. Cliquez sur le bouton + dans le coin supérieur gauche de la boîte de dialogue et sélectionnez Python Remote Debug dans le menu déroulant.

3. Dans le champ Nom , entrez un nom pour la configuration d'exécution.

4. Dans le champ Chemin du script , spécifiez le chemin d'accès au script que je veux déboguer.

5. Dans le champ Hôte , entrez l'adresse IP de la machine hôte sur laquelle le serveur de débogage sera exécuté. Dans cet exemple, il s'agit de "localhost".

6. Dans le champ Port , entrez le numéro de port sur lequel le serveur de débogage écoutera. Dans cet exemple, c'est 5678.

7. Dans la section Mappages de chemins, je peux spécifier comment les chemins sur la machine hôte correspondent aux chemins dans le conteneur. Ceci est utile si je débogue du code monté dans le conteneur à partir de l'hôte, car les chemins peuvent ne pas être les mêmes dans les deux environnements. Dans cet exemple, je veux mapper

 path/to/project/on/host/authors_service
sur la machine hôte, pour
 /app
dans le conteneur de débogage author_service, ou
 path/to/project/on/host/posts_service
pour
 /app
sur le conteneur pour le débogage de posts_service (il devrait s'agir de deux configurations d'exécution distinctes).

8. Cliquez sur OK pour enregistrer la configuration d'exécution.

Pour commencer le débogage, je vais sélectionner la configuration d'exécution ci-dessus dans le menu déroulant Exécuter et cliquer sur le bouton Déboguer , puis faire tourner le ou les conteneurs concernés avec le

 docker-compose up
commande. Le débogueur PyCharm s'attachera au script et mettra l'exécution en pause à la ligne où le
 pydevd_pycharm.settrace
fonction est appelée, ce qui me permet de commencer à éliminer ces bogues.


En résumé

Dans ce guide, j'ai donné un aperçu général mais pratique de ce que sont les environnements de développement python conteneurisés, pourquoi ils sont utiles et comment écrire, déployer et déboguer du code python en les utilisant. Veuillez noter qu'il ne s'agit en aucun cas d'un guide complet sur l'utilisation de ces environnements. Ce n'est qu'un point de départ à partir duquel s'étendre. Voici quelques liens utiles à cette fin :

1. Aperçu de la conteneurisation par redhat

3.Documents Docker officiels

4. Documents officiels JetBrains PyCharm pour le débogage à distance

5.Documents VSCode officiels pour le développement de Python sur des conteneurs de développement

J'espère que vous avez trouvé ce guide utile - merci d'avoir lu !