Automatyzacja procesu weryfikacji pydrive
Próbuję zautomatyzować proces {[3] } podczas korzystania z biblioteki pydrive
(https://pypi.python.org/pypi/PyDrive).
Skonfigurowałem pydrive i google API tak, że mój secret_client.json
działa, ale wymaga uwierzytelniania internetowego dla dostępu gdrive za każdym razem, gdy uruchamiam mój skrypt:
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
gauth = GoogleAuth()
gauth.LocalWebserverAuth()
drive = GoogleDrive(gauth)
textfile = drive.CreateFile()
textfile.SetContentFile('eng.txt')
textfile.Upload()
print textfile
drive.CreateFile({'id':textfile['id']}).GetContentFile('eng-dl.txt')
eng.txt
to tylko plik tekstowy. Co więcej, gdy próbuję korzystać z powyższego skryptu, gdy jestem zalogowany na inne konto. nie wgrywa eng.txt
do mojego gdrive, który wygenerował secret_client.json
ale konto, które było zalogowane, gdy autoryzowałem uwierzytelnianie
Z poprzedniego postu próbowałem zautomatyzować proces weryfikacji, ale to daje komunikaty o błędach:
import base64, httplib2
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from apiclient.discovery import build
from oauth2client.client import SignedJwtAssertionCredentials
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
#gauth = GoogleAuth()
#gauth.LocalWebserverAuth()
# from google API console - convert private key to base64 or load from file
id = "464269119984-j3oh4aj7pd80mjae2sghnua3thaigugu.apps.googleusercontent.com"
key = base64.b64decode('COaV9QUlO1OdqtjMiUS6xEI8')
credentials = SignedJwtAssertionCredentials(id, key, scope='https://www.googleapis.com/auth/drive')
credentials.authorize(httplib2.Http())
gauth = GoogleAuth()
gauth.credentials = credentials
drive = GoogleDrive(gauth)
drive = GoogleDrive(gauth)
textfile = drive.CreateFile()
textfile.SetContentFile('eng.txt')
textfile.Upload()
print textfile
drive.CreateFile({'id':textfile['id']}).GetContentFile('eng-dl.txt')
Błąd:
Traceback (most recent call last):
File "/home/alvas/git/SeedLing/cloudwiki.py", line 29, in <module>
textfile.Upload()
File "/usr/local/lib/python2.7/dist-packages/pydrive/files.py", line 216, in Upload
self._FilesInsert(param=param)
File "/usr/local/lib/python2.7/dist-packages/pydrive/auth.py", line 53, in _decorated
self.auth.Authorize()
File "/usr/local/lib/python2.7/dist-packages/pydrive/auth.py", line 422, in Authorize
self.service = build('drive', 'v2', http=self.http)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/util.py", line 132, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/apiclient/discovery.py", line 192, in build
resp, content = http.request(requested_url)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/util.py", line 132, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 475, in new_request
self._refresh(request_orig)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 653, in _refresh
self._do_refresh_request(http_request)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 677, in _do_refresh_request
body = self._generate_refresh_request_body()
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 861, in _generate_refresh_request_body
assertion = self._generate_assertion()
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 977, in _generate_assertion
private_key, self.private_key_password), payload)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/crypt.py", line 131, in from_string
pkey = crypto.load_pkcs12(key, password).get_privatekey()
OpenSSL.crypto.Error: [('asn1 encoding routines', 'ASN1_get_object', 'header too long')]
Moje uwierzytelnianie w gdrive api wygląda tak:
Jak mogę używać pydrive tak, że nie muszę uwierzytelniać za każdym razem, gdy go używam?
Jak zezwolić na automatyczne uwierzytelnianie takie że skrypt Pythona za pomocą skryptu pydrive będzie przesyłany tylko do konta, które wygenerowało secret_client.json
, a nie do aktualnie zalogowanego konta w przeglądarce internetowej?
2 answers
Po pierwsze, nie rozumiesz jednego bardzo ważnego fragmentu tego, jak to działa:
Dokładnie tak to powinno działać. Ty, jako deweloper, rozpowszechniaszKiedy próbuję użyć powyższego skryptu, gdy jestem zalogowany do innego konto. Nie wgrywa eng.txt do mojego gdrive, który generował secret_client.json ale konto, które było zalogowane kiedy I authorize the authentication
client_secret.json
ze swoją aplikacją, a plik ten jest używany przez PyDrive do Uwierzytelnij aplikację za pomocą Google. Google chce wiedzieć, ile żądań API jest składanych przez każdą aplikację z różnych powodów (metryki, obciążenie konta, cofnięcie dostępu itp.), wymaga więc uwierzytelnienia aplikacji.
Teraz, gdy Twoja aplikacja działa LocalWebserverAuth
, uwierzytelnia klienta z Google. Klientem jest oczywiście osoba faktycznie korzystająca z Twojej aplikacji. W tym przypadku deweloper i klient są ta sama osoba (ty), ale wyobraź sobie, że chcesz rozpowszechniać swoją aplikację milionowi różnych osób. Muszą być w stanie uwierzytelnić się i przesłać pliki na własne konto dysku, a nie, aby wszystkie trafiły do twojego (dewelopera), który dostarczył client_secret.json
.
To powiedziawszy, to naprawdę bardzo drobna zmiana, aby aplikacja nie musiała prosić Klienta o uwierzytelnienie za każdym razem, gdy uruchomisz aplikację. Wystarczy użyć LoadCredentialsFile
oraz SaveCredentialsFile
.
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
gauth = GoogleAuth()
# Try to load saved client credentials
gauth.LoadCredentialsFile("mycreds.txt")
if gauth.credentials is None:
# Authenticate if they're not there
gauth.LocalWebserverAuth()
elif gauth.access_token_expired:
# Refresh them if expired
gauth.Refresh()
else:
# Initialize the saved creds
gauth.Authorize()
# Save the current credentials to a file
gauth.SaveCredentialsFile("mycreds.txt")
drive = GoogleDrive(gauth)
textfile = drive.CreateFile()
textfile.SetContentFile('eng.txt')
textfile.Upload()
print textfile
drive.CreateFile({'id':textfile['id']}).GetContentFile('eng-dl.txt')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-12 17:02:11
Alternatywnym sposobem jest użycie niestandardowego przepływu auth przez zapisanie ustawienia.plik yaml do katalogu roboczego. I ta metoda działa lepiej, ponieważ LocalWebserverAuth()
wygeneruje token, który wygasa w ciągu jednej godziny i nie ma tokena odświeżania.
Przykładowe ustawienia.plik yaml wygląda tak
client_config_backend: file
client_config:
client_id: <your_client_id>
client_secret: <your_secret>
save_credentials: True
save_credentials_backend: file
save_credentials_file: credentials.json
get_refresh_token: True
oauth_scope:
- https://www.googleapis.com/auth/drive
- https://www.googleapis.com/auth/drive.install
W tym pliku nadal musisz użyć przeglądarki, aby zakończyć uwierzytelnianie po raz pierwszy, a następnie poświadczenia.plik json zostanie wygenerowany w katalogu roboczym z odśwież token.
Ta metoda działa lepiej, jeśli próbujesz zautomatyzować skrypt na serwerze
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-10 19:43:02