pythonでlocalからGoogle Driveへファイルアップロード、テスト中

環境:MacOS
Python
Anaconda、JupiterLab(結果はJupyterLabでは実行できない)、Chrome
ターミナル(こっちでPython実行)

GoogleCloudPlatformの認証設定とJsonファイルのダウンロードが必要

目的:ローカルドライブのCSVをグーグルドライブにアップロードしたい

エラーになったスクリプト、動作しない

 

(1)ライブラリ、モジュールインストール

pip install google-api-python-client
pip install oauth2client
したあとで
WEBで拾ったPythonスクリプトをjupyterで実行したら、
以下のエラー ’client_secret.json’がないということか?


/Users/toshiromaseda/opt/anaconda3/lib/python3.7/site-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access credentials.json: No such file or directory
warnings.warn(_MISSING_FILE_MESSAGE.format(filename))
(略)
InvalidClientSecretsError: (‘Error opening file’, ‘client_secret.json’, ‘No such file or directory’, 2)

(2)間違い

サービスアカウントキー(JSONファイル)の発行が必要らしい
参考
https://algorithm.joho.info/programming/python/google-spread-sheet-py/

GoogleCloudPlatformでプロジェクトを作成して、「ウェブアプリケーション」として
作成した。
https://console.developers.google.com/cloud-resource-manager
>>>これは後ほど間違いで「デスクトップアプリ」で作成する

そのJsonファイルをダウンロードして、実行するPyファイルと同じ階層に
入れておいてリネームしておく
yearhigh2022-4fe5fcXXXXXX.json(ファイル名は仮名)

client_secret.json

そして、スクリプト内のファイル名だけだと、No such fileになるので、フルパス+ファイル名にした。

(3)他のJsonファイルを作成

次のエラー

InvalidClientSecretsError: Invalid file format. See https://developers.google.com/api-client-library/python/guide/aaa_client_secrets Expected a JSON object with a single property for a “web” or “installed” application」

たぶん(2)で取得したJsonファイルではだめらしい。
他のJsonファイルを作成してみる。

スプレッドシートのキーではなくて、ドライブのキーを作成してみる。2022/03/08
https://dev.classmethod.jp/articles/google-spreadsheet-append-csv-from-command-line/

OAuth 2.0 クライアント IDのキーをダウンロードした。
画面の右側に操作という項目があるので、その下にダウロードアイコン(下矢印)をクリックすると
ダウンロードできた。
「client_secret_XXXX.apps.googleusercontent.com.json」というファイルがダウンロードできた。
これをリネームすればよさそう

(4)不要

(>>結果的に、アプリケーションの種類では「デスクトップアプリ」なので
このリダイレクトは不要になった)

次のエラー
Jsonファイルを作成したところまでできた。
「redirect_uris」についてなにか違うようだ。


InvalidClientSecretsError: Missing property “redirect_uris” in a client type of “web”.

https://stackoverflow.com/questions/48362621/oauth2client-clientsecrets-invalidclientsecretserror-missing-property-redirect

GoogleCloudPlatform画面のどこかにURIを設定するようだ

>GoogleCloudPlatform画面の「認証情報」のOAuth 2.0 クライアント IDの欄で
作成したウェブクライアントの編集を行う。

「ウェブ アプリケーション のクライアント ID」画面で
「承認済みのリダイレクト URI」を設定する
http://localhost:8080
そして再度、またJsonファイルをダウンロードする。
リネームした。

jupyterで実行すると、また別のエラーになった
「credentials.json」がないそうだ。2022/03/09


