63703


ここにあるサイトを<https://qiita.com/zaki-
lknr/items/97c363c12ede4c1f25d2>のアルバム作成を行いたくて。  
Pythonのrequestsを用いてリクエストを作成したのですが400がサーバから帰ってきて上手く動作しません。

コード

[code]

    zaki@wensley% curl -s -X POST -H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-type: application/json" -d '{ "album": { "title":"create by api" } }' https://photoslibrary.googleapis.com/v1/albums
    
[/code]

コードPythonに直した。

[code]

    import requests
    
    
    # アルバム作成URL
    url = 'https://photoslibrary.googleapis.com/v1/albums'
    headers = {"Content-type": "application/json", "Authorization": "Bearer アクセストークン"}
    payload = { "album": { "title": "create by api" } }
    
    createdid = requests.post(url, params=payload, headers=headers)
    print(createdid)
    
[/code]

見ていただけないでしょうか？お願いします。


CC BY-SA 4.0
2020-03-09T09:28:36.130
63694
2022-04-14T09:01:53.283
2022-04-14T09:01:53.283
3060
22565
question
python python3 google-api python-requests
google photo apiにrequestsでアクセスしたい。


コメントで解決したので資料として回答化します。

問題の肝は、送信する JSON を指定する先のパラーメータの間違いでしょう。  
`payload`全体を文字列化して、`params`ではなく`data`パラメータに指定することで上手くいったようです。

[code]

    payload = '{ "album": { "title": "create by api" } }'
    
    createdid = requests.post(url, data=payload, headers=headers)
    
[/code]

`requests`の仕様として、以下のように`params`に渡すとURLに付加され、`data`に渡すとボディとして送られるようですね。  
ただし`data`に渡す場合に必ずしも文字列にしなくても良いのかもしれません。

[Passing Parameters In
URLs](https://requests.readthedocs.io/en/latest/user/quickstart/#passing-
parameters-in-urls)

> Requests allows you to provide these arguments as a dictionary of strings,
> using the `params` keyword argument. As an example, if you wanted to pass
> key1=value1 and key2=value2 to httpbin.org/get, you would use the following
> code:
>
> リクエストでは、`params`キーワード引数を使用して、これらの引数を文字列の辞書として提供できます。 例として、key1 =
> value1およびkey2 = value2をhttpbin.org/getに渡したい場合、次のコードを使用します。

途中省略

>
[code]

>     >>> payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
>  
>     >>> r = requests.get('https://httpbin.org/get', params=payload)
>     >>> print(r.url)
>     https://httpbin.org/get?key1=value1&key2=value2&key2=value3
>  
[/code]

[More complicated POST
requests](https://requests.readthedocs.io/en/latest/user/quickstart/#more-
complicated-post-requests)

> Typically, you want to send some form-encoded data — much like an HTML form.
> To do this, simply pass a dictionary to the `data` argument.
>
> 通常、HTML形式のように、フォームでエンコードされたデータを送信します。これを行うには、`data`引数に辞書を渡すだけです。
[code]

>     >>> payload = {'key1': 'value1', 'key2': 'value2'}
>  
>     >>> r = requests.post("https://httpbin.org/post", data=payload)
>     >>> print(r.text)
>     {
>       ...
>       "form": {
>         "key2": "value2",
>         "key1": "value1"
>       },
>       ...
>     }
>  
[/code]

* * *

余談  
上記判明の切っ掛けは、変換ツールとかあるのでは？と考えて以下のサイトを見つけたことです。  
多分色々と使い勝手が良さそうなので、資料的な意味でここに記述しておきます。

[Convert curl syntax to Python, Ansible URI, MATLAB, Node.js, R, PHP, Strest,
Go, Dart, JSON, Elixir, Rust](https://curl.trillworks.com/)

ここで問題の元の curl コマンドを入力すると以下が得られました。

[code]

    import requests
    
    headers = {
        'Authorization': 'Bearer $ACCESS_TOKEN',
        'Content-type': 'application/json',
    }
    
    data = '{ "album": { "title":"create by api" } }'
    
    response = requests.post('https://photoslibrary.googleapis.com/v1/albums', headers=headers, data=data)
    
[/code]

設定するパラメータやデータ形式が質問記事のものと微妙に違うので、その辺を検索して以下の記事にたどり着きました。

[what is the difference between data and params in
requests?](https://stackoverflow.com/q/33496953/9014308)

> According to the requests documentation a requests.post(url, data=data) will
> make an HTTP POST request, while a requests.get(url, params=params), making
> an HTTP GET, will pass parameters in the URL, eg.
>
> リクエストのドキュメントによると、requests.post（url、data = data）はHTTP
> POSTリクエストを作成し、一方、requests.get（url、params = params）はHTTP
> GETを作成し、URLのパラメーターを渡します。

上記承認回答にはイマイチ内容を網羅していないという物言いと対応する追加回答が付いていますが、それは置いておいて。

ここから更に冒頭の`requests`の仕様を探して、それを元にコメントしてみたという状況です。


CC BY-SA 4.0
2020-03-09T14:03:38.083
63703
2020-03-09T14:03:38.083
26370
63694
answer