この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWS LambdaからいくつかのWeb APIを呼び出すコードをrequestsなどの外部ライブラリを使わずにささっと書きたくて、標準ライブラリであるurllibを色々使ってみたのでそのメモです。
使ったもの
- Python: 3.7.6
- ライブラリ: urllib
GET
GETの場合はurlopenに直接URLを指定するか、下記のようにRequestを生成します。
認証ヘッダーなどつけたい場合がほとんどだと思うのでRequestを使ってみます。
from urllib import request, parse
import json
from pprint import pprint
## GET
get_header = {'Authorization': 'XXXXXXXXXX'}
get_req = request.Request('https://httpbin.org/get', headers=get_header)
with request.urlopen(get_req, headers=get_header) as res:
# resは http.client.HTTPResponse
body = json.loads(res.read()) # レスポンスボディ
headers = res.getheaders() # ヘッダー(dict)
status = res.getcode() # ステータスコード
pprint(headers)
pprint(status)
pprint(body)
POST
POSTに限らずGET以外のHTTPメソッドの場合はmethod
パラメータを指定します。
そしてリクエストボディはdata
で指定します。ドキュメントによるとこのパラメータは・・・
The supported object types include bytes, file-like objects, and iterables.
ということなので、stringの場合はencode
してbytesに変換します。formの送信の場合は下記のようになります。
JSONをPOSTする場合は同様にJSON文字列をencodeします。
## POST(form)
post_form_data = parse.urlencode({'key': 'value'})
post_form_headers = {'content-type': 'application/x-www-form-urlencoded'}
post_req = request.Request('https://httpbin.org/post', data=post_form_data.encode(), method='POST')
with request.urlopen(post_req) as res:
body = json.loads(res.read()) # レスポンスボディ
pprint(body)
Basic認証
Basic認証もライブラリなしで頑張ってみます。
ハンドラを使った方法もサポートされているのですが、ズボラなのでヘッダーを組み立ててみました。
## BASIC認証
import base64
basic_auth_token = base64.b64encode('user:password'.encode()).decode()
basic_auth_header = {'Authorization': 'Basic ' + basic_auth_token}
basic_auth_req = request.Request('https://httpbin.org/basic-auth/user/password', headers=basic_auth_header)
with request.urlopen(basic_auth_req) as res:
body = json.loads(res.read()) # レスポンスボディ
pprint(body)
レスポンスステータスが4XX, 5XXの時
urllib.error.HTTPErrorがスローされるので必要に応じてハンドリングします。 下記の例ではいずれもHTTPErrorがスローされてexcept内が実行されます。
from urllib import request, parse, error
for code in [300, 400, 500]:
req = request.Request('https://httpbin.org/status/{}'.format(code))
try:
with request.urlopen(req) as res:
pprint(res.getcode())
except error.HTTPError as e:
pprint(e)
まとめ
urllibだけでHTTPリクエストを頑張ってみました。