Automatically verifying gdrive app login in python program - google-drive-api

I want to automatically verify my credentials without going to the link and pasting the verification code every time I run this program.
might storing credentials will work but I don't know how to store it and reuse it..
my code is given below
#!/usr/bin/python
import httplib2
import pprint
from apiclient.discovery import build
from apiclient.http import MediaFileUpload
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.file import Storage
# Copy your credentials from the console
CLIENT_ID = 'my_id' #i have client id but dont wanna share
CLIENT_SECRET = 'my_secret' #i have client secret but dont wanna share
# Check https://developers.google.com/drive/scopes for all available scopes
OAUTH_SCOPE = 'https://www.googleapis.com/auth/drive'
# Redirect URI for installed apps
REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob'
# Path to the file to upload
FILENAME = 'hello.txt'
# Run through the OAuth flow and retrieve credentials
flow = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET, OAUTH_SCOPE,
redirect_uri=REDIRECT_URI)
authorize_url = flow.step1_get_authorize_url()
print 'Go to the following link in your browser: ' + authorize_url
code = raw_input('Enter verification code: ').strip()
credentials = flow.step2_exchange(code)
# Create an httplib2.Http object and authorize it with our credentials
http = httplib2.Http()
http = credentials.authorize(http)
drive_service = build('drive', 'v2', http=http)
# Insert a file
media_body = MediaFileUpload(FILENAME, mimetype='text/plain', resumable=True)
body = {
'title': 'My document',
'description': 'A test document',
'mimeType': 'text/plain'
}
file = drive_service.files().insert(body=body, media_body=media_body).execute()
pprint.pprint(file)
any help is appreciated !

Here you can find the documentation on OAuth with python: https://developers.google.com/api-client-library/python/guide/aaa_oauth (edited url)
basically you will have to use self.redirect(authorize_url) to make that step automatically and then in the second step you will use flow.step2_exchange(self.request.params)
In the documentation will find a better explanation of the process.

Related

How to get file information in google drive using google drive url in google drive api

Does anyone know if this is possible?
i think i can do it by extracting id from url.
then execute code like below.
service = build('drive', 'v3', credentials=creds)
# Call the Drive v3 API
results = service.files().list(
pageSize=10, fields="nextPageToken, files(id, name,parents,owners)",q="'drive id' in parents"
).execute()
https://developers.google.com/drive/api/guides/search-files
however parsing url might fail sometime.
so i would like to know how to get file information in drive by specify url.
To ensure the parsing URL will not fail, you can use the findall function in regex in extracting the folder ID from the folder URL. Since the structure of the folder URL is static except for the id part, this pattern will guarantee the extraction of folder Id
Regex Pattern
"/folders\/(.*)\?resourcekey"
Please see sample code below for getting the files in a specific folder in my google drive
Code:
from googleapiclient.discovery import build
from google.colab import auth
from google.auth import default
import re
auth.authenticate_user()
creds, _ = default()
# Build the service
service = build('drive', 'v3', credentials=creds)
# Google drive folder's URL
folder_url = 'https://drive.google.com/corp/drive/folders/1bBWIXbinmb-DQ1z_fspsvxlw3vt8v6Wa?resourcekey=0-3Q_nXWmlLp_eG79NzcRe5w'
# Get the folder's ID from the URL using regex
folder_id = re.findall("/folders\/(.*)\?resourcekey", folder_url)
#query
query = f"'{folder_id[0]}' in parents"
# List the files in the folder
results = service.files().list(pageSize=10, fields="nextPageToken, files(id, name,parents,owners)",q=query).execute()
items = results.get('files', [])
if not items:
print('No files found.')
else:
print('Files:')
for item in items:
print(u'{0} ({1})'.format(item['name'], item['id']))
Output:
Resources:
Search for files and folders
Regular Expression
https://regex101.com/

Can I post a .json file on github using python requests?

