Error 404 when trying to get file metadata - google-drive-api

I am getting a 404 error when trying to access a file metadata with Google Drive Api, files.get method.
I've tried to reproduce the error using the same user and the same fileID, from the Api test page: https://developers.google.com/drive/api/v3/reference/files/get
But I can't reproduce the error. From this page I get a 200 response and I get the metadata I need (file name, etc.) That means the FileID is correct and the file does exist
According to Google the 404 error can be due to insufficient permissions (I don't think this is the case, in my code I am using https://www.googleapis.com/auth/drive which I understand includes access to metadata). Or else the file does not exist, which is also not the case.
I don't know what else to try. Here's my simple Python code:
#GET THE FILES LIST - THIS WORKS PERFECTLY:
theFiles = drive_service.files().list(pageSize=1000,q="trashed=false and mimeType != 'application/vnd.google-apps.folder'",orderBy="quotaBytesUsed desc, name, modifiedTime desc",fields="files(id,name,modifiedTime,quotaBytesUsed,starred,webViewLink, parents)").execute()
dicFiles = theFiles.get('files',[])
#GET METADATA
for item in dicFiles:
parentID=item.get('parents',[0])
#HERE I GET THE 404 ERROR
metadata= drive_service.files().get(fileId=parentID).execute()
Error:
https://www.googleapis.com/drive/v3/files/%5B%271uP0WhJXtjHBSnBb4KS80GexG9P5OLH-p%27%5D?alt=json returned "File not found: ['1uP0WhJXtjHBSnBb4KS80GexG9P5OLH-p'].">

Ok, I found the problem.
item.get('parents',[0]) wasn't returning a string, but a list.
I replaced that by item['parents'][0] and now it's working.

Related

Python capturing "HTTP status code" exception messages

I am having problems error handling code when deleting a file from box.com using Box API. The code establishes a connection to Box.com via JSON.
client.file(file_id=99999999999).delete()
When I run the command, the Box APIs uses HTTP status codes to communicate if a request has been successfully processed or not. This is what I see in PyCharm:
Error output
How do I use this error response (the red text in the bottom of the screen to handle errors so I can do something like this:
try:
client.file(file_id=xxxxxxxxxx).delete()
except 404:
print('error 404 occurred')
except 405:
print('error 405 occurred')
Thanks
#xaleel
I have tried this:
config = JWTAuth.from_settings_file(JSONFile)
client = Client(config)
try:
client.file(file_id=99999999999).delete()
except BoxAPIException as e:
print(e.status)
The error returned is:
Traceback (most recent call last):
File "C:\Temp\Box\Test\Test.py", line 20, in
except BoxAPIException as e:
NameError: name 'BoxAPIException' is not defined. Did you mean: 'BaseException'?
I have also tried "BoxException". Is this case sensitive? where can I look to see the correct possible name to use? Sorry I am not a programmer and really new to Python. I just set myself this challenge to learn!

Cannot name get parameter 'pid' in google scripts get request

I want to pass a parameter to my google spreadsheet with a get request. The get parameter name is 'pid', which seems to make Google Sheets crash.
My example script just returns the get parameters to the client:
function doGet(e){
try {
return ContentService
.createTextOutput(JSON.stringify({"result":"your parameters", "parameters": e.parameter}))
.setMimeType(ContentService.MimeType.JSON);
} catch(ee){
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error message": ee}))
.setMimeType(ContentService.MimeType.JSON);
}
}
The following request works:
https://script.google.com/macros/s/<sheet-id-here>/exec?a=1
returns:
{"result":"your parameters","parameters":{"a":"1"}}
But simply changing the get parameter name returns an error:
https://script.google.com/macros/s/<sheet-id-here>/exec?pid=1
returns:
We're sorry, a server error occurred. Please wait a bit and try again.
Any idea what's going on here and how to fix this? Is this a bug? Is there a way to handle this on the server side (can't really change my client code)?
It seems Google has changed reserved parameters. As written in the documentation,
Warning: The following parameter names are reserved by the system and shouldn't be used in URL parameters or POST bodies:
c
sid
Using these parameters may result in an HTTP 405 response with the error message "Sorry, the file you have requested does not exist." If possible, update your script to use different parameter names.
It seems both c and sid parameters are valid now and pid parameter is reserved and throws
Sorry, unable to open the file at this time.
There doesn't seem to be anything that you can do server side.

Google App Script for Tag Manager Container List

I am running a google app script to get a list of containers for my GTM account. I have the follow piece of code:
TagManager.Accounts.Containers.list(parent)
parent = my GTM account ID, I even tried putting as a string, EG "xxxxx". I am sure the GTM account ID is correct.
The following error is returned:
Uncaught Error: Response Code: 404. Message: Not Found.
at fetchContainers (Code:19)
Can anyone please help me?
"Parent" is a path:
Inserting just the ID will give an invalid path, and since the API client tries to retrieve a response from that path an invalid path will result in an error.
You need to use a call like this:
TagManager.Accounts.Containers.list(
'accounts/' + accountId,
{fields: 'container(name,publicId)'}
).container;
You can find a complete and working example here:
http://www.appsscript.it/tutorial/lista-dei-containers-di-google-tag-manager-in-spreadsheet-con-google-apps-script/

Issue with Google-API-PHP Client, getting error when running the quick start script

I am facing an issue with quickstart php script here: https://developers.google.com/drive/v2/web/quickstart/php
When I run the script first time, it executes perfectly and the access token is stored in a file called: drive-php-quickstart.json
When I run the script second time, it gives me the error:
Error start:
Notice: Undefined index: expires_in in \google-api-php-client\src\Google\Client.php on line 485
Fatal error: Uncaught exception 'LogicException' with message 'refresh token must be passed in or set as part of setAccessToken' in
Error end:
My assumption is that access token been saved in the file is not in the right format.
Current format:
ya29.CODE-oN_Bearer36001/_ANOTHER-CODE-ANOTHER_ANOTHER_CODE
As you can see, it does not contain the variable "expires_in"
Any suggestions where I am going wrong ? I am running the script as it is, with no modifications.
I've debugged it.... The person who wrote it made a mistake by not calling json_encode before writing the auth result to the token.json file.
You can fix it by adding json_encode on line 45.
So...
file_put_contents($credentialsPath, $accessToken);
...should be:
file_put_contents($credentialsPath, json_encode($accessToken));
I've submitted feedback so hopefully it'll be fixed.
edit: same issue happens for the token refresh call in that same method
edit2: Here's my related comment in a Github discussion and an answer from Google: https://github.com/google/google-api-php-client/issues/263#issuecomment-186557360
I suggested something along the following lines:
if ($client->isAccessTokenExpired()) {
$refreshToken = $client->getRefreshToken();
$client->refreshToken($refreshToken);
$newAccessToken = $client->getAccessToken();
$newAccessToken['refresh_token'] = $refreshToken;
file_put_contents($credentialsPath, json_encode($newAccessToken));
}
Instead of:
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->refreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, $client->getAccessToken());
}
Google has updated their PHP Quickstart, with an improved method to handle this:
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}

