I was trying to upload a resumable file upload on google api drive as per the documentation from https://developers.google.com/drive/api/v3/manage-uploads#python_1 . A sample code is given below, I am stuck with the current situation.
SCOPES = ['https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/drive.file','https://www.googleapis.com/auth/drive.appdata']
credentials = ServiceAccountCredentials.from_json_keyfile_name('json-file', SCOPES)
http=Http()
http.redirect_codes = http.redirect_codes - {308}
http_auth = credentials.authorize(http)
drive_service = build('drive', 'v3', http=http_auth,cache_discovery=False)
parent_id="folder-id"
source='/root/test.tar'
target='test.tar'
file_metadata = {'name': target, 'parents': [parent_id], 'mimeType': 'application/vnd.google-apps.file'}
media = MediaFileUpload(source,mimetype='application/vnd.google-apps.file',chunksize=1024*1024,resumable=True)
putfile=drive_service.files().create(body=file_metadata,media_body=media,fields='id').execute()
dest_id=putfile.get('id')
These lines are trowing the following errors. I have no idea about it.
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://www.googleapis.com/upload/drive/v3/files?fields=id&alt=json&uploadType=resumable returned "Bad Request">
I wonder what is making this issue ?
You are missing chunk size.
parent_id = "folder-id"
source = '/root/test.tar'
target = 'test.tar'
file_metadata = {'name': target, 'parents': [parent_id],
'mimeType': 'application/vnd.google-apps.file'}
media = MediaFileUpload(source, mimetype='application/vnd.google-apps.file',
chunksize=1024*1024, resumable=True)
putfile = drive_service.files().create(body=file_metadata,
media_body=media,fields='id').execute()
dest_id = putfile.get('id')
Related
Using this code, I am uploading the files to google drive successfully. But each time when I run this code, it uploads the same files to google drive again. What I want is to stop this repetition of uploading the data and just upload the newly created file.
import os
import httplib2
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
http = httplib2.Http()
SCOPES = ['https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name('thermal-highway.json', SCOPES)
drive_service = build('drive', 'v3', http=credentials.authorize(http))
def upload_folders(name, folder_id):
file_metadata = {
'name': name,
'mimeType': 'application/vnd.google-apps.folder',
'parents': folder_id
}
file = drive_service.files().create(body=file_metadata, fields='id').execute()
print('Folder ID: %s' % file.get('id'))
def list_files(path):
folderId = ['62bewyZXHy9JfSLG9N96U1e548luuCAWR']
for files in os.listdir(path):
d = os.path.join(path, files)
if os.path.isdir(d):
upload_folders(files, folderId)
path = "/home/bilal/Videos/folder1/"
list_files(path)
Your code uses file.create which creates a new file each time. If you want to update an existing file then you should be using file.update
# File's new content.
media_body = MediaFileUpload(
new_filename, mimetype=new_mime_type, resumable=True)
# Send the request to the API.
updated_file = service.files().update(
fileId=file_id,
body=file,
media_body=media_body).execute()
How I can create a folder inside the google drive and upload files into that folder? (in python)
I have tried with the google tutorials but it is giving me errors
creating a folder, not working giving me errors like 'drive_service not defined'
file_metadata = {
'title': 'Files',
'mimeType': 'application/vnd.google-apps.folder'
}
file = drive_service.files().insert(body=file_metadata,
fields='id').execute()
print 'Folder ID: %s' % file.get('id')
Used this code for uploading a file and it is working, how I can modify it for uploading a file into a folder if that exists, if not create one and upload.
import json
import requests
headers = {"Authorization": "Bearer Token"}
para = {
"name": "index.jpeg",
}
files = {
'data': ('metadata', json.dumps(para), 'application/json; charset=UTF-8'),
'file': open("./index.jpeg", "rb")
}
r = requests.post(
"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
headers=headers,
files=files
)
print(r.text)
Here is an example of what I think you're looking for (its a self-contained example, but I think you can modify it to your own existing code):
from __future__ import print_function
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from httplib2 import Http
from oauth2client import file, client, tools
# If modifying these scopes, delete the file token.json.
SCOPES = 'https://www.googleapis.com/auth/drive.file'
def main():
# Access the Drive service
store = file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
service = build('drive', 'v3', http=creds.authorize(Http()))
# Check if folder exists (simply matching by name)
folder_name = "Photos"
folder_id = None
query = "mimeType='application/vnd.google-apps.folder' and trashed=false and name='" + folder_name + "'"
results = service.files().list(
pageSize=1, q=query, fields="files(id, name)").execute()
folders = results.get('files', [])
if folders:
folder_id = folders[0]['id']
# If folder not found, then create it.
else:
file_metadata = {
'name': folder_name,
'mimeType': 'application/vnd.google-apps.folder'
}
folder_file = service.files().create(body=file_metadata,
fields='id').execute()
folder_id = folder_file.get('id')
# Add file to folder.
file_metadata = {
'name': 'photo.png',
'parents': [folder_id]
}
media = MediaFileUpload('photo.png',
mimetype='image/png',
resumable=True)
image_file = service.files().create(body=file_metadata,
media_body=media,
fields='id').execute()
if __name__ == '__main__':
main()
I am using the Google Drive API to create a .csv, and I see it in my "Drive" display but I don't see it in "Sheets." How can I make it show in Sheets? Here is my code:
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v3', http=http)
results = service.files().create(body={"name":"Test7.csv"}, media_body='/tmp/inputfile.csv', keepRevisionForever=None, useContentAsIndexableText=None, supportsTeamDrives=None, ocrLanguage=None, ignoreDefaultVisibility=None).execute()
Looks like you are just adding a CSV file to Drive.
You need to specify the mime type as Google Spreadsheet:
from apiclient.http import MediaFileUpload
file_metadata = {
'name' : 'My Report',
'mimeType' : 'application/vnd.google-apps.spreadsheet'
}
media = MediaFileUpload('test7.csv',
mimetype='text/csv',
resumable=True)
file = drive_service.files().create(body=file_metadata,
media_body=media,
fields='id').execute()
https://developers.google.com/drive/v3/web/manage-uploads#importing_to_google_docs_types_wzxhzdk18wzxhzdk19
I'm trying to upload a text file from my non-Google server to Google storage. It works when the file is an image (png), but not when it's a text file. I get
<HttpError 400 when requesting https://www.googleapis.com/upload/storage/v1/b/my_bucket_name/o?uploadType=resumable&alt=json&predefinedAcl=publicRead&name=media%2Fmy_file.txt returned "Bad Request"
.
credentials = GoogleCredentials.get_application_default()
google_service = build('storage', 'v1', credentials=credentials)
bucket = "my_bucket_name"
filename = "/home/path/my_image.png"
filename_new = "media/my_image.png"
# Fails with txt file instead of image
#filename = "/home/path/my_file.txt"
#filename_new = "media/my_file.txt"
media = MediaFileUpload(filename, chunksize=4194304, resumable=True)
req = google_service.objects().insert(bucket=bucket,
name=filename_new ,
media_body=media,
body={"cacheControl": "public,max-age=31536000"},
predefinedAcl='publicRead')
resp = None
while resp is None:
status, resp = req.next_chunk()
The key was to include mimetype:
filename = "/home/path/my_file.txt"
media = MediaFileUpload(filename, chunksize=4194304, mimetype='plain/text', resumable=True)
Others:
mimetype='image/png'
mimetype='application/gzip'
So I'm new to python (and this is a first post to stack overflow). I'm trying to use python to upload and download files to and from a google drive account (and eventually reference files from this drive on a customized work tiki wiki). The code below is from google's python api resources. It will successfully list the files on my drive (as it should). However, when I attempt to upload a file (see 10th line from bottom) I am given the following error:
An error occured: <HttpError 403 "Insufficient Permission">
I've been looking around for a few hours now and I can't figure out how to get around this. I'm thinking I need to request some sort of token. Not really sure. Again, I'm new to this. Any help would be greatly appreciated!
import httplib2
import os
from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Drive API Quickstart'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'drive-quickstart.json')
store = oauth2client.file.Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatability with Python 2.6
credentials = tools.run(flow, store)
print 'Storing credentials to ' + credential_path
return credentials
from apiclient import errors
from apiclient.http import MediaFileUpload
# ...
def insert_file(service, title, description, parent_id, mime_type, filename):
"""Insert new file.
Args:
service: Drive API service instance.
title: Title of the file to insert, including the extension.
description: Description of the file to insert.
parent_id: Parent folder's ID.
mime_type: MIME type of the file to insert.
filename: Filename of the file to insert.
Returns:
Inserted file metadata if successful, None otherwise.
"""
media_body = MediaFileUpload(filename, mimetype=mime_type, resumable=True)
body = {
'title': title,
'description': description,
'mimeType': mime_type
}
# Set the parent folder.
if parent_id:
body['parents'] = [{'id': parent_id}]
try:
file = service.files().insert(
body=body,
media_body=media_body).execute()
# Uncomment the following line to print the File ID
# print 'File ID: %s' % file['id']
return file
except errors.HttpError, error:
print 'An error occured: %s' % error
return None
def main():
"""Shows basic usage of the Google Drive API.
Creates a Google Drive API service object and outputs the names and IDs
for up to 10 files.
"""
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('drive', 'v2', http=http)
insert_file(service, 'picture.jpg', 'no_description', False, 'image/jpeg', '/Users/ethankay/Documents/Work/Current_Work/Astrophysics/Code/Logger_Program/Master/TestUploadFiles/test3.jpg')
results = service.files().list(maxResults=10).execute()
items = results.get('items', [])
if not items:
print 'No files found.'
else:
print 'Files:'
for item in items:
print '{0} ({1})'.format(item['title'], item['id'])
if __name__ == '__main__':
main()
your Google Drive scope is
SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
which has no permission to upload files. You need to change it to
SCOPES = 'https://www.googleapis.com/auth/drive'
to be able to manage files. Try to re-authenticate with your Google API project.
Save this code as quickstart.py
Run it from command line using sudo. [ sudo python quickstart.py ]
Use your Windows Password
The quickstart.py will attempt to open a new window or tab in your default browser. If this fails, copy the URL from the console and manually open it in your browser.
Click the Accept button
DONE