

Avis de fin de support : le 31 mai 2026, AWS le support de AWS Panorama. Après le 31 mai 2026, vous ne pourrez plus accéder à la AWS Panorama console ni aux AWS Panorama ressources. Pour plus d'informations, voir [AWS Panorama fin du support](https://docs.aws.amazon.com/panorama/latest/dev/panorama-end-of-support.html). 

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# AWS Panorama Applications de construction
<a name="panorama-development"></a>

Des applications s'exécutent sur l' AWS Panorama appliance pour effectuer des tâches de vision par ordinateur sur des flux vidéo. Vous pouvez créer des applications de vision par ordinateur en combinant du code Python et des modèles d'apprentissage automatique, puis les déployer sur l' AWS Panorama appliance via Internet. Les applications peuvent envoyer des vidéos sur un écran ou utiliser le SDK AWS pour envoyer les résultats aux services AWS.

Un [modèle](applications-models.md) analyse les images pour détecter les personnes, les véhicules et d'autres objets. Sur la base d'images qu'il a vues pendant l'entraînement, le modèle vous indique ce qu'il pense d'une chose et dans quelle mesure il est sûr de deviner. Vous pouvez entraîner des modèles avec vos propres données d'image ou commencer avec un échantillon.

Le [code](gettingstarted-sample.md) de l'application traite les images fixes d'un flux de caméra, les envoie à un modèle et traite le résultat. Un modèle peut détecter plusieurs objets et renvoyer leurs formes et leur emplacement. Le code peut utiliser ces informations pour ajouter du texte ou des graphiques à la vidéo, ou pour envoyer les résultats à un AWS service pour stockage ou traitement ultérieur.

