

Aviso de fin de soporte: el 31 de mayo de 2026, AWS finalizará el soporte para AWS Panorama. Después del 31 de mayo de 2026, ya no podrás acceder a la AWS Panorama consola ni a AWS Panorama los recursos. Para obtener más información, consulta [AWS Panorama el fin del soporte](https://docs.aws.amazon.com/panorama/latest/dev/panorama-end-of-support.html). 

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Creación de AWS Panorama aplicaciones
<a name="panorama-development"></a>

Las aplicaciones se ejecutan en el AWS Panorama dispositivo para realizar tareas de visión artificial en transmisiones de vídeo. Puede crear aplicaciones de visión artificial combinando código Python y modelos de aprendizaje automático e implementarlas en el AWS Panorama dispositivo a través de Internet. Las aplicaciones pueden enviar vídeo a una pantalla o utilizar el SDK de AWS para enviar los resultados a los servicios de AWS.

Un [modelo](applications-models.md) analiza las imágenes para detectar personas, vehículos y otros objetos. Basándose en las imágenes que ha visto durante el entrenamiento, el modelo le dice qué cree que es algo y qué tan seguro está al adivinarlo. Puede entrenar modelos con sus propios datos de imagen o empezar con una muestra.

El [código](gettingstarted-sample.md) de la aplicación procesa imágenes fijas de una secuencia de cámara, las envía a un modelo y procesa el resultado. Un modelo puede detectar varios objetos y devolver sus formas y ubicación. El código puede usar esta información para añadir texto o gráficos al vídeo, o para enviar los resultados a un servicio AWS para su almacenamiento o procesamiento posterior.

Para obtener imágenes de una transmisión, interactuar con un modelo y generar vídeo, el código de la aplicación utiliza [el SDK de AWS Panorama aplicaciones](applications-panoramasdk.md). El SDK de la aplicación es una biblioteca de Python que admite modelos generados con PyTorch Apache MXNet y TensorFlow.

**Topics**
+ [Modelos de visión artificial](applications-models.md)
+ [Creación de una imagen de aplicación](applications-image.md)
+ [Llamar a los servicios de AWS desde el código de su aplicación](applications-awssdk.md)
+ [El SDK de aplicaciones de AWS Panorama](applications-panoramasdk.md)
+ [Ejecutar múltiples subprocesos](applications-threading.md)
+ [Ofrecer servicios al tráfico de entrada](applications-ports.md)
+ [Uso de la GPU](applications-gpuaccess.md)
+ [Configuración de un entorno de desarrollo en Windows](applications-devenvwindows.md)

# Modelos de visión artificial
<a name="applications-models"></a>

Un *modelo de visión artificial* es un programa de software que está entrenado para detectar objetos en imágenes. Un modelo aprende a reconocer un conjunto de objetos analizando primero las imágenes de esos objetos mediante el entrenamiento. Un modelo de visión artificial toma una imagen como entrada y genera información sobre los objetos que detecta, como el tipo de objeto y su ubicación. AWS Panorama admite modelos de visión artificial creados con PyTorch Apache MXNet y TensorFlow.

**nota**  
Para ver una lista de los modelos prediseñados que se han probado con AWS Panorama, consulte [Compatibilidad del modelo](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/model-compatibility.md).

**Topics**
+ [Uso de modelos en código](#applications-models-using)
+ [Creación de un modelo personalizado](#applications-models-custom)
+ [Empaquetar un modelo](#applications-models-package)
+ [Modelos de formación](#applications-models-training)

## Uso de modelos en código
<a name="applications-models-using"></a>

Un modelo devuelve uno o más resultados, que pueden incluir probabilidades de las clases detectadas, información de ubicación y otros datos. En el siguiente ejemplo, se muestra cómo realizar inferencias en una imagen a partir de una transmisión de vídeo y enviar la salida del modelo a una función de procesamiento.

**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): inferencia**  

```
    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)
```

El siguiente ejemplo muestra una función que procesa los resultados del modelo de clasificación básico. El modelo de muestra devuelve una matriz de probabilidades, que es el primer y único valor de la matriz de resultados.

**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): procesando los resultados**  

```
    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)
```

El código de la aplicación busca los valores con las probabilidades más altas y los asigna a las etiquetas de un archivo de recursos que se carga durante la inicialización.

## Creación de un modelo personalizado
<a name="applications-models-custom"></a>

Puede usar los modelos que haya creado PyTorch, en Apache MXNet y TensorFlow en las aplicaciones de AWS Panorama. Como alternativa a la creación y el entrenamiento de modelos en SageMaker IA, puedes usar un modelo entrenado o crear y entrenar tu propio modelo con un marco compatible y exportarlo a un entorno local o a Amazon EC2.

**nota**  
Para obtener más información sobre las versiones de los marcos y los formatos de archivo compatibles con SageMaker AI Neo, consulte [los marcos compatibles](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-supported-devices-edge-frameworks.html) en la Guía para desarrolladores de Amazon SageMaker AI.

El repositorio de esta guía proporciona un ejemplo de aplicación que muestra este flujo de trabajo para un modelo de Keras en TensorFlow `SavedModel` formato. Utiliza TensorFlow 2 y se puede ejecutar localmente en un entorno virtual o en un contenedor Docker. La aplicación de muestra también incluye plantillas y scripts para crear el modelo en una EC2 instancia de Amazon.

****
+ [Ejemplo de aplicación de modelo personalizado](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/custom-model)

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


AWS Panorama usa SageMaker AI Neo para compilar modelos para usarlos en el dispositivo AWS Panorama. Para cada marco, utilice el [formato compatible con SageMaker AI Neo](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-compilation-preparing-model.html) y empaquete el modelo en un `.tar.gz` archivo.

Para obtener más información, consulte [Compilar e implementar modelos con Neo](https://docs.aws.amazon.com/sagemaker/latest/dg/neo.html) en la Guía para desarrolladores de Amazon SageMaker AI.

## Empaquetar un modelo
<a name="applications-models-package"></a>

Un paquete de modelos consta de un descriptor, una configuración de paquete y un archivo de modelos. Al igual que en un [paquete de imágenes de aplicaciones](applications-image.md), la configuración del paquete indica al servicio AWS Panorama dónde se almacenan el modelo y el descriptor en Amazon S3. 

**Example [packages/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
                ]
            }
        ]
    }
}
```

**nota**  
Especifique únicamente la versión principal y secundaria de la versión del framework. Para obtener una lista de las versiones compatibles PyTorch MXNet, de Apache y de las TensorFlow versiones, consulte [Marcos compatibles](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-supported-devices-edge-frameworks.html).

Para importar un modelo, utilice el comando `import-raw-model` CLI de la aplicación AWS Panorama. Si realiza algún cambio en el modelo o en su descriptor, debe volver a ejecutar este comando para actualizar los activos de la aplicación. Para obtener más información, consulte [Cambiar el modelo de visión artificial](gettingstarted-sample.md#gettingstarted-sample-model).

Para ver el esquema JSON del archivo descriptor, consulte [assetDescriptor.schema.json.](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/manifest-schema/ver_2021-01-01/assetDescriptor.schema.json)

## Modelos de formación
<a name="applications-models-training"></a>

Cuando entrene un modelo, use imágenes del entorno de destino o de un entorno de prueba que se parezca mucho al entorno de destino. Tenga en cuenta los siguientes factores que pueden afectar al rendimiento del modelo:

****
+ **Iluminación**: la cantidad de luz que refleja un sujeto determina la cantidad de detalles que el modelo debe analizar. Es posible que un modelo entrenado con imágenes de sujetos bien iluminados no funcione bien en un entorno con poca luz o retroiluminado.
+ **Resolución**: el tamaño de entrada de un modelo suele fijarse en una resolución de entre 224 y 512 píxeles de ancho en una relación de aspecto cuadrada. Antes de pasar un fotograma de vídeo al modelo, puede reducirlo o recortarlo para que se ajuste al tamaño requerido.
+ **Distorsión de la imagen**: la distancia focal y la forma de la lente de la cámara pueden provocar que las imágenes se distorsionen alejándose del centro del encuadre. La posición de la cámara también determina qué características del sujeto son visibles. Por ejemplo, una cámara de techo con una lente gran angular mostrará la parte superior del sujeto cuando esté en el centro del encuadre y una vista sesgada del costado del sujeto a medida que se aleja del centro.

Para solucionar estos problemas, puede preprocesar las imágenes antes de enviarlas al modelo y entrenar al modelo sobre una variedad más amplia de imágenes que reflejen las variaciones de los entornos del mundo real. Si un modelo necesita funcionar en situaciones de iluminación y con una variedad de cámaras, necesitará más datos para el entrenamiento. Además de recopilar más imágenes, puede obtener más datos de entrenamiento creando variaciones de las imágenes existentes que estén sesgadas o tengan una iluminación diferente.

# Creación de una imagen de aplicación
<a name="applications-image"></a>

El dispositivo de AWS Panorama ejecuta aplicaciones como sistemas de archivos contenedores exportados a partir de una imagen que usted cree. Debe especificar las dependencias y los recursos de la aplicación en un Dockerfile que utiliza la imagen base de la aplicación de AWS Panorama como punto de partida.

Para crear una imagen de aplicación, utilice Docker y la CLI de aplicaciones de AWS Panorama. El siguiente ejemplo de la aplicación de muestra de esta guía muestra estos casos de uso.

**Example [packages/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
```

