質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

2018閲覧

PythonのKeyErrorの解消

konan513

総合スコア2

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2022/10/07 02:08

編集2022/10/07 13:54

前提

AWSで自動電話通知システムを作っています。(Lambda Python3.9)

https://infrastructure-engineer.com/aws-amzaonconnect-008/#index_id3

こちらのサイトを拝見しコードを入力していたのですが下記のようなエラーがでてしまいました。

発生している問題・エラーメッセージ

[ERROR] KeyError: 'cycle'
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 76, in lambda_handler
now_cycle = get_cycle(event)
File "/var/task/lambda_function.py", line 19, in get_cycle
cycle = json_record["cycle"]

該当のソースコード

python3.9

1import json 2import boto3 3from boto3.dynamodb.conditions import Key, Attr 4 5#boto3からDynamoDBへアクセスするためのオブジェクトを取得 6dynamodb = boto3.resource('dynamodb') 7 8#"amazonconnect-contact-list"へアクセスするためのオブジェクトを取得 9contactlist = dynamodb.Table("amazonconnect-contact-list") 10 11#"amazonconnect-response-status"へアクセスするためのオブジェクトを取得 12responsestatus = dynamodb.Table("amazonconnect-response-status") 13 14#残り周回数を取得する関数 15 16def get_cycle(sqs_event): 17 18 record = sqs_event['Records'][0] 19 json_record = json.loads(record["body"]) 20 cycle = json_record["cycle"] 21 22 return cycle 23 24 25#"amazonconnect-response-status"の内容を返す関数 26def status_scan(): 27 28 scanData = responsestatus.scan() 29 items=scanData['Items'] 30 31 return scanData["Items"] 32 33 34#"amazonconnect-contact-list"の内容を返す関数 35def operation_scan(): 36 37 scanData = contactlist.scan() 38 items=scanData['Items'] 39 40 return scanData["Items"] 41 42 43#電話番号リストの行数を返す関数 44def get_contactinfo_item_number(json_contactinfo): 45 46 count = 0 47 48 for line in json_contactinfo: 49 count += 1 50 51 return count 52 53 54#前回のプライオリティを返す関数 55def get_before_priority(sqs_event): 56 57 record = sqs_event['Records'][0] 58 json_record = json.loads(record["body"]) 59 priority = json_record["priority"] 60 61 return priority 62 63 64#指定されたプライオリティの電話番号を返す関数 65def get_phone_number(json_contactinfo, now_priority): 66 67 for line in json_contactinfo: 68 if line['Priority']==now_priority: 69 phone_number = line['Phone'] 70 71 return phone_number 72 73 74def lambda_handler(event, context): 75 76 # 残り周回数を取得 77 now_cycle = get_cycle(event) 78 79 # 応答結果を確認 80 statustinfo = status_scan() 81 82 # 応答結果がNGの場合 83 if statustinfo[0]['CallStatus'] == "NG": 84 85 # 電話番号リストを取得 86 contactinfo = operation_scan() 87 88 # 電話番号リストの行数を取得 89 contactinfo_item_number = get_contactinfo_item_number(contactinfo) 90 91 # 前回のプライオリティを取得 92 before_priority = get_before_priority(event) 93 94 # 前回のプラオリティが電話番号リストの行数と同じ場合(リストの最後まで通知した場合) 95 if before_priority == contactinfo_item_number: 96 97 # プライオリティを1に設定(最初に戻る) 98 priority = 1 99 100 # 残り周回数を1減らす 101 now_cycle -= 1 102 103 # 前回のプラオリティが電話番号リストの行数と異なる場合(リストの最後まで通知していない場合) 104 else: 105 106 # プライオリティに1を足す(次のプライオリティを設定) 107 priority = before_priority + 1 108 109 # 残り周回数が0以外の場合 110 if now_cycle != 0: 111 112 # 指定したプライオリティの電話番号を取得 113 phone_number = get_phone_number(contactinfo, priority) 114 115 # boto3からAmazonConnectへアクセスするためのオブジェクトを取得 116 connect = boto3.client('connect') 117 118 # AmzaonConnectの問い合わせフローを呼び出し電話発信 119 connect.start_outbound_voice_contact( 120 DestinationPhoneNumber=phone_number, 121 ContactFlowId='***', 122 InstanceId='***', 123 SourcePhoneNumber='***', 124 ) 125 126 # boto3からSQSへアクセスするためのオブジェクトを取得 127 sqs = boto3.resource('sqs') 128 129 # "amazonconnect-queue-confirm"へアクセスするためのオブジェクトを取得 130 name = 'amazonconnect-queue-confirm' 131 queue = sqs.get_queue_by_name(QueueName=name) 132 133 # 現在のプライオリティと周回数をセットしてステータス確認用のキューにメッセージ送信 134 response = queue.send_message(MessageBody=json.dumps({"priority": priority, "cycle": now_cycle}))

もし分かる方いらっしゃいましたら回答お願いしたいです。
よろしくお願いします。

※ひとつ前のLambdaも追加させていただきます。
event変数は恐らく 2 でSQSに送信されていると思うのですが…