"AccessTokenRefreshError: Invalid Response 403" from oauth2client

I am creating a script that will download all files for a particular Google Apps user by using a service account that is impersonates that user (using the Python template code provided here (see code block below).
def createDriveService(user_email):
"""Build and returns a Drive service object authorized with the service accounts
that act on behalf of the given user.
Args:
user_email: The email of the user.
Returns:
Drive service object.
"""
f = file(SERVICE_ACCOUNT_PKCS12_FILE_PATH, 'rb')
key = f.read()
f.close()
credentials = SignedJwtAssertionCredentials(SERVICE_ACCOUNT_EMAIL, key,
scope='https://www.googleapis.com/auth/drive', prn=user_email)
http = httplib2.Http()
http = credentials.authorize(http)
return build('drive', 'v2', http=http)
I have been able to successfully authenticate using this function, and can perform downloads, file list requests, etc. However, if I try to perform more than four downloads in a short period of time, I get the following error:
Traceback (most recent call last):
// snip //
File "C:\***\changeScan2.py", line 48, in createDriveService
return build('drive', 'v2', http=http)
File "build\bdist.win32\egg\oauth2client\util.py", line 120, in positional_wrapper
File "build\bdist.win32\egg\apiclient\discovery.py", line 193, in build
File "build\bdist.win32\egg\oauth2client\util.py", line 120, in positional_wrapper
File "build\bdist.win32\egg\oauth2client\client.py", line 405, in new_request
File "build\bdist.win32\egg\oauth2client\client.py", line 573, in _refresh
File "build\bdist.win32\egg\oauth2client\client.py", line 629, in _do_refresh_request
oauth2client.client.AccessTokenRefreshError: Invalid response 403
The program successfully gets a list of files to download (files.list), downloads four files (authenticating each time), and then on the fifth download it provides the above error. The entire process takes 5-10 seconds. In multiple runs with different files, the program returns an error in the process of downloading the fifth file.
I trimmed the app down to the bare essentials, tried downloading different files, and received the same error. I tried catching exceptions and implementing exponential backoff for my createDriveService function, but the error seems to be in the Google API client files so I haven't been able to mitigate it. Here's a link to view the code for the oauth2client\client.py that seems to be giving me the problems.
Any ideas?
In the APIs Console where you got the private key for the SignedJwtAssertionCredentials there is also an API key at the bottom of that page. Pass that API key in as the developerKey parameter to the discovery.build() function:
http://google-api-python-client.googlecode.com/hg/docs/epy/apiclient.discovery-module.html#build
The 403 response is returned when you reach the limit of your quota, either a total daily limit, or a short term limit. Since Drive comes with a daily courtesy quota limit of 500,000 requests per day I don't think you are hitting that limit, but you probably need to add that API key so that you get actually get that full quota.
I have recently committed a change to the client library so that 403 errors are handled better, this isn't in the released version yet, but if you pull from head you will actually see the 403 as an exception that should will the full information about why the call failed.