Se utilizan las siguientes instrucciones de Dockerfile.

****
+ `FROM`: carga la imagen base de la aplicación (`public.ecr.aws/panorama/panorama-application`). 
+ `WORKDIR`: establece el directorio de trabajo en la imagen. `/panorama` se utiliza para el código de la aplicación y los archivos relacionados. Esta configuración solo se conserva durante la compilación y no afecta al directorio de trabajo de su aplicación en tiempo de ejecución (`/`).
+ `COPY`: copia los archivos de una ruta local a una ruta de la imagen. `COPY . .` copia los archivos del directorio actual (el directorio del paquete) al directorio de trabajo de la imagen. Por ejemplo, el código de la aplicación se copia de `packages/123456789012-SAMPLE_CODE-1.0/application.py` a `/panorama/application.py`.
+ `RUN`: ejecuta comandos del intérprete de comandos en la imagen durante la compilación. Una sola operación `RUN` puede ejecutar varios comandos en secuencia si se utiliza `&&` entre comandos. Este ejemplo actualiza el administrador de paquetes `pip` y, a continuación, instala las bibliotecas enumeradas en `requirements.txt`.

Puede utilizar otras instrucciones, como `ADD` y `ARG`, que resulten útiles en el momento de la compilación. Las instrucciones que añaden información de tiempo de ejecución al contenedor, por ejemplo `ENV`, no funcionan con AWS Panorama. AWS Panorama no ejecuta ningún contenedor desde la imagen. Solo utiliza la imagen para exportar un sistema de archivos, que se transfiere al dispositivo.

