{"id":1262,"date":"2020-04-12T09:52:05","date_gmt":"2020-04-12T00:52:05","guid":{"rendered":"https:\/\/ts-engine.net\/?p=1262"},"modified":"2020-04-12T09:52:05","modified_gmt":"2020-04-12T00:52:05","slug":"google-photo-api%e5%88%a9%e7%94%a8%e3%81%ab%e3%81%82%e3%81%9f%e3%81%a3%e3%81%a6%e3%81%aeoauth%e8%aa%8d%e8%a8%bcpython","status":"publish","type":"post","link":"http:\/\/ts-engine.net\/?p=1262","title":{"rendered":"Google photo api\u5229\u7528\u306b\u3042\u305f\u3063\u3066\u306eOauth\u8a8d\u8a3c(Python)"},"content":{"rendered":"<h2>\u5199\u771f\u304c\u7121\u6599\u3067\u5bb9\u91cf\u7121\u5236\u9650<\/h2>\n<p>\nGoogle photo\u306e\u5199\u771f\u306e\u5bb9\u91cf\u7121\u5236\u9650\u3067\u4fdd\u5b58\u3067\u304d\u308b\u3068\u3044\u3046\u3053\u3068\u3067\u30ed\u30fc\u30ab\u30eb\u306b\u3042\u308b\u5199\u771f\u306f\u5168\u90e8Google photo\u306b\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3092\u53d6\u308d\u3046\u3068\u601d\u3046\u304c\u3001GUI\u3067\u3044\u3061\u3044\u3061\u5b9f\u65bd\u3059\u308b\u306e\u306f\u9762\u5012\u306a\u306e\u3067\u3001API\u3067\u3084\u308d\u3046\u3068\u601d\u3046\u3002\n<\/p>\n<p><\/p>\n<h2>google photo API\u306fOAuth\u8a8d\u8a3c<\/h2>\n<p>\nGoogle photo API\u306fOauth\u3068\u3044\u3046\u3053\u3068\u3067\u3061\u3087\u3063\u3068\u624b\u9593\u304c\u304b\u304b\u308b\u3002\n<\/p>\n<p><!--more--><\/p>\n<p>\n\u307e\u305a\u306f\u4ee5\u4e0b\u306e\u30b5\u30a4\u30c8\u3067API\u3092\u6709\u52b9\u5316\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002\u3082\u3061\u308d\u3093Google\u306e\u30b5\u30fc\u30d3\u30b9\u306a\u306e\u3067Google\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u6301\u3063\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002\n<\/p>\n<p><a href=\"https:\/\/developers.google.com\/photos\/library\/guides\/get-started\">API\u306e\u6709\u52b9\u53ef<\/a><\/p>\n<p>\n\u3053\u3053\u308c\u3067credencials.json\u3068\u3044\u3046\u30d5\u30a1\u30a4\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3067\u304d\u308c\u3070\u6210\u529f\u3002\n<\/p>\n<h2>\n\u30ed\u30b0\u30a4\u30f3\u306e\u30b9\u30af\u30ea\u30d7\u30c8\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3002Python\u3067\u8a18\u8f09\u3057\u305f\u3002<br \/>\n<\/h2>\n<p>[python]<\/p>\n<p>from pathlib import Path<br \/>\nfrom requests_oauthlib import OAuth2Session<br \/>\nimport json<\/p>\n<p>google = OAuth2Session(<br \/>\n        auth_info.get(&#8220;client_id&#8221;),<br \/>\n        scope=scope,<br \/>\n        token=token,<br \/>\n        auto_refresh_kwargs=extras,<br \/>\n        token_updater=save_token,<br \/>\n        auto_refresh_url=auth_info.get(&#8220;token_uri&#8221;),<br \/>\n        redirect_uri=auth_info.get(&#8220;redirect_uris&#8221;)[0]<br \/>\n    )<\/p>\n<p>    if not google.authorized:<br \/>\n        print(&#8220;not authorized&#8221;)<br \/>\n        authorization_url, state = google.authorization_url(<br \/>\n            auth_info.get(&#8220;auth_uri&#8221;),<br \/>\n            access_type=&#8221;offline&#8221;,<br \/>\n            prompt=&#8221;select_account&#8221;<br \/>\n        )<br \/>\n        print(&#8220;Access {} and paste code.&#8221;.format(authorization_url))<br \/>\n        access_code = input(&#8220;>>> &#8220;)<\/p>\n<p>        google.fetch_token(<br \/>\n            auth_info.get(&#8220;token_uri&#8221;),<br \/>\n            client_secret=auth_info.get(&#8220;client_secret&#8221;),<br \/>\n            code=access_code<br \/>\n        )<\/p>\n<p>        assert google.authorized<br \/>\n        save_token(google.token)<\/p>\n<p>    return google<\/p>\n<p>def save_token(token):<br \/>\n    token = {<br \/>\n        &#8220;access_token&#8221;: token.get(&#8220;access_token&#8221;),<br \/>\n        &#8220;refresh_token&#8221;: token.get(&#8220;refresh_token&#8221;),<br \/>\n        &#8220;token_type&#8221;: token.get(&#8220;token_type&#8221;),<br \/>\n        &#8220;expires_in&#8221;: token.get(&#8220;expires_in&#8221;)<br \/>\n    }<br \/>\n    Path(&#8220;token.json&#8221;).write_text(json.dumps(token))<\/p>\n<p>def load_token():<br \/>\n    token = {<br \/>\n        &#8220;access_token&#8221;: &#8220;&#8221;,<br \/>\n        &#8220;refresh_token&#8221;: &#8220;&#8221;,<br \/>\n        &#8220;token_type&#8221;: &#8220;&#8221;,<br \/>\n        &#8220;expires_in&#8221;: &#8220;-30&#8221;,<br \/>\n    }<br \/>\n    path = Path(&#8220;token.json&#8221;)<br \/>\n    if path.exists():<br \/>\n        token = json.loads(path.read_text())<br \/>\n    return token<\/p>\n<p>def refresh(google):<br \/>\n    auth_info = json.loads(Path(&#8220;credentials.json&#8221;).read_text()).get(&#8220;installed&#8221;, None)<br \/>\n    assert auth_info is not None<br \/>\n    token = load_token()<br \/>\n    extras = {<br \/>\n        &#8220;client_id&#8221;: auth_info.get(&#8220;client_id&#8221;),<br \/>\n        &#8220;client_secret&#8221;: auth_info.get(&#8220;client_secret&#8221;),<br \/>\n    }<br \/>\n    authorization_url, state = google.authorization_url(<br \/>\n        auth_info.get(&#8220;auth_uri&#8221;),<br \/>\n        access_type=&#8221;offline&#8221;,<br \/>\n        prompt=&#8221;select_account&#8221;,<br \/>\n    )<br \/>\n    google.refresh_token(<br \/>\n        auth_info.get(&#8220;token_uri&#8221;),<br \/>\n        refresh_token=token.get(&#8220;refresh_token&#8221;),<br \/>\n        client_secret=auth_info.get(&#8220;client_secret&#8221;),<br \/>\n    )<\/p>\n<p>    assert google.authorized<br \/>\n    save_token(google.token)<\/p>\n<p>If __name__ == &#8216;__main__&#8217;:<br \/>\n\tgoogle = login()<\/p>\n<p>[\/python]<\/p>\n<p><a href=\"https:\/\/blog.sakaki333.com\/blog\/view\/62\">\u53c2\u8003\u30b5\u30a4\u30c8<br \/>\n<\/a><\/p>\n<p>\n\u307b\u307c\u3053\u306e\u65b9\u306e\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u53c2\u8003\u306b\u3057\u305f\u3002\n<\/p>\n<p>\n\u53c2\u8003\u306b\u3055\u305b\u3066\u3044\u305f\u3060\u3044\u305f\u8a18\u4e8b\u306b\u306fToken\u3092Refresh\u3059\u308bmethod\u306f\u306a\u304b\u3063\u305f\u306e\u3067\u3001refresh\u3092\u8ffd\u52a0\u3057\u305f\u3002\n<\/p>\n<h2>\nAccess Token\u306f\uff11\u6642\u9593\u3067\u5207\u308c\u308b\u3002\u307e\u305f\u3001Google photo API\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306f\u3059\u3054\u304f\u9045\u3044\u3002<br \/>\n<\/h2>\n<p>\nGUI\u3067\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b\u3068\uff11\u679a\/\u79d2\u304f\u3089\u3044\u306e\u9593\u9694\u3067\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b\u304c\u3001API\u3067\u5199\u771f\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b\u30685-10\u500d\u8fd1\u304f\u304b\u304b\u308b\u3002\n<\/p>\n<p>\n\u3059\u308b\u3068\u5927\u91cf\u306e\u5199\u771f\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3057\u3088\u3046\u3068\u3059\u308b\u3068\u3001\uff11\u6642\u9593\u306eTOKEN\u304c\u5207\u308c\u3066\u3057\u307e\u3063\u3066\u52dd\u624b\u306b\u505c\u6b62\u3059\u308b\u306a\u3069\u3001\u82e6\u52b4\u3059\u308b\u3053\u3068\u304c\u7d50\u69cb\u3042\u3063\u305f\u306e\u3067\u3001\u4e0a\u8a18\u306e\u901a\u308aRefresh\u30e1\u30bd\u30c3\u30c9\u3082\u8ffd\u8a18\u3057\u3066\u3001<br \/>\n\u6642\u9593\u3092\u8a08\u6e2c\u3057\u30013500\u79d2\u304f\u3089\u3044\u306e\u9593\u9694\u3067Refresh\u3055\u305b\u308b\u3053\u3068\u3067\u5b8c\u5168\u81ea\u52d5\u3067\u5199\u771f\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u3063\u305f\u3002\n<\/p>\n<p>\n\u6b21\u56de\u306bAPI\u3092\u5229\u7528\u3057\u305f\u30a2\u30eb\u30d0\u30e0\u306e\u4f5c\u6210\u3001\u6307\u5b9a\u3057\u305f\u30a2\u30eb\u30d0\u30e0\u306b\u5199\u771f\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3059\u308b\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u53c2\u8003\u307e\u3067\u306b\u307e\u3068\u3081\u305f\u3044\u3068\u601d\u3046\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5199\u771f\u304c\u7121\u6599\u3067\u5bb9\u91cf\u7121\u5236\u9650 Google photo\u306e\u5199\u771f\u306e\u5bb9\u91cf\u7121\u5236\u9650\u3067\u4fdd\u5b58\u3067\u304d\u308b\u3068\u3044\u3046\u3053\u3068\u3067\u30ed\u30fc\u30ab\u30eb\u306b\u3042\u308b\u5199\u771f\u306f\u5168\u90e8Google photo\u306b\u30d0\u30c3\u30af\u30a2\u30c3\u30d7\u3092\u53d6\u308d\u3046\u3068\u601d\u3046\u304c\u3001GUI\u3067\u3044\u3061\u3044\u3061\u5b9f\u65bd\u3059\u308b\u306e\u306f\u9762\u5012\u306a\u306e\u3067\u3001API\u3067\u3084\u308d\u3046\u3068\u601d\u3046\u3002 google photo API\u306fOAuth\u8a8d\u8a3c Google photo API\u306fOauth\u3068\u3044\u3046\u3053\u3068\u3067\u3061\u3087\u3063\u3068\u624b\u9593\u304c\u304b\u304b\u308b\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,7],"tags":[],"class_list":["post-1262","post","type-post","status-publish","format-standard","hentry","category-20","category-7"],"_links":{"self":[{"href":"http:\/\/ts-engine.net\/index.php?rest_route=\/wp\/v2\/posts\/1262","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/ts-engine.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/ts-engine.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/ts-engine.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/ts-engine.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1262"}],"version-history":[{"count":0,"href":"http:\/\/ts-engine.net\/index.php?rest_route=\/wp\/v2\/posts\/1262\/revisions"}],"wp:attachment":[{"href":"http:\/\/ts-engine.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1262"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/ts-engine.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1262"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/ts-engine.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1262"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}