python3.9

1import json 2import boto3 3from boto3.dynamodb.conditions import Key, Attr 4 5# boto3からDynamoDBへアクセスするためのオブジェクトを取得 6dynamodb = boto3.resource('dynamodb') 7 8# "amazonconnect-contact-list"へアクセスするためのオブジェクトを取得 9contactlist = dynamodb.Table("amazonconnect-contact-list") 10 11# "amazonconnect-response-status"へアクセスするためのオブジェクトを取得 12responsestatus = dynamodb.Table("amazonconnect-response-status") 13 14# CallStatusを"NG"に変更する関数 15def status_ng(): 16 response = responsestatus.update_item( 17 Key={ 18 'No': 1, 19 'Name': "Response" 20 }, 21 UpdateExpression="set CallStatus=:c", 22 ExpressionAttributeValues={ 23 ':c': "NG" 24 }, 25 ReturnValues="UPDATED_NEW" 26 ) 27 return response 28 29 30# "amazonconnect-contact-list"の内容を返す関数 31def operation_scan(): 32 33 scanData = contactlist.scan() 34 items=scanData['Items'] 35 36 return scanData["Items"] 37 38 39# 指定されたプライオリティの電話番号を返す関数 40def get_phone_number(json_contactinfo, now_priority): 41 42 for line in json_contactinfo: 43 if line['Priority']==now_priority: 44 phone_number = line['Phone'] 45 46 return phone_number 47 48 49def lambda_handler(event, context): 50 51 # 応答結果を初期化 52 status_ng() 53 54 # 電話番号リストを取得 55 contactinfo = operation_scan() 56 57 # 初回のプライオリティを"1"に設定 58 priority = 1 59 60 # 周回数を"2"に設定 61 cycle = 2 62 63 # 指定したプライオリティの電話番号を取得 64 phone_number = get_phone_number(contactinfo, priority) 65 66 # boto3からAmazonConnectへアクセスするためのオブジェクトを取得 67 connect = boto3.client('connect') 68 69 # AmzaonConnectの問い合わせフローを呼び出し電話発信 70 connect.start_outbound_voice_contact( 71 DestinationPhoneNumber=phone_number, 72 ContactFlowId='***', 73 InstanceId='***', 74 SourcePhoneNumber='***', 75 ) 76 77 # boto3からSQSへアクセスするためのオブジェクトを取得 78 sqs = boto3.resource('sqs') 79 80 # "amazonconnect-queue-confirm"へアクセスするためのオブジェクトを取得 81 name = 'amazonconnect-queue-confirm' 82 queue = sqs.get_queue_by_name(QueueName=name) 83 84 # 現在のプライオリティと周回数をセットしてステータス確認用のキューにメッセージ送信 85 response = queue.send_message(MessageBody=json.dumps({"priority": priority, "cycle": cycle}))

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2022/10/07 02:23

もし以下のようなことを追記すると回答得られやすくなると思います。 - event変数の中身およびそれが意図通りか - 参考にしたサイト(ソースコードの出典)
can110

2022/10/07 04:43

この欄は目立たないので質問本文に追記ください。 またソースコードが崩れてインデントがなくなっているのであわせて修正ください。
guest

回答1

0

ベストアンサー

0. エラーの原因

KeyError: 'cycle'の原因は,辞書型オブジェクトjson_recordが持っていないKeycycleへのアクセスを行ったため,生じたものです.元を辿れば関数lambda_handler(event, context)が受け取ったJSON形式文字列event["Records"][0]["body"]にKeycycleが存在しなかったことに起因します.

したがって,can110さんのコメントで

event変数の中身およびそれが意図通りか

という情報を要求することになっています.

1. event変数の中身が意図通りでないこともある場合

辞書型のKeyアクセスの際に,cycleが存在しないことがある場合でもプログラムを動作させることができます.Keyアクセスに対してデフォルト値を設定することができることを利用します.

Python

1def get_cycle(sqs_event): 2 3 record = sqs_event['Records'][0] 4 json_record = json.loads(record["body"]) 5 cycle = json_record.get("cycle", -1) # デフォルト値 -1 を設定しておく 6 7 return cycle

2. event変数の中身が必ず意図通りである場合

辞書型オブジェクトでのアクセス方法が間違っています.中身を教えていただければ適切な手続きを例示できます.

投稿2022/10/07 11:49

編集2022/10/07 12:01
PondVillege

総合スコア1579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

konan513

2022/10/07 13:59

回答ありがとうございます。初心者すぎてSQSから届いたevent変数の中身を確かめる方法がわからない状態です。。申し訳ありません。 ひとつ前のLambdaも追記します。
konan513

2022/10/08 05:06

AWS Lambdaに以下のコードを入力したところ、 import json def lambda_handler(event, context): print(event["Records"][0]["body"]) ログに以下のようにでてきました。 { "priority": 2, "cycle": 2 }
PondVillege

2022/10/08 06:58

では,そのケースでエラーは起きないはずです.エラーが起きるときはcycleが無かったはずです.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問