Cato APIのPythonスクリプトの説明

Prev Next

この記事は、Cato APIを紹介し、サンプルのPythonアプリケーションを解析します。

はじめに

Cato APIは、仕様に基づいて実装されています。 GraphQLは使いやすいAPIを生成することを意図していますが、新しい技術を学ぶには開発者の時間の投資が必要です。 このドキュメントの目的は、投資のレベルを下げ、小規模なPythonアプリケーションを使用してadmins Cato API呼び出しを実行し、アカウントに定義されている管理者の数を返すことです。 その過程で、CatoのGraphQL APIアプリケーションの重要な要素を紹介します。

注意事項:

読者は、以下の基本的な理解を持っていることが期待されます:

  • スクリプトまたはプログラミング (例: 変数やコードライブラリなどの概念に慣れている場合)

  • JSON 仕様 (例: JSONドキュメントを扱ったことがある場合)

  • ネットワーク (例: HTTPプロトコルの存在とサーバーとは何かを知っている場合)

Python言語に関するある程度の経験があれば役立ちますが、これがなくても記事を理解することは可能です。

基本のCato APIアプリケーションのウォークスルー

ここで提示するアプリケーションはPythonで書かれており、Cato API admins呼び出しを使用して、アカウントに定義された管理者の総数を取得します。  Pythonとadmins API呼び出しは以下の理由で選ばれました:

  • Pythonは非常に一般的な言語で、読みやすく理解しやすいです

  • admins APIは、CatoのGraphQL APIを呼び出す非常にシンプルな例を作成するために使用できます

サンプルプログラムは基本的で、エラーチェックを含みません。  プログラムはアカウントに定義された管理者の総数を出力するだけです。 

注:

Cato APIは特定のプログラミング言語に依存していません。  HTTP POST機能とJSONドキュメントを処理できる言語を使用してアプリケーションを実装することが可能です。  

サンプルプログラムの概要

このサンプルプログラムは短く、意思決定ロジックや操作を繰り返すコードを含んでいません。  コードのいくつかの行を単一行にまとめることで、さらに短くすることも可能でした。  説明を円滑にするために、追加のコード行が含まれています。

# Pythonライブラリコードのインポート
import os
import urllib.request
import ssl
import json

# Cato APIキーを環境変数から取得
cato_api_key = os.getenv("CATO_API_KEY")

# 送信されるGraphQLリクエストの作成
get_total_admins = '''{
    admins (accountID: 12345) {
        total        
    }
}'''
graphql_query = {'query': get_total_admins}

# HTTPリクエストの構築
cato_api_url = "https://api.catonetworks.com/api/v1/graphql2"
headers = {'x-api-key': cato_api_key,
           'Content-Type':'application/json'}
unverified_ctx = ssl._create_unverified_context()
json_post = json.dumps(graphql_query)
json_post_encoded = json_post.encode()
request = urllib.request.Request(url=cato_api_url, data=json_post_encoded, headers=headers)

# クエリを送信し、レスポンスをPython辞書に変換
response = urllib.request.urlopen(request, context=unverified_ctx, timeout=30)
json_response_encoded = response.read()
json_response = json_response_encoded.decode()
get_admins_total_result = json.loads(json_response)

# 返されたデータから合計を抽出して出力
total = get_admins_total_result['data']['admins']['total']
print('アカウントに定義された管理者の総数: {}'.format(total))

重要!

このプログラムは、PythonでCato APIにアクセスする方法を示すためのデモンストレーションとして提供されています。 これは公式のCatoリリースではなく、サポートの保証はありません。 エラーハンドリングは、APIと連携するために必要最小限のものに限定されており、プロダクション環境には不十分かもしれません。

すべての質問やフィードバックは api@catonetworks.com に送信してください

以下に提供される図は、プログラムが実行されたときに起こる一連のイベントを示しています:

  1. プログラムはCato API GraphQLサーバーに送信されるJSONドキュメントを作成します。

  2. Cato API GraphQLサーバーは、JSONドキュメントに定義されたAPI呼び出しが正しいことを確認し、Catoサービスから要求されたデータを取得します。

  3. Cato API GraphQLサーバーはデータをJSONファイルでプログラムに返します。

Cato_API_FLow.jpeg

Pythonライブラリコードのインポート

