PythonでcURL

標準ライブラリのurllibか、サードパーティライブラリのRequestsを使う方法があるが、urllibの方でやってみる。

# GET

```python:get.py
import urllib.request
import json

url = 'https://petstore.swagger.io/v2/store/inventory'

try:
    with urllib.request.urlopen(url) as response:
        body = json.loads(response.read())
        headers = response.getheaders()
        status = response.getcode()

        print(headers)
        print(status)
        print(body)

except urllib.error.URLError as e:
     print(e.reason)
```

```
>python get.py
[('Date', 'Fri, 10 Apr 2020 10:25:52 GMT'), ('Access-Control-Allow-Origin', '*'), ('Access-Control-Allow-Methods', 'GET, POST, DELETE, PUT'), ('Access-Control-Allow-Heade/python.exe c:/Users/hoge/Desktop/get.pyrs', 'Content-Type, api_key, Authorization'), ('Content-Type', 'application/json'), (ccess-Control-Allow-Methods', 'GET, POST, DELETE, PUT'), ('Access-Control-Allow-Headers', 'Content-Type, api_key, Aut'Connection', 'close'), ('Server', 'Jetty(9.2.9.v20150224)')]                        ', 'Jetty(9.2.9.v20150224)')]
200
{'sold': 51, 'string': 187, 'pending': 52, 'available': 671, 'Available': 1}
```

# POST

```python:post.py
import urllib.request
import json

url = 'https://petstore.swagger.io/v2/store/order'
req_header = {
    'Content-Type': 'application/json',
}
req_data = json.dumps({
  'id': 0,
  'petId': 0,
  'quantity': 0,
  'shipDate': '2020-04-10T10:11:13.419Z',
  'status': 'placed',
  'complete': True,
})

req = urllib.request.Request(url, data=req_data.encode(), method='POST', headers=req_header)

try:
    with urllib.request.urlopen(req) as response:
        body = json.loads(response.read())
        headers = response.getheaders()
        status = response.getcode()

        print(headers)
        print(status)
        print(body)

except urllib.error.URLError as e:
     print(e.reason)
```

```
>python post.py
[('Date', 'Fri, 10 Apr 2020 10:54:21 GMT'), ('Access-Control-Allow-Origin', '*'), ('Access-Control-Allow-Methods', 'GET, POST, DELETE, PUT'), ('Access-Control-Allow-Headers', 'Content-Type, api_key, Authorization'), ('Content-Type', 'application/json'), ('Connection', 'close'), ('Server', 'Jetty(9.2.9.v20150224)')]
200
{'id': 890544, 'petId': 0, 'quantity': 0, 'shipDate': '2020-04-10T10:11:13.419+0000', 'status': 'placed', 'complete': True}
```

# Basic認証を通す

```python:post.py
～省略
user = 'user'
password = 'password'
basic_auth = base64.b64encode('{}:{}'.format(user, password).encode('utf-8'))

url = 'https://petstore.swagger.io/v2/store/order'
req_header = {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + basic_auth.decode('utf-8'),
}
～省略
```

# SSLエラーを回避する

```python:post.py
～省略
import ssl
context = ssl.create_default_context()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
～省略
with urllib.request.urlopen(req, context=context) as response:
～省略
```

# エラー時のレスポンスボディを取得する
```python:post.py
～省略
try:
    with urllib.request.urlopen(req) as response:
        body = json.loads(response.read())
        headers = response.getheaders()
        status = response.getcode()

        print(headers)
        print(status)
        print(body)

except urllib.error.HTTPError as e:
    print(e.reason)
    if e.code >= 400:
        error_body = json.loads(e.read())
        print(error_body)
```