2019-01-18 03:31 PM 2019-01-18 03:42 PM 更新
このドキュメントでは、Cisco Meeting Server(CMS) のAPI をプログラミング言語Python(バージョン3) を用いて実行する例を紹介します。
CMS のAPI はHTTP リクエスト(GET/POST/PUT/DELETE) でクライアントからサーバ(CMS) に対して操作を行い、その結果をHTTP レスポンスで得る、REST と呼ばれるアーキテクチャで実装されています。
詳細はCMS Programming Reference Guide に記載しています。
REST API を実行するツール等はいくつかありますが、プログラミングで実行することにより、柔軟性・自由度が高い操作を実現することが可能です。同じシナリオを繰り返し実行するテストや複雑なシナリオを実行するテスト等、手動では困難な処理を行う際には特に有用です。Python は広く一般的に使用されているプログラミング言語であり、様々なプラットフォーム上に実行環境を容易に用意することが可能ですので、CMS のAPI をテストするために適しています。
本ドキュメントで使用するサンプルプログラムは、Pyrhon3 のライブラリを使用しますので、プログラムを実行するPC にPython 3 をインストールすることが必要です。
PC のコマンドプロンプト/コンソールで「python3 --version」を実行し、以下のようにバージョン番号が表示されていれば、インストール済であることが確認できます。
> python3 --version
Python 3.6.5
PC にPython3 がインストールされていない場合には、Python のダウンロードサイトからPython3 をダウンロードし、PC にインストールしてください。
添付の「CMS_api_sample.py」は、下記操作を実行するAPI を実行するプログラムのソースコードです。
PC のコマンドプロンプト/コンソールで「CMS_api_sample.py」が保存されているディレクトリで「python3 CMS_api_sample.py」と入力すると、プログラムが実行されます。
> python3 CMS_api_sample.py
coSpaceId: 8ba71f87-a7ac-4677-93fe-9a6fa7024cb3 <- 作成したスペースのID
callId: ee7b52b7-ebe0-4db5-a202-a06aaac5f629 <- 作成したコールのID
participantId for 13100@yyoshina86.cisco.com: 18967249-bfe3-4998-b378-665895120c3c <- 参加者(13100@yyoshina86.cisco.com のID(以下同様)
participantId for 13101@yyoshina86.cisco.com: 05a18042-94d7-481d-a008-3bd970dae2e7
participantId for 13102@yyoshina86.cisco.com: cc7f5d4f-1dd1-49f6-8081-94b5de077612
participantId for 13103@yyoshina86.cisco.com: dbbfb597-14db-4280-a3e1-53d22c62a4bc
Put [Enter] to end call. <- コンソールでEnter を入力すると全参加者を切断し、コールとスペースを削除してプログラム終了
Bye!
以下、プログラムの処理順に説明します。
以下は「CMS_api_sample.py」の1-14 行目です。
# coding: utf-8
import urllib.request, base64, time
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
# API 送信先(CMS)アドレス
api_host = '192.168.86.99:445'
# API を実行するユーザ認証情報から、Authorization ヘッダを作成する
username = 'apitest'
password = 'apitestpw'
# CMS スペースから発信する宛先の一覧
#participants_list = ['13100@yyoshina86.cisco.com']
participants_list = ['13100@yyoshina86.cisco.com', '13101@yyoshina86.cisco.com', '13102@yyoshina86.cisco.com', '13103@yyoshina86.cisco.com']
2-4 行目で、必要なライブラリをインポートしています。urllib.request はHTTP リクエスト送信/レスポンス受信の処理に使用します。base64 はAPI に設定する認証(Authorization) ヘッダをBase64 形式にフォーマットするために使用します。time はプログラムの実行を一定時間停止するsleep 関数を含むライブラリです。
CMS API はHTTPS で通信しますので、ssl ライブラリも必要です。
7 行目のapi_host は、API を送信するCMS のWeb Admin アドレスです。このサンプルではIP アドレス「192.168.86.99」ポート番号「445」がCMS のWeb Admin アドレスです。
9-10 行目のusername/password はCMS のMMP ユーザの情報です。CMS API の実行にはapi 権限(ROLE)を持つユーザが必要です(admin 権限はapi 権限を含みます)。下記は、CMS MMP のuser list コマンドでユーザ一覧を表示した例です。
CMS MMP ユーザについては「CMS - MMP ユーザパスワード」もご参照ください。
cms> user list
USERNAME ROLE PASSWORD EXPIRY LOGGED IN
admin admin 2019-Apr-30 no
yyoshina admin 2292-Aug-13 yes
apitest api 2292-Nov-01 no
particpant_list は、CMS スペースから発信する宛先のリストです。このリストに含まれる全ての宛先に発信します。この例では14 行目に記述しているとおり、4 つの宛先を指定しています。コメントアウトしている13 行目のようにリストに1 つの宛先しか存在しない場合には、1 参加者に発信します。
以下は「CMS_api_sample.py」の39-50 行目です。
# API 送信間隔(秒)
api_interval = 0.5
# 新規スペース作成
space_param = {'name' : 'ApiTestSpace'}
coSpaceId = sendApiRequest('POST', '/coSpaces', space_param)
if coSpaceId == None:
print('[ERROR] failed to get coSpaceId')
sys.exit(main())
print('coSpaceId: {}'.format(coSpaceId))
time.sleep(api_interval)
39 行目のmain からプログラムが実行されます。
41 行目のapi_interval は各API リクエストを実行する間に挿入するスリープ時間です。スリープを設ける必要性については「CMS でAPI を使用する際のベストプラクティス - パフォーマンスに関するチューニング」をご参照ください。ここでは例として0.5 秒の間隔を指定していますが、実際の実行環境でテストし、プログラムが問題なく実行される最適な値をチューニングしてください。
44 行目では、スペースを新規作成する際のパラメータを設定しています。ここでは必須パラメータの「name(スペース名)」のみを指定しています。
45 行目では、リクエストメソッド「POST」、リクエストAPI「/coSpaces」、パラメータを指定してリクエスト送信関数「sendApiRequest」を実行しています。「sendApiRequest」は次で説明します。
メソッド「POST」は新規作成のために使用します。ここではスペースを作成するため「/coSpaces」を指定しています。
スペースの新規作成が成功すると「sendApiRequest」がスペースID をreturn します。失敗するとNone となるため、46 行目でエラーチェックをしています。エラーの場合は47 行目でコンソールにエラーの旨を表示し、48 行目でプログラムを終了しています。成功の場合は49 行目でスペースID を表示し、50 行目でスリープし、以降の処理に続きます。
以下は「CMS_api_sample.py」の16-37 行目です。
def sendApiRequest(api_method, api_request, api_param):
request_url = 'https://{}/api/v1{}'.format(api_host, api_request)
auth_header = {
'Authorization': 'Basic {}'.format(str(base64.b64encode(bytes('{}:{}'.format(username, password), 'utf-8')), 'utf-8'))
}
if api_param != None:
encoded_param = urllib.parse.urlencode(api_param).encode('utf-8')
else:
encoded_param = None
request = urllib.request.Request(request_url, data=encoded_param, method=api_method, headers=auth_header)
with urllib.request.urlopen(request) as response:
if response.getcode() == 200:
response_headers = response.info()
if 'Location' in response_headers.keys():
responseId = response_headers.get('Location').split('/')[-1]
else:
return None
else:
print('[ERROR] {} {}: {}'.format(api_method, api_request, response.getcode()))
return None
return responseId
16 行目で引数「api_method」「api_request」「api_param」を受け取ります。
18-20 行目はユーザ認証情報をHTTP Authorization ヘッダに組み立てています。
21-24 行目は「api_param」をCMS API が受け付けるURL encode 形式にフォーマットしています。'GET' / 'DELETE' でパラメータを指定しない場合にはNone としています。
26 行目のRequest でHTTP リクエストを作成し、27 行目のurlopen で送信します。
28 行目でレスポンスを取得し、以降の処理を継続します。
29 行目はレスポンスのステータスコードをチェックしています。200(OK) 以外の場合には34-26 行目のエラー処理を行い、None をreturn します。200(OK) の場合には、29-30 行目でレスポンスのLocation ヘッダを取得し、ヘッダが存在する場合には31 行目で値として含まれるID 値を取得します。レスポンスにはLocation ヘッダが存在しない場合もありますので、その場合には33 行目でNone をreturn します。Location ヘッダのID 値を取得した場合には37 行目でID 値をreturn します。
以下は「CMS_api_sample.py」の52-60 行目です。
# 作成したスペースに新規コールを作成
call_param = {'coSpace' : coSpaceId}
callId = sendApiRequest('POST', '/calls', call_param)
if callId == None:
print('[ERROR] failed to get callId')
sendApiRequest('DELETE', '/coSpaces/{}'.format(coSpaceId), api_param=None)
sys.exit(main())
print('callId: {}'.format(callId))
time.sleep(api_interval)
基本は新規スペース作成と同様です。
53 行目でスペースID をパラメータ「coSpace」に指定し、54 行目で「POST /calls」を実行します。
55 行目でリクエストの成否をcallId の有無でチェックし、56-58 行目はエラー処理、59-60 行目は成功時の処理を行います。エラー処理内の57-58 行目では、前段で作成済のスペースを削除する処理を行っています。DELETE メソッドにパラメータは設定しませんので、「api_param」にはNone を指定します。
以下は「CMS_api_sample.py」の62-77 行目です。
# 作成したコールに新規参加者を作成
participantId_list = []
for participant in participants_list:
participant_param = {'remoteParty' : participant}
participantId = sendApiRequest('POST', '/calls/{}/participants'.format(callId), participant_param)
if participantId == None:
print('[ERROR] failed to get participantId for {}'.format(participant))
for participantId in participantId_list:
sendApiRequest('DELETE', '/calls/{}/participants/{}'.format(callId, participantId), api_param=None)
sendApiRequest('DELETE', '/calls/{}'.format(callId), api_param=None)
sendApiRequest('DELETE', '/coSpaces/{}'.format(coSpaceId), api_param=None)
sys.exit(main())
else:
print('participantId for {}: {}'.format(participant, participantId))
participantId_list.append(participantId)
time.sleep(api_interval)
63 行目の「participantId_list」は複数参加者のID を保持するためのリストです。
64 行目のfor ループで「participant_list(13-14 行目参照)」に含まれる全ての宛先に対して65-77 行目の処理を実行します。
65 行目はAPI「POST /calls/<callId>/participants」に指定する「remoteParty」パラメータを設定しています。ループの1 周目は「participant」に「participant_list」内の1 つ目の宛先が、2 周目では2 つ目の宛先が適用されます。
66 行目で「POST /calls/<callId>/participant」を送信します。67-73 行目はエラー処理です。失敗した時点で作成済の参加者(69-70 行目)・コール(71 行目)・スペース(72 行目)を削除してから73 行目でプログラムの実行を終了します。74-77 行目は成功時の処理です。75 行目で参加者ID を表示し、76 行目のappend 関数で「participantId_list」に保存、77 行目でスリープします。
下図は、全参加者が接続完了した際のCMS Web Admin Status > Calls の表示例です。
以下は「CMS_api_sample.py」の79-83 行目です。
print('Put [Enter] to end call.')
input()
for participantId in participantId_list:
sendApiRequest('DELETE', '/calls/{}/participants/{}'.format(callId, participantId), api_param=None)
79 行目でユーザに[Enter] キー入力を促すよう表示し、80 行目のinput 関数でキー入力を待ちます。
ユーザが[Enter] キーを入力すると以降の処理を継続し、82-83 行目で接続済の全ての参加者のID を「participantId_list」から順に取得して「DELETE /calls/<callId>/participants/<participantId>」で削除します。
以下は「CMS_api_sample.py」の84 行目です。API「DELETE /calls/<callId>」を実行します。
sendApiRequest('DELETE', '/calls/{}'.format(callId), api_param=None)
以下は「CMS_api_sample.py」の85-87 行目です。85 行目でAPI「DELETE /cospaces/<coSpaceId>」を実行し、87 行目でプログラムの終了を示す表示を行います。
sendApiRequest('DELETE', '/coSpaces/{}'.format(coSpaceId), api_param=None)
print('Bye!')
CMS でAPI を使用する際のベストプラクティスCMS - API 関連のトラブルシューティング
SR オープン前の確認事項(TelePresence - CMS)
検索バーにキーワード、フレーズ、または質問を入力し、お探しのものを見つけましょう
シスコ コミュニティをいち早く使いこなしていただけるよう役立つリンクをまとめました。みなさんのジャーニーがより良いものとなるようお手伝いします
下記より関連するコンテンツにアクセスできます