## Especificación de dependencias
<a name="applications-image-dependencies"></a>

`requirements.txt` es un archivo de requisitos de Python que especifica las bibliotecas utilizadas por la aplicación. La aplicación de ejemplo utiliza Open CV y AWS SDK para Python (Boto3).

**Example [packages/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.*
```

El comando `pip install` del Dockerfile instala estas bibliotecas en el directorio `dist-packages` de Python que se encuentra debajo de `/usr/local/lib`, para que el código de su aplicación pueda importarlas.

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

AWS Panorama reserva el directorio `/opt/aws/panorama/storage` para el almacenamiento de aplicaciones. Su aplicación puede crear y modificar archivos en esta ruta. Los archivos creados en el directorio de almacenamiento se conservan tras los reinicios. Las demás ubicaciones de los archivos temporales se borran al arrancar.

## Creación de activos de imagen
<a name="applications-image-build"></a>

Cuando crea una imagen para el paquete de aplicaciones con la CLI de aplicaciones de AWS Panorama, la CLI ejecuta `docker build` en el directorio del paquete. Esto crea una imagen de la aplicación que contiene el código de la aplicación. Luego, la CLI crea un contenedor, exporta su sistema de archivos, lo comprime y lo almacena en la carpeta `assets`.

```
$ 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
```

El bloque JSON de la salida es una definición de activo que la CLI agrega a la configuración del paquete (`package.json`) y registra en el servicio AWS Panorama. La CLI también copia el archivo descriptor, que especifica la ruta al script de la aplicación (el punto de entrada de la aplicación).

**Example [packages/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"
        }
    }
}
```

En la carpeta de activos, el descriptor y la imagen de la aplicación reciben el nombre de su suma de verificación SHA-256. Este nombre se utiliza como identificador único del activo cuando se almacena en Amazon S3. 

# Llamar a los servicios de AWS desde el código de su aplicación
<a name="applications-awssdk"></a>

Puede utilizarla AWS SDK para Python (Boto) para llamar a los servicios de AWS desde el código de su aplicación. Por ejemplo, si su modelo detecta algo fuera de lo común, puede publicar métricas en Amazon CloudWatch, enviar una notificación con Amazon SNS, guardar una imagen en Amazon S3 o invocar una función Lambda para su posterior procesamiento. La mayoría de los servicios de AWS tienen una API pública que puede usar con el SDK de AWS.

De forma predeterminada, el dispositivo no tiene permiso para acceder a ningún servicio de AWS. Para concederle permiso, [cree un rol para la aplicación](permissions-application.md) y asígnelo a la instancia de la aplicación durante la implementación.

**Topics**
+ [Uso de Amazon S3](#applications-awssdk-s3)
+ [Uso del tema MQTT AWS IoT](#monitoring-messagestream)

## Uso de Amazon S3
<a name="applications-awssdk-s3"></a>

Puede utilizar Amazon S3 para almacenar los resultados del procesamiento y otros datos de aplicación.

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

## Uso del tema MQTT AWS IoT
<a name="monitoring-messagestream"></a>

[Puede utilizar el SDK para Python (Boto3) para enviar mensajes a un tema de MQTT](https://docs.aws.amazon.com/iot/latest/developerguide/topics.html) en AWS IoT. En el siguiente ejemplo, la aplicación publica en un tema que lleva el *nombre del objeto* del dispositivo y que se encuentra en la [consola de AWS IoT](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")
```

Elija un nombre que indique el ID del dispositivo u otro identificador de su elección. Para publicar mensajes, la aplicación necesita permiso para llamar a `iot:Publish`.

**Para supervisar una cola de MQTT**

1. Abra la [página Pruebas de la consola de AWS IoT](https://console.aws.amazon.com/iot/home?region=us-east-1#/test).

1. Para **Tema de suscripción**, escriba un nombre para el tema. Por ejemplo, `panorama/panorama_my-appliance_Thing_a01e373b`.

1. Elija **Suscribirse al tema**.

# El SDK de aplicaciones de AWS Panorama
<a name="applications-panoramasdk"></a>

El SDK de aplicaciones de AWS Panorama es una biblioteca de Python para desarrollar aplicaciones de AWS Panorama. En el [código de su aplicación](gettingstarted-sample.md), usted utiliza el SDK de aplicaciones de AWS Panorama para cargar un modelo de visión artificial, ejecutar inferencias y enviar vídeo a un monitor.

**nota**  
Para asegurarse de tener acceso a las funciones más recientes del SDK de aplicaciones de AWS Panorama, [actualice el software del dispositivo](appliance-manage.md#appliance-manage-software).

Para obtener más información sobre las clases que define el SDK de la aplicación y sus métodos, consulte la [referencia del SDK de la aplicación](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/applicationsdk-reference.md).

**Topics**
+ [Añadir texto y cuadros a la salida de vídeo](#applications-panoramasdk-overlays)

## Añadir texto y cuadros a la salida de vídeo
<a name="applications-panoramasdk-overlays"></a>

Con el SDK de AWS Panorama, puede enviar una transmisión de vídeo a una pantalla. El vídeo puede incluir texto y cuadros que muestren el resultado del modelo, el estado actual de la aplicación u otros datos.

Cada objeto de la matriz `video_in` es una imagen de una transmisión de cámara que está conectada al dispositivo. El tipo de este objeto es `panoramasdk.media`. Tiene métodos para añadir texto y cuadros rectangulares a la imagen, que luego puede asignar a la matriz `video_out`.

En el ejemplo siguiente, la aplicación de muestra añade una etiqueta para cada uno de los resultados. Cada resultado se coloca en la misma posición a la izquierda, pero a diferentes alturas.

```
        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)
```

Para añadir un cuadro a la imagen de salida, utilice `add_rect`. Este método toma 4 valores entre 0 y 1, indicando la posición de las esquinas superior izquierda e inferior derecha del cuadro.

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

# Ejecutar múltiples subprocesos
<a name="applications-threading"></a>

Puede ejecutar la lógica de la aplicación en un subproceso de procesamiento y utilizar otros subprocesos para otros procesos en segundo plano. Por ejemplo, puede crear un hilo que [sirva al tráfico HTTP](applications-ports.md) para la depuración o un hilo que supervise los resultados de las inferencias y envíe datos a. AWS

Para ejecutar varios subprocesos, utilice el [módulo de subprocesos](https://docs.python.org/3/library/threading.html) de la biblioteca estándar de Python para crear un subproceso para cada proceso. El siguiente ejemplo muestra el bucle principal de la aplicación de muestra del servidor de depuración, que crea un objeto de aplicación y lo utiliza para ejecutar tres subprocesos.

**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): bucle principal**  

```
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.')
```

Cuando se cierran todos los subprocesos, la aplicación se reinicia automáticamente. El bucle `run_cv` procesa las imágenes de las transmisiones de la cámara. Si recibe una señal para detenerse, cierra el proceso de depuración, lo cual ejecuta un servidor HTTP y no puede apagarse solo. Cada subproceso debe gestionar sus propios errores. Si no se detecta ni registra un error, el subproceso se cierra silenciosamente.

**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): bucle de procesamiento**  

```
    # 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")
```

Los subprocesos se comunican a través del objeto `self` de la aplicación. Para reiniciar el ciclo de procesamiento de la aplicación, el subproceso del depurador llama al método `stop`. Este método establece un atributo de `terminate` que indica a los demás subprocesos que se cierren.

**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étodo de parada**  

```
    # 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)
```



# Ofrecer servicios al tráfico de entrada
<a name="applications-ports"></a>

Puede monitorizar o depurar aplicaciones de forma local ejecutando un servidor HTTP junto con el código de la aplicación. Para atender el tráfico externo, asigne los puertos del dispositivo de AWS Panorama a los puertos del contenedor de aplicaciones.

**importante**  
De forma predeterminada, el dispositivo de AWS Panorama no acepta tráfico entrante en ningún puerto. Abrir puertos en el dispositivo conlleva un riesgo de seguridad implícito. Al utilizar esta característica, debe tomar medidas adicionales para [proteger el dispositivo del tráfico externo](appliance-network.md) y proteger las comunicaciones entre los clientes autorizados y el dispositivo.  
El código de muestra incluido en esta guía tiene fines de demostración y no implementa la autenticación, la autorización ni el cifrado.

Puede abrir puertos en el rango de 8000 a 9000 en el dispositivo. Estos puertos, una vez abiertos, pueden recibir tráfico de cualquier cliente enrutable. Al implementar la aplicación, debe especificar qué puertos abrir, y asignar los puertos del dispositivo a los puertos del contenedor de aplicaciones. El software del dispositivo reenvía el tráfico al contenedor y envía las respuestas al solicitante. Las solicitudes se reciben en el puerto del dispositivo que especifique y las respuestas se envían a un puerto efímero al azar.

## Configuración de puertos de entrada
<a name="applications-ports-configuration"></a>

Las asignaciones de puertos se especifican en tres lugares de la configuración de la aplicación. En el paquete de códigos `package.json`, usted especifica el puerto que escucha el nodo de código en un bloque de `network`. El siguiente ejemplo declara que el nodo escucha en el puerto 80.

**Example [packages/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"
                        }
                    ]
                }
```

En el manifiesto de la aplicación, se declara una regla de enrutamiento que asigna un puerto del dispositivo a un puerto del contenedor de códigos de la aplicación. El siguiente ejemplo agrega una regla que asigna el puerto 8080 del dispositivo al puerto 80 del contenedor de `code_node`.

**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."
                }
            }
        ]
