Try   HackMD
tags: Python勉強会

【50期】Python勉強会 第8回

<第8回Web会議日程>
2023年06月21日(水)19:00から

第7回 解説

・課題

現在、「lambda_function.py」は、以下のようにLINEで入力した場合、
2行目をキー、3行目を値としたJSONファイルをS3に書き込みます。

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

上記に以下のようにLINEで入力した場合、S3のJSONファイルを読み込み、
キーに対応する値をに応答する処理を追加してください

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

・回答例

def s3_output(from_text): ​ # 入力内容を改行コードで区切ってリスト型に格納str = from_text.split('\n') ​ # リストの要素数が1つより大きいの場合if( len(str) > 1 ): ​ ​ # リストの2要素目(キー)がjson_dataに含まれる場合if( str[1] in json_data ): ​ ​ # キーに対応する値を「to_text」に格納 ​ to_text = json_data[str[1]] ​ # リストの2要素目(キー)がjson_dataに含まれない場合else: ​ to_text = str[1] + 'は登録されていません' ​ ​ else: ​ to_text = '2行目にキーを入力してください'return to_text

・解説

「s3_output」関数実行時には、
「s3_function.py」内のjsonファイル読み込み処理実行済みのため、
変数「json_data」は以下となる

# json_data
{'明日の予定': '仕事'}

「from_text」には、LINEでの入力内容が以下の文字列として入る

# from_text
'出力\n明日の予定'

このままでは処理できないため、「from_text」を改行コードで区切ってリスト型「str」に格納する

str = from_text.split('\n')

「str」は以下のようなリストの値となる

# str
['出力', '明日の予定']

リスト型「str」の2つ目の要素の値をキーとして、
辞書型「json_data」から値を取り出し、「to_text」に代入できていれば、OK

​to_text = json_data[str[1]]

上記に加え、想定外の入力があった場合の処理として、以下を追加
・「出力」から始まる1行しか入力がなかった場合、「2行目にキーを入力してください」を返す
・2行目にs3のjsonにないキーが指定された場合、「 キー は登録されていません」を返す


第8回 課題

・課題の前に。。。

各自第7回で対応したLambdaに以下の修正を追加してください。

・「NewFile」をクリック

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

・展開した「hotpepper_function.py」を反映し、「Save As」をクリック

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

・FileNameに「hotpepper_function.py」と入力し、「Save」をクリック

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

・「lambda_function.py」で「hotpepper_function」をインポート

import hotpepper_function

・requestsモジュールを利用するためのレイヤーを関数に追加
 ※対応済み

・HotpepperAPIを利用するためのAPIキーを環境変数に追加
 ※対応済み


・課題

現在、「lambda_function.py」は、以下のようにLINEで入力した場合、
何も処理されません

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

上記に以下のようにLINEで入力した場合、2行目を検索キーワードとして、
HotpepperのグルメサーチAPIにリクエストを送信し、
おすすめのお店を一軒紹介するよう処理を追加してください

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →


・課題の概要

今回からの課題では、HotpepperAPIという無料で公開されているAPIを利用します。

このAPIは、公開されているURLにリクエストを送信すると、
キーワードに応じて店舗を検索し、その情報を返してくれます。

今回の課題では、LINEの入力内容をキーワードにこのAPIにリクエストを送信し、
APIから返された情報から掲載店名を抽出し、LINEに返すように関数を修正いただきます。

※要修正
ーーーーーーーーーーーーーーー

「公開されているURLにリクエストを送信する」部分は、
上記で追加した「hotpepper_function.py」に定義済みのため、
以下の修正をお願いいたします。

・「lambda_function.py」から「hotpepper_function.py」のshop_search関数を呼び出す
・APIから返された情報から、掲載店名を取り出し、LINEに返す
ーーーーーーーーーーーーーーー


・前回からの変更点

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

①個人のスマホからLine公式アカウントにメッセージ送信
②Line公式からWebhookしたAPI GatewayのURLへメッセージを送信
③API Gatewayに関連付けられたLambdaを呼び出し
④HotpepperAPIにリクエスト
⑤Lambdaで作り込んだ処理に沿ってメッセージを応答


・「hotpepper_function.py」概要

1 . HotpepperAPIにリクエストを送信

入力内容(from_text)を改行コードで区切って変数「str」にリスト型で格納

['ホットペッパー', '池袋']

変数「hp_pram」に、リクエストに必要な検索条件を定義し、
HotpepperAPIのURLにGETリクエストを送信

# HotpepperAPIへのリクエストパラメータ準備
hp_pram = {
    'key':HP_API_KEY,
    'keyword':keyword,
    'order':4,
    'count':1,
    'format':'json'
}