例示プログラムでPythonを使用する理由の一つは、多くのライブラリが利用できることです。  これらのライブラリは、広範なタスクを処理できる関数とオブジェクトを提供します。  今から、各インポート済みライブラリを通過し、それが必要な理由を説明するためのノートを提供します。

import os
  • OSライブラリは、オペレーティングシステムの環境変数に含まれるデータにアクセスできる関数を提供します。

    import urllib.request
  • urllibライブラリのrequestモジュールは、URLを介してアクセスされるリモートサーバーとの通信を処理できるオブジェクトを作成するRequestクラスを定義します。

  • これにより、Cato APIのリクエストをCato GraphQL APIサーバーに送信することが可能になります。

    import ssl
  • SSLライブラリは、Cato GraphQL APIサーバーに送信されるリクエスト用のカスタム未確認コンテキストを作成するために必要です。

    import json
  • このライブラリには、Pythonの辞書をJSON文字列に変換すること、およびその逆を可能にする関数が含まれています。

  • 異なる形式間での変換が可能なため、JSONドキュメントと一緒に作業するコードを書くのが非常に簡単になります。

Cato APIキーを取得する

このコード行では、APIキーを環境変数から読み取り、変数に代入するためにgetenvライブラリ関数を使用しています。

cato_api_key = os.getenv("CATO_API_KEY")

Cato GraphQLサーバーは、このキーをHTTPヘッダーで受け取ることを期待しています。  このキーは、JSONドキュメントで提供されていません。なぜなら、GraphQL仕様には認証が標準として含まれていないからです。  JSONドキュメントに認証を含めることは、仕様の違反となります。  Cato APIキーは、Cato管理アプリケーションを通じて生成されます。  APIキーの作成についての詳細は、Generating API Keys for the Cato APIをご覧ください。

警告!

Cato APIキーをコードに直接記述することは可能でも、それはお勧めいたしません。

送信されるGraphQLリクエストの作成

次のコード行は、1つのキー/バリューペアを含むPythonディレクトリを作成します。  エントリーの値は、GraphQLサーバーに送信されるクエリを定義するためにPythonのマルチライン文字列を使用して作成されています。

get_total_admins = '''{
    admins (accountID: 12345) {
        total    
    }
}'''
graphql_query = {'query': get_total_admins}

Cato GraphQLサーバーは、この文字列を解釈して、get_total_admins関数を実行し、2つの引数(accountIDとタイプ)を渡し、「合計」エンティティ数のみを返します。  つまり、「サンプルアカウント #12345 に定義された管理者のエンティティ数を返します。」  admins API呼び出しのこの具体例は、GraphQL APIの重要な利点を示しています。

  • GraphQLサーバーは、アプリケーションが要求したデータのみを返します。

事実、このadmins呼び出しは、さらに多くのデータを返すことができます。  例えば、アプリケーションがそれぞれの管理者についての詳細を返すようにadminsに要求することが可能です。 しかし、このアプリケーションが必要とするのは管理者の総数のみです。  このGraphQLの特徴は、over-fetchingと呼ばれるものを回避し、アプリケーションを実装するためのコードを大幅に簡素化します。

HTTPリクエストの構築

このプログラムのセクションでは、リクエストオブジェクトが構築されます。  このオブジェクトは、GraphQLサーバーにHTTPSを使用してAPI呼び出しを送信するために使用されます。 このリクエストオブジェクトは、まず作成する必要がある他のいくつかのオブジェクトによって提供される情報を必要とします。  まず、リクエストオブジェクトがクエリを送信するGraphQLサーバーのURLを含むシンプルな文字列オブジェクトが構築されます。

cato_api_url = "https://api.catonetworks.com/api/v1/graphql2"

注意:

GraphQL APIは、すべてのAPI呼び出しに対して1つのURLのみを使用します。 呼び出しの詳細、例えば引数などはJSONドキュメントで提供されます。  これはREST APIとは対照的で、REST APIはそれぞれのAPI呼び出しに異なるURLを使用し、引数をURLに付加して呼び出しを行います。 1つのURLの使用は、GraphQL APIのもう一つの利点と考えられています。

次に、2つのHTTPヘッダーを定義する辞書が作成されます。  これらのヘッダーは、GraphQLサーバーが受け入れるHTTP POSTリクエストを構築するためにリクエストオブジェクトによって使用されます。  これらのヘッダーがなければ、HTTP POSTリクエストはサーバーによって拒否されます。