```

Al implementar la aplicación, se especifican las mismas reglas en la consola de AWS Panorama o se transfiere un documento de anulación a la [CreateApplicationInstance](https://docs.aws.amazon.com/panorama/latest/api/API_CreateApplicationInstance.html)API. Debe proporcionar esta configuración en el momento de la implementación para confirmar que desea abrir los puertos del dispositivo.

**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 otra aplicación utiliza el puerto del dispositivo especificado en el manifiesto de la aplicación, puedes usar el documento de anulación para elegir otro puerto.

## Ofrecer servicios al tráfico
<a name="applications-ports-serverthread"></a>

Con los puertos abiertos en el contenedor, puede abrir un socket o ejecutar un servidor para gestionar las solicitudes entrantes. El ejemplo de `debug-server` muestra una implementación básica de un servidor HTTP que se ejecuta junto con el código de una aplicación de visión artificial.

**importante**  
La implementación de ejemplo no es segura para su uso en producción. Para evitar que su dispositivo sea vulnerable a los ataques, debe implementar los controles de seguridad adecuados en la configuración de código y red.

**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): servidor 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.')
```

El servidor acepta solicitudes GET en la ruta de `/status` para recuperar cierta información sobre la aplicación. También acepta una solicitud POST a `/restart` para reiniciar la aplicación.

