Google Drive API v3 : there isn't any way to get a download url for a google document? - google-api

The Google Drive API v2 to v3 migration guide says:
The exportLinks field has been removed from files. To export Google Documents, use the files.export method instead.
I don't want to export (download) the file right away. "files.export" will actually download the file. I want a link to download the file, later. This was possible in v2 by means of the exportLinks.
How can I in v3 accomplish the same? If it is not possible, why was this useful feature removed?
Besides, (similar problem to above) downloadUrl was also removed, and the suggested alternative ("files.get with ?alt=media") downloads the file instead of providing a download link. This means there is no way in v3 to get a public short lived URL for a file?
EDIT:
there is no way in v3 to get a public short lived URL for a file?
For regular files, apparently yes.
This seems to work fine (a public short lived link to the file with its right name and contents):
https://www.googleapis.com/drive/v3/files/ID?alt=media&access_token=TOKEN
For google apps files, no (not even private, as v2 exportLinks used to be).
https://www.googleapis.com/drive/v3/files/ID/exportmimeType=TYPEv&access_token=TOKEN
Similar to regular files, this URL is a short lived link to the file contents, but lacking of its right name.
BTW, I see the API is not behaving consistently: /drive/v3/files/FILEID delivers the right file name, but /drive/v3/files/FILEID/export does not.
I think the API itself should be setting the right Content-Disposition, as it is apparently doing when issuing a /drive/v3/files/FILEID call.
This file naming problem invalidates the workaround to the lack of ExportLinks in v3.
The v2 ExportLinks allowed me to link a file (which is not the same as getting its content right away). Anyone logged in and with the proper permissions was able to access it, and the link didn't needed any access_token, and it wasn't short lived. It was good and useful.
Building a link with a raw API call like /drive/v3/files/FILEID/export (with mandatory access_token) would be an close enough workaround (it is temporary and public, not the same as it was, anyway). However, the naming problem invalidates it.
In v2, regular files have a WebContentLink and google apps files have exportLinks. In v3 exportLinks are gone, and I don't see any suitable alternative to them.

Once you query for your file by id you can use the function getWebContentLink() to get the download link of the file (eg. $file->getWebContentLink() ).

I think you're placing too much emphasis on the word "method".
There is still a link to export a file, it's https://www.googleapis.com/drive/v3/files/fileIdxxxxx/export&mimeType=xxxxx/xxxxx. Make sure you URL encode the mime type.
Eg
https://www.googleapis.com/drive/v3/files/1fGBQ81haNU_nEiC5GITZD3bxT0ppL2LHg-C0ubD4Q_s/export?mimeType=text/csv&access_token=ya29.Gmo0BMvO-pVEPKsiD9j4D-NZVGE91MChRvwOcBSg3cTHt5uAClf-jFxcovQScbO2QQhwHS95eSGW1eQQcK5G1UQ6oI4BFEJJkntEBkgriZ14GbHuvpDL7LT2pKA--WiPuNoDDIuZMm5lWtlr
These links form part of the API, so the expectation is that you've written a client that sends authenticated requests, and deals with the response data. This explains why, if you simply paste the link into a browser without an access_token, it will fail. It also explains why the filename is export, ie. it isn't intended that your client would ever use a filename, but rather it should receive the data as a stream. This SO answer discusses the situation in more detail How to set name of file downloaded from browser?

Related

Google API service account authentication can't find JSON credentials file

I can't get the Google API to find my service account's credentials. I downloaded the necessary JSON file with the right name into the proper place, and I'm using Python code straight off the API documentation:
import gspread
gc = gspread.service_account()
sh = gc.open("Example spreadsheet (I'll replace this with my actual sheet name later)")
print(sh.sheet1.get('A1'))
The code stops at gc = gspread.service_account() with a FileNotFoundError. I discovered via an error message that this is because it's looking at the complete wrong file path (I think it's thinking I'm on a Mac when I'm actually on a Windows PC??). Overriding the file name, i.e.
gc = gspread.service_account(filename="insert\actual\path\here.json"),
does not work either, which is the mystifying part. I copied that path straight out of my file explorer, doubled the backslashes so Unicode doesn't try to escape it all (that happened once), tried every modification on the file path I could think of (%APPDATA%\gspread\service_account.json instead of the whole thing, etc.) - what could be going wrong?
Edit: #mods, feel free to close the question! I found the issue, which is that I was using the Repl.it online coding environment instead of a local one. I ported everything over to IDLE and it worked fine. I strongly suspect Repl.it just couldn't access my local files at all (I also tried it on Repl.it with a random screenshot in a different place, and it threw the same error).

Download Using Google Drive API with the original filename and extension

