Python Language Guide (v3.0) – Google Documents List Data API v3.0 – Google Code:
Python Language Guide (v3.0)
In addition to providing some background on the capabilities of the Documents List Data API, this guide provides examples for interacting with the API using the Python client library. If you’re interested in understanding more about the underlying protocol used by the Python client library to interact with the Documents List, please see the protocol guide.
Important: The Google Documents List Data API v3.0 is in Labs, and its features might change unexpectedly until it graduates. Version 2.0 is the latest graduated version.
Audience
This document is intended for developers who want to write client applications using the Google Data Python client library that interact with Google Documents.
Getting started
Google Documents uses Google Accounts for authentication, so if you have a Google account you are all set. Otherwise, you can create a new account.
Installing the library
To use the Python client library, you’ll need Python 2.2+ and the modules listed on the DependencyModules wiki page. After downloading the client library, see Getting Started with the Google Data Python Library for help installing and using the Python client.
Setting up your own project
To include the examples in this guide into your own code, you’ll need the following import statements:
import gdata.docs.data
import gdata.docs.client
You will also need to setup a DocsClient object, which represents a client connection (with authentication) to the Documents List API.
client = gdata.docs.client.DocsClient(source='yourCo-yourAppName-v1')
client.ssl = True # Force all API requests through HTTPS
client.http_client.debug = False # Set to True for debugging HTTP requests
The source argument is optional and should follow the format: company-applicationname-version. It’s recommended to include this parameter for logging purposes.
Note: The rest of the guide assumes you created a DocsClient in the variable client.
Authenticating to the Documents List API
The Python client library can be used to work with either public or private feeds, however the Documents List Data API only provides access to private feeds. That means your client application must send authenticated requests to the API. This can be done via ClientLogin username/password authentication, AuthSub, or OAuth.
Please see the Google Data APIs Authentication Overview for more information on AuthSub, OAuth, and ClientLogin.
Tip: The API supports SSL (HTTPS). If you’re using AuthSub/OAuth, make sure to specify a scope of https://docs.google.com/feeds/ in order to request feeds over SSL. You can force all API requests to be over HTTPS by setting the DocsClient‘s ssl property: client.ssl = True.
AuthSub for web applications
AuthSub Authentication for Web Applications should be used by client applications which need to authenticate their users to Google or Google Apps accounts. The operator does not need access to the username and password for the Google Docs user – only an AuthSub token is required.
Request a single-use token
When the user first visits your application, they need to authenticate. Typically, developers print some text and a link directing the user to the AuthSub approval page to authenticate the user and request access to their documents. The Google Data Python client library provides a function, generate_auth_sub_url() to generate this URL. The code below sets up a link to the AuthSubRequest page.
import gdata.gauth
def GetAuthSubUrl():
next = 'http://www.example.com/myapp.py'
scopes = ['http://docs.google.com/feeds/', 'https://docs.google.com/feeds/']
secure = False # set secure=True to request a secure AuthSub token
session = True
return gdata.gauth.generate_auth_sub_url(next, scopes, secure=secure, session=session)
print '<a href="%s">Login to your Google account</a>' % GetAuthSubUrl()
If you want to authenticate users on a Google Apps hosted domain, pass in the domain name to generate_auth_sub_url():
def GetAuthSubUrl():
domain = 'example.com'
next = 'http://www.example.com/myapp.py'
scopes = ['http://docs.google.com/feeds/', 'https://docs.google.com/feeds/']
secure = False # set secure=True to request a secure AuthSub token
session = True
return gdata.gauth.generate_auth_sub_url(next, scopes, secure=secure, session=session, domain=domain)
The generate_auth_sub_url() method takes several parameters (corresponding to the query parameters used by the AuthSubRequest handler):
- the next URL — URL that Google will redirect to after the user logs into their account and grants access;
http://www.example.com/myapp.py in the example above
- the scope —
http://docs.google.com/feeds/ (and https://docs.google.com/feeds/) in the example above. Note, both are used as a convenience to your app. Later, if you decide to initiate API requests over SSL, your existing AuthSub tokens will be valid.
- secure, a boolean to indicate whether the token will be used in secure and registered mode or not;
False in the example above
- session, a second boolean to indicate whether the single-use token will later be exchanged for a session token or not;
True in the example above
Upgrading to a session token
See Using AuthSub with the Google Data API Client Libraries.
Retrieving information about a session token
See Using AuthSub with the Google Data API Client Libraries.
Revoking a session token
See Using AuthSub with the Google Data API Client Libraries.
Tip: Once your application has successfully acquired a long lived sessions token, store that token in your database to recall for later use. There’s no need to send the user back to AuthSub on every run of your application. Use client.auth_token = gdata.gauth.AuthSubToken(TOKEN_STR) to set an existing token on the client.
OAuth for web or installed/mobile applications
OAuth can be used as an alternative to AuthSub, and is intended for web applications. OAuth is similar to using the secure and registered mode of AuthSub in that all data requests must be digitally signed and you must register your domain.
ClientLogin for installed/mobile applications
ClientLogin should be used by installed or mobile applications which need to authenticate their users to Google accounts. On first run, your application prompts the user for their username/password. On subsequent requests, an authentication token is referenced.
To use ClientLogin, invoke the ClientLogin() method of DocsClient object, which is inherited from GDClient. Specify the email address and password of the user on whose behalf your client is making requests. For example:
client = gdata.docs.client.DocsClient(source='yourCo-yourAppName-v1')
client.ClientLogin('[email protected]', 'pa$$word', client.source);
Tip: Once your application has successfully authenticated the user for the first time, store the auth token in your database to recall for later use. There’s no need to prompt the user for his/her password on every run of your application. See Recalling an auth token for more information.
For more information on using ClientLogin in your Python applications, see the Using ClientLogin with the Google Data API Client Libraries.
Back to top
Retrieving a list of documents
To fetch a feed containing a list of the currently authenticated user’s documents, call the client’s GetDocList() method. By default, this method queries the main doclist feed URI:
https://docs.google.com/feeds/default/private/full
You can pass GetDocList() an optional customized query URI and/or limit for the maximum number of results to return within a page.
Here is an example of querying the user’s doclist and printing the title, type, and resource id of a document:
def PrintFeed(feed):
print '\n'
if not feed.entry:
print 'No entries in feed.\n'
for entry in feed.entry:
print entry.title.text.encode('UTF-8'), entry.GetDocumentType(), entry.resource_id.text
# List folders the document is in.
for folder in entry.InFolders():
print folder.title
feed = client.GetDocList()
PrintFeed(feed)
The resulting feed is a gdata.docs.data.DocList containing a list of gdata.docs.data.DocsEntry. Each entry represents a document (spreadsheet, presentation, word processor document, pdf, etc.) in the user’s document list. The DocsEntry encapsulates the information shown in the protocol developer’s guide.
Document resource ID
This guide often refers to the notion of a “document ID” and a document “resource ID”. The resource ID can be used in a number of places, most notably when exporting the document or querying for the entry again. Each resource ID includes the type of document and the document’s unique ID. It can be found as a property of a gdata.docs.data.DocsEntry object:
entry.resource_id.text
The document ID is the alphanumeric portion of the resource ID: everything following the ‘:’ or ‘%3A’. It is recommend that you store a document’s full resource ID rather than just the document ID because the type is included within the entire resource ID.
Paging through results
By default the API will return the first 100 documents in the user’s document list. This saves bandwidth and improves performance. To retrieve the rest of the user’s docs, your client needs to page through the results by following the feed.GetNextLink(). Alternatively, the library’s GetEverything() method can be used to fetch the entire list:
docs = client.GetEverything() # makes multiple HTTP requests.
print 'User has a total of %s documents in their account' % len(docs)
for doc in docs:
print doc.title.text, ' - ', doc.GetDocumentType()
Retrieving a entry or resource again
If you want to retrieve a document entry that you’ve retrieved before, you can improve efficiency by telling the server to send the entry only if it has changed since the last time you retrieved it.
To do this sort of conditional retrieval, call the GetDoc() with the document’s resource id and the entry’s ETag (entry.etag). For example:
import gdata.client
try:
doc = client.GetDoc('document%3A0AdkQLCU4KIBYZGZya2o4NGdfMTQ2NWhiemZjZ2M5', etag='"WEwVFBBDBSp7ImBr"')
except gdata.client.NotModified, error:
print error
When the server receives this request, it checks to see whether the item that you requested has the same ETag as the one you specified. If the ETags match, then the item hasn’t changed, and the server returns either an HTTP 304 Not Modified status code or an HTTP 412 Precondition Failed status code. Both of those status codes indicate that the item you just retrieved is up-to-date.
If the ETags don’t match, then the item has been modified since the last time you requested it, and the server returns the updated entry.
For more information about ETags, see the Google Data APIs Reference Guide.
Back to top
Searching the documents feed
You can search the Document List using some of the standard Google Data API query parameters. Categories are used to restrict the type of document (spreadsheet, folder, etc.) returned. The full-text query string (q parameter) is used to search the content of all the documents. More detailed information on parameters specific to the Documents List can be found in the Documents List Data API Reference Guide.
Retrieving all documents and folders
A list of all the user’s document and folders can be retrieved by addingthe showfolders=true parameter to the main doclist URI:
feed = client.GetDocList(uri='/feeds/default/private/full?showfolders=true')
Retrieving all word processor documents
A list of only word processor documents can be retrieved by using the document category as follows:
feed = client.GetDocList(uri='/feeds/default/private/full/-/document')
Retrieving all spreadsheets
A list of only spreadsheets can be retrieved by using the spreadsheet category as follows:
feed = client.GetDocList(uri='/feeds/default/private/full/-/spreadsheet')
Category queries can work for other document types as well. For a list of possible categories, see the Reference Guide.
Retrieving all presentations that I own
A list of pdfs the user’s owns can be queried with the pdf and mine categories:
feed = client.GetDocList(uri='/feeds/default/private/full/-/pdf/mine')
Retrieving a list of folders
A list of only folders can be retrieved by using the folder category:
feed = client.GetDocList(uri='/feeds/default/private/full/-/folder')
Retrieving a certain arbitrary file type
To return a list of arbitrary files of mimetype application/msword, send a category query that includes the scheme and content type:
feed = client.GetDocList(uri='/feeds/default/private/full/-/{http://schemas.google.com/g/2005#kind}application/msword')
Note, this URL needs to be fully URL encoded:
feed = client.GetDocList(
uri='/feeds/default/private/full/-/%7Bhttp%3A%2F%2Fschemas.google.com%2Fg%2F2005%23kind%7Dapplication%2Fmsword')
More example queries can be found in the protocol guide.
Performing title queries
It is possible to retrieve documents by matching on their title rather than contents. To do this, add the title parameter query URI. To match a title exactly, add a title-exact=true parameter to indicate this is the full, explicit title. Since this parameter is case-insensitive and since multiple docs can have the same title, a feed is returned.
feed = client.GetDocList(uri='/feeds/default/private/full?title=Test&title-exact=true&max-results=5')
Note: title-exact queries are case-insenstive. For example, the sample above will print documents that match “Test”, “test”, and “TeSt”, but not “Test title”.
Performing a full text query
You can also search the contents of documents by using the q parameter:
feed = client.GetDocList(uri='/feeds/default/private/full?q=example+query')
This searches the entire contents of every document for the string “example query” and returns all documents where this string is found. This is different than searching just the title of every document, which can be done as described in the section Performing title queries.
Back to top
Retrieving folder contents
To retrieve a list of items in a particular folder, pass the GetDocList() method a folder’s content feed URI:
https://docs.google.com/feeds/default/private/full/folder%3Afolder_id/contents
A folder’s content feed can be found as entry.content.src on a folder entry. Each folder entry in the documents list will contain such a link.
The following example queries for a list of folders, fetches the items contained in the first result, and prints the title and folders the resource is in:
feed = client.GetDocList(uri='/feeds/default/private/full/-/folder')
folder = feed.entry[0]
print 'Contents of folder: ' + folder.title.text
feed = client.GetDocList(uri=folder.content.src)
for doc in feed.entry:
print doc.title.text, [f.title for f in doc.InFolders()]
By default, folder entries will be returned within the folders feed (e.g. you don’t have to include the showfolders=true parameter. The folders feed can also be queried using the query parameters defined in the Documents List Data API Reference Guide.
Querying for resources at the root folder level
You can query for a list of documents/folders at the root level by using folder:root as the folder feed’s resource ID. For example:
feed = client.GetDocList(uri='/feeds/default/private/full/folder%3Aroot/contents/-/folder')
Back to top
Uploading documents
Creating an empty document
The API allows for creating empty documents using the Create() method. The examples below create a few documents (of various types) in the user’s doclist.
# Create an empty document
new_doc = client.Create(gdata.docs.data.DOCUMENT_LABEL, 'My Doc')
print 'Document "%s" created' % new_doc.title.text
# Create an empty spreadsheet. By default, the writers_can_invite setting is True.
new_spreadsheet = client.Create(gdata.docs.data.SPREADSHEET_LABEL, 'My Spreadsheet', writers_can_invite=False)
print 'Spreadsheet "%s" created' % new_spreadsheet.title.text
# Create an empty presentation
new_preso = client.Create(gdata.docs.data.PRESENTATION_LABEL, 'My Presentation')
print 'Presentation "%s" created' % new_preso.title.text
Uploading documents with content
The Python client library provides an Upload() method for uploading documents to Google Docs. You can choose to use a gdata.data.MediaSource object or pass the file name directly. For more information on the MediaSource class, please use the Python built-in documentation system:
import gdata.data
help(gdata.data.MediaSource)
For your convenience, there is a static dictionary member in the gdata.docs.data module named MIMETYPES. It maps upper-case file extensions to their common MIME types.
This example uploads a word processor document, assuming file_path is the path to a valid document. The entry returned from the upload is a gdata.docs.data.DocsEntry object containing information about the document that was created on the server.
ms = gdata.data.MediaSource(file_path='/path/to/your/test.doc', content_type='application/msword')
entry = client.Upload(ms, 'MyDocTitle')
print 'Document now accessible online at:', entry.GetAlternateLink().href
Similarly, you can pass in the file name directly to Upload():
entry = client.Upload('/path/to/your/test.doc', 'MyDocTitle', content_type='application/msword')
print 'Document now accessible online at:', entry.GetAlternateLink().href
If passing a filename, always provide the content type.
Creating/uploading documents to folders
Both Create() and Upload() accept an additional keyword arg for specifying a folder to create/upload a document to.
Creating an empty document in a folder
To create an empty document, presentation, or spreadsheet in an existing folder, pass Create() a DocsEntry object or resource ID representing the destination folder.
new_doc = client.Create(gdata.docs.data.DOCUMENT_LABEL, 'MyDocTitle', folder_or_id=dest_folder)
It is assumed dest_folder is a gdata.docs.data.DocsEntry object representing the destination folder.
Uploading a document to a folder
Similar to creating a document inside a folder, you can upload an existing resource directly into a folder by passing Upload() a DocsEntry object or full URI of the destination folder.
new_spreadsheet = client.Upload('/path/to/your/test.csv', 'MyDocTitle', content_type='text/csv', folder_or_uri=dest_folder)
It is assumed dest_folder is a gdata.docs.data.DocsEntry object representing the destination folder.
Uploading files of any type
Note: This feature is only available to Google Apps Premier domains.
Google Apps Premier domains can upload files of arbitrary type. Uploading an arbitrary file is the same as uploading documents (with and without metadata), except there is no restriction on the file’s Content-Type. Unlike normal document uploads, arbitrary file uploads preserve their original format/extension, meaning there is no loss in fidelity when the file is stored in Google Docs.
By default, uploaded document files will be converted to a native Google Docs format. For example, an .xls upload will create a Google Spreadsheet. To keep the file as an Excel spreadsheet (and therefore upload the file as an arbitrary file), specify the convert=false parameter to preserve the original format. The convert parameter is true by default for document files. The parameter will be ignored for types that are not convertible (e.g. .exe, .mp3, .mov, etc.).
Here is an example of uploading a .doc file as an arbitrary file:
import os.path
f = open('/path/to/your/test.doc')
ms = gdata.data.MediaSource(file_handle=f, content_type='application/msword', content_length=os.path.getsize(f.name))
entry = client.Upload(ms, f.name, folder_or_uri=client.DOCLIST_FEED_URI + '?convert=false')
A list of common mimetypes can be found here.
All document entries will be marked with a field that indicates the amount of quota a file is using: entry.quota_bytes_used.text. File size limits for arbitrary uploads are posted in the Google Docs Help Center.
Back to top
Copying documents
Note: The copy feature is only available for document, spreadsheet, and presentation types. Other formats (e.g. PDFs) do not support the copy command.
To duplicate a document in a user’s document list, set the entry.id.text to the source entry’s self link (source_entry.GetSelfLink().href). The library has a Copy() method to do this for you.
duplicated_entry = client.Copy(source_entry, 'MyTwin')
Note: A document cannot be copied directly into a folder. Instead, first issue the copy command, followed by a move operation. See Moving a resource into a folder.
Back to top
Updating existing documents
Updating documents requires the use of ETags to make sure you are not overwriting another client’s changes. An entry’s ETag can be found by calling entry.etag.
Note: If you want to update a document regardless of whether someone else has updated it since you last retrieved it, substitute "*" for the entry’s ETag value or include the force=True argument on the call to Update(). That will force a unconditional delete on the entry.
For more information on ETags, see the Google Data APIs Reference Guide.
Here is an example of updating a presentation’s metadata, but leaving its content unchanged. The presentation’s name will be changed to ‘Better presentation title’. Simply pass your modified entry to the client’s Update() method.
existing_entry.title.text = 'Better presentation title'
updated_entry = client.Update(existing_entry)
# To force the update, even if another client has made changes.
# updated_entry = client.Update(existing_entry, force=True)
Replacing a document’s content
To update a document’s content, use the Atom entry’s edit-media link. The following example replaces the document’s content with replacementContent.doc’s content, and updates the document’s title to ‘updated document’ in the same request.
import gdata.data
# Load the replacement content in a MediaSource. Also change the attachment's title and description.
ms = gdata.data.MediaSource(file_path='/path/to/replacementContent.doc', content_type='application/msword')
entry.title.text = 'updated document'
updated_entry = client.Update(entry, media_source=ms)
print "Document '%s' changed to '%s'" % (entry.title.text, updated_entry.title.text)
Back to top
Deleting documents and folders
Trashing a document or folder
To trash a document or folder, use the Delete() method of the client object on the edit link of the Atom entry representing the document. For example, to trash one of the new documents from the upload examples above, you would execute the following.
client.Delete(entry)
# To force the update, regardless of another client's changes:
# client.Delete(entry, force=True)
If the document was deleted successfully, the server responds with an HTTP 200 OK.
Deleting a document or folder
Deleting a document or folder permanently removes the object from the user’s documents list. The process for deleting a document is similar to trashing a document, just include the delete=true parameter.
client.Delete(entry.GetEditLink().href + '?delete=true', force=True)
Back to top
Downloading and exporting documents
To export documents from the Documents List feed, you need an entry object or the resource ID (e.g. document:12345) of the document, spreadsheet, or presentation.
Tip: You can use the gdata.client.DocsClient.GetFileContent() method to return a files contents in memory (rather than writing it to local disk). The examples below write the file to disk.
Exporting word processor documents
The following example fetches a document by its resource id, and exports the entry as a .doc file:
entry = client.GetDoc('document%3A0AdkQLChiemZjZ2M5')
file_path = '/path/to/save/your_document.doc'
print 'Exporting document to %s...' % file_path
client.Export(entry, file_path)
print 'Exported %s as a .doc file' % entry.title.text
Alternatively, you can pass in the resource id, as the Export helper method also accepts that. The following example exports the same resource as a .html file:
file_path = '/path/to/save/your_document.html'
print 'Exporting document to %s...' % file_path
client.Export('document%3A0AdkQLChiemZjZ2M5', file_path)
print 'Exported document as a .doc file'
Exporting presentations
The following example exports a presentation entry as a .swf file:
file_path = '/path/to/save/your_presentation.swf'
print 'Downloading presentation to %s...' % file_path
client.Export(entry, file_path)
Exporting spreadsheets
The following example exports a spreadsheet entry as an .xls file:
file_path = '/path/to/save/your_spreadsheets.xls'
print 'Downloading spreadsheet to %s...' % file_path
client.Export(entry, file_path)
When exporting to .csv or .tsv, you can specify which grid/sheet to download by using the gid argument:
file_path = '/path/to/save/your_spreadsheets.csv'
print 'Downloading spreadsheet to %s...' % file_path
client.Export(entry, file_path, gid=1) # export the second sheet
Important: In order to download spreadsheets, your client needs a valid token for the Spreadsheets API service. See the downloading spreadsheets section of the protocol guide for more details.
Exporting Spreadsheets using AuthSub/OAuth
If you’re using AuthSub, request a multi-scoped token, good for both the Documents List API and the Spreadsheets API. Pass in scope=['https://docs.google.com/feeds/', 'https://spreadsheets.google.com/feeds/'] to gdata.gauth.generate_auth_sub_url().
Exporting Spreadsheets using ClientLogin
For ClientLogin, first create a SpreadsheetsService object (to obtain a spreadsheets token), and then swap that token into your DocsClient object. This example demonstrates that process:
import gdata.spreadsheet.service
spreadsheets_client = gdata.spreadsheet.service.SpreadsheetsService(source='yourCo-yourAppName-v1')
spreadsheets_client.ClientLogin('[email protected]', 'pa$$word', client.source)
# substitute the spreadsheets token into our client
docs_token = client.auth_token
client.auth_token = gdata.gauth.ClientLoginToken(spreadsheets_client.GetClientLoginToken())
client.Export(entry, file_path)
client.auth_token = docs_token # reset the DocList auth token
Downloading PDFs and arbitrary files
PDF and arbitrary files cannot be exported in a format other than the format they are stored in. It is also not possible to manually construct the download URL for these types of files. Instead, your client can use the Download() method to send an HTTP GET to the entry’s content ‘src’ link:
entry = client.GetDoc('pdf%3A0B9kQLCU4KIBNzA4NTQ4NTdhYmM4')
client.Download(entry, '/path/to/save/%s.pdf' % entry.title.text)
print 'Downloaded pdf'
Tip: You can use the gdata.client.DocsClient.GetFileContent() method to return a file’s contents in memory (rather than writing it to local disk). The examples below write the file to disk.
Back to top
Folder management
Creating folders
The Create() helper can also be used to create a folder. Simply pass it a folder category and folder name:
new_folder = client.Create(gdata.docs.data.FOLDER_LABEL, 'My Folder')
print 'Folder "%s" created' % new_folder.title.text
To create a folder inside another folder, pass in a parent folder entry (or resource ID) as the folder_or_id kwarg. This example will create a new subfolder named ‘SubFolder’ under the previous example ‘My Folder’:
sub_folder = client.Create(gdata.docs.data.FOLDER_LABEL, 'SubFolder', folder_or_id=new_folder)
Moving documents and folders
Moving a document into a folder requires that you have a gdata.data.DocsEntry object for the document, and another for the folder to which the document should be moved. The DocsClient module provides a Move() method for moving resources in and out of folders.
source_doc = client.GetDoc('document%3A0AdkQLCU4KIBYZGZya2o4NGdfMTQ2MmdkbW1wamM3')
dest_folder = client.GetDoc('folder%3A0B9kQLCU4KIBYZWM4YjIwMjYtZDI1My00YWM4LWE1ZDktZTZjOGVjMzJkNjYz')
new_entry = client.Move(source_doc, dest_folder)
print '%s moved into %s' % (source_doc.title.text, dest_folder.title.text)
The first argument to Move() is a DocsEntry object representing the source folder or document to relocate. The second argument is a DocsEntry object representing the destination folder.
Note: This method performs a true move; meaning the resource will be removed from any folder(s) it is currently in. To add a resource to an additional folder, be sure to specify the keep_in_folders=True keyword argument.
This example removes a document from the folder(s) it is in, moving it to the root level:
was_moved = client.Move(source_doc)
print '%s moved to root level' % source_doc.title.text
Back to top
Modifying Document Sharing Permissions
Overview of Sharing (ACLs)
Document and folder sharing is controlled via the access control list feed. Access control lists are just basic lists that show who has access to a given resource. In the ACL feed, we have the following roles for a given document or folder:
- owner — the owner of the document. As an owner you have the ability to modify the ACL feed, delete the document, etc.
- writer — a collaborator.
- reader — a viewer (equivalent to read-only access).
Note: Please note that the accepted values for each role are case-sensitive.
The API supports sharing permissions on multiple levels. These values correspond to the acl_entry.scope.type attribute:
- user — a user’s email address.
- group — a Google Group email address.
- domain — a Google Apps domain.
Retrieving the ACL feed for a document
The GetAclPermissions() method can be used to retrieve the sharing permissions for a document. To retrieve the permission for a given resource, you need the acl feed link: doc_entry.GetAclFeedLink().
The following example fetches the first document the authenticated user owns, queries its ACL feed, and prints out the permission entries:
feed = client.GetDocList(uri='/feeds/documents/private/full/-/mine?max-results=1')
acl_feed = client.GetAclPermissions(feed.entry[0].resource_id.text)
for acl in acl_feed.entry:
print '%s (%s) is %s' % (acl.scope.value, acl.scope.type, acl.role.value)
Modifying the ACL feed for a document
Adding a new permission
To add a new permission to a document, your client needs to create a new gdata.docs.data.Acl and POST it to the server.
Here’s an example that adds ‘[email protected]’ as a reader to a document represented by doc_entry:
import gdata.acl.data
scope = gdata.acl.data.AclScope(value='[email protected]', type='user')
role = gdata.acl.data.AclRole(value='reader')
acl_entry = gdata.docs.data.Acl(scope=scope, role=role)
new_acl = client.Post(acl_entry, doc_entry.GetAclFeedLink().href)
print "%s %s added as a %s" % (new_acl.scope.type, new_acl.scope.value, new_acl.role.value)
Possible values for the Role are reader, writer, and owner.
Group and Domain level sharing
Similar to sharing with a single user, you can share documents or folders across a Group or domain if you have a Google Apps domain.
To share a resource or folder with an entire Google Apps domain, set the AclScope as such:
scope = gdata.acl.data.AclScope(value='example.com', type='domain')
Note: Certain sharing ACLs may only be possible if the domain is configured to allow such permissions (e.g. if sharing outside of the domain for Google Apps domains is enabled, etc).
To share a document or folder with a Google Group mailing list, set the AclScope as such:
scope = gdata.acl.data.AclScope(value='[email protected]', type='group')
Updating sharing permissions
We can update the ACL entry that was just added by calling Update() with the updated ACL entry.
This example modifies our previous acl_entry by updating ‘[email protected]’ to be a writer (collaborator):
acl_entry.role.value = 'writer'
updated_acl = client.Update(acl_entry)
# To force the update, even if you do not have the latest changes to the entry:
# updated_acl = client.Update(acl_entry, force=True)
Removing sharing permissions
To remove an existing sharing permission, first retrieve the AclEntry, then call the client’s Delete() method. For example:
acl_entry = client.GetAclPermissions('presentation%3A0A1234567890').entry[0]
client.Delete(acl_entry)
You can also pass the ACL entry’s edit link instead of an entry object, and/or force the deletion with force=True:
# force=True sets the If-Match: * header instead of using the entry's ETag.
client.Delete(acl_entry.GetEditLink().href, force=True)
For more information about ETags, see the Google Data APIs Reference Guide.
Back to top
Document Revisions
Retrieving document revisions
Document revisions are available via the revisions feed. Similar to the <gd:feedLink> for ACLs, every document entry will have a <gd:feedLink> pointing to the revisions feed:
revision_feed_link = entry.GetRevisionsFeedLink().href
To fetch the revision history for a given document, use the GetRevisions() method, passing it a resource ID:
revision_feed = client.GetRevisions('spreadsheet%3A0A1234567890')
The server will respond with a gdata.docs.data.RevisionFeed containing a list of gdata.docs.data.Revision entries.
Properties of a revision entry:
- The
entry.updated.text field is the timestamp a revision was created.
- The
entry.author[0].email.text field is the creator of that revision.
- An
entry.publish element will be present and its value attribute set to “true” if the revision is published. The entry’s published link can be accessed by revision_entry.GetPublishLink().href
- A
entry.publish_auto element will be present if the revision is published. Its value attribute will be set to “true” if the “Automatically re-publish when changes are made” checkbox has been selected in the Google Docs UI.
- A
entry.publish_outside_domain field will be present if the revision is published and the document is in a Google Apps domain. Its value property will be set to “true” (the default) if the document has been published outside of the domain.
Note: While document and presentation revisions have an auto-incrementing revision number, this may have gaps if revisions are deleted so you should not rely on a consecutive numbering. Spreadsheet revisions look almost identical, but their revision IDs are not zero-based and auto-incrementing – instead they are based on the revision’s timestamp, and so they will be an increasing series of seemingly random numbers.
Downloading a revision
The <atom:content> field’s ‘src’ attribute can be used to download a particular revision. In the case of a native Google Document format, you can also download the document in the API’s supported exportFormats:
entry.content.src
See the Downloading documents section for examples of how to download/export documents.
Note: You will need a valid AuthSub/OAuth or ClientLogin token valid for the appropriate service. See the Downloading and exporting documents section.
Publishing documents
Note: The publishing features are only available for document, spreadsheet, and presentation types. Other formats (e.g. PDFs) do not support the publishing commands.
The API supports the following modifications to a document’s published settings:
- Publish/unpublish a document
- Publish a document at a different revision
- Change whether document changes are auto-republished
- Change whether documents are published outside of a Google Apps domain
To change the published settings on a document, fetch the revision entry in question, modify the publish properties of the entry, and call the client’s Update() method.
This example fetches the revision feed for a document, and publishes the first revision by modifying its publish settings:
# Fetch document document%3A0AdkQp0MnpnZjQz's revision feed.
revision_feed = client.GetRevisions('document%3A0AdkQp0MnpnZjQz')
entry = revision_feed.entry[0]
# Modify the first revision entry's publised settings.
entry.publish = gdata.docs.data.Publish(value='true')
entry.publish_auto = gdata.docs.data.PublishAuto(value='false')
# Send the modified entry to the server.
updated_entry = client.Update(entry, force=True)
print 'Revision published at %s' % updated_entry.GetPublishLink().href
Note that entry.publish_auto.value must be set to “false” in order to publish a version other than the latest version. If you try to publish a revision and publish_auto is set to “true”, the document’s head revision will still be the version published.
Note: Unless you are unpublishing a document, the revision entry should include all published elements: publish, publish_auto (and publish_outside_domain if in a Google Apps domain). Also, whether or not a document can be published outside the domain will be determined by the domain’s policy settings in the Google Apps control panel.