headers = {'x-api-key': cato_api_key,           
           'Content-Type':'application/json'}

次のコード行は、SSLコンテキストオブジェクトを作成します。 Pythonは、このオブジェクトを使用して、HTTPリクエストをどのように暗号化し、トランスポートレベルセキュリティ (TLS) を使用して送信するかを決定します。 ここで、証明書を検証しないSSLコンテキストオブジェクトを作成しています。 これは、上流のTLSインスペクションを受けるネットワークでの証明書エラーを避けるために行われました。

unverified_ctx = ssl._create_unverified_context()

重要!

未確認のSSLコンテキストオブジェクトを使用することは、証明書が有効であることを確認しないことを意味します。 Cato Networksでは、プロダクションではそのようなアプローチを決して使用しないように推奨しています。 セキュリティを強化する方法の詳細は、このドキュメントの範囲外です。

次の2行のコードは、Cato API呼び出しを含むPython辞書を文字列に変換し、その文字列をバイトにエンコードします。  この手順は、文字列をネットワーク上で送信できるようにするために必要です。

json_post = json.dumps(graphql_query)
json_post_encoded = json_post.encode()

最後に、リクエストオブジェクトが作成され、プログラムはサーバーにget_total_admins呼び出しを送信する準備が整いました。

request = urllib.request.Request(url=cato_api_url, data=json_post_encoded, headers=headers)

クエリを送信してレスポンスを処理する

ここで、プログラムはurlopen関数を呼び出してGraphQLサーバーにリクエストを送信します。 この関数を呼び出すことによって、HTTPResponseオブジェクトが返されます。  

response = urllib.request.urlopen(request, context=unverified_ctx, timeout=30)

警告!

urlopen関数を呼び出すことで、エラーが発生する可能性があります。  例えば、GraphQLサーバーが構文エラーによりリクエストを拒否することや、ネットワークの問題でタイムアウト(すなわち、30秒後に返答がない)などがあります。  これらのエラーはここでは処理されていません。

urlopen関数によって返されたオブジェクトには、サーバーから返されたJSONドキュメントを保持するボディフィールドが含まれています。  このボディデータはreadメソッドを実行して抽出され、バイトオブジェクトが返されます。  このバイトオブジェクトは、その後decodeメソッドを使用して、文字列オブジェクトに変換されます。

json_response_encoded = response.read()
json_response = json_response_encoded.decode()

このデコードされた文字列には次のように見えるJSONドキュメントが含まれています:

{    
    "data" : {
         "admins" : {
              "total": 4
         }
    }
}

ご覧の通り、返されたデータの形式は、サーバーに送信されたリクエストの形式に非常に似ています。  これは意図的であり、APIの実装にGraphQL仕様を使用するもう一つの利点です。  このアプローチは、返されたデータをリクエストと同じ形状に保つことで、アプリケーションのコーディングを簡素化します。

このセクションのプログラムコードの最後の行は、jsonライブラリ関数『loads』を使用して、返されたJSON文字列をPythonのネストされた辞書に変換します。  

get_total_admin_result = json.loads(json_response)

返されたデータから合計を抽出してそれを印刷する

コードの最後の2行は、サーバーから返されたtotalフィールドから値を抽出し、コンソールに出力します。 

total = get_total_admins_result['data']['get_total_admins']['total']
print('アカウントに定義された管理者の総数: {}'.format(total)) 

出力は次のようになります:

アカウントに定義された管理者の総数: 4

要約

このドキュメントの目標は、Cato APIをどれだけ簡単に使用できるかを読者に示すことでした。  Cato APIに関する包括的な詳細は含まれておらず、エラーハンドリング用のコードも記述されていません。  その代わりに、シンプルなPythonプログラムを使用してCato APIアプリケーションの最も重要な要素を強調しました。  それらは以下です:

  • Cato API呼び出しを作成し、JSONドキュメントに追加する

  • Cato APIキーを取得する

  • Cato APIキーを含み送信されるデータのフォーマット(JSON)を定義するHTTPプロトコルのヘッダーを作成する

  • TLSで暗号化されたHTTP POSTコマンドを使用して、JSONドキュメント(バイトでエンコード)をCato GraphQL APIサーバーに送信する

  • サーバーから返された対応オブジェクトをJSONドキュメントに変換する

  • プログラムで使用するフォーマットにJSONドキュメントを変換する