Python Boto3のAttributeError: module ‘botocore.vendored.requests’ has no attribute エラーを解決するには?

2019.10.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

問題

2019/10/21 以降にリリースされた AWS SDK For Python(Boto3)では、ソースコード内に requests ライブラリーが含まれなりました。 ソースコード内にヴェンダーバージョンの requests ライブラリーが含まれていることを期待して

from botocore.vendored import requests
response = requests.get('https://...')
...

のような処理をすると、AttributeError: module 'botocore.vendored.requests' has no attribute エラーが発生します。

[ERROR] AttributeError: module 'botocore.vendored.requests' has no attribute 'get'
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 8, in lambda_handler
    requests.get('https://aws.amazon.com/')
{
  "errorMessage": "module 'botocore.vendored.requests' has no attribute 'get'",
  "errorType": "AttributeError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 8, in lambda_handler\n    requests.get('https://aws.amazon.com/')\n"
  ]
}

解決方法

requests ライブラリーを別途インストールし、requests ライブラリのインポート方法を変更します。

requests ライブラリーのインストール

$ pip install requests でインストールします。

AWS Lambda の Python ランタイムで実行している場合、requests ライブラリーを AWS Lambda レイヤーで登録すると、Lambda 関数のライブラリー管理がスッキリします。

インポート方法の変更

修正前

from botocore.vendored import requests
response = requests.get('https://...')

修正後

import requests
response = requests.get('https://...')

botocore.vendored.requests を利用しているか確認するには?

既存プログラムが botocore.vendored.requests に依存しているか検証には以下の方法があります。

  • botocore ライブラリーをアップグレードし検証
  • ソースコードから botocore.vendored.requests の利用を grep する
  • アプリケーションログからヴェンダーライブラリの利用に関する警告メッセージを確認

3つ目の警告メッセージについて補足します。

2018年12月以降にリリースされたバージョンでは、ログ出力設定によっては警告メッセージがログ出力されるようになり、2019年5月以降のバージョンでは、デフォルトでログ出力されるようになっています。

実際の警告メッセージが以下です。

/var/runtime/botocore/vendored/requests/api.py:67: DeprecationWarning: You are using the get() function from 'botocore.vendored.requests'. This is not a public API in botocore and will be removed in the future. Additionally, this version of requests is out of date. We recommend you install the requests package, 'import requests' directly, and use the requests.get() function instead. DeprecationWarning

AWS Lambda Python で実行している場合、CloudWatch Logs からかんたんに警告メッセージを検索できます。

ヴェンダーバージョンが削除されたバージョン

botocore 1.13.0 からヴェンダー requests が削除されました。

botocore のバージョンを確認するには、次のようにします。

import botocore
print(botocore.__version__)

2019/10/26 時点で AWS Lambda Python 3.7 ランタイムを確認すると、 botocore のバージョンはヴェンダーライブラリ削除前の 1.12.221 でした。

今後、ランタイムのライブラリがバージョンアップされると(高頻度でバージョンアップされます)、新規にデプロイする Lambda 関数が影響をうけます。

背景

AWS SDK For Python(Boto3)の低レイヤーライブラリーの botocore では、 HTTP クライアントとして requests を利用し、ソースコードに同梱していました。

パブリックな API ではありませんでしたが、vendor を利用すると、別途インストールすることなく requests ライブラリーが使えることから、少なくないユーザーが、このヴェンダーバージョンを利用してきました。

一方で、より複雑な HTTP 通信への要求から、botocore の HTTP ライブラリーは ハイレベルな requests から urllib3 に切り替わり、このタイミングでは、ヴェンダーバージョンの requests は残っていました。

この度、ヴェンダーバージョンの requests と互換性のない Python 3.8 のリリース(2019/10/14)に合わせて、ヴェンダーバージョンの requests を削除するという決断がくだされました。

参考