How to update File appProperties using Google Drive v3 - python

With file uploaded and file_id known:
media_body = MediaFileUpload(filepath, mimetype=mimetype)
body = {'name': os.path.basename(filepath), 'appProperties':{'my_key': 'my_value'}}
file = drive_service.files().create(body=body, media_body=media_body, fields='id, appProperties').execute()
file_id = file['id']
How to modify the file's appProperties using v3?
There is a Google Drive API v3 Migration post that could be used to get some idea on things not covered in the documentaion. This post's Trash / Update section talks about update functionality in Google Drive API v3.
But it is written in Java and not Python. It suggests of using an empty File object: File newContent = new File();
Another post this time for PHP mentions about update method and this empty File approach too: How to update file in google drive v3 PHP
I would appreciate if someone here would trough a couple of Python snippets to guide me in a right direction.

How about following sample? In order to update appProperties, you can use drive.files.update. The detail information is here.
Sample script :
body = {'appProperties': {'my_key': 'updated_my_value'}}
updated_file = drive_service.files().update(
body=body,
fileId="### file id ###",
fields='id, appProperties'
).execute()
If I misunderstand your question, I'm sorry.

Related

Download google drive attachments of an email using Gmail API in python

I currently use this solution to download attachments from Gmail using Gmail API via python.
However, every time an attachment exceeds 25MB, the attachments automatically get uploaded to Google Drive and the files are linked in the mail. In such cases, there is no attachmentId in the message.
I can only see the file names in 'snippet' section of the message file.
Is there any way I can download the Google dive attachments from mail?
There is a similar question posted here, but there's no solution provided to it yet
How to download a Drive "attachment"
The "attachment" referred to is actually just a link to a Drive file, so confusingly it is not an attachment at all, but just text or HTML.
The issue here is that since it's not an attachment as such, you won't be able to fetch this with the Gmail API by itself. You'll need to use the Drive API.
To use the Drive API you'll need to get the file ID. Which will be within the HTML content part among others.
You can use the re module to perform a findall on the HTML content, I used the following regex pattern to recognize drive links:
(?<=https:\/\/drive\.google\.com\/file\/d\/).+(?=\/view\?usp=drive_web)
Here is a sample python function to get the file IDs. It will return a list.
def get_file_ids(service, user_id, msg_id):
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
for part in message['payload']['parts']:
if part["mimeType"] == "text/html":
b64 = part["body"]["data"].encode('UTF-8')
unencoded_data = str(base64.urlsafe_b64decode(b64))
results = re.findall(
'(?<=https:\/\/drive\.google\.com\/file\/d\/).+(?=\/view\?usp=drive_web)',
unencoded_data
)
return results
Once you have the IDs then you will need to make a call to the Drive API.
You could follow the example in the docs:
file_ids = get_file_ids(service, "me", "[YOUR_MSG_ID]"
for id in file_ids:
request = service.files().get_media(fileId=id)
fh = io.BytesIO()
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
print "Download %d%%." % int(status.progress() * 100)
Remember, seeing as you will now be using the Drive API as well as the Gmail API, you'll need to change the scopes in your project. Also remember to activate the Drive API in the developers console, update your OAuth consent screen, credentials and delete the local token.pickle file.
References
Drive API Docs
Managing Downloads Guide
Gmail API Docs
Drive API has also limtitation of downloading 10MBs only

Get file from GoogleDrive without downloading it to storage - Python

I have a python-script running on a server and I need to get a json-file from my GoogleDrive.
I want to use the GoogleDrive API to get the file, which I know the name, location and ID of but I only could find code-samples which downloads the file to storage. The json-content is supposed to be a dict in my script and the file must not be downloaded to storage. I'm new to Python and the GoogleDrive API, so I don't know how to manage it by myself.
This is the website I followed: https://www.thepythoncode.com/article/using-google-drive--api-in-python
I hope you can help me because I really need it.
Thanks in advance.
I believe your goal as follows.
You want to directly download the file to the memory without creating the data as a file using python.
From I need to get a json-file from my GoogleDrive., the file you want to download is the file except for Google Docs files (Spreadsheet, Document, Slides and so on). In this case, it's a text file.
You have already been able to use Drive API with googleapis for python.
You are using the script for authorizing from https://www.thepythoncode.com/article/using-google-drive--api-in-python.
In this case, in order to retrieve the file content to the memory, I would like to propose to retrieve it using requests. For this, the access token is retrieved from creds of get_gdrive_service().
In order to retrieve the file content, the method of "Files: get" is used by adding the query parameter of alt=media.
Sample script:
file_id = "###" # Please set the file ID you want to download.
access_token = creds.token
url = "https://www.googleapis.com/drive/v3/files/" + file_id + "?alt=media"
res = requests.get(url, headers={"Authorization": "Bearer " + access_token})
obj = json.loads(res.text)
print(obj)
At above script, creds of creds.token is from get_gdrive_service().
From your question, I thought that the file you want to download is the JSON data. So at above script, the downloaded data is parsed as JSON object.
In this case, please import json and requests.
Note:
When the returned content is JSON data, I think that you can also use res.json() instead of res.text. But when JSONDecodeError occurs, please check the value of res.text.
Reference:
Download files

How to upload file into specific folder with Google Drive API and Python?

I'm uploading a jpg file into my google drive account. It works fine, but I need it to upload to a specific folder but am not sure how to set the parents parameter in the metadata.
Here's my code:
data = {"file": open(filedirectory, 'rb').read(), "title" : filename, "parents" : [{"id": "<folderid>"}]}
drive_url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=media"
drive_r = requests.post(drive_url, data=data, headers={"Authorization": "Bearer " + access_token, "Content-type": "image/jpeg"})
I believe your goal as follows.
You want to upload a file to the specific folder in Google Drive.
You want to achieve this using requests of python.
Modification points:
In the case of uploadType=media, the official document says as follows.
Simple upload (uploadType=media). Use this upload type to quickly transfer a small media file (5 MB or less) without supplying metadata. To perform a simple upload, refer to Perform a simple upload.
So in order to upload the file content and file metadata, please use uploadType=multipart.
And also, in your endpoint, Drive API v3 is used. But "parents" : [{"id": "<folderid>"}] is for Drive API v2. It is required to also modify it.
When your script is modified for uploadType=multipart, it becomes as follows.
Modified script:
When you use this script, please set the variables of filedirectory, filename, folderid, access_token.
import json
import requests
filedirectory = '###'
filename = '###'
folderid = '###'
access_token = '###'
metadata = {
"name": filename,
"parents": [folderid]
}
files = {
'data': ('metadata', json.dumps(metadata), 'application/json'),
'file': open(filedirectory, "rb").read() # or open(filedirectory, "rb")
}
r = requests.post(
"https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
headers={"Authorization": "Bearer " + access_token},
files=files
)
print(r.text)
Note:
This modified script supposes that your access token can be used for uploading the file to Google Drive.
References:
Upload file data
Create files
it seems I have been able to get the Javascript SDK to react, with this code
gapi.client.drive.files.create({
name: 'multapart.jpg', //OPTIONAL
uploadType: 'multipart',
},{body:'your content here',content:'your content here'})
where media is bytes representation for an image
in chronium edge it complained that
Access to XMLHttpRequest at 'https://content.googleapis.com/drive/v3/files?name=resumable.jpg&body=%EF%BF%BD%EF%....%BD&uploadType=multipart&alt=json&key=[you cant see this haha]'
from origin 'https://content.googleapis.com'
has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, edge, https, chrome-untrusted.
in edge legacy it said it was a malformed and when I did uploadType=media, it said is was using https://content.googleapis.com/drive/v3/files instead of https://content.googleapis.com/upload/drive/v3/files, so the JS SDK is unreliable and riddled with bugs, glad I got it to react, if only someone can find the logic to give it the right URL because I believe the js SDK is not buggy, google doesnt want ppl to use it

How do I properly open an html document in Google Drive?

Im using Google Drive API for creating and opening html file. But the problem is that the document opens with the technical content (links to css, js files, html tags ...) like this
How to make it so that it would open correctly, in a user-friendly form?
part of my google-api code
def file_to_drive(import_file=None):
service = build('drive', 'v3', credentials=creds)
file_name = import_file
media_body = MediaFileUpload(file_name, resumable=True, mimetype='text/html')
body = {
'title': file_name,
'description': 'Uploaded By You'}
file = service.files().create(body=body, media_body=media_body, fields='id')
The google drive API is a file store api. It allows you to upload and download files. It does not have the ability to open files. You could share a link to the file with someone that has access then when they click on the link it will open for them in the google drive web application.
The only api able to open files for editing would be the Google docs api which gives you limited ability to open google doc files. that however would require that you covert your html file to a google docs format. Even if this was an option you would need to create your own "user friendly form" Google apis return data as json and not user friendly options thats not what APIs are for.

Google Drive API check json response after upload

Looking for best practice here. I am uploading a file to a folder, and then wanting to check if the json response is good using an if statement.
def upload_report(report,save_folder_id,http):
service = discovery.build('drive', 'v3', http=http)
head, tail = os.path.split(report)
file_metadata = {
'name' : tail,
'mimeType' : 'application/vnd.google-apps.document',
'parents' : [ folder_id ]
}
media = MediaFileUpload(report,mimetype='application/vnd.google-apps.document',resumable=True)
gfile = service.files().create(body=file_metadata,media_body=media,fields='id').execute()
So essentially, if the json response validates successful upload, return true, else, return false. What would be best practice to accomplish this?
Pardon such a rudimentary question, still new to using the api with python.
and this is why I don't like libraries!
The documentation should describe how errors are presented, ideally at https://developers.google.com/resources/api-libraries/documentation/drive/v2/python/latest/drive_v2.files.html#insert
To confirm if the insert succeeded, checking file for a string in the id property would suffice. Unfortunately that doesn't answer your next question which will be "if there is an error, how do I find out what it is, so I can deal with it correctly?".
Hopefully somebody who's used the Python lib can provide more info.

Categories

Resources