

サポート終了通知: 2026 年 5 月 31 日、 AWS は のサポートを終了します AWS Panorama。2026 年 5 月 31 日以降、 AWS Panorama コンソールまたは AWS Panorama リソースにアクセスできなくなります。詳細については、[AWS Panorama 「サポート終了](https://docs.aws.amazon.com/panorama/latest/dev/panorama-end-of-support.html)」を参照してください。

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# AWS Panorama アプリケーションの構築
<a name="panorama-development"></a>

アプリケーションは AWS Panorama アプライアンスで実行され、ビデオストリームでコンピュータビジョンタスクを実行します。Python コードと機械学習モデルを組み合わせてコンピュータビジョンアプリケーションを構築し、インターネット経由で AWS Panorama アプライアンスにデプロイできます。アプリケーションはディスプレイに動画を送信したり、AWS SDK を使用して結果を AWS のサービスに送信したりできます。

[モデル](applications-models.md) は画像を分析して人物、車両、その他の物体を検出します。トレーニング中に見た画像に基づいて、モデルはそれが何だと思っているか、その推測にどの程度自信があるのかを教えてくれます。独自の画像データを使用してモデルをトレーニングすることも、サンプルから始めることもできます。

アプリケーションの [コード](gettingstarted-sample.md) は、カメラストリームからの静止画像を処理してモデルに送信し、結果を処理します。モデルは複数のオブジェクトを検出し、その形状と位置を返す場合があります。コードはこの情報を使用してビデオにテキストやグラフィックを追加したり、結果を AWS サービスに送信して保存したり、さらなる処理を行うことができます。

ストリームからイメージを取得し、モデルを操作し、ビデオを出力するために、アプリケーションコードは [AWS Panorama Application SDK](applications-panoramasdk.md) を使用します。アプリケーション SDK は PyTorch、Apache MXNet、TensorFlow で生成されたモデルをサポートする Python ライブラリです。

**Topics**
+ [コンピュータービジョンモデル](applications-models.md)
+ [アプリケーションイメージを構築する](applications-image.md)
+ [アプリケーションコードから AWS サービスを呼び出す](applications-awssdk.md)
+ [AWS Panorama アプリケーション SDK](applications-panoramasdk.md)
+ [複数のスレッドの実行](applications-threading.md)
+ [インバウンドトラフィックへの対応](applications-ports.md)
+ [GPU を使用する](applications-gpuaccess.md)
+ [Windows 開発環境でのセットアップ](applications-devenvwindows.md)

# コンピュータービジョンモデル
<a name="applications-models"></a>

コンピュータビジョンモデルは、画像内のオブジェクトを検出するようにトレーニングされたソフトウェアプログラムです。モデルは、最初にトレーニングを通じてそれらのオブジェクトの画像を分析することで、一連のオブジェクトを認識することを学習します。コンピュータビジョンモデルは、画像を入力として受け取り、検出したオブジェクトに関する情報 (オブジェクトのタイプや位置など) を出力します。AWS Panorama は PyTorch、Apache MXNet、TensorFlow で構築されたコンピュータビジョンモデルをサポートしています。

**注記**  
AWS Panorama でテストされたビルド済みモデルのリストについては、[「モデルの互換性」](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/model-compatibility.md)を参照してください。

**Topics**
+ [コード内でのモデルの使用](#applications-models-using)
+ [カスタムモデルの構築](#applications-models-custom)
+ [モデルのパッケージ化](#applications-models-package)
+ [モデルのトレーニング](#applications-models-training)

## コード内でのモデルの使用
<a name="applications-models-using"></a>

モデルは 1 つ以上の結果を返します。これには、検出されたクラスの確率、位置情報、その他のデータが含まれる場合があります。次の例は、ビデオストリームの画像に対して推論を実行し、モデルの出力を処理関数に送信する方法を示しています。

**Example [アプリケーション.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/application.py) — 推論**  

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

次の例は、基本分類モデルから結果を処理する関数を示しています。サンプルモデルは確率の配列を返します。これは結果配列の最初で唯一の値です。

**Example [アプリケーション.py](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/aws-panorama-sample/packages/123456789012-SAMPLE_CODE-1.0/application.py) — 処理結果**  

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

アプリケーションコードは確率が最も高い値を見つけて、初期化時に読み込まれるリソースファイル内のラベルにマッピングします。

## カスタムモデルの構築
<a name="applications-models-custom"></a>

PyTorch、Apache MXNet、TensorFlow で構築したモデルを AWS Panorama アプリケーションで使用できます。SageMaker AI でモデルを構築およびトレーニングする代わりに、トレーニング済みモデルを使用するか、サポートされているフレームワークを使用して独自のモデルを構築およびトレーニングし、ローカル環境または Amazon EC2 にエクスポートできます。

**注記**  
SageMaker AI Neo でサポートされているフレームワークのバージョンとファイル形式の詳細については、Amazon SageMakerデベロッパーガイド[」の「サポートされているフレームワーク](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-supported-devices-edge-frameworks.html)」を参照してください。

このガイドのリポジトリには、TensorFlow `SavedModel`形式の Keras モデルのこのワークフローを示すサンプルアプリケーションが用意されています。TensorFlow 2 を使用しており、仮想環境でローカルに実行することも、Docker コンテナで実行することもできます。サンプルアプリケーションには、Amazon EC2 インスタンスでモデルを構築するためのテンプレートとスクリプトも含まれています。

****
+ [カスタムモデルサンプルアプリケーション](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/custom-model)

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


AWS Panorama は SageMaker AI Neo を使用して、AWS Panorama アプライアンスで使用するモデルをコンパイルします。フレームワークごとに、[SageMaker AI Neo でサポートされている形式](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-compilation-preparing-model.html)を使用し、モデルを`.tar.gz`アーカイブにパッケージ化します。

詳細については、Amazon SageMaker [SageMaker AI デベロッパーガイド」の「Neo でモデルをコンパイルしてデプロイ](https://docs.aws.amazon.com/sagemaker/latest/dg/neo.html)する」を参照してください。

## モデルのパッケージ化
<a name="applications-models-package"></a>

モデルパッケージは、記述子、パッケージ構成、モデルアーカイブで構成されます。[アプリケーションイメージパッケージ](applications-image.md)と同様に、パッケージ構成は、モデルと記述子が Amazon S3 のどこに保存されているかを AWS Panorama サービスに伝えます。

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

**注記**  
フレームワークバージョンのメジャーバージョンとマイナーバージョンのみを指定してください。サポートされている PyTorch、Apache MXNet、および TensorFlow バージョンのリストについては、[「サポートされているフレームワーク」](https://docs.aws.amazon.com/sagemaker/latest/dg/neo-supported-devices-edge-frameworks.html)を参照してください。

モデルをインポートするには、AWS Panorama アプリケーション CLI `import-raw-model` コマンドを使用します。モデルやその記述子に変更を加えた場合は、このコマンドを再実行してアプリケーションのアセットを更新する必要があります。詳細については、「[コンピュータービジョンモデルの変更](gettingstarted-sample.md#gettingstarted-sample-model)」を参照してください。

ディスクリプターファイルの JSON スキーマについては、[「AssetDescriptor.schema.json」](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/manifest-schema/ver_2021-01-01/assetDescriptor.schema.json)を参照してください。

## モデルのトレーニング
<a name="applications-models-training"></a>

モデルをトレーニングするときは、ターゲット環境、またはターゲット環境によく似たテスト環境のイメージを使用してください。モデルのパフォーマンスに影響を与える可能性がある以下の要因を考慮してください。

****
+ **照明** — 被写体が反射する光の量によって、モデルがどの程度詳細に分析しなければならないかが決まります。明るい被写体の画像でトレーニングしたモデルは、暗い場所や逆光の環境ではうまく機能しない可能性があります。
+ **解像度** — モデルの入力サイズは、通常、幅 224 ～ 512 ピクセル (縦横比) の解像度に固定されます。ビデオのフレームをモデルに渡す前に、必要なサイズに合うように縮小またはトリミングできます。
+ **画像のゆがみ** — カメラの焦点距離とレンズの形状により、画像がフレームの中心から離れるにつれて歪みが生じることがあります。また、カメラの位置によって、被写体のどの部分が見えるかが決まります。たとえば、広角レンズを搭載したオーバーヘッドカメラでは、被写体がフレームの中央にあるときは被写体の上部が表示され、中心から遠ざかるにつれて被写体の側面が歪んで表示されます。

このような問題に対処するには、画像をモデルに送る前に前処理を行い、実世界の環境の変化を反映するさまざまな画像でモデルをトレーニングできます。照明環境やさまざまなカメラでモデルを動作させる必要がある場合は、トレーニングのためにより多くのデータが必要になります。より多くの画像を収集するだけでなく、歪んだ画像や照明が異なる既存の画像のバリエーションを作成することで、より多くのトレーニングデータを取得できます。

# アプリケーションイメージを構築する
<a name="applications-image"></a>

AWS Panorama アプライアンス は、構築したイメージからエクスポートされたコンテナファイルシステムとしてアプリケーションを実行します。アプリケーションの依存関係とリソースは、AWS Panorama アプリケーションのベースイメージを開始点として使用する Dockerfile で指定します。

アプリケーションイメージを構築するには、Docker と AWS Panorama アプリケーション CLI を使用します。このガイドのサンプルアプリケーションの次の例は、これらのユースケースを示しています。

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

次の Dockerfile 指示を使用します。

****
+ `FROM` — アプリケーションベースイメージ (`public.ecr.aws/panorama/panorama-application`) をロードします。
+ `WORKDIR` — イメージに作業ディレクトリを設定します。 `/panorama` はアプリケーションコードおよび関連ファイルに使用されます。この設定は構築中のみ保持され、ランタイム (`/`) のアプリケーションの作業ディレクトリには影響しません。
+ `COPY` — ファイルをローカルパスからイメージ上のパスにコピーします。`COPY . .` は現在のディレクトリ (パッケージディレクトリ) のファイルをイメージ上の作業ディレクトリにコピーします。たとえば、アプリケーションコードは `packages/123456789012-SAMPLE_CODE-1.0/application.py` から `/panorama/application.py` にコピーされます。
+ `RUN` — 構築中にイメージ上でシェルコマンドを実行します。コマンド間に `&&` を使用することで、1回の `RUN` 操作で複数のコマンドを順番に実行することができます。この例では、`pip` パッケージマネージャーを更新し、`requirements.txt` に記載されているライブラリをインストールします。

`ADD` や `ARG` など、構築時に役立つ他の指示も使用できます。`ENV` のような、ランタイム情報をコンテナに追加する指示は、AWS Panorama では機能しません。AWS Panorama はイメージからコンテナを実行しません。イメージを使用してファイルシステムをエクスポートし、アプライアンスに転送するだけです。

## 依存関係の指定
<a name="applications-image-dependencies"></a>

`requirements.txt` は、アプリケーションが使用するライブラリを指定する Python 要件ファイルです。サンプルアプリケーションは Open CV と AWS SDK for 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.*
```

Dockerfile の `pip install` コマンドは、これらのライブラリを `/usr/local/lib` の Python `dist-packages` ディレクトリにインストールし、アプリケーションコードでインポートできるようにします。

## ローカルストレージ
<a name="applications-image-storage"></a>

AWS Panorama はアプリケーションストレージ用の `/opt/aws/panorama/storage` ディレクトリを確保します。アプリケーションはこのパスでファイルを作成および変更できます。ストレージディレクトリに作成されたファイルは、再起動しても保持されます。他の一時ファイルの場所は起動時にクリアされます。

## イメージアセットの構築
<a name="applications-image-build"></a>

AWS Panorama Application CLI でアプリケーションパッケージのイメージを構築すると、CLI はパッケージディレクトリで `docker build` を実行します。これにより、アプリケーションコードを含むアプリケーションイメージが構築されます。次に、CLI はコンテナを作成し、そのファイルシステムをエクスポートして圧縮し、`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
```

出力の JSON ブロックは、CLI がパッケージ設定 (`package.json`) に追加して AWS Panorama サービスに登録するアセット定義です。CLI は、アプリケーションスクリプト (アプリケーションのエントリポイント) へのパスを指定する記述子ファイルもコピーします。

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

アセットフォルダーでは、記述子とアプリケーションイメージには SHA-256 チェックサムにちなんだ名前が付けられています。この名前は、アセットが Amazon S3 に保存されるときに、アセットの一意の識別子として使用されます。

# アプリケーションコードから AWS サービスを呼び出す
<a name="applications-awssdk"></a>

を使用して AWS SDK for Python (Boto) 、アプリケーションコードから AWS サービスを呼び出すことができます。たとえば、モデルが異常を検出した場合、Amazon CloudWatch にメトリクスを投稿したり、Amazon SNS で通知を送信したり、イメージを Amazon S3 に保存したり、Lambda 関数を呼び出してさらに処理したりすることができます。ほとんどの AWS サービスには、AWS SDK で使用できるパブリック API があります。

デフォルトでは、アプライアンスには AWS サービスへのアクセス権限がありません。アクセス権限を付与するには、[アプリケーションのロールを作成し](permissions-application.md)、デプロイ時にアプリケーションインスタンスに割り当てます。

**Topics**
+ [Amazon S3 の使用](#applications-awssdk-s3)
+ [AWS IoT MQTT トピックの使用](#monitoring-messagestream)

## Amazon S3 の使用
<a name="applications-awssdk-s3"></a>

Amazon S3 を使用して処理結果やその他のアプリケーションデータを保存できます。

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

## AWS IoT MQTT トピックの使用
<a name="monitoring-messagestream"></a>

SDK for Python (Boto3) を使用して、 AWS IoTの [MQTT トピック](https://docs.aws.amazon.com/iot/latest/developerguide/topics.html)にメッセージを送信できます。次の例では、アプリケーションは [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")
```

デバイス ID または任意のその他の識別子を示す名前を選択します。メッセージを公開するには、アプリケーションに `iot:Publish` を呼び出す権限が必要です。

**MQTT キューをモニタリングするには**

1. [AWS IoT コンソールの Test (テスト) ページ](https://console.aws.amazon.com/iot/home?region=us-east-1#/test)を開きます。

1. **サブスクリプショントピック**に、トピック名を入力します。例えば、`panorama/panorama_my-appliance_Thing_a01e373b` と指定します。

1. **トピックに登録する** を選択します。

# AWS Panorama アプリケーション SDK
<a name="applications-panoramasdk"></a>

AWS Panorama アプリケーション SDK は、AWS Panorama アプリケーションを開発するための Python ライブラリです。[アプリケーションコード](gettingstarted-sample.md)では、AWS Panorama アプリケーション SDK を使用してコンピュータビジョンモデルをロードし、推論を実行し、ビデオをモニタに出力します。

**注記**  
AWS Panorama アプリケーション SDK の最新機能にアクセスできるようにするには、[アプライアンスソフトウェアをアップグレード](appliance-manage.md#appliance-manage-software)してください。

アプリケーション SDK が定義するクラスとそのメソッドの詳細については、[「アプリケーション SDK リファレンス」](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/resources/applicationsdk-reference.md)を参照してください。

**Topics**
+ [出力ビデオへのテキストとボックスの追加](#applications-panoramasdk-overlays)

## 出力ビデオへのテキストとボックスの追加
<a name="applications-panoramasdk-overlays"></a>

AWS Panorama SDK を使用すると、ビデオストリームをディスプレイに出力できます。動画には、モデルからの出力、アプリケーションの現在の状態、またはその他のデータを表示するテキストやボックスを含めることができます。

`video_in` 配列内の各オブジェクトは、アプライアンスに接続されたカメラストリームからの画像です。このオブジェクトのタイプは `panoramasdk.media` です。画像にテキストや長方形のボックスを追加して、`video_out` 配列に割り当てるメソッドがあります。

次の例で、サンプルアプリケーションは結果ごとに 1 つのラベルを追加します。各結果は同じ左位置に配置されますが、高さは異なります。

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

出力イメージにボックスを追加するには、`add_rect` を使用します。このメソッドは、ボックスの左上隅と右下隅の位置を示す 0 から 1 までの値を 4 つ取ります。

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

# 複数のスレッドの実行
<a name="applications-threading"></a>

アプリケーションロジックを処理スレッドで実行し、他のスレッドを他のバックグラウンドプロセスに使用することができます。例えば、デバッグのために [HTTP トラフィックを処理する](applications-ports.md)スレッドや、推論結果をモニタリングしてデータを送信するスレッドを作成できます AWS。

複数のスレッドを実行するには、Python 標準ライブラリの[スレッディングモジュール](https://docs.python.org/3/library/threading.html)を使用して、プロセスごとにスレッドを作成します。次の例は、アプリケーションオブジェクトを作成し、それを使用して 3 つのスレッドを実行するデバッグサーバーのサンプルアプリケーションのメインループを示しています。

**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) — メインループ**  

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

すべてのスレッドが終了すると、アプリケーションは自動的に再起動します。`run_cv` ループはカメラストリームからの画像を処理します。停止のシグナルを受け取ると、デバッガープロセスをシャットダウンします。デバッガープロセスは HTTP サーバーを実行していますが、それ自体をシャットダウンすることはできません。各スレッドは独自のエラーを処理する必要があります。エラーが捕捉されログに記録されない場合、スレッドは静かに終了します。

**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) — 処理ループ**  

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

スレッドはアプリケーションの `self` オブジェクトを介して通信します。アプリケーション処理ループを再開するには、デバッガースレッドが `stop` メソッドを呼び出します。このメソッドは、ほかのスレッドにシャットダウンを知らせる`terminate` 属性を設定します。

**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) — 停止メソッド**  

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



# インバウンドトラフィックへの対応
<a name="applications-ports"></a>

アプリケーションコードと一緒に HTTP サーバーを実行することで、アプリケーションをローカルでモニタリングまたはデバッグできます。外部トラフィックを処理するには、AWS Panorama アプライアンスのポートをアプリケーションコンテナのポートにマッピングします。

**重要**  
デフォルトでは、AWS Panorama アプライアンスはどのポートでも着信トラフィックを受け付けません。アプライアンスのポートを開くことには、暗黙のセキュリティリスクがあります。この機能を使用するときは、[外部トラフィックからアプライアンスを保護](appliance-network.md)し、許可されたクライアントとアプライアンス間の通信を保護するための追加措置を講じる必要があります。  
このガイドに含まれるサンプルコードはデモンストレーションを目的としており、認証、認可、暗号化は実装されていません。

アプライアンスでは 8000 ～ 9000 の範囲のポートを開くことができます。これらのポートを開くと、ルーティング可能なすべてのクライアントからのトラフィックを受信できます。アプリケーションをデプロイするときは、開くポートを指定し、アプライアンス上のポートをアプリケーションコンテナのポートにマッピングします。アプライアンスソフトウェアはトラフィックをコンテナに転送し、要求者に応答を送り返します。リクエストは指定したアプライアンスポートで受信され、応答はランダムなエフェメラルポートに送信されます。

## インバウンドポートの設定
<a name="applications-ports-configuration"></a>

ポートマッピングはアプリケーション設定の 3 つの場所で指定します。コードパッケージの `package.json` では、コードノードがリッスンするポートを `network` ブロック内で指定します。次の例では、ノードがポート 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"
                        }
                    ]
                }
```

アプリケーションマニフェストでは、アプライアンスのポートをアプリケーションのコードコンテナのポートにマップするルーティングルールを宣言します。次の例では、デバイスのポート 8080 を `code_node` コンテナのポート 80 にマッピングするルールを追加します。

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

アプリケーションをデプロイするときは、AWS Panorama コンソールで同じルールを指定するか、[CreateApplicationInstance](https://docs.aws.amazon.com/panorama/latest/api/API_CreateApplicationInstance.html) API に渡されるオーバーライドドキュメントを使用して指定します。アプライアンスでポートを開きたいことを確認するために、デプロイ時にこの設定を提供する必要があります。

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

アプリケーションマニフェストで指定されているデバイスポートが別のアプリケーションで使用されている場合は、オーバーライドドキュメントを使用して別のポートを選択できます。

## トラフィックを処理する
<a name="applications-ports-serverthread"></a>

コンテナのポートが開いていると、ソケットを開いたり、サーバーを実行して受信リクエストを処理したりできます。この `debug-server` サンプルは、コンピュータービジョンのアプリケーションコードと一緒に稼働する HTTP サーバーの基本的な実装を示しています。

**重要**  
このサンプル実装は、実稼働環境では安全ではありません。アプライアンスが攻撃に対して脆弱にならないようにするには、コードとネットワーク構成に適切なセキュリティ制御を実装する必要があります。

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

サーバーは `/status` パスで GET リクエストを受け付けて、アプリケーションに関する情報を取得します。また、アプリケーションを再起動するための `/restart` への POST リクエストも受け付けます。

この機能を実証するために、サンプルアプリケーションは別のスレッドで HTTP クライアントを実行します。クライアントは起動後すぐにローカルネットワーク経由で `/status` パスを呼び出し、数分後にアプリケーションを再起動します。

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

メインループはスレッドを管理し、終了時にアプリケーションを再起動します。

**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) — メインループ**  

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

サンプルアプリケーションをデプロイするには、[このガイドの GitHub リポジトリにある「手順](https://github.com/awsdocs/aws-panorama-developer-guide/blob/main/sample-apps/debug-server/README.md)」を参照してください。

# GPU を使用する
<a name="applications-gpuaccess"></a>

AWS Panorama アプライアンス のグラフィックプロセッサ (GPU) にアクセスして GPU アクセラレーションライブラリを使用したり、アプリケーションコードで機械学習モデルを実行したりできます。GPU アクセスを有効にするには、アプリケーションコードコンテナを構築した後に、パッケージ設定に GPU アクセスを要件として追加します。

**重要**  
GPU アクセスを有効にすると、アプライアンス上のどのアプリケーションでもモデルノードを実行できなくなります。セキュリティ上の理由から、アプライアンスが SageMaker AI Neo でコンパイルされたモデルを実行する場合、GPU アクセスは制限されます。GPU アクセスでは、モデルをアプリケーションコードノードで実行し、デバイス上のすべてのアプリケーションが GPU へのアクセスを共有する必要があります。

アプリケーションの GPU アクセスを有効にするには、AWS Panorama Application CLI [でパッケージを構築した後に パッケージ設定](applications-packages.md) を更新します。次の例は、GPU アクセスをアプリケーションコードノードに追加する `requirements` ブロックを示しています。

**Example 要件ブロックを含む package.json**  

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

開発ワークフローのビルドステップとパッケージングステップの間にパッケージ設定を更新します。

**GPU アクセスでアプリケーションをデプロイするには**

1. アプリケーションコンテナを構築するには、 `build-container` コマンドを使用します。

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

1. `requirements` ブロックをパッケージ設定に追加します。

1. コンテナアセットとパッケージ設定をアップロードするには、`package-application` コマンドを使用します。

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

1. アプリケーションをデプロイします。

GPU アクセスを使用するサンプルアプリケーションについては、[aws-panorama-samples](https://github.com/aws-samples/aws-panorama-samples) GitHub リポジトリをご覧ください。

# Windows 開発環境でのセットアップ
<a name="applications-devenvwindows"></a>

AWS Panorama アプリケーションを構築するには、Docker、コマンドラインツール、および Python を使用します。Windows では、Linux と Ubuntu 用の Docker デスクトップと Windows サブシステムを使用して開発環境をセットアップできます。このチュートリアルでは、AWS Panorama ツールとサンプルアプリケーションでテストされた開発環境の設定プロセスを順を追って説明します。

**Topics**
+ [前提条件](#applications-devenvwindows-prerequisites)
+ [WSL 2、Ubuntu でインストールする](#applications-devenvwindows-wsl2)
+ [Docker をインストールする](#applications-devenvwindows-docker)
+ [Ubuntu の設定](#applications-devenvwindows-ubuntu)
+ [次のステップ](#applications-devenvwindows-nextsteps)

## 前提条件
<a name="applications-devenvwindows-prerequisites"></a>

このチュートリアルに沿って作業するためには、Linux 2 用 Windows サブシステム (WSL 2) をサポートするバージョンの Windows が必要です。

****
+ Windows 10 バージョン 1903 以降 (ビルド 18362 以降) または Windows 11
+ Windows の機能
  + Windows Subsystem for Linux
  + Hyper-V
  + 仮想マシンのプラットフォーム

このチュートリアルは、次のソフトウェアバージョンで開発されました。

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

## WSL 2、Ubuntu でインストールする
<a name="applications-devenvwindows-wsl2"></a>

Windows 10 バージョン 2004 以降 (ビルド 19041 以降) をお使いの場合は、次の PowerShell コマンドを使用して WSL 2 と Ubuntu 20.04 をインストールできます。

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

古いバージョンの Windows の場合は、WSL 2 ドキュメントの指示に従ってください：[古いバージョンの手動インストール手順](https://docs.microsoft.com/en-us/windows/wsl/install-manual)

## Docker をインストールする
<a name="applications-devenvwindows-docker"></a>

Docker Desktop をインストールするには、[hub.docker.com](https://hub.docker.com/editions/community/docker-ce-desktop-windows/) からインストーラーパッケージをダウンロードして実行します。問題が発生した場合は、Docker ウェブサイトの「[Docker デスクトップ WSL 2 バックエンド](https://docs.docker.com/desktop/windows/wsl/)」に記載されている指示に従ってください。

Docker Desktop を実行し、初回実行のチュートリアルに従ってサンプルコンテナを構築します。

**注記**  
Docker Desktop はデフォルトのディストリビューションでのみ Docker を有効にします。このチュートリアルを実行する前に他の Linux ディストリビューションをインストールしていた場合は、**[リソース]**、**[WSL 統合]**の [Docker Desktop 設定] メニューで、新しくインストールした Ubuntu ディストリビューションで Docker を有効にしてください。

## Ubuntu の設定
<a name="applications-devenvwindows-ubuntu"></a>

これで Ubuntu 仮想マシンで Docker コマンドを実行できるようになりました。コマンドラインターミナルを開くには、スタートメニューからディストリビューションを実行します。初めて実行するときは、管理者コマンドの実行に使用できるユーザー名とパスワードを設定します。

開発環境の設定を完了するには、仮想マシンのソフトウェアを更新し、ツールをインストールします。

**仮想マシンを設定するには**

1. Ubuntu に付属するソフトウェアを更新します。

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

1. apt で開発ツールをインストールします。

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

1. pip で Python ライブラリをインストールします。

   ```
   $ pip3 install awscli panoramacli
   ```

1. 新しいターミナルを開き、`aws configure` を実行して AWS CLIを設定します。

   ```
   $ aws configure
   ```

   アクセスキーがない場合は、[IAM コンソール](https://console.aws.amazon.com/iamv2/home?#/users)で生成することができます。

最後に、サンプルアプリケーションをダウンロードしてインポートします。

**サンプルアプリケーションを入手する**

1. サンプルアプリケーションをダウンロードして解凍する。

   ```
   $ 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. 付属のスクリプトを実行して、コンパイルをテストし、アプリケーションコンテナを構築し、パッケージを 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
   ```

AWS Panorama アプリケーション CLI はパッケージをアップロードし、AWS Panorama サービスに登録します。これで、AWS Panorama コンソールで[サンプルアプリケーション](gettingstarted-deploy.md#gettingstarted-deploy-deploy)をデプロイできます。

## 次のステップ
<a name="applications-devenvwindows-nextsteps"></a>

プロジェクトファイルを確認して編集するには、ファイルエクスプローラーまたは WSL をサポートする統合開発環境 (IDE) を使用できます。

仮想マシンのファイルシステムにアクセスするには、ファイルエクスプローラーを開き、ナビゲーションバーに「 `\\wsl$` 」と入力します。このディレクトリには、仮想マシンのファイルシステム (`Ubuntu-20.04`) と Docker のデータ用のファイルシステムへのリンクが含まれています。`Ubuntu-20.04` の下、ユーザーディレクトリは `home\username` にあります。

**注記**  
Ubuntu 内から Windows インストール内のファイルにアクセスするには、`/mnt/c` ディレクトリに移動します。たとえば、`ls /mnt/c/Users/windows-username/Downloads` を実行することで、ダウンロードディレクトリにあるファイルを一覧表示できます。

Visual Studio Code では、開発環境でアプリケーションコードを編集し、統合ターミナルでコマンドを実行できます。Visual Studio Code をインストールするには、[code.visualstudio.com](https://code.visualstudio.com/) にアクセスしてください。インストール後、[リモート WSL](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl) 拡張機能を追加します。

Windows ターミナルは、これまでコマンドを実行してきた標準 Ubuntu ターミナルの代わりとなるものです。複数のタブをサポートし、PowerShell、コマンドプロンプト、およびインストールするその他のさまざまな Linux のターミナルを実行できます。 Ctrl C  や  Ctrl V  を使ったコピーアンドペースト、クリック可能な URL、その他の便利な機能強化をサポートしています。Windows ターミナルをインストールするには、[microsoft.com](https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701) にアクセスしてください。