標準ライブラリrequest と 外部モジュールrequests をLambdaで使用してみた [Python]

# はじめに
Lambdaでapiにリクエストする際、requestのモジュールが必要でした。
標準ライブラリurllib request と 外部モジュールrequests がありましたので、それぞれまとめます。

外部モジュールであるrequestsの方が、コード量が少ないですが、モジュールをアップする手間があります。
ただ、手間と言ってもchalice等を使用することで、手間を無くすことはできます。

# 標準ライブラリurllib request
requestsライブラリをデプロイパッケージに含める必要はなく、`import request`するだけでよいです。


https://docs.python.org/ja/3/library/urllib.request.html



## GET,POSTの場合

```py
from urllib import request
import urllib
import json
import os

# get
def  get_api(event):

  api = '/test'
  request_url = os.environ['URL'] + api
  headers = {'x-api-key': os.environ['API_KEY']}

  try:
    request_get = request.Request(url=request_url, headers=headers)
    with request.urlopen(request_get) as res:
      body = res.read().decode()
    return json.loads(body)

  except (urllib.error.HTTPError) as error:
    status_code = error.code
    print("エラーログなし %s\n URL: %s" %(status_code,request_url))
  except (urllib.error.URLError) as error:
    status_code = "HTTP通信の不可"
    print(status_code)

# post
def  post_api(id,count):
  api = '/test'
  request_url = os.environ['URL'] + api
  headers = {'x-api-key': os.environ['API_KEY'], 'content-type': 'application/json'}
  
  data = {
    'id': int(id),
    'count': int(count)
  }
  try:
    request_post = request.Request(url=request_url, method="POST",headers=headers,data=json.dumps(data).encode())
    with request.urlopen(request_post) as res:
        body = res.read().decode()
    return json.loads(body)

  except (urllib.error.HTTPError) as error:
    status_code = error.code
    print("エラーログなし %s\n URL: %s" %(status_code,request_url))
  except (urllib.error.URLError) as error:
    status_code = "HTTP通信の不可"
    print(status_code)

```

- `urllib.error.URLError` : HTTP 通信に失敗した場合
- `urllib.error.HTTPError` : HTTP ステータスコードが 4xx または 5xx の場合

例外処理も必須ですね。

また、`API_KEY`と`URL`は、環境変数を使用しています。

## PUT、PATCH、DELETEの場合
基本的に、POSTのコードのうち`method`を変えるだけです。


```py
request_put = request.Request(url=request_url, method="PUT",headers=headers)
```

# 外部モジュールrequests
Python の HTTP ライブラリで、`標準ライブラリurllib request`よりも読みやすくコーディングできます。

https://docs.python-requests.org/en/latest/

https://docs.python-requests.org/en/latest/user/quickstart/#make-a-request

## 導入方法
モジュールをLambda、もしくは、Lambdaレイヤーにアップする必要があります。以下の記事を参考にアップできます。

https://qiita.com/holdout0521/items/58a968cc940051bd2fbd#python%E5%A4%96%E9%83%A8%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AElayer%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E3%81%84%E5%A0%B4%E5%90%88

## GET,POSTの場合

```py
import json
import os
import requests

def  get_api(event):
  api = '/test'
  request_url = os.environ['URL'] + api
  headers = {'x-api-key': os.environ['API_KEY']}
  try:
    requests_get = requests.get(request_url,headers=headers)
    response = requests_get.json()
    print(response)
    requests_get.raise_for_status()
  except requests.exceptions.RequestException as e:
    print(e.response.text)


def post_api(id, count):
  api = '/ex/busstops'
  request_url = os.environ['URL'] + api
  headers = {'x-api-key': os.environ['API_KEY'], "Content-Type":"application/json"}
  data = {
    'id': int(id),
    'count': int(count)
  }

  try:
    requests_post = requests.post(request_url,headers=headers,data=json.dumps(data))
    response = requests_post.json()
    print(response)
    requests_post.raise_for_status()
  except requests.exceptions.RequestException as e:
    print(e.response.text)
```

`requests_get.raise_for_status()`:ステータスコードが200番以外の場合、例外を起こす、つまりエラーメッセージを吐き出してスクリプトを停止させます。

純粋にステータスコードが知りたい場合、以下のメソッドを使います。
`requests_get.status_code`:ステータスコードを出力する

## PUT、PATCH、DELETEの場合
基本的に、POSTのコードのうち`メソッド`を変えるだけです。

```py
requests_put = requests.put(request_url,headers=headers)
```

# 参照

https://qiita.com/hoto17296/items/8fcf55cc6cd823a18217

https://qiita.com/holdout0521/items/9d359332254eb3d5d498

https://qiita.com/sqrtxx/items/49beaa3795925e7de666

https://note.nkmk.me/python-requests-usage/