/Users/toshiromaseda/opt/anaconda3/lib/python3.7/site-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access credentials.json: No such file or directory
warnings.warn(_MISSING_FILE_MESSAGE.format(filename))
usage: ipykernel_launcher.py [–auth_host_name AUTH_HOST_NAME]
[–noauth_local_webserver]
[–auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT …]]]
[–logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
ipykernel_launcher.py: error: unrecognized arguments: -f /Users/toshiromaseda/Library/Jupyter/runtime/kernel-ba689470-fac8-4b05-9082-70df85f8e27f.json
An exception has occurred, use %tb to see the full traceback.

SystemExit: 2

空のファイルcredentials.jsonを作成する必要があるらしいので、
空のファイルcredentials.jsonをテキストエディタ(CotEditor)で作成した

(5)ターミナルコンソールでPython

jupyterで実行したらまたエラー


usage: ipykernel_launcher.py [–auth_host_name AUTH_HOST_NAME]
[–noauth_local_webserver]
[–auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT …]]]
[–logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
ipykernel_launcher.py: error: unrecognized arguments: -f /Users/toshiromaseda/Library/Jupyter/runtime/kernel-ba689470-fac8-4b05-9082-70df85f8e27f.json
An exception has occurred, use %tb to see the full traceback.

コマンドライン引数は jupyter では対応できないらしい
https://qiita.com/uenonuenon/items/09fa620426b4c5d4acf9

ということは、JupyterLabで実行しなければよいということか?
つまり、ターミナルコンソールでPythonで実行すればよいのかな?

(6)承認エラー

ターミナルで実行した。
するとChromeが開き、
「承認エラー
エラー 400: redirect_uri_mismatch
このアプリは Google の OAuth 2.0 ポリシーを遵守していないため、ログインできません。

となった。

参考
pydriveで「エラー 400: redirect_uri_mismatch」
https://awesome03.com/2021/01/10/pydrive%E3%81%A7%E3%80%8C%E3%82%A8%E3%83%A9%E3%83%BC-400-redirect_uri_mismatch%E3%80%8D/

GoogleCloudPlatform画面で
アプリケーションの種類では「デスクトップアプリ」を選択する必要があるらしい

GoogleCloudPlatform画面で「+認証情報を作成」をクリック
OAuth 2.0 クライアント IDでアプリケーションの種類では「デスクトップアプリ」を選択
して作成した。
そして、Jsonファイルをダウンロード
client_secret.jsonにリネームした

(7)承認エラー エラー 403: access_denied

実行したらChromeが開き、

アカウント(自分が持ってるアカウント)の選択で、アカウントを選択したらアクセス権がないらしい

承認エラー
エラー 403: access_denied
The developer hasn’t given you access to this app. It’s currently being tested and it hasn’t been verified by Google. If you think you should have access, contact the developer (maXXX@gmail.com).

アクセス権を与えてみる
https://console.developers.google.com/cloud-resource-manager

サービスアカウントの管理から
サービス アカウントでグーグルのアカウントを追加した。
いつも使っているグーグルメール mas***@gmail.com

画像

でもだめだったので
OAuth 同意画面
にテストユーザとして
グーグルアカウントのメールを追加した。

いくつかの画面が表示された
そしてChrome画面に

The authentication flow has completed.

もう一度ターミナルで実行すると
python upload_gdrive.py
Chromeには何も表示されず
ターミナル側にエラーになってた。


Traceback (most recent call last):
File “upload_gdrive.py”, line 32, in <module>
fields=’id’).execute()
File “/Users/toshiromaseda/opt/anaconda3/lib/python3.7/site-packages/googleapiclient/_helpers.py”, line 131, in positional_wrapper
return wrapped(*args, **kwargs)
File “/Users/toshiromaseda/opt/anaconda3/lib/python3.7/site-packages/googleapiclient/http.py”, line 901, in execute
_, body = self.next_chunk(http=http, num_retries=num_retries)
File “/Users/toshiromaseda/opt/anaconda3/lib/python3.7/site-packages/googleapiclient/_helpers.py”, line 131, in positional_wrapper
return wrapped(*args, **kwargs)
File “/Users/toshiromaseda/opt/anaconda3/lib/python3.7/site-packages/googleapiclient/http.py”, line 1021, in next_chunk
raise ResumableUploadError(resp, content)
googleapiclient.errors.ResumableUploadError: <HttpError 403 when requesting None returned “Insufficient Permission: Request had insufficient authentication scopes.”. Details: “[{‘domain’: ‘global’, ‘reason’: ‘insufficientPermissions’, ‘message’: ‘Insufficient Permission: Request had insufficient authentication scopes.’}]”>