Pour obtenir des images à partir d'un flux, interagir avec un modèle et produire une vidéo, le code de l'application utilise [le SDK AWS Panorama d'application](applications-panoramasdk.md). Le SDK de l'application est une bibliothèque Python qui prend en charge les modèles générés avec PyTorch MXNet, Apache et TensorFlow.

**Topics**
+ [Modèles de vision par ordinateur](applications-models.md)
+ [Création d'une image d'application](applications-image.md)
+ [Appeler les services AWS depuis le code de votre application](applications-awssdk.md)
+ [Le SDK de l'application AWS Panorama](applications-panoramasdk.md)
+ [Exécution de plusieurs threads](applications-threading.md)
+ [Au service du trafic entrant](applications-ports.md)
+ [Utilisation du GPU](applications-gpuaccess.md)
+ [Configuration d'un environnement de développement sous Windows](applications-devenvwindows.md)

# Modèles de vision par ordinateur
<a name="applications-models"></a>

Un *modèle de vision par ordinateur* est un logiciel formé pour détecter des objets dans des images. Un modèle apprend à reconnaître un ensemble d'objets en analysant d'abord des images de ces objets par entraînement. Un modèle de vision par ordinateur prend une image en entrée et produit des informations sur les objets qu'il détecte, tels que le type d'objet et son emplacement. AWS Panorama prend en charge les modèles de vision par ordinateur PyTorch créés avec MXNet, Apache et TensorFlow.

**Note**  
Pour obtenir la liste des modèles prédéfinis qui ont été testés avec AWS Panorama, consultez la section [Compatibilité des modèles](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/model-compatibility.md).

**Topics**
+ [Utilisation de modèles dans le code](#applications-models-using)
+ [Création d'un modèle personnalisé](#applications-models-custom)
+ [Emballage d'un modèle](#applications-models-package)
+ [Entraînement de modèles](#applications-models-training)

## Utilisation de modèles dans le code
<a name="applications-models-using"></a>

Un modèle renvoie un ou plusieurs résultats, qui peuvent inclure des probabilités pour les classes détectées, des informations de localisation et d'autres données.L'exemple suivant montre comment exécuter une inférence sur une image à partir d'un flux vidéo et envoyer le résultat du modèle à une fonction de traitement.

**Example [application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/application.py) — Inférence**  

```
    def process_media(self, stream):
        """Runs inference on a frame of video."""
        image_data = preprocess(stream.image,self.MODEL_DIM)
        logger.debug('Image data: {}'.format(image_data))
        # Run inference
        inference_start = time.time()
        inference_results = self.call({"data":image_data}, self.MODEL_NODE)
         # Log metrics
        inference_time = (time.time() - inference_start) * 1000
        if inference_time > self.inference_time_max:
            self.inference_time_max = inference_time
        self.inference_time_ms += inference_time
        # Process results (classification)
        self.process_results(inference_results, stream)
```

L'exemple suivant montre une fonction qui traite les résultats d'un modèle de classification de base. Le modèle d'échantillon renvoie un tableau de probabilités, qui est la première et unique valeur du tableau de résultats.

**Example [application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/application.py) — Traitement des résultats**  

```
    def process_results(self, inference_results, stream):
        """Processes output tensors from a computer vision model and annotates a video frame."""
        if inference_results is None:
            logger.warning("Inference results are None.")
            return
        max_results = 5
        logger.debug('Inference results: {}'.format(inference_results))
        class_tuple = inference_results[0]
        enum_vals = [(i, val) for i, val in enumerate(class_tuple[0])]
        sorted_vals = sorted(enum_vals, key=lambda tup: tup[1])
        top_k = sorted_vals[::-1][:max_results]
        indexes =  [tup[0] for tup in top_k]

        for j in range(max_results):
            label = 'Class [%s], with probability %.3f.'% (self.classes[indexes[j]], class_tuple[0][indexes[j]])
            stream.add_label(label, 0.1, 0.1 + 0.1*j)
```

Le code de l'application trouve les valeurs présentant les probabilités les plus élevées et les associe aux étiquettes d'un fichier de ressources chargé lors de l'initialisation.

## Création d'un modèle personnalisé
<a name="applications-models-custom"></a>

Vous pouvez utiliser les modèles que vous créez dans PyTorch Apache MXNet et TensorFlow dans les applications AWS Panorama. Comme alternative à la création et à la formation de modèles dans l' SageMaker IA, vous pouvez utiliser un modèle entraîné ou créer et entraîner votre propre modèle avec un framework pris en charge et l'exporter dans un environnement local ou sur Amazon EC2.

**Note**  
Pour en savoir plus sur les versions de framework et les formats de fichiers pris en charge par SageMaker AI Neo, consultez la section [Frameworks pris en charge](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-supported-devices-edge-frameworks.html) dans le manuel Amazon SageMaker AI Developer Guide.

Le référentiel de ce guide fournit un exemple d'application qui illustre ce flux de travail pour un modèle Keras au TensorFlow `SavedModel` format. Il utilise TensorFlow 2 et peut être exécuté localement dans un environnement virtuel ou dans un conteneur Docker. L'exemple d'application inclut également des modèles et des scripts pour créer le modèle sur une EC2 instance Amazon.

****
+ [Exemple d'application de modèle personnalisé](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/custom-model)

![\[\]](http://docs.aws.amazon.com/fr_fr/panorama/latest/dev/images/sample-custom-model.png)


AWS Panorama utilise SageMaker AI Neo pour compiler des modèles destinés à être utilisés sur l'appliance AWS Panorama. Pour chaque framework, utilisez le [format pris en charge par SageMaker AI Neo](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-compilation-preparing-model.html) et empaquetez le modèle dans une `.tar.gz` archive.

Pour plus d'informations, consultez [Compiler et déployer des modèles avec Neo](https://docs.aws.amazon.com/sagemaker/latest/dg/neo.html) dans le manuel Amazon SageMaker AI Developer Guide.

## Emballage d'un modèle
<a name="applications-models-package"></a>

Un package modèle comprend un descripteur, une configuration de package et une archive de modèle. Comme dans le cas d'un [package d'image d'application](applications-image.md), la configuration du package indique au service AWS Panorama où le modèle et le descripteur sont stockés dans Amazon S3. 

**Example [Paquets/123456789012-squeezenet\$1pytorch-1.0/descriptor.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SQUEEZENET_PYTORCH-1.0/descriptor.json)**  

```
{
    "mlModelDescriptor": {
        "envelopeVersion": "2021-01-01",
        "framework": "PYTORCH",
        "frameworkVersion": "1.8",
        "precisionMode": "FP16",
        "inputs": [
            {
                "name": "data",
                "shape": [
                    1,
                    3,
                    224,
                    224
                ]
            }
        ]
    }
}
```

**Note**  
Spécifiez uniquement les versions majeure et mineure de la version du framework. Pour obtenir la liste des versions prises en charge PyTorch, d'Apache MXNet et des TensorFlow versions, voir [Frameworks pris en charge](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-supported-devices-edge-frameworks.html).

Pour importer un modèle, utilisez la `import-raw-model` commande CLI de l'application AWS Panorama. Si vous apportez des modifications au modèle ou à son descripteur, vous devez réexécuter cette commande pour mettre à jour les actifs de l'application. Pour de plus amples informations, veuillez consulter [Modification du modèle de vision par ordinateur](gettingstarted-sample.md#gettingstarted-sample-model).

Pour le schéma JSON du fichier descripteur, consultez [AssetDescriptor.schema.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/manifest-schema/ver_2021-01-01/assetDescriptor.schema.json).

## Entraînement de modèles
<a name="applications-models-training"></a>

Lorsque vous entraînez un modèle, utilisez des images provenant de l'environnement cible ou d'un environnement de test qui ressemble beaucoup à l'environnement cible. Tenez compte des facteurs suivants qui peuvent affecter les performances du modèle :

****
+ **Éclairage** : la quantité de lumière réfléchie par un sujet détermine le niveau de détail que le modèle doit analyser. Un modèle entraîné avec des images de sujets bien éclairés peut ne pas fonctionner correctement dans un environnement peu éclairé ou rétroéclairé.
+ **Résolution** — La taille d'entrée d'un modèle est généralement fixée à une résolution comprise entre 224 et 512 pixels de large dans un format carré. Avant de transférer une image vidéo au modèle, vous pouvez la réduire ou la recadrer pour l'adapter à la taille requise.
+ **Distorsion de l'image** : la distance focale et la forme de l'objectif d'un appareil photo peuvent entraîner une distorsion des images par rapport au centre du cadre. La position d'une caméra détermine également les caractéristiques visibles d'un sujet. Par exemple, un rétroviseur équipé d'un objectif grand angle affiche le dessus d'un sujet lorsqu'il se trouve au centre du cadre, et une vue biaisée du côté du sujet lorsqu'il s'éloigne du centre.

Pour résoudre ces problèmes, vous pouvez prétraiter les images avant de les envoyer au modèle et entraîner le modèle sur une plus grande variété d'images qui reflètent les variations dans les environnements réels. Si un modèle doit fonctionner dans des situations d'éclairage et avec une variété de caméras, vous avez besoin de plus de données pour la formation. En plus de collecter davantage d'images, vous pouvez obtenir davantage de données d'entraînement en créant des variations de vos images existantes qui sont biaisées ou ont un éclairage différent.

# Création d'une image d'application
<a name="applications-image"></a>

L'appliance AWS Panorama exécute des applications sous forme de systèmes de fichiers conteneurs exportés à partir d'une image que vous créez. Vous spécifiez les dépendances et les ressources de votre application dans un Dockerfile qui utilise l'image de base de l'application AWS Panorama comme point de départ.

Pour créer une image d'application, vous utilisez Docker et la CLI d'application AWS Panorama. L'exemple suivant, tiré de l'exemple d'application de ce guide, illustre ces cas d'utilisation.

**Example [/Paquets/123456789012-sample\$1code-1.0/dockerfile](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/Dockerfile)**  

```
FROM public.ecr.aws/panorama/panorama-application
WORKDIR /panorama
COPY . .
RUN pip install --no-cache-dir --upgrade pip && \
    pip install --no-cache-dir -r requirements.txt
```

Les instructions Dockerfile suivantes sont utilisées.

****
+ `FROM`— Charge l'image de base de l'application (`public.ecr.aws/panorama/panorama-application`). 
+ `WORKDIR`— Définissez le répertoire de travail sur l'image. `/panorama`est utilisé pour le code de l'application et les fichiers associés. Ce paramètre ne persiste que pendant la construction et n'affecte pas le répertoire de travail de votre application au moment de l'exécution (`/`).
+ `COPY`— Copie les fichiers d'un chemin local vers un chemin de l'image. `COPY . .`copie les fichiers du répertoire actuel (le répertoire du package) dans le répertoire de travail de l'image. Par exemple, le code de l'application est copié de `packages/123456789012-SAMPLE_CODE-1.0/application.py` vers`/panorama/application.py`.
+ `RUN`— Exécute des commandes shell sur l'image pendant la compilation. Une seule `RUN` opération peut exécuter plusieurs commandes en séquence en utilisant `&&` entre les commandes. Cet exemple met à jour le gestionnaire de `pip` packages, puis installe les bibliothèques répertoriées dans`requirements.txt`.

Vous pouvez utiliser d'autres instructions, telles que `ADD` et`ARG`, qui sont utiles au moment de la construction. Les instructions qui ajoutent des informations d'exécution au conteneur, telles que`ENV`, ne fonctionnent pas avec AWS Panorama. AWS Panorama n'exécute pas de conteneur à partir de l'image. Il utilise uniquement l'image pour exporter un système de fichiers, qui est transféré vers l'appliance.

## Spécification des dépendances
<a name="applications-image-dependencies"></a>

`requirements.txt`est un fichier d'exigences Python qui spécifie les bibliothèques utilisées par l'application. L'exemple d'application utilise Open CV et le AWS SDK pour Python (Boto3).

**Example [Paquets/123456789012-sample\$1code-1.0/requirements.txt](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/requirements.txt)**  

```
boto3==1.24.*
opencv-python==4.6.*
```

La `pip install` commande du Dockerfile installe ces bibliothèques dans le `dist-packages` répertoire Python ci-dessous`/usr/local/lib`, afin qu'elles puissent être importées par le code de votre application.

## Stockage local
<a name="applications-image-storage"></a>

AWS Panorama réserve le `/opt/aws/panorama/storage` répertoire au stockage des applications. Votre application peut créer et modifier des fichiers à ce chemin. Les fichiers créés dans le répertoire de stockage sont conservés après les redémarrages. Les autres emplacements de fichiers temporaires sont effacés au démarrage.

## Création de ressources d'image
<a name="applications-image-build"></a>

Lorsque vous créez une image pour votre package d'application à l'aide de l'interface de ligne de commande d'application AWS Panorama, celle-ci s'exécute `docker build` dans le répertoire du package. Cela crée une image d'application qui contient le code de votre application. La CLI crée ensuite un conteneur, exporte son système de fichiers, le compresse et le stocke dans le `assets` dossier.

```
$ panorama-cli build-container --container-asset-name code_asset --package-path packages/123456789012-SAMPLE_CODE-1.0
docker build -t code_asset packages/123456789012-SAMPLE_CODE-1.0 --pull
docker export --output=code_asset.tar $(docker create code_asset:latest)
gzip -1 code_asset.tar
{
    "name": "code_asset",
    "implementations": [
        {
            "type": "container",
            "assetUri": "6f67xmpl32743ed0e60c151a02f2f0da1bf70a4ab9d83fe236fa32a6f9b9f808.tar.gz",
            "descriptorUri": "1872xmpl129481ed053c52e66d6af8b030f9eb69b1168a29012f01c7034d7a8f.json"
        }
    ]
}
Container asset for the package has been succesfully built at  /home/user/aws-panorama-developer-guide/sample-apps/aws-panorama-sample/assets/6f67xmpl32743ed0e60c151a02f2f0da1bf70a4ab9d83fe236fa32a6f9b9f808.tar.gz
```

Le bloc JSON dans la sortie est une définition d'actif que la CLI ajoute à la configuration du package (`package.json`) et enregistre auprès du service AWS Panorama. La CLI copie également le fichier descripteur, qui indique le chemin d'accès au script d'application (le point d'entrée de l'application).

**Example [Paquets/123456789012-sample\$1code-1.0/descriptor.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/descriptor.json)**  

```
{
    "runtimeDescriptor":
    {
        "envelopeVersion": "2021-01-01",
        "entry":
        {
            "path": "python3",
            "name": "/panorama/application.py"
        }
    }
}
```

Dans le dossier des actifs, le descripteur et l'image de l'application sont nommés d'après leur somme de contrôle SHA-256. Ce nom est utilisé comme identifiant unique pour l'actif lorsqu'il est stocké dans Amazon S3. 

# Appeler les services AWS depuis le code de votre application
<a name="applications-awssdk"></a>

Vous pouvez utiliser le AWS SDK pour Python (Boto) pour appeler les services AWS à partir du code de votre application. Par exemple, si votre modèle détecte quelque chose qui sort de l'ordinaire, vous pouvez publier des métriques sur Amazon CloudWatch, envoyer une notification via Amazon SNS, enregistrer une image sur Amazon S3 ou invoquer une fonction Lambda pour un traitement ultérieur. La plupart des services AWS disposent d'une API publique que vous pouvez utiliser avec le kit SDK AWS.

L'appliance n'est pas autorisée à accéder aux services AWS par défaut. Pour lui accorder une autorisation, [créez un rôle pour l'application](permissions-application.md) et attribuez-le à l'instance d'application lors du déploiement.

**Topics**
+ [Utilisation d'Amazon S3](#applications-awssdk-s3)
+ [Utilisation de la rubrique AWS IoT MQTT](#monitoring-messagestream)

## Utilisation d'Amazon S3
<a name="applications-awssdk-s3"></a>

Vous pouvez utiliser Amazon S3 pour stocker les résultats du traitement et d'autres données d'application.

```
import boto3
s3_client=boto3.client("s3")
s3_clients3.upload_file(data_file,
                    s3_bucket_name,
                    os.path.basename(data_file))
```

## Utilisation de la rubrique AWS IoT MQTT
<a name="monitoring-messagestream"></a>

[Vous pouvez utiliser le SDK pour Python (Boto3) pour envoyer des messages à un sujet MQTT dans.](https://docs.aws.amazon.com/iot/latest/developerguide/topics.html) AWS IoT Dans l'exemple suivant, l'application publie dans une rubrique nommée d'après le *nom de l'objet* de l'appliance, que vous pouvez trouver dans [AWS IoT la console](https://console.aws.amazon.com/iot/home#/thinghub).

```
import boto3
iot_client=boto3.client('iot-data')
topic = "panorama/panorama_my-appliance_Thing_a01e373b"
iot_client.publish(topic=topic, payload="my message")
```

Choisissez un nom qui indique l'identifiant de l'appareil ou un autre identifiant de votre choix. Pour publier des messages, l'application doit être autorisée à appeler`iot:Publish`.

**Pour surveiller une file d'attente MQTT**

1. Ouvrez la [page de test de la AWS IoT console](https://console.aws.amazon.com/iot/home?region=us-east-1#/test).

1. Pour le **sujet d'abonnement**, entrez le nom du sujet. Par exemple, `panorama/panorama_my-appliance_Thing_a01e373b`.

1. Choisissez **Subscribe to topic (S'abonner à la rubrique)**.

# Le SDK de l'application AWS Panorama
<a name="applications-panoramasdk"></a>

Le SDK d'applications AWS Panorama est une bibliothèque Python permettant de développer des applications AWS Panorama. Dans le [code de votre application](gettingstarted-sample.md), vous utilisez le SDK d'application AWS Panorama pour charger un modèle de vision par ordinateur, exécuter des inférences et générer une vidéo sur un moniteur.

**Note**  
Pour vous assurer d'avoir accès aux dernières fonctionnalités du SDK de l'application AWS Panorama, [mettez à niveau le logiciel de l'appliance](appliance-manage.md#appliance-manage-software).

Pour plus de détails sur les classes définies par le SDK de l'application et leurs méthodes, consultez la section Référence du [SDK d'application](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/applicationsdk-reference.md).

**Topics**
+ [Ajout de texte et de zones pour la sortie vidéo](#applications-panoramasdk-overlays)

## Ajout de texte et de zones pour la sortie vidéo
<a name="applications-panoramasdk-overlays"></a>

Avec le SDK AWS Panorama, vous pouvez générer un flux vidéo sur un écran. La vidéo peut inclure du texte et des zones indiquant les résultats du modèle, l'état actuel de l'application ou d'autres données.

Chaque objet de la `video_in` matrice est une image provenant d'un flux de caméra connecté à l'appliance. Le type de cet objet est`panoramasdk.media`. Il propose des méthodes pour ajouter du texte et des zones rectangulaires à l'image, que vous pouvez ensuite attribuer au `video_out` tableau.

Dans l'exemple suivant, l'exemple d'application ajoute une étiquette pour chacun des résultats. Chaque résultat est positionné à la même position gauche, mais à des hauteurs différentes.

```
        for j in range(max_results):
            label = 'Class [%s], with probability %.3f.'% (self.classes[indexes[j]], class_tuple[0][indexes[j]])
            stream.add_label(label, 0.1, 0.1 + 0.1*j)
```

Pour ajouter une boîte à l'image de sortie, utilisez`add_rect`. Cette méthode prend 4 valeurs comprises entre 0 et 1, indiquant la position des coins supérieur gauche et inférieur droit de la boîte.

```
        w,h,c = stream.image.shape
        stream.add_rect(x1/w, y1/h, x2/w, y2/h)
```

# Exécution de plusieurs threads
<a name="applications-threading"></a>

Vous pouvez exécuter la logique de votre application sur un thread de traitement et utiliser d'autres threads pour d'autres processus en arrière-plan. Par exemple, vous pouvez créer un thread qui [diffuse le trafic HTTP](applications-ports.md) à des fins de débogage, ou un thread qui surveille les résultats d'inférence et envoie des données à. AWS

Pour exécuter plusieurs threads, vous utilisez le [module de threading](https://docs.python.org/3/library/threading.html) de la bibliothèque standard Python afin de créer un thread pour chaque processus. L'exemple suivant montre la boucle principale de l'exemple d'application du serveur de débogage, qui crée un objet d'application et l'utilise pour exécuter trois threads.

**Example [Packages/123456789012-debug\$1server-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) — Boucle principale**  

```
def main():
    panorama = panoramasdk.node()
    while True:
        try:
            # Instantiate application
            logger.info('INITIALIZING APPLICATION')
            app = Application(panorama)
            # Create threads for stream processing, debugger, and client
            app.run_thread = threading.Thread(target=app.run_cv)
            app.server_thread = threading.Thread(target=app.run_debugger)
            app.client_thread = threading.Thread(target=app.run_client)
            # Start threads
            logger.info('RUNNING APPLICATION')
            app.run_thread.start()
            logger.info('RUNNING SERVER')
            app.server_thread.start()
            logger.info('RUNNING CLIENT')
            app.client_thread.start()
            # Wait for threads to exit
            app.run_thread.join()
            app.server_thread.join()
            app.client_thread.join()
            logger.info('RESTARTING APPLICATION')
        except:
            logger.exception('Exception during processing loop.')
```

Lorsque tous les threads sont fermés, l'application redémarre d'elle-même. La `run_cv` boucle traite les images issues des flux de caméras. S'il reçoit un signal d'arrêt, il arrête le processus de débogage, qui exécute un serveur HTTP et ne peut pas s'arrêter tout seul. Chaque thread doit gérer ses propres erreurs. Si aucune erreur n'est détectée et enregistrée, le thread se ferme silencieusement.

**Example [Packages/123456789012-debug\$1server-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) — Boucle de traitement**  

```
    # Processing loop
    def run_cv(self):
        """Run computer vision workflow in a loop."""
        logger.info("PROCESSING STREAMS")
        while not self.terminate:
            try:
                self.process_streams()
                # turn off debug logging after 15 loops
                if logger.getEffectiveLevel() == logging.DEBUG and self.frame_num == 15:
                    logger.setLevel(logging.INFO)
            except:
                logger.exception('Exception on processing thread.')
        # Stop signal received
        logger.info("SHUTTING DOWN SERVER")
        self.server.shutdown()
        self.server.server_close()
        logger.info("EXITING RUN THREAD")
```

Les threads communiquent via l'`self`objet de l'application. Pour redémarrer la boucle de traitement de l'application, le thread du débogueur appelle la `stop` méthode. Cette méthode définit un `terminate` attribut qui indique aux autres threads de s'arrêter.

**Example [Packages/123456789012-debug\$1server-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) — Méthode d'arrêt**  

```
    # Interrupt processing loop
    def stop(self):
        """Signal application to stop processing."""
        logger.info("STOPPING APPLICATION")
        # Signal processes to stop
        self.terminate = True
    # HTTP debug server
    def run_debugger(self):
        """Process debug commands from local network."""
        class ServerHandler(SimpleHTTPRequestHandler):
            # Store reference to application
            application = self
            # Get status
            def do_GET(self):
                """Process GET requests."""
                logger.info('Get request to {}'.format(self.path))
                if self.path == "/status":
                    self.send_200('OK')
                else:
                    self.send_error(400)
            # Restart application
            def do_POST(self):
                """Process POST requests."""
                logger.info('Post request to {}'.format(self.path))
                if self.path == '/restart':
                    self.send_200('OK')
                    ServerHandler.application.stop()
                else:
                    self.send_error(400)
```



# Au service du trafic entrant
<a name="applications-ports"></a>

Vous pouvez surveiller ou déboguer des applications localement en exécutant un serveur HTTP à côté du code de votre application. Pour desservir le trafic externe, vous mappez les ports de l'appliance AWS Panorama aux ports de votre conteneur d'applications.

**Important**  
Par défaut, l'appliance AWS Panorama n'accepte le trafic entrant sur aucun port. L'ouverture de ports sur l'appliance présente un risque de sécurité implicite. Lorsque vous utilisez cette fonctionnalité, vous devez prendre des mesures supplémentaires pour [protéger votre appliance contre le trafic externe](appliance-network.md) et sécuriser les communications entre les clients autorisés et l'appliance.  
L'exemple de code inclus dans ce guide est destiné à des fins de démonstration et n'implémente pas l'authentification, l'autorisation ou le chiffrement.

Vous pouvez ouvrir des ports compris entre 8000 et 9000 sur l'appliance. Ces ports, lorsqu'ils sont ouverts, peuvent recevoir du trafic en provenance de n'importe quel client routable. Lorsque vous déployez votre application, vous spécifiez les ports à ouvrir et vous mappez les ports de l'appliance aux ports de votre conteneur d'applications. Le logiciel de l'appliance achemine le trafic vers le conteneur et renvoie les réponses au demandeur. Les demandes sont reçues sur le port de l'appliance que vous spécifiez et les réponses sont envoyées sur un port éphémère aléatoire.

## Configuration des ports entrants
<a name="applications-ports-configuration"></a>

Vous spécifiez les mappages de ports à trois endroits dans la configuration de votre application. Dans le package de code`package.json`, vous spécifiez le port que le nœud de code écoute dans un `network` bloc. L'exemple suivant déclare que le nœud écoute sur le port 80.

**Example [Paquets/123456789012-debug\$1server-1.0/package.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/package.json)**  

```
                "outputs": [
                    {
                        "description": "Video stream output",
                        "name": "video_out",
                        "type": "media"
                    }
                ],
                "network": {
                    "inboundPorts": [
                        {
                            "port": 80,
                            "description": "http"
                        }
                    ]
                }
```

Dans le manifeste de l'application, vous déclarez une règle de routage qui mappe un port de l'appliance à un port du conteneur de code de l'application. L'exemple suivant ajoute une règle qui mappe le port 8080 du périphérique au port 80 du `code_node` conteneur.

**Example [graphs/my-app/graph.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/graphs/my-app/graph.json)**  

```
            {
                "producer": "model_input_width",
                "consumer": "code_node.model_input_width"
            },
            {
                "producer": "model_input_order",
                "consumer": "code_node.model_input_order"
            }
        ],
        "networkRoutingRules": [
            {
                "node": "code_node",
                "containerPort": 80,
                "hostPort": 8080,
                "decorator": {
                    "title": "Listener port 8080",
                    "description": "Container monitoring and debug."
                }
            }
        ]
```

Lorsque vous déployez l'application, vous spécifiez les mêmes règles dans la console AWS Panorama ou dans un document de dérogation transmis à l'[CreateApplicationInstance](https://docs.aws.amazon.com/panorama/latest/api/API_CreateApplicationInstance.html)API. Vous devez fournir cette configuration au moment du déploiement pour confirmer que vous souhaitez ouvrir des ports sur l'appliance.

**Example [graphs/my-app/override.json](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/graphs/my-app/override.json)**  

```
            {
                "replace": "camera_node",
                "with": [
                    {
                        "name": "exterior-north"
                    }
                ]
            }
        ],
        "networkRoutingRules":[
            {
                "node": "code_node",
                "containerPort": 80,
                "hostPort": 8080
            }
        ],
        "envelopeVersion": "2021-01-01"
    }
}
```

Si le port du périphérique spécifié dans le manifeste de l'application est utilisé par une autre application, vous pouvez utiliser le document de remplacement pour choisir un autre port.

## Au service du trafic
<a name="applications-ports-serverthread"></a>

Lorsque les ports du conteneur sont ouverts, vous pouvez ouvrir un socket ou exécuter un serveur pour gérer les demandes entrantes. L'`debug-server`exemple montre une implémentation de base d'un serveur HTTP exécuté parallèlement au code d'une application de vision par ordinateur.

**Important**  
L'exemple d'implémentation n'est pas sécurisé pour une utilisation en production. Pour éviter de rendre votre appliance vulnérable aux attaques, vous devez implémenter des contrôles de sécurité appropriés dans votre code et dans la configuration réseau.

**Example [Packages/123456789012-debug\$1server-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) — Serveur HTTP**  

```
    # HTTP debug server
    def run_debugger(self):
        """Process debug commands from local network."""
        class ServerHandler(SimpleHTTPRequestHandler):
            # Store reference to application
            application = self
            # Get status
            def do_GET(self):
                """Process GET requests."""
                logger.info('Get request to {}'.format(self.path))
                if self.path == '/status':
                    self.send_200('OK')
                else:
                    self.send_error(400)
            # Restart application
            def do_POST(self):
                """Process POST requests."""
                logger.info('Post request to {}'.format(self.path))
                if self.path == '/restart':
                    self.send_200('OK')
                    ServerHandler.application.stop()
                else:
                    self.send_error(400)
            # Send response
            def send_200(self, msg):
                """Send 200 (success) response with message."""
                self.send_response(200)
                self.send_header('Content-Type', 'text/plain')
                self.end_headers()
                self.wfile.write(msg.encode('utf-8'))
        try:
            # Run HTTP server
            self.server = HTTPServer(("", self.CONTAINER_PORT), ServerHandler)
            self.server.serve_forever(1)
            # Server shut down by run_cv loop
            logger.info("EXITING SERVER THREAD")
        except:
            logger.exception('Exception on server thread.')
```

Le serveur accepte les requêtes GET sur le `/status` chemin pour récupérer des informations sur l'application. Il accepte également une requête POST `/restart` pour redémarrer l'application.

Pour démontrer cette fonctionnalité, l'exemple d'application exécute un client HTTP sur un thread distinct. Le client appelle le `/status` chemin via le réseau local peu après le démarrage et redémarre l'application quelques minutes plus tard.

**Example [Paquets/123456789012-debug\$1server-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) — Client HTTP**  

```
    # HTTP test client
    def run_client(self):
        """Send HTTP requests to device port to demnostrate debug server functions."""
        def client_get():
            """Get container status"""
            r = requests.get('http://{}:{}/status'.format(self.device_ip, self.DEVICE_PORT))
            logger.info('Response: {}'.format(r.text))
            return
        def client_post():
            """Restart application"""
            r = requests.post('http://{}:{}/restart'.format(self.device_ip, self.DEVICE_PORT))
            logger.info('Response: {}'.format(r.text))
            return
        # Call debug server
        while not self.terminate:
            try:
                time.sleep(30)
                client_get()
                time.sleep(300)
                client_post()
            except:
                logger.exception('Exception on client thread.')
        # stop signal received
        logger.info("EXITING CLIENT THREAD")
```

La boucle principale gère les threads et redémarre l'application à leur sortie.

**Example [Packages/123456789012-debug\$1server-1.0/application.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/packages/123456789012-DEBUG_SERVER-1.0/application.py) — Boucle principale**  

```
def main():
    panorama = panoramasdk.node()
    while True:
        try:
            # Instantiate application
            logger.info('INITIALIZING APPLICATION')
            app = Application(panorama)
            # Create threads for stream processing, debugger, and client
            app.run_thread = threading.Thread(target=app.run_cv)
            app.server_thread = threading.Thread(target=app.run_debugger)
            app.client_thread = threading.Thread(target=app.run_client)
            # Start threads
            logger.info('RUNNING APPLICATION')
            app.run_thread.start()
            logger.info('RUNNING SERVER')
            app.server_thread.start()
            logger.info('RUNNING CLIENT')
            app.client_thread.start()
            # Wait for threads to exit
            app.run_thread.join()
            app.server_thread.join()
            app.client_thread.join()
            logger.info('RESTARTING APPLICATION')
        except:
            logger.exception('Exception during processing loop.')
```

Pour déployer l'exemple d'application, consultez les [instructions figurant dans le GitHub référentiel de ce guide.](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/README.md)

# Utilisation du GPU
<a name="applications-gpuaccess"></a>

Vous pouvez accéder au processeur graphique (GPU) de l'appliance AWS Panorama pour utiliser des bibliothèques accélérées par GPU ou exécuter des modèles d'apprentissage automatique dans le code de votre application. Pour activer l'accès au GPU, vous devez ajouter l'accès au GPU comme exigence à la configuration du package après avoir créé le conteneur de code de votre application.

**Important**  
Si vous activez l'accès au GPU, vous ne pouvez exécuter de nœuds de modèle dans aucune application de l'appliance. Pour des raisons de sécurité, l'accès au GPU est restreint lorsque l'appliance exécute un modèle compilé avec SageMaker AI Neo. Avec l'accès au GPU, vous devez exécuter vos modèles dans des nœuds de code d'application, et toutes les applications de l'appareil partagent l'accès au GPU.

Pour activer l'accès au GPU pour votre application, mettez à jour la [configuration du package](applications-packages.md) après l'avoir créé avec l'interface de ligne de commande de l'application AWS Panorama. L'exemple suivant montre le `requirements` bloc qui ajoute l'accès au GPU au nœud de code de l'application.

**Example package.json avec bloc d'exigences**  

```
{
    "nodePackage": {
        "envelopeVersion": "2021-01-01",
        "name": "SAMPLE_CODE",
        "version": "1.0",
        "description": "Computer vision application code.",
        "assets": [
            {
                "name": "code_asset",
                "implementations": [
                    {
                        "type": "container",
                        "assetUri": "eba3xmpl71aa387e8f89be9a8c396416cdb80a717bb32103c957a8bf41440b12.tar.gz",
                        "descriptorUri": "4abdxmpl5a6f047d2b3047adde44704759d13f0126c00ed9b4309726f6bb43400ba9.json",
                        "requirements": [
                            {
                                "type": "hardware_access",
                                "inferenceAccelerators": [
                                    {
                                        "deviceType": "nvhost_gpu",
                                        "sharedResourcePolicy": {
                                            "policy" : "allow_all"
                                        }
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ],
        "interfaces": [
        ...
```

Mettez à jour la configuration du package entre les étapes de construction et d'empaquetage de votre flux de travail de développement.

**Pour déployer une application avec accès au GPU**

1. Pour créer le conteneur d'applications, utilisez la `build-container` commande.

   ```
   $ panorama-cli build-container --container-asset-name code_asset --package-path packages/123456789012-SAMPLE_CODE-1.0
   ```

1. Ajoutez le `requirements` bloc à la configuration du package.

1. Pour télécharger la configuration de l'actif et du package du conteneur, utilisez la `package-application` commande.

   ```
   $ panorama-cli package-application
   ```

1. Déployez l'application.

Pour des exemples d'applications utilisant l'accès au GPU, visitez le [aws-panorama-samples](https://github.com/aws-samples/aws-panorama-samples) GitHub référentiel.

# Configuration d'un environnement de développement sous Windows
<a name="applications-devenvwindows"></a>

Pour créer une application AWS Panorama, vous utilisez Docker, des outils de ligne de commande et Python. Sous Windows, vous pouvez configurer un environnement de développement à l'aide de Docker Desktop avec le sous-système Windows pour Linux et Ubuntu. Ce didacticiel explique le processus de configuration d'un environnement de développement qui a été testé avec les outils AWS Panorama et des exemples d'applications.

**Topics**
+ [Prérequis](#applications-devenvwindows-prerequisites)
+ [Installez WSL 2 et Ubuntu](#applications-devenvwindows-wsl2)
+ [Installer Docker](#applications-devenvwindows-docker)
+ [Configurer Ubuntu](#applications-devenvwindows-ubuntu)
+ [Étapes suivantes](#applications-devenvwindows-nextsteps)

## Prérequis
<a name="applications-devenvwindows-prerequisites"></a>

Pour suivre ce didacticiel, vous devez disposer d'une version de Windows compatible avec le sous-système Windows pour Linux 2 (WSL 2).

****
+ Windows 10 version 1903 et ultérieure (build 18362 et supérieur) ou Windows 11
+ Fonctionnalités de Windows
  + WSL (Windows Subsystem for Linux)
  + Hyper-V
  + Plateforme de machines virtuelles

Ce didacticiel a été développé avec les versions logicielles suivantes.

****
+ Ubuntu 20.04
+ Python 3.8.5
+ Docker 20.10.8

## Installez WSL 2 et Ubuntu
<a name="applications-devenvwindows-wsl2"></a>

Si vous utilisez Windows 10 version 2004 ou supérieure (version 19041 et ultérieure), vous pouvez installer WSL 2 et Ubuntu 20.04 à l'aide de la commande suivante. PowerShell 

```
> wsl --install -d Ubuntu-20.04
```

Pour les anciennes versions de Windows, suivez les instructions de la documentation WSL 2 : [Étapes d'installation manuelle pour les anciennes](https://docs.microsoft.com/en-us/windows/wsl/install-manual) versions

## Installer Docker
<a name="applications-devenvwindows-docker"></a>

Pour installer Docker Desktop, téléchargez et exécutez le package d'installation depuis [hub.docker.com](https://hub.docker.com/editions/community/docker-ce-desktop-windows/). Si vous rencontrez des problèmes, suivez les instructions sur le site Web de Docker : [Docker Desktop WSL](https://docs.docker.com/desktop/windows/wsl/) 2 backend.

Exécutez Docker Desktop et suivez le didacticiel de première exécution pour créer un exemple de conteneur.

**Note**  
Docker Desktop n'active Docker que dans la distribution par défaut. Si d'autres distributions Linux sont installées avant d'exécuter ce didacticiel, activez Docker dans la distribution Ubuntu récemment installée dans le menu des paramètres de Docker Desktop sous **Ressources**, intégration **WSL**.

## Configurer Ubuntu
<a name="applications-devenvwindows-ubuntu"></a>

Vous pouvez désormais exécuter des commandes Docker sur votre machine virtuelle Ubuntu. Pour ouvrir un terminal de ligne de commande, exécutez la distribution depuis le menu Démarrer. La première fois que vous l'exécutez, vous configurez un nom d'utilisateur et un mot de passe que vous pouvez utiliser pour exécuter des commandes d'administrateur.

Pour terminer la configuration de votre environnement de développement, mettez à jour le logiciel de la machine virtuelle et installez les outils.

**Pour configurer la machine virtuelle**

1. Mettez à jour le logiciel fourni avec Ubuntu.

   ```
   $ sudo apt update && sudo apt upgrade -y && sudo apt autoremove
   ```

1. Installez les outils de développement avec apt.

   ```
   $ sudo apt install unzip python3-pip
   ```

1. Installez les bibliothèques Python avec pip.

   ```
   $ pip3 install awscli panoramacli
   ```

1. Ouvrez un nouveau terminal, puis exécutez `aws configure` pour configurer le AWS CLI.

   ```
   $ aws configure
   ```

   Si vous ne disposez pas de clés d'accès, vous pouvez les générer dans la [console IAM](https://console.aws.amazon.com/iamv2/home?#/users).

Enfin, téléchargez et importez l'exemple d'application.

**Pour obtenir l'exemple d'application**

1. Téléchargez et extrayez l'exemple d'application.

   ```
   $ wget https://github.com/awsdocs/aws-panorama-developer-guide/releases/download/v1.0-ga/aws-panorama-sample.zip
   $ unzip aws-panorama-sample.zip
   $ cd aws-panorama-sample
   ```

1. Exécutez les scripts inclus pour tester la compilation, créer le conteneur d'applications et télécharger des packages sur AWS Panorama.

   ```
   aws-panorama-sample$ ./0-test-compile.sh
   aws-panorama-sample$ ./1-create-role.sh
   aws-panorama-sample$ ./2-import-app.sh
   aws-panorama-sample$ ./3-build-container.sh
   aws-panorama-sample$ ./4-package-app.sh
   ```

La CLI de l'application AWS Panorama télécharge les packages et les enregistre auprès du service AWS Panorama. Vous pouvez désormais [déployer l'exemple d'application](gettingstarted-deploy.md#gettingstarted-deploy-deploy) avec la console AWS Panorama.

## Étapes suivantes
<a name="applications-devenvwindows-nextsteps"></a>

Pour explorer et modifier les fichiers du projet, vous pouvez utiliser l'explorateur de fichiers ou un environnement de développement intégré (IDE) compatible avec WSL.

Pour accéder au système de fichiers de la machine virtuelle, ouvrez l'explorateur de fichiers et entrez `\\wsl$` dans la barre de navigation. Ce répertoire contient un lien vers le système de fichiers de la machine virtuelle (`Ubuntu-20.04`) et les systèmes de fichiers pour les données Docker. Sous`Ubuntu-20.04`, votre répertoire d'utilisateurs se trouve à`home\username`.

**Note**  
Pour accéder aux fichiers de votre installation Windows depuis Ubuntu, accédez au `/mnt/c` répertoire. Par exemple, vous pouvez répertorier les fichiers de votre répertoire de téléchargements en exécutant`ls /mnt/c/Users/windows-username/Downloads`.

Visual Studio Code vous permet de modifier le code de l'application dans votre environnement de développement et d'exécuter des commandes à l'aide d'un terminal intégré. Pour installer Visual Studio Code, rendez-vous sur [code.visualstudio.com](https://code.visualstudio.com/). Après l'installation, ajoutez l'extension [Remote WSL.](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl)

Le terminal Windows est une alternative au terminal Ubuntu standard dans lequel vous avez exécuté des commandes. Il prend en charge plusieurs onglets et peut s'exécuter PowerShell, une invite de commande et des terminaux pour toute autre variété de Linux que vous installez. Il prend en charge le copier-coller avec  Ctrl C  et Ctrl V , le clickable URLs, ainsi que d'autres améliorations utiles. Pour installer Windows Terminal, rendez-vous sur [microsoft.com](https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701).