So, here goes the line I'm trying to use:
r= requests.post('https://github.com/Gevez/gameficacao/upload/master', auth=HTTPBasicAuth('user', 'pass'), data='data.json')
The server returns a 403 code, even if I put the credentials correctly. Now I want to know if I'm doing it the wrong way or if github doesn't allow me to do it.
You can use Github create repo content API for creating a file on your repository via the API :
PUT /repos/:owner/:repo/contents/:path
You would need to create a personal access token first. For example :
import requests
import base64
token = "YOUR_TOKEN"
repo = 'bertrandmartel/test-repo'
path = 'data.json'
data = open("data.json", "r").read()
r = requests.put(
f'https://api.github.com/repos/{repo}/contents/{path}',
headers = {
'Authorization': f'Token {token}'
},
json = {
"message": "add new file",
"content": base64.b64encode(data.encode()).decode(),
"branch": "master"
}
)
print(r.status_code)
print(r.json())
You can also use PyGithub library :
from github import Github
token = "YOUR_TOKEN"
repo = "bertrandmartel/test-repo"
path = "data.json"
# if using username and password
#g = Github("user", "password")
g = Github(token)
data = open("data.json", "r").read()
repo = g.get_repo(repo)
repo.create_file(
path = path,
message = "add new file",
content = data,
branch = "master"
)

Change Google Drive file from public to private