このエラーを分析する

(8)エラー

2022/03/10
わかったスコープのURLがReadOnlyだ。ファイルをアップロードするからリードオンリーではだめなはず。
スクリプトに記載のURLがreadonly、読み込みのみ。アップロードするからReadではだめ。
SCOPES = ‘https://www.googleapis.com/auth/drive.metadata.readonly’
#https://www.googleapis.com/auth/drive
#https://www.googleapis.com/auth/drive.file
#https://www.googleapis.com/auth/drive.appdata
#https://www.googleapis.com/auth/drive.apps.readonly

参考8
[Python]GoogleDriveAPIの基本的な使い方
https://zenn.dev/wtkn25/articles/python-googledriveapi-operation
>>わかりやすい
最初にWebで拾ったスクリプトの内容が怪しい、自分の思うように動作しない
ように思えたので、「参考8」サイトを参考にして作り直す。

現在、2022/03/13作業中で、まだ実行すらしていない状態のスクリプト、参考8から抜粋した。

でも実行したらエラー。今ここ。

 

エラー

「Traceback (most recent call last):
File “uploadgoogledrive2.py”, line 26, in <module>
fields=’id’).execute()
File “/Users/toshiromaseda/opt/anaconda3/lib/python3.7/site-packages/googleapiclient/_helpers.py”, line 131, in positional_wrapper
return wrapped(*args, **kwargs)
File “/Users/toshiromaseda/opt/anaconda3/lib/python3.7/site-packages/googleapiclient/http.py”, line 937, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/drive/v3/files?fields=id&alt=json returned “Insufficient Permission: Request had insufficient authentication scopes.”. Details: “[{‘domain’: ‘global’, ‘reason’: ‘insufficientPermissions’, ‘message’: ‘Insufficient Permission: Request had insufficient authentication scopes.’}]”>

>たぶんグーグルドライブのフォルダーのパーミッションの読み書きとかの設定が、
違っているのだろう。
またグーグル先生に頼る

(9)
Googleドライブの[設定]-> [アプリの管理]にリストされているアプリケーションを確認
認証しているスコープを確認

>>わかった。スコープの設定を飛ばしたから認証情報(/auth/drive 、auth/drive.file 等の設定)
がなかったのでエラーになってた。

もう一度認証情報を作成することにした。
作成のときにウィザードを選択

 

一度削除して、
設定して、再度Jsonファイルをダウンロードして、リネームした。client_secret.jsonにした
credentials.jsonも空のファイルにした。

2022/03/13、17:34

とりあえず、Chromeで認証まで進めた。
「$ python uploadgoogledrive2.py

Your browser has been opened to visit:

https://accounts.google.com/o/oauth2/auth?client_id=548555605276-j7kpa1otv5b387ekn3ndf6ktlp5aubs3.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&response_type=code

If your browser is on a different machine then exit and re-run this
application with the command-line parameter

–noauth_local_webserver

Authentication successful.
Traceback (most recent call last):
File “uploadgoogledrive2.py”, line 29, in <module>
print (‘Folder ID: %s’ % file.get(‘id’))
AttributeError: module ‘oauth2client.file’ has no attribute ‘get’

printのところでエラーになってるからとりあえずコメントにしておく
再度実行する


(10)成功、アップロードできた

「Traceback (most recent call last):
File “uploadgoogledrive2.py”, line 42, in <module>
file = drive_service.files().create(
AttributeError: ‘dict’ object has no attribute ‘files’」

dictオブジェクトにfielsアトリビュートがないらしい。でもそんなdictなんてしらない。

25行目で自分に代入しているので別のオブジェクトにしておく
drive_service = drive_service.files()

file = drive_service.files()
ターミナルから実行して、うまくいった。グーグルドライブの指定フォルダにCSVがアップロードできた

以下にうまく行ったコードを記入

Documents/2020年株関連/kabu_python/

uploadgoogledrive2.py

。不要なコードもある

最新版2022/03/22