

Aviso de fim do suporte: em 31 de maio de 2026, AWS encerrará o suporte para AWS Panorama. Depois de 31 de maio de 2026, você não poderá mais acessar o AWS Panorama console ou os AWS Panorama recursos. Para obter mais informações, consulte [AWS Panorama Fim do suporte](https://docs.aws.amazon.com/panorama/latest/dev/panorama-end-of-support.html). 

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Criação de AWS Panorama aplicativos
<a name="panorama-development"></a>

Os aplicativos são executados no AWS Panorama equipamento para realizar tarefas de visão computacional em streams de vídeo. Você pode criar aplicativos de visão computacional combinando código Python e modelos de aprendizado de máquina e implantá-los no AWS Panorama Appliance pela Internet. As aplicações podem enviar vídeo para um monitor ou usar o SDK da AWS para enviar resultados para os serviços da AWS.

Um [modelo](applications-models.md) analisa imagens para detectar pessoas, veículos e outros objetos. Com base nas imagens que viu durante o treinamento, o modelo diz o que ele acha que algo é, e o nível de confiança dessa suposição. Você pode treinar modelos com seus próprios dados de imagem ou começar com um exemplo.

O [código](gettingstarted-sample.md) da aplicação processa imagens estáticas de um stream de câmera, as envia para um modelo e processa o resultado. Um modelo pode detectar vários objetos e retornar suas formas e localização. O código pode usar essas informações para adicionar texto ou gráficos ao vídeo ou para enviar resultados a um serviço da AWS para armazenamento ou processamento adicional.

Para obter imagens de um stream, interagir com um modelo e gerar vídeo, o código do aplicativo usa [o SDK do AWS Panorama aplicativo](applications-panoramasdk.md). O SDK do aplicativo é uma biblioteca Python que oferece suporte a modelos gerados PyTorch com, MXNet Apache e. TensorFlow

**Topics**
+ [Modelos de visão computacional](applications-models.md)
+ [Construir uma imagem de aplicação](applications-image.md)
+ [Chamada de serviços da AWS a partir do código da sua aplicação](applications-awssdk.md)
+ [O SDK para aplicações do AWS Panorama](applications-panoramasdk.md)
+ [Execução de vários threads](applications-threading.md)
+ [Fornecimento de tráfego de entrada](applications-ports.md)
+ [Uso da GPU](applications-gpuaccess.md)
+ [Configurar um ambiente de desenvolvimento no Windows](applications-devenvwindows.md)

# Modelos de visão computacional
<a name="applications-models"></a>

Um *modelo de visão computacional* é um programa de software treinado para detectar objetos em imagens. Um modelo aprende a reconhecer um conjunto de objetos analisando primeiro as imagens desses objetos por meio de treinamento. Um modelo de visão computacional usa uma imagem como entrada e gera informações sobre os objetos que detecta, como tipo de objeto e sua localização. O AWS Panorama oferece suporte a modelos de visão computacional criados com PyTorch MXNet, Apache e. TensorFlow

**nota**  
Para obter uma lista de modelos pré-criados que foram testados com o AWS Panorama, consulte [Compatibilidade de modelos](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/model-compatibility.md).

**Topics**
+ [Uso de modelos em código](#applications-models-using)
+ [Criação de um modelo personalizado](#applications-models-custom)
+ [Empacotamento de um modelo](#applications-models-package)
+ [Modelos de treinamento](#applications-models-training)

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

Um modelo retorna um ou mais resultados, que podem incluir probabilidades de classes detectadas, informações de localização e outros dados. O exemplo a seguir mostra como executar inferência em uma imagem de um stream de vídeo e enviar a saída do modelo para uma função de processamento.

**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): inferência**  

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

O exemplo a seguir mostra uma função que processa resultados do modelo de classificação básico. O modelo de amostra retorna uma matriz de probabilidades, que é o primeiro e único valor na 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): resultados do processo**  

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

O código da aplicação encontra os valores com as maiores probabilidades e os mapeia para rótulos em um arquivo de recurso que é carregado durante a inicialização.

## Criação de um modelo personalizado
<a name="applications-models-custom"></a>

Você pode usar modelos que você cria no PyTorch Apache MXNet e TensorFlow nos aplicativos do AWS Panorama. Como alternativa à criação e treinamento de modelos em SageMaker IA, você pode usar um modelo treinado ou criar e treinar seu próprio modelo com uma estrutura compatível e exportá-lo em um ambiente local ou na Amazon EC2.

**nota**  
Para obter detalhes sobre as versões da estrutura e os formatos de arquivo suportados pelo SageMaker AI Neo, consulte [Estruturas suportadas](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-supported-devices-edge-frameworks.html) no Amazon SageMaker AI Developer Guide.

O repositório deste guia fornece um aplicativo de amostra que demonstra esse fluxo de trabalho para um modelo Keras em formato. TensorFlow `SavedModel` Ele usa TensorFlow 2 e pode ser executado localmente em um ambiente virtual ou em um contêiner Docker. O aplicativo de amostra também inclui modelos e scripts para criar o modelo em uma EC2 instância da Amazon.

****
+ [Aplicação de exemplo de modelo personalizado](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/custom-model)

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


O AWS Panorama usa o SageMaker AI Neo para compilar modelos para uso no AWS Panorama Appliance. Para cada estrutura, use o [formato compatível com o SageMaker AI Neo](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-compilation-preparing-model.html) e empacote o modelo em um `.tar.gz` arquivo.

Para obter mais informações, consulte [Compilar e implantar modelos com o Neo](https://docs.aws.amazon.com/sagemaker/latest/dg/neo.html) no Amazon SageMaker AI Developer Guide.

## Empacotamento de um modelo
<a name="applications-models-package"></a>

Um pacote de modelos abrange um descritor, uma configuração de pacote e um arquivo de modelos. Assim como em um [pacote de imagem da aplicação](applications-image.md), a configuração do pacote informa ao serviço AWS Panorama onde o modelo e o descritor estão armazenados no 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 somente a versão principal e secundária da versão da estrutura. Para obter uma lista das versões compatíveis PyTorch, do Apache MXNet e TensorFlow das versões, consulte [Estruturas suportadas](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-supported-devices-edge-frameworks.html).

Para importar um modelo, use o comando `import-raw-model` da CLI da aplicação do AWS Panorama. Se você fizer alguma alteração no modelo ou em seu descritor, será necessário executar novamente esse comando para atualizar os ativos da aplicação. Para obter mais informações, consulte [Alteração do modelo de visão computacional](gettingstarted-sample.md#gettingstarted-sample-model).

[Para o esquema JSON do arquivo descritor, 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 treinamento
<a name="applications-models-training"></a>

Ao treinar um modelo, use imagens do ambiente de destino ou de um ambiente de teste que se assemelhe muito ao ambiente de destino. Considere os seguintes fatores que podem afetar o desempenho do modelo:

****
+ **Iluminação**: a quantidade de luz refletida por um objeto determina a quantidade de detalhes que o modelo precisa analisar. Um modelo treinado com imagens de objetos bem iluminados pode não funcionar bem em um ambiente com pouca luz ou baixa retroiluminação.
+ **Resolução**: o tamanho da entrada de um modelo geralmente é fixado em uma resolução entre 224 e 512 pixels de largura em uma proporção quadrada. Antes de passar um quadro de vídeo para o modelo, você pode reduzi-lo ou cortá-lo para que ela caiba no tamanho necessário.
+ **Distorção da imagem**: a distância focal e o formato da lente da câmera podem fazer com que as imagens exibam distorção longe do centro do quadro. A posição de uma câmera também determina quais atributos de um objeto são visíveis. Por exemplo, uma câmera suspensa com lente grande angular mostrará a parte superior de um objeto quando ele estiver no centro do quadro e uma visão distorcida da lateral do objeto à medida que ele se afasta do centro.

Para resolver esses problemas, você pode pré-processar imagens antes de enviá-las ao modelo e treinar o modelo com uma variedade maior de imagens que refletem variações em ambientes do mundo real. Se um modelo precisar operar em situações de iluminação e com várias câmeras, você precisará de mais dados para o treinamento. Além de coletar mais imagens, você pode obter mais dados de treinamento criando variações de suas imagens existentes que estão distorcidas ou têm iluminação diferente.

# Construir uma imagem de aplicação
<a name="applications-image"></a>

O AWS Panorama Appliance executa aplicações como sistemas de arquivos de contêiner exportados a partir de uma imagem que você cria. Você especifica as dependências e os recursos da sua aplicação em um Dockerfile que usa a imagem base da aplicação do AWS Panorama como ponto de partida.

Para criar uma imagem da aplicação, você usa o Docker e a CLI da aplicação do AWS Panorama. O exemplo a seguir da aplicação de exemplo deste guia demonstra esses 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
```

As seguintes instruções do Dockerfile são usadas.

****
+ `FROM`: carrega a imagem base da aplicação (`public.ecr.aws/panorama/panorama-application`). 
+ `WORKDIR`: define o diretório de trabalho na imagem. `/panorama` é usado para o código da aplicação e arquivos relacionados. Essa configuração só persiste durante a compilação e não afeta o diretório de trabalho da sua aplicação em runtime (`/`).
+ `COPY`: copia arquivos de um caminho local para um caminho na imagem. `COPY . .` copia os arquivos no diretório atual (o diretório do pacote) para o diretório de trabalho na imagem. Por exemplo, o código da aplicação é copiado de `packages/123456789012-SAMPLE_CODE-1.0/application.py` para `/panorama/application.py`.
+ `RUN`: executa comandos de shell na imagem durante a compilação. Uma única operação `RUN` pode executar vários comandos em sequência usando `&&` entre comandos. Este exemplo atualiza o gerenciador de pacotes `pip` e, em seguida, instala as bibliotecas listadas em `requirements.txt`.

Você pode usar outras instruções, como `ADD` e `ARG`, que são úteis no momento da compilação. Instruções que adicionam informações de runtime ao contêiner, como `ENV`, não funcionam com o AWS Panorama. O AWS Panorama não executa um contêiner a partir da imagem. Ele só usa a imagem para exportar um sistema de arquivos, que é transferido para o dispositivo.

## Especificação de dependências
<a name="applications-image-dependencies"></a>

`requirements.txt` é um arquivo de requisitos do Python que especifica as bibliotecas usadas pela aplicação. A aplicação de exemplo usa Open CV e o 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.*
```

O comando `pip install` no Dockerfile instala essas bibliotecas no diretório `dist-packages` Python abaixo de `/usr/local/lib`, para que elas possam ser importadas pelo código da sua aplicação.

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

O AWS Panorama reserva o diretório `/opt/aws/panorama/storage` para armazenamento de aplicações. Sua aplicação pode criar e modificar arquivos nesse caminho. Os arquivos criados no diretório de armazenamento persistem nas reinicializações. Outros locais de arquivos temporários são apagados na inicialização.

## Criação de ativos de imagem
<a name="applications-image-build"></a>

Quando você cria uma imagem para seu pacote de aplicações com a CLI da aplicação do AWS Panorama, a CLI executa `docker build` no diretório do pacote. Isso cria uma imagem da aplicação que contém o código da aplicação. Em seguida, a CLI cria um contêiner, exporta seu sistema de arquivos, o compacta e o armazena na pasta `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
```

O bloco JSON na saída é uma definição de ativo que a CLI adiciona à configuração do pacote (`package.json`) e registra no serviço AWS Panorama. A CLI também copia o arquivo descritor, que especifica o caminho para o script da aplicação (o ponto de entrada da aplicação).

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

Na pasta de ativos, o descritor e a imagem da aplicação são nomeados de acordo com sua soma de verificação SHA-256. Esse nome é usado como um identificador exclusivo para o ativo quando ele é armazenado no Amazon S3. 

# Chamada de serviços da AWS a partir do código da sua aplicação
<a name="applications-awssdk"></a>

Você pode usar o AWS SDK para Python (Boto) para chamar os serviços da AWS a partir do código do seu aplicativo. Por exemplo, se seu modelo detectar algo fora do comum, você pode publicar métricas na Amazon CloudWatch, enviar uma notificação com o Amazon SNS, salvar uma imagem no Amazon S3 ou invocar uma função Lambda para processamento adicional. A maioria dos serviços da AWS tem uma API pública que você pode usar com o SDK da AWS.

O dispositivo não tem permissão para acessar nenhum serviço da AWS por padrão. Para conceder permissão, [crie uma função para a aplicação](permissions-application.md) e atribua-a à instância da aplicação durante a implantação.

**Topics**
+ [Usar o Amazon S3](#applications-awssdk-s3)
+ [Usando o tópico AWS IoT MQTT](#monitoring-messagestream)

## Usar o Amazon S3
<a name="applications-awssdk-s3"></a>

É possível usar o Amazon S3 para armazenar resultados de processamento e outros dados da aplicação.

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

## Usando o tópico AWS IoT MQTT
<a name="monitoring-messagestream"></a>

É possível usar o SDK para Python (Boto3) para enviar mensagens para um [tópico MQTT](https://docs.aws.amazon.com/iot/latest/developerguide/topics.html) no AWS IoT. No exemplo a seguir, a aplicação publica um tópico com o *nome da coisa* do dispositivo, que você pode encontrar no [AWS IoT 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")
```

Escolha um nome que indique o ID do dispositivo ou outro identificador de sua escolha. Para publicar mensagens, a aplicação precisa de permissão para chamar `iot:Publish`.

**Para monitorar uma fila MQTT**

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

1. Em **Tópico de assinatura**, insira o nome do tópico. Por exemplo, `panorama/panorama_my-appliance_Thing_a01e373b`.

1. Escolha **Assinar um tópico**.

# O SDK para aplicações do AWS Panorama
<a name="applications-panoramasdk"></a>

O SDK para aplicações do AWS Panorama é uma biblioteca Python para o desenvolvimento de aplicações do AWS Panorama. No [código da sua aplicação](gettingstarted-sample.md), você usa o SDK para aplicações do AWS Panorama para carregar um modelo de visão computacional, executar inferência e enviar vídeo para um monitor.

**nota**  
Para garantir que você tenha acesso às funcionalidades mais recentes do SDK para aplicações do AWS Panorama, [atualize o software do dispositivo](appliance-manage.md#appliance-manage-software).

Para obter detalhes sobre as classes que o SDK para aplicações define e seus métodos, consulte a [Referência do SDK para aplicações](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/applicationsdk-reference.md).

**Topics**
+ [Adição de texto e caixas à saída de vídeo](#applications-panoramasdk-overlays)

## Adição de texto e caixas à saída de vídeo
<a name="applications-panoramasdk-overlays"></a>

Com o SDK do AWS Panorama, você pode enviar um stream de vídeo para um monitor. O vídeo pode incluir texto e caixas que mostram a saída do modelo, o estado atual da aplicação ou outros dados.

Cada objeto na matriz `video_in` é uma imagem de um stream de câmera conectado ao dispositivo. O tipo desse objeto é `panoramasdk.media`. Ele tem métodos para adicionar texto e caixas retangulares à imagem, que você pode então atribuir à matriz `video_out`.

No exemplo a seguir, a aplicação de exemplo adiciona um rótulo para cada um dos resultados. Cada resultado é posicionado na mesma posição à esquerda, mas em alturas diferentes.

```
        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 adicionar uma caixa à imagem de saída, use `add_rect`. Esse método usa 4 valores entre 0 e 1, indicando a posição dos cantos superior esquerdo e inferior direito da caixa.

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

# Execução de vários threads
<a name="applications-threading"></a>

Você pode executar a lógica da aplicação em um thread de processamento e usar outros thread para outros processos em segundo plano. Por exemplo, você pode criar um encadeamento que [veicule tráfego HTTP](applications-ports.md) para depuração ou um encadeamento que monitore os resultados da inferência e envie dados para. AWS

Para executar vários threads, use o [módulo de thread](https://docs.python.org/3/library/threading.html) da biblioteca padrão do Python para criar um thread para cada processo. O exemplo a seguir mostra o loop principal da aplicação de exemplo do servidor de depuração, que cria um objeto de aplicação e o usa para executar três 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): loop 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.')
```

Quando todos os threads são encerrados, a aplicação se reinicia sozinha. O loop `run_cv` processa imagens de streams de câmera. Se ele receber um sinal para parar, ele desliga o processo do depurador, que executa um servidor HTTP e não consegue se desligar sozinho. Cada thread deve lidar com seus próprios erros. Se um erro não for detectado e registrado em log, o thread será encerrado 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): Loop de processamento**  

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

Os threads se comunicam por meio do objeto `self` da aplicação. Para reiniciar o loop de processamento da aplicação, o thread do depurador chama o método `stop`. Esse método define um atributo `terminate` que sinaliza que os outros threads sejam encerrados.

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



# Fornecimento de tráfego de entrada
<a name="applications-ports"></a>

Você pode monitorar ou depurar aplicações localmente executando um servidor HTTP junto com o código da aplicação. Para fornecer tráfego externo, mapeie as portas no AWS Panorama Appliance para portas no contêiner do sua aplicação.

**Importante**  
Por padrão, o AWS Panorama Appliance não aceita tráfego de entrada em nenhuma porta. A abertura de portas no dispositivo tem um risco de segurança implícito. Ao usar esse atributo, você deve tomar medidas adicionais para [proteger seu dispositivo contra tráfego externo](appliance-network.md) e proteger as comunicações entre clientes autorizados e o dispositivo.  
O código de exemplo incluído neste guia serve para fins de demonstração e não implementa autenticação, autorização ou criptografia.

Você pode abrir portas na faixa de 8.000 a 9.000 no dispositivo. Essas portas, quando abertas, podem receber tráfego de qualquer cliente roteável. Ao implantar sua aplicação, você especifica quais portas abrir e mapeia as portas do dispositivo para as portas do contêiner da aplicação. O software do dispositivo encaminha o tráfego para o contêiner e envia as respostas de volta ao solicitante. As solicitações são recebidas na porta do dispositivo que você especificar, e as respostas são enviadas em uma porta efêmera aleatória.

## Configuração de portas de entrada
<a name="applications-ports-configuration"></a>

Você especifica mapeamentos de portas em três locais na configuração da sua aplicação. No pacote de código `package.json`, você especifica a porta que o nó de código escuta em um bloco `network`. O exemplo a seguir declara que o nó escuta na porta 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"
                        }
                    ]
                }
```

No manifesto da aplicação, você declara uma regra de roteamento que mapeia uma porta no dispositivo para uma porta no contêiner de código da aplicação. O exemplo a seguir adiciona uma regra que mapeia a porta 8080 no dispositivo para a porta 80 no contêiner `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."
                }
            }
        ]
```

Ao implantar o aplicativo, você especifica as mesmas regras no console do AWS Panorama ou com um documento de substituição passado para a [CreateApplicationInstance](https://docs.aws.amazon.com/panorama/latest/api/API_CreateApplicationInstance.html)API. Você deve fornecer essa configuração no momento da implantação para confirmar que deseja abrir portas no 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"
    }
}
```

Se a porta do dispositivo especificada no manifesto da aplicação estiver sendo usada por outra aplicação, você poderá usar o documento de substituição para escolher uma porta diferente.

## Fornecimento de tráfego
<a name="applications-ports-serverthread"></a>

Com as portas abertas no contêiner, você pode abrir um soquete ou executar um servidor para processar as solicitações recebidas. O exemplo `debug-server` mostra uma implementação básica de um servidor HTTP em execução junto com o código da aplicação de visão computacional.

**Importante**  
A implementação de exemplo não é segura para uso em produção. Para evitar tornar seu dispositivo vulnerável a ataques, você deve implementar controles de segurança apropriados em seu código e na configuração de rede.

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

O servidor aceita solicitações GET no caminho `/status` para recuperar algumas informações sobre a aplicação. Ele também aceita uma solicitação POST para `/restart` para reiniciar a aplicação.

Para demonstrar essa funcionalidade, a aplicação de exemplo executa um cliente HTTP em um thread separado. O cliente chama o caminho `/status` pela rede local logo após a inicialização e reinicia a aplicação alguns minutos depois.

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

O loop principal gerencia os threads e reinicia a aplicação quando eles saem.

**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): loop 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 implantar o aplicativo de amostra, consulte as [instruções no GitHub repositório deste guia](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/README.md).

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

Você pode acessar o processador gráfico (GPU) no AWS Panorama Appliance para usar bibliotecas aceleradas por GPU ou executar modelos de machine learning no código da sua aplicação. Para ativar o acesso à GPU, adicione o acesso à GPU como requisito na configuração do pacote depois de criar o contêiner de código da aplicação.

**Importante**  
Se você habilitar o acesso à GPU, não poderá executar nós de modelo em nenhuma aplicação no dispositivo. Por motivos de segurança, o acesso à GPU é restrito quando o equipamento executa um modelo compilado com o SageMaker AI Neo. Com o acesso à GPU, você deve executar seus modelos nos nós de código da aplicação, e todas as aplicações no dispositivo compartilham o acesso à GPU.

Para ativar o acesso à GPU para sua aplicação, atualize a [configuração do pacote](applications-packages.md) depois de criar o pacote com a CLI da aplicação do AWS Panorama. O exemplo a seguir mostra o bloco `requirements` que adiciona acesso à GPU ao nó do código da aplicação.

**Example package.json com bloco 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": [
        ...
```

Atualize a configuração do pacote entre as etapas de compilação e empacotamento em seu fluxo de trabalho de desenvolvimento.

**Para implantar uma aplicação com acesso à GPU**

1. Para criar o contêiner da aplicação, use o comando `build-container`.

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

1. Adicione o bloco `requirements` à configuração do pacote.

1. Para carregar o ativo do contêiner e a configuração do pacote, use o comando `package-application`.

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

1. Implante o aplicativo .

Para exemplos de aplicativos que usam acesso à GPU, visite o [aws-panorama-samples](https://github.com/aws-samples/aws-panorama-samples) GitHub repositório.

# Configurar um ambiente de desenvolvimento no Windows
<a name="applications-devenvwindows"></a>

Para criar uma aplicação do AWS Panorama, você usa o Docker, ferramentas de linha de comando e Python. No Windows, você pode configurar um ambiente de desenvolvimento usando o Docker Desktop com o Subsistema do Windows para Linux e Ubuntu. Este tutorial mostra o processo de configuração de um ambiente de desenvolvimento que foi testado com ferramentas e aplicações de exemplo do AWS Panorama.

**Topics**
+ [Pré-requisitos](#applications-devenvwindows-prerequisites)
+ [Instalação do WSL 2 e do Ubuntu](#applications-devenvwindows-wsl2)
+ [Instalar o Docker](#applications-devenvwindows-docker)
+ [Configuração do Ubuntu](#applications-devenvwindows-ubuntu)
+ [Próximas etapas](#applications-devenvwindows-nextsteps)

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

Para seguir este tutorial, você precisa de uma versão do Windows que ofereça suporte ao Subsistema do Windows para Linux 2 (WSL 2).

****
+ Windows 10 versão 1903 e superior (compilação 18362 e superior) ou Windows 11
+ Atributos do Windows
  + Subsistema Windows para Linux
  + Hyper-V
  + Plataforma de máquina virtual

Este tutorial foi desenvolvido com as seguintes versões de software.

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

## Instalação do WSL 2 e do Ubuntu
<a name="applications-devenvwindows-wsl2"></a>

Se você tiver o Windows 10 versão 2004 e superior (compilação 19041 e superior), poderá instalar o WSL 2 e o Ubuntu 20.04 com o comando a seguir. PowerShell 

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

Para versões mais antigas do Windows, siga as instruções na documentação do WSL 2: [Etapas de instalação manual para versões mais antigas](https://docs.microsoft.com/en-us/windows/wsl/install-manual)

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

Para instalar o Docker Desktop, baixe e execute o pacote do instalador em [hub.docker.com](https://hub.docker.com/editions/community/docker-ce-desktop-windows/). Se você encontrar problemas, siga as instruções no site do Docker: [Docker Desktop WSL 2 backend](https://docs.docker.com/desktop/windows/wsl/).

Execute o Docker Desktop e siga o tutorial de primeira execução para criar um contêiner de exemplo.

**nota**  
O Docker Desktop só ativa o Docker na distribuição padrão. Se você tiver outras distribuições Linux instaladas antes de executar este tutorial, habilite o Docker na distribuição Ubuntu recém-instalada no menu de configurações do Docker Desktop em **Resources**, **WSL integration**.

## Configuração do Ubuntu
<a name="applications-devenvwindows-ubuntu"></a>

Agora você pode executar comandos do Docker na sua máquina virtual Ubuntu. Para abrir um terminal de linha de comando, execute a distribuição no menu Iniciar. Na primeira execução, configure um nome de usuário e uma senha que podem ser usados para executar comandos do administrador.

Para concluir a configuração do seu ambiente de desenvolvimento, atualize o software da máquina virtual e instale as ferramentas.

**Para configurar a máquina virtual**

1. Atualize o software que vem com o Ubuntu.

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

1. Instale ferramentas de desenvolvimento com apt.

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

1. Instale as bibliotecas Python com o pip.

   ```
   $ pip3 install awscli panoramacli
   ```

1. Abra um novo terminal e, em seguida, execute `aws configure` para configurar a AWS CLI.

   ```
   $ aws configure
   ```

   Se não tiver chaves de acesso, você poderá criá-las no [console do IAM](https://console.aws.amazon.com/iamv2/home?#/users).

Por fim, baixe e importe a aplicação de exemplo.

**Para obter a aplicação de exemplo**

1. Faça o download e extraia a aplicação de exemplo.

   ```
   $ 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. Execute os scripts incluídos para testar a compilação, criar o contêiner da aplicação e fazer upload de pacotes para o 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
   ```

A CLI da aplicação do AWS Panorama carrega pacotes e os registra no serviço AWS Panorama. Agora você pode [implantar a aplicação de exemplo](gettingstarted-deploy.md#gettingstarted-deploy-deploy) com o console do AWS Panorama.

## Próximas etapas
<a name="applications-devenvwindows-nextsteps"></a>

Para explorar e editar os arquivos do projeto, você pode usar o Explorador de arquivos ou um ambiente de desenvolvimento integrado (IDE) que suporte WSL.

Para acessar o sistema de arquivos da máquina virtual, abra o Explorador de arquivos e digite `\\wsl$` na barra de navegação. Esse diretório contém um link para o sistema de arquivos da máquina virtual (`Ubuntu-20.04`) e sistemas de arquivos para os dados do Docker. Em `Ubuntu-20.04`, seu diretório de usuários está em `home\username`.

**nota**  
Para acessar arquivos em sua instalação do Windows a partir do Ubuntu, navegue até o diretório `/mnt/c`. Por exemplo, você pode listar arquivos em seu diretório de downloads executando `ls /mnt/c/Users/windows-username/Downloads`.

Com o Visual Studio Code, você pode editar o código da aplicação em seu ambiente de desenvolvimento e executar comandos com um terminal integrado. Para instalar o Visual Studio Code, visite [code.visualstudio.com](https://code.visualstudio.com/). Após a instalação, adicione a extensão [Remote WSL.](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl)

O Windows Terminal é uma alternativa ao terminal padrão do Ubuntu no qual você está executando comandos. Ele suporta várias guias e pode ser executado PowerShell, prompt de comando e terminais para qualquer outra variedade de Linux que você instalar. Ele suporta copiar e colar com  Ctrl C  e Ctrl V , clicável URLs e outras melhorias úteis. Para instalar o Windows Terminal, visite [microsoft.com](https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701).