I created a public File on my Google Drive, I used the v3 API from Google Drive on Python to get a list of all my files.
Now I want to change a file permissions so it would be private and can only be seen by me (owner)
from __future__ import print_function
from apiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
# Setup the Drive v3 API
SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
store = file.Storage('credentials.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('client_id.json', SCOPES)
creds = tools.run_flow(flow, store)
service = build('drive', 'v3', http=creds.authorize(Http()))
# Call the Drive v3 API
results = service.files().list(
pageSize=10, fields="nextPageToken, files(id, name, modifiedTime, owners, permissions)").execute()
items = results.get('files', [])
if not items:
print('No files found.')
else:
print('Files:')
for item in items:
print('{0} ({1}) ({2})'.format(item['name'], item['id'], item["modifiedTime"])
Cosa = items[2]
print("--- Archivo Publico ---")
print(Cosa["permissions"])
print("---- Modifico los Permisos ----")
service.permissions().delete(fileId="ExampleID",permissionId="anyone").execute()
Now, when I execute the code I get:
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/drive/v3/files/1KHjbcJkN79cccgwywrwsBHlOuLUgtOqXZk4gvZKR1eE/permissions/anyone? returned "Insufficient Permission">
Why? I´m the owner of the File.
edit: The file has 2 permissions. The first is "anyone" which let´s everyone see and edit the file. The second is my permission which makes me the owner. I'm trying to delete the first to make the file private
I had to change de SCOPE from:
SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
to
SCOPES = 'https://www.googleapis.com/auth/drive'
I also deleted my credentials.json and made the web authentication. It works as spected now

Get Google Drive file owner email address using Google Drive API V3 via python

I'm having trouble getting the owner of a file on Google Drive via the Google Drive API v3.
I could do this under v2, but things have changed.
According to the documentation I need to:
List the permissions on a file (no problem)
Find Id of the permission with the 'owner' role from that list of permissions (no problem)
Get that permission ... which should return a permissions resource which should include the email address (problem!)
Unfortunately, what I'm getting back includes some of the information, but not the email address.
I suspect that I need to change my "get" call to tell the API which fields I'm after, but I can't see how to do this.
This is what I've got (v3):
from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
from apiclient.discovery import build
def build_service(user):
keyfile = 'C:\Python27\Scripts\Certificates for Transfer owner script\Transfer Ownership on Drive-f240cff252af.json'
SCOPE = 'https://www.googleapis.com/auth/drive'
credentials = ServiceAccountCredentials.from_json_keyfile_name(keyfile, scopes=SCOPE).create_delegated(user)
http_auth = credentials.authorize(Http())
return build('drive', 'v2', http=http_auth)
service = build_service('lpglobaldrive#lonelyplanet.com.au')
f = service.files().get(fileId='1lASRBuAHRxEC-T0X5SdlF3w7X_168Q2QV9L0V6QaXUk').execute()
p = service.permissions().get(fileId='1lASRBuAHRxEC-T0X5SdlF3w7X_168Q2QV9L0V6QaXUk',permissionId='18137907375963748644').execute()
currentOwner = p['emailAddress']
Unfortunately I get a "KeyError: 'emailAddress'" (and if I look at the contents of "p", there's role, kind, type and id, but no email Address).
This works for me (using v2):
from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
from apiclient.discovery import build
def build_service(user):
keyfile = 'C:\Python27\Scripts\Certificates for Transfer owner script\Transfer Ownership on Drive-f240cff252af.json'
SCOPE = 'https://www.googleapis.com/auth/drive'
credentials = ServiceAccountCredentials.from_json_keyfile_name(keyfile, scopes=SCOPE).create_delegated(user)
http_auth = credentials.authorize(Http())
return build('drive', 'v2', http=http_auth)
service = build_service('lpglobaldrive#lonelyplanet.com.au')
f = service.files().get(fileId='1lASRBuAHRxEC-T0X5SdlF3w7X_168Q2QV9L0V6QaXUk').execute()
currentOwner = f['owners'][0]['emailAddress']
Too simple ... just needed to add the following to the get call:
,fields='emailAddress'
i.e.
currentOwner = service.permissions().get(fileId='1lASRBuAHRxEC-T0X5SdlF3w7X_168Q2QV9L0V6QaXUk',permissionId='18137907375963748644',fields='emailAddress').execute()['emailAddress']

Store access token from Google OAuth 2.0 to access drive data from application account

I am able to execute quickstart.py for Google Drive using python. But how do we store the token and use it again - again for the same user without prompting user. Is their some way i can map user with access token when sending request for file on Google drive.
There are many different Storage types offered by google-api-python-client, some of which are well documented.
Some examples:
oauth2client.file.Storage:
from oauth2client.file import Storage
...
storage = Storage('a_credentials_file')
storage.put(credentials)
...
credentials = storage.get()
oauth2client.keyring_storage.Storage:
from oauth2client.keyring_storage import Storage
...
storage = Storage('application name', 'user name')
storage.put(credentials)
...
credentials = storage.get()
oauth2client.appengine.StorageByKeyName:
from oauth2client.keyring_storage import StorageByKeyName
from oauth2client.keyring_storage import CredentialsNDBModel
...
storage = StorageByKeyName(CredentialsNDBModel, some_user_id, 'credentials')
storage.put(credentials)
...
credentials = storage.get()
oauth2client.django_orm.Storage:
from django.contrib.auth.models import User
from oauth2client.django_orm import Storage
from your_project.your_app.models import CredentialsModel
...
user = # A User object usually obtained from request.
storage = Storage(CredentialsModel, 'id', user, 'credential')
credential = storage.get()
...
storage.put(credential)
I think you should give credit to bossylobster for a more complete answer, but based on your comment, which is precisely my setup, I've augmented the quickstart.py using the Storage class:
#!/usr/bin/python
import httplib2
import pprint
from apiclient.discovery import build
from apiclient.http import MediaFileUpload
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.file import Storage
# Copy your credentials from the console
CLIENT_ID = 'PASTE_YOUR_ID'
CLIENT_SECRET = 'PASTE_YOUR_SECRET'
# Check https://developers.google.com/drive/scopes for all available scopes
OAUTH_SCOPE = 'https://www.googleapis.com/auth/drive'
# Redirect URI for installed apps
REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob'
# Create a credential storage object. You pick the filename.
storage = Storage('a_credentials_file')
# Attempt to load existing credentials. Null is returned if it fails.
credentials = storage.get()
# Only attempt to get new credentials if the load failed.
if not credentials:
# Run through the OAuth flow and retrieve credentials
flow = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET, OAUTH_SCOPE, REDIRECT_URI)
authorize_url = flow.step1_get_authorize_url()
print 'Go to the following link in your browser: ' + authorize_url
code = raw_input('Enter verification code: ').strip()
credentials = flow.step2_exchange(code)
storage.put(credentials)
# Create an httplib2.Http object and authorize it with our credentials
http = httplib2.Http()
http = credentials.authorize(http)
drive_service = build('drive', 'v2', http=http)
# Use 'drive_service' for all of the API calls