Para demostrar esta funcionalidad, la aplicación de ejemplo ejecuta un cliente HTTP en un hilo independiente. El cliente llama a la ruta de `/status` a través de la red local poco después del inicio y reinicia la aplicación unos minutos más tarde.

**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): cliente 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")
```

El circuito principal gestiona los subprocesos y reinicia la aplicación cuando se cierran.

**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): bucle principal**  

```
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.')
```

Para implementar la aplicación de muestra, consulte las [instrucciones del GitHub repositorio de esta guía](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/README.md).

# Uso de la GPU
<a name="applications-gpuaccess"></a>

Puede acceder al procesador de gráficos (GPU) del dispositivo de AWS Panorama para usar bibliotecas aceleradas por GPU o ejecutar modelos de machine learning en el código de la aplicación. Para activar el acceso a la GPU, añada el acceso a la GPU como requisito a la configuración del paquete después de crear el contenedor de código de la aplicación.

**importante**  
Si habilita el acceso a la GPU, no podrá ejecutar nodos modelo en ninguna aplicación en el dispositivo. Por motivos de seguridad, el acceso a la GPU está restringido cuando el dispositivo ejecuta un modelo compilado con SageMaker AI Neo. Con el acceso a la GPU, debe ejecutar sus modelos en nodos de código de aplicación y todas las aplicaciones en el dispositivo comparten el acceso a la GPU.

Para activar el acceso a la GPU de su aplicación, actualice la [configuración del paquete](applications-packages.md) después de crearlo con la CLI de aplicaciones de AWS Panorama. En el siguiente ejemplo, se muestra el bloque `requirements` que añade el acceso de la GPU al nodo de código de la aplicación.

**Example package.json con bloque de requisitos**  

```
{
    "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": [
        ...
```

Actualice la configuración del paquete entre los pasos de creación y empaquetado de su flujo de trabajo de desarrollo.

**Para implementar una aplicación con acceso a la GPU**

1. Para crear el contenedor de aplicaciones, utilice el comando `build-container`.

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

1. Añada el bloque `requirements` a la configuración del paquete.

1. Para cargar la configuración del paquete y el activo del contenedor, utilice el comando `package-application`.

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

1. Implemente la aplicación .

Para ver ejemplos de aplicaciones que utilizan el acceso a la GPU, visite el [aws-panorama-samples](https://github.com/aws-samples/aws-panorama-samples) GitHub repositorio.

# Configuración de un entorno de desarrollo en Windows
<a name="applications-devenvwindows"></a>

Para crear una aplicación de AWS Panorama, debe utilizar Docker, herramientas de línea de comandos y Python. En Windows, puede configurar un entorno de desarrollo mediante Docker Desktop con el subsistema de Windows para Linux y Ubuntu. En este tutorial, se explica el proceso de configuración de un entorno de desarrollo que se ha probado con las herramientas y aplicaciones de muestra de AWS Panorama.

**Topics**
+ [Requisitos previos](#applications-devenvwindows-prerequisites)
+ [Instalar WSL 2 y Ubuntu](#applications-devenvwindows-wsl2)
+ [Instalar Docker](#applications-devenvwindows-docker)
+ [Configurar Ubuntu](#applications-devenvwindows-ubuntu)
+ [Pasos a seguir a continuación](#applications-devenvwindows-nextsteps)

## Requisitos previos
<a name="applications-devenvwindows-prerequisites"></a>

Para seguir este tutorial, necesita una versión de Windows que sea compatible con el subsistema de Windows para Linux 2 (WSL 2).

****
+ Windows 10 versión 1903 y superior (compilación 18362 y superior) o Windows 11
+ Características de Windows
  + Windows Subsystem for Linux
  + Hyper-V
  + Plataforma de máquinas virtuales

Este tutorial se desarrolló con las siguientes versiones de software.

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

## Instalar WSL 2 y Ubuntu
<a name="applications-devenvwindows-wsl2"></a>

Si tiene Windows 10 versión 2004 o superior (compilación 19041 y superior), puede instalar WSL 2 y Ubuntu 20.04 con el siguiente comando. PowerShell 

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

Para versiones anteriores de Windows, siga las instrucciones de la documentación de WSL 2: [Pasos de la instalación manual para versiones anteriores](https://docs.microsoft.com/en-us/windows/wsl/install-manual)

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

Para instalar Docker Desktop, descargue y ejecute el paquete de instalación desde [hub.docker.com.](https://hub.docker.com/editions/community/docker-ce-desktop-windows/) Si tiene problemas, siga las instrucciones del sitio web de Docker: [Docker Desktop WSL 2 backend](https://docs.docker.com/desktop/windows/wsl/).

Ejecute Docker Desktop y siga el tutorial de primera ejecución para crear un contenedor de ejemplo.

**nota**  
Docker Desktop solo habilita Docker en la distribución predeterminada. Si tiene otras distribuciones de Linux instaladas antes de ejecutar este tutorial, habilite Docker en la distribución de Ubuntu recién instalada en el menú de configuración de Docker Desktop, en **Recursos**, **integración con WSL**.

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

Ahora puede ejecutar los comandos de Docker en su máquina virtual Ubuntu. Para abrir un terminal de línea de comandos, ejecute la distribución desde el menú de inicio. La primera vez que la ejecute, configurará un nombre de usuario y una contraseña que podrá utilizar para ejecutar comandos de administrador.

Para completar la configuración de su entorno de desarrollo, actualice el software de la máquina virtual e instale las herramientas.

**Para configurar la máquina virtual**

1. Actualice el software que viene con Ubuntu.

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

1. Instale las herramientas de desarrollo con apt.

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

1. Instale las bibliotecas de Python con pip.

   ```
   $ pip3 install awscli panoramacli
   ```

1. Abra una nueva terminal y, a continuación, ejecute `aws configure` para configurar AWS CLI.

   ```
   $ aws configure
   ```

   Si no tiene claves de acceso, puede generarlas en la [consola de IAM](https://console.aws.amazon.com/iamv2/home?#/users).

Por último, descargue e importe la aplicación de muestra.

**Para obtener la aplicación de muestra**

1. Descargue y extraiga la aplicación de muestra.

   ```
   $ 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. Ejecute los scripts incluidos para probar la compilación, crear el contenedor de aplicaciones y cargar los paquetes en 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 aplicaciones de AWS Panorama carga los paquetes y los registra en el servicio AWS Panorama. Ahora puede implementar [la aplicación de muestra](gettingstarted-deploy.md#gettingstarted-deploy-deploy) con la consola de AWS Panorama.

## Pasos a seguir a continuación
<a name="applications-devenvwindows-nextsteps"></a>

Para explorar y editar los archivos del proyecto, puede utilizar el explorador de archivos o un entorno de desarrollo integrado (IDE) compatible con WSL.

Para acceder al sistema de archivos de la máquina virtual, abra el explorador de archivos y escriba `\\wsl$` en la barra de navegación. Este directorio contiene un enlace al sistema de archivos de la máquina virtual (`Ubuntu-20.04`) y a los sistemas de archivos de los datos de Docker. En `Ubuntu-20.04`, su directorio de usuarios está en `home\username`.

**nota**  
Para acceder a los archivos de su instalación de Windows desde Ubuntu, navegue hasta el directorio `/mnt/c`. Por ejemplo, puede ver una lista de los archivos de su directorio de descargas ejecutando `ls /mnt/c/Users/windows-username/Downloads`.

Con Visual Studio Code, puede editar el código de la aplicación en su entorno de desarrollo y ejecutar comandos con una terminal integrada. Para instalar Visual Studio Code, visite [code.visualstudio.com](https://code.visualstudio.com/). Tras la instalación, añada la extensión [Remote WSL](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl).

La terminal de Windows es una alternativa a la terminal estándar de Ubuntu en la que ha estado ejecutando comandos. Admite múltiples pestañas y puede ejecutar PowerShell, línea de comandos y terminales para cualquier otra variedad de Linux que instale. Es compatible con las funciones de copiar y pegar con  Ctrl C  los  Ctrl V  botones «y hacer clic» URLs, entre otras mejoras útiles. Para instalar la terminal de Windows, visite [microsoft.com](https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701).