今回のリクエストでは、以下のパラメータを利用
詳細やその他のパラメータはAPIリファレンスを参照

・key
 APIを利用するためのキー

・keyword
 フリーワード検索のためのキーワード
 LINEでの入力内容でお店を検索する

・order
 検索結果の並び順を指定できる
 「4」はおすすめ順

・count
 検索結果のデータ数を指定できる
 「1」を指定しているため、1店舗だけの情報が返る

・format
 レスポンスの形式を指定できる
 Pythonで処理するため、「JSON」を指定

2 . レスポンスからお店の情報を取得

お店の情報が格納されたJSON形式のレスポンスを辞書型「response_dict」に変換
必要情報を抽出し、LINEへの返答内容(to_text)を定義

※「response_dict」は見やすいよう整形した状態でログに出力しています

logger.info(json.dumps(response_dict,indent=2,ensure_ascii=False))

・ホットペッパーAPI

<ホットペッパーAPIとは>

【URL】ホットペッパーAPI
https://webservice.recruit.co.jp/doc/hotpepper/reference.html

リクルートが提供してくれている無料のAPIサービス。
 ※今回はグルメサーチAPIを利用
ホットペッパーAPIを利用するには利用申請が必要となる。
リンクより新規登録し、APIキーを取得する必要がある。
 ※今回は講師側で取得し、環境変数に登録済み。

<使い方>

①APIに対し、リクエストを送信する

・以下のURLに対してリクエストを送信する
http://webservice.recruit.co.jp/hotpepper/gourmet/v1/

・送信時に検索クエリをリクエストパラメータとして送信できる

・検索クエリの条件に一致するお店をホットペッパー内で検索してくれる

・どのような検索クエリを指定可能か、は
 リファレンスのグルメサーチAPI、検索クエリを参照

②レスポンスを受け取る

・検索クエリに指定した条件に一致する店舗の情報がレスポンスとして返される

・データの形式はリクエスト時に指定でき、
 JSONを選択すると、Pythonで辞書型に変換可能

・レスポンスにどのような情報が含まれるか、は
 リファレンスのグルメサーチAPI、レスポンスフィールドを参照


・Lambda レイヤー

・Lambdaレイヤーは、追加のコードまたはデータを含むことができる .zipファイルをまとめたもの。ライブラリ、カスタムランタイム、データ、または設定ファイルを含めることができる。
・lambdaでサードパーティライブラリを使うにはLayerを使う必要があり、AWS Lambda上でもサードパーティー製のライブラリを使うことができる。
・Lambdaは標準ライブラリしか使えず、外部モジュールを使用するにはインストールしなければならない。
また、ファイルをAWSにアップロードすると、関数で利用できる

※今回は講師側でrequestsのレイヤーを登録済みです!!


・requestsについて

<requestsとは>
HTTP通信用のPythonのライブラリ
GET、POST、PUTなどのメソッドが用意されている
今回は、HTTPでHotpepperAPIにGETリクエストを送るために使用

外部モジュールのため、利用するにはインストールの必要がある
今回はLambdaのため、Layerとして追加

pip install requests

<GETメソッド>
requests.get(リクエスト送信先URL,リクエストパラメータ)

URLに対してGETリクエストを送ることができる
リスエストの結果が、Responseオブジェクトとして返される


・辞書型を見やすく表示する方法について

<json.dumps>

・PythonオブジェクトをJSONデータに変換するための関数
・変換時にindentパラメータを設定すると、
 print()や、loggerで表示した時に見やすくなる
・日本語が含まれる場合は、「ensure_ascii = False」を引数に指定する

logger.info(json.dumps(response_json,indent=2,ensure_ascii=False))

・ローカルで実行するためのコード

Lambda上で試行錯誤することが煩わしい場合、
ローカルで「hotpepper_function.py」と同様のAPI利用結果を
取得できるコードを準備してしましたので、ご利用ください

import requests import json HP_URL = 'http://webservice.recruit.co.jp/hotpepper/gourmet/v1/' HP_API_KEY = '003698bcd54c9063' keyword = '池袋' # HotpepperAPIへのリクエストパラメータ準備 hp_pram = { 'key':HP_API_KEY, 'keyword':keyword, 'order':4, 'count':1, 'format':'json' } # HotpepperAPIにリスクエスト response = requests.get(HP_URL,hp_pram) # レスポンスを辞書型に変換 response_dict = response.json() print(json.dumps(response_dict,indent=2,ensure_ascii=False))

「ModuleNotFoundError」が出る場合は、requestsとjsonを
コマンドプロンプトでpip install してください