As the Google Drive API document said about downloading a file:
https://www.googleapis.com/drive/v3/files/FILEID?alt=media%26key=API_KEY
If we paste this link to Chrome or Safari It will start downloading.
But the problem is
The name is changed to FIELDID
The extension is gone
For example
I have file mywork.fbx I upload to google drive, and the FileID is ABCDEFG
Then I go to the link below.
https://www.googleapis.com/drive/v3/files/ABCDEFG?alt=media%26key=MYAPIKEY
I got the file that name is ABCDEFG without extension
It should be mywork.fbx or anyname.fbx not just ABCDEFG
Tried
add &download="mywork.fbx"
use PHP header('Content-Disposition: attachment; filename="mywork.fbx"'); filename is mywork.fbx but the bandwidth is also mine too It's not only Google Drive!!!
$file_url = 'https://www.googleapis.com/drive/v3/files/ABCDEFG?alt=media&key=KEY';
header('Content-Disposition: attachment; filename="mywork.fbx"');
readfile($file_url);
check articles in stack overflow but I can't found the right one
You want to download a file which is not Google Docs using the browser.
You want to download a file with the filename which has the filename and extension of the original file.
You are using the API key.
In this case, the file is publicly shared.
If my understanding is correct, how about this answer? In this answer, webContentLink is used as the endpoint. The official document says as follows.
webContentLink:
A link for downloading the content of the file in a browser using cookie based authentication. In cases where the content is shared publicly, the content can be downloaded without any credentials.
Modified endpoint:
Please try to access the following endpoint with your browser.
https://drive.google.com/uc?export=download&id={fileId}
When you use this, please set the file ID. In this case, the file is not Google Docs.
When it accesses to the above endpoint, the file with the filename can be retrieved.
Reference:
Files of Drive API
If I misunderstood your question and this was not the direction, I apologize.
Look at the originalFilename property of https://developers.google.com/drive/api/v3/reference/files. You can use that in a content disposition header, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

Dredd can't find my API documentation, how do i tell it where it is if it's not on my local drive (it's on apiary.io server)

I am using the Dredd tool to test my API (which resides on apiary.io).
Question
I would like to provide dredd with a path to my documentation (it even asks for it), however my API doc is on apiary.io but i don't know the exact url that points to it. What would be the correct way to provide dredd with the API path?
What did work (but not what i'm looking for)
Note: I tried downloading the api to my local drive and providing dredd with a local path to the file (yml or apib) which works fine (yay!), but i would like to avoid keeping a local copy and simply providing dredd with the location of my real API doc which is being maintained on the apiary server.
How do I do this (without first fetching the file to local drive)?
Attempts to solve this that failed
I also read (and tried) on the following topics, they may be relevant but i wasn't successful in resolving the issue
- Using authentication token as environment variable
- Providing the domain provided by apiary.io//settings to dredd
- Providing the in the dredd command
all of these attempts still produces the same result, Dredd has no idea where to find the API document unless i provide a path in my local computer to the file (which i have to download or create manually on my computer first).
Any help is appreciated, Thanks!
If I understand it correctly, you would like to use dredd and feed it using the API description document residing on Apiar.io platform, right?
If so, you should be able to do that simply calling the init command with the right options:
dredd init -r apiary -j apiaryApiKey:privateToken -j apiaryApiName:sasdasdasd
You can find the private token going into the Test section of the target API (you'll find the button on the application header).
Let me know if this solves the problem for you - I'll make sure to propagate this and document it accordingly on our help page
P.S: You can also use your own reporter - in that case, simply omit -r apiary when writing the command line parameters.
You can feed Dredd not only with a path to file on your disk, but also with an URL.
If your API in Apiary is public, the API description document (in this case API Blueprint) should have a public URL. For example, if you go to http://docs.apiblueprintapi.apiary.io/, you can see on the left there is a Download link. Unfortunately, the link is visible only for users who do not have access to the editor of the API, so you can’t see the link if you’re owner of the API. Try to log out from Apiary and the link should appear:
Then you can feed Dredd with the link:
$ dredd 'http://docs.apiblueprintapi.apiary.io/api-description-document' 'http://example.com:8080/api'
I agree this isn’t very intuitive and since you’re not the first one to come up with this, I think we’ll think of some ways how to make it easier.
If your API isn't public then unfortunately there's no way to get the URL as of now. However, you can either use GitHub Sync or Apiary CLI to get the file on your disk in an automated manner.

Call Google Spreadsheet by bash

I would like to call my private google spreadsheet by bash/shell. I don't want to edit it or something, only read it and put the content on the stand-output...
Is it possible?
I found a way, where I can call published projects from Google Drive, but that doesn't fit, as I have confidential data in that spreadsheet!
Also I haven't find an easy to use API solution to do that one simple thing.
Thanks!
Yes it's possible.
Your script will need to do 3 things, each with curl:-
Use a saved Refresh Token to request an Access Token
Use the Access Token to fetch your spreadsheet's File resource (json)
Parse the json to extract the exportLinks object, and choose which format (eg. csv) you want to download
GET that exportLink

Firefox-Addon: Add search engine with varying URL and suggestions

my Firefox addon shall add a search engine, that
provides suggestions
gets its search template URL specified on runtime (i.e.: template URL depends on the preferences of the user)
And I don't see a way to do both at the same time.
I see two options to add a search engine:
addEngineWithDetails
addEngine
addEngineWithDetails() allows me to add a search engine with the template URL. But it does (apparently?) not allow to provide a suggestions URL.
addEngine() allows me to add a search engine that is specified in an XML file. But if have that file saved locally in my addon directory (e.g. chrome://example-engine/content/search.xml), how can I change the template URL on runtime? And using an online XML is an unsafe options since the internet connection could be broken or bad during the addon install.
First fo all, you're right, addEngineWithDetails does not support suggestions.
The way to go would be to use addEngine (and removeEngine).
As for the "dynamic" part of your question: While I didn't test it, the implementation seems to happily accept data: URIs. So you could:
Construct a data URI using whatever methods you like (even constructing a full XML DOM and serializing it).
Call addEngine with the data URI.
When the user changes a pref, remove the old engine, and construct a new one.

Resources