The Blogger Data API allows client applications to view and update Blogger content in the form of Google Data API feeds.
Your client application can use the Blogger Data API to create new blog posts, edit or delete existing blog posts, and query for blog posts that match particular criteria.
In addition to providing some background on the capabilities of the Blogger Data API, this document provides examples of basic Data API interactions using the Python client library. If you're interested in understanding more about the underlying protocol that the library uses, see the Protocol section of this developer's guide.
Contents
Audience
This document is intended for programmers who want to write Python client applications that can interact with Blogger.
This document assumes that you understand the general ideas behind the Google Data APIs protocol.
For general Blogger Data API reference information, see the Protocol reference guide.
Getting started
For help setting up the client library, see the Getting Started Guide.
The Python client library requires Python 2.2 or newer. After downloading the client library, you will also need to download and install the ElementTree package.
Creating a Blogger account
You may want to sign up for a Blogger account for testing purposes. Blogger uses Google Accounts, so if you already have a Google account, you're all set.
Running the sample code
A full working sample client, containing all the sample code shown in this
document, is available in the BloggerExample.py
file, under the directory
gdata-python-client/samples/blogger/
.
The sample client performs several operations on the provided blog to demonstrate the use of the Blogger Data API.
You can run the sample with the following arguments:
python BloggerExample.py --email [email_address] --password [password]
To use the examples in this document in your own code, you'll need the
following import
statements:
from gdata import service import gdata import atom
Authenticating to the Blogger service
You can access both public and private feeds using the Blogger Data API. Public feeds don't require any authentication, but they are read-only. If you want to modify blogs, then your client needs to authenticate before requesting private feeds. It can authenticate using any of three approaches:OAuth authentication, AuthSub proxy authentication or ClientLogin username/password authentication.
For more information about authentication with Google Data APIs in general, see the authentication documentation.
Most of the samples in subsequent sections of this document assume you have
an authenticated GDataService
instance.
OAuth authentication
For documentation about OAuth authentication using the Python GData library, please see OAuth in the Google Data Protocol Client Libraries.
AuthSub proxy authentication
AuthSub proxy authentication is used by web applications that need to authenticate their users to Google Accounts. The website operator and the client code don't have access to the username and password for the Blogger user; instead, the client obtains special AuthSub tokens that allow the client to act on a particular user's behalf. For more detailed information, see the AuthSub documentation.
When a user first visits your application, they have not yet been authenticated. In this case, you need to display some information and a link directing the user to a Google page to authenticate your request for access to their blogs. The Python client library provides a function to generate the Google page's URL. The code below retrieves the URL of the AuthSubRequest page:
def GetAuthSubUrl(): next = 'http://www.example.com/welcome.pyc' scope = 'http://www.blogger.com/feeds/' secure = False session = True blogger_service = service.GDataService() return blogger_service.GenerateAuthSubURL(next, scope, secure, session); authSubUrl = GetAuthSubUrl(); print '<a href="%s">Login to your Google account</a>' % authSubUrl
The GenerateAuthSubURL
method takes the following parameters
(corresponding to the query parameters used by the AuthSubRequest handler):
- next
- The URL of the page that Google should redirect the user to after authentication.
- scope
- Indicates that the application is requesting a token to access Blogger feeds. The scope string to use is
http://www.blogger.com/feeds/
(URL-encoded, of course). - secure
- Indicates whether the client is requesting a secure token.
- session
- Indicates whether the token returned can be exchanged for a multi-use (session) token.
The above example shows a call that doesn't request a secure token (the value of secure
is False
). The resulting request URL might look like this:
https://www.google.com/accounts/AuthSubRequest?scope=https%3A%2F%2F1.800.gay%3A443%2Fhttp%2Fwww.blogger.com%2Ffeeds%2F&session=1&secure=0&next=https%3A%2F%2F1.800.gay%3A443%2Fhttp%2Fwww.example.com%2Fwelcome.pyc
The user follows the link to Google's site and authenticates to their Google Account.
After the user authenticates, the AuthSub system redirects them to the URL
you specified in the next
query parameter of the AuthSubRequest
URL. The AuthSub system appends an authentication token to that URL, as the
value of the token
query parameter. For example:
http://www.example.com/welcome.pyc?token=yourAuthToken
There are several ways to retrieve the token value from the URL; for example:
import cgi parameters = cgi.FieldStorage() authsub_token = parameters['token']
This token value represents a single-use AuthSub token. In this example,
since session = True
was specified, this token can be exchanged for
an AuthSub session token using the UpgradeToSessionToken
method,
which calls the AuthSubSessionToken
service:
blogger_service = service.GDataService() blogger_service.auth_token = authsub_token blogger_service.UpgradeToSessionToken()
That is, you pass your one-time-use token to the
UpgradeToSessionToken
method, and the AuthSub interface returns a
session token.
Your application can then use the session token value in subsequent interactions with Blogger. The client library automatically sends the token along with requests.
ClientLogin username/password authentication
Use ClientLogin authentication if your client is a standalone, single-user
"installed" client (such as a desktop application). Just call the
ProgrammaticLogin()
method on your GDataService
instance and all subsequent interactions with Blogger will be
authenticated:
blogger_service = service.GDataService('[email protected]', 'secretPassword') blogger_service.source = 'exampleCo-exampleApp-1.0' blogger_service.service = 'blogger' blogger_service.account_type = 'GOOGLE' blogger_service.server = 'www.blogger.com' blogger_service.ProgrammaticLogin()
In the snippet above, we set three properties on the
GDataService
instance. The first is the name of our application in
the form companyName-applicationName-versionID.
The second is the name of the service we want to interact with; the third is the
server's address.
Notice that account_type
is explicitly set to
GOOGLE
. Failure to set this parameter will prevent G Suite users from successfully using
the Blogger API.
For more information about ClientLogin authentication, including sample requests and responses, see the Authentication for Installed Applications documentation.
Note: Use the same token for all requests in a given session; don't acquire a new token for each Blogger request.
Note: As described in the ClientLogin
documentation, the authentication request may fail and request a CAPTCHA
challenge. If you want Google to issue and handle the CAPTCHA challenge, then
send the user to
https://www.google.com/accounts/DisplayUnlockCaptcha?service=blogger
(rather than to the CAPTCHA-handling URL given in the ClientLogin
documentation).
Retrieving a list of blogs
The Blogger Data API provides a feed that lists the blogs for a particular user; that feed is known as a "metafeed."
The following sample code uses an authenticated GDataService
instance to retrieve the metafeed and then prints each blog's title.
def PrintUserBlogTitles(blogger_service): query = service.Query() query.feed = '/feeds/default/blogs' feed = blogger_service.Get(query.ToUri()) print feed.title.text for entry in feed.entry: print "\t" + entry.title.text
Note the URL used by the Get
method. This is the default
metafeed URL; it returns a list of blogs for the currently authenticated user.
To access a feed for a different user, you can put the user's ID in place of
default
in the metafeed URL. The user's ID is the string of digits
at the end of the user's profile URL.
The snippet of code below demonstrates how to extract a blog ID from the feed. You will need the blog ID to perform create, update, and deletion operations on posts and comments. The snippet below chooses the first blog retrieved for a user.
blog_id = feed.entry[0].GetSelfLink().href.split("/")[-1]
In the BloggerExample.py
sample, a BloggerExample
class is created, and the blog ID is set in the constructor for easy access
later on. For most of the following examples in this document,
blog_id
is passed in as a variable.
Creating posts
The Blogger Data API allows you to create and publish new blog entries, as well as creating drafts of entries.
Note: Setting a custom author for posts is currently not supported. All new posts will appear as if they were created by the currently authenticated user.
Publishing a blog post
You can use the Python client library to publish new blog entries.
First, create a GDataEntry
instance to represent the blog post.
Then you can set the title, content and other attributes of the blog post.
Finally, use the GDataService
instance to insert the post. Here's
an example of how to publish a new blog post:
def CreatePublicPost(blogger_service, blog_id, title, content): entry = gdata.GDataEntry() entry.title = atom.Title('xhtml', title) entry.content = atom.Content(content_type='html', text=content) return blogger_service.Post(entry, '/feeds/%s/posts/default' % blog_id) blogEntry = CreatePublicPost(blogger_service, blog_id, title='I have the answer', content='Eureka! It is 42!')
Creating a draft blog post
Draft posts are created in the same way as public posts, but you need to set
the draft
extension element in the GDataEntry
instance. The blog post above could be created as a draft by adding the
highlighted lines:
def CreateDraftPost(blogger_service, blog_id, title, content): entry = gdata.GDataEntry() entry.title = atom.Title('xhtml', title) entry.content = atom.Content(content_type='html', text=content) control = atom.Control() control.draft = atom.Draft(text='yes') entry.control = control return blogger_service.Post(entry, '/feeds/%s/posts/default' % blog_id) draftEntry = CreateDraftPost(blogger_service, blog_id, title='I have the question', content='What do you get if you multiply six by nine?')
You can turn an existing draft blog post into a published post by retrieving
the draft post, setting the draft attribute to no
, and then
updating the post. We'll cover retrieving and updating posts in the next two
sections.
Retrieving posts
The following sections describe how to retrieve a list of blog posts, with and without query parameters.
You can query a Blogger public feed without authentication. Therefore, you don't need to set credentials or do AuthSub authentication before retrieving posts from a public blog.
Retrieving all blog posts
To retrieve the user's posts, call the GetFeed
method with the
blog-post feed URL:
def PrintAllPosts(blogger_service, blog_id): feed = blogger_service.GetFeed('/feeds/' + blog_id + '/posts/default') print feed.title.text for entry in feed.entry: print "\t" + entry.title.text print "\t" + entry.content.text print "\t" + entry.updated.text print
Retrieving posts using query parameters
The Blogger Data API lets you request a set of entries that match specified
criteria, such as requesting blog posts published or updated in a given date
range. To do this, you create a Query
instance and then call the
Get()
method.
For example, to send a date-range query, set the published_min
and published_min
properties of the Query
instance.
The following code snippet prints the title and content of each blog post
published between the given start time and end time:
def PrintPostsInDateRange(blogger_service, blog_id, start_time='2007-04-01', end_time='2007-04-25'): query = service.Query() query.feed = '/feeds/' + blog_id + '/posts/default' query.published_min = start_time query.published_max = end_time feed = blogger_service.Get(query.ToUri()) print feed.title.text + " posts between " + start_time + " and " + end_time for entry in feed.entry: print "\t" + entry.title.text print "\t" + entry.content.text print "\t" + entry.updated.text print
Notice that the Query
object is constructed using the same post
feed URL used to retrieve posts.
The Blogger Data API supports the following Query
properties:
- categories
- Specifies categories (also known as labels) to filter the feed results. For example,
http://www.blogger.com/feeds/blogID/posts/default/-/Fritz/Laurie
returns entries with both the labelsFritz
andLaurie
. To specify that category query in the Python client library, you can usequery.categories = ['Fritz','Laurie',]
- max_results
- The maximum number of entries to return.
- published_min, published_max
- The bounds on entry publication dates.
- start_index
- The 1-based index of the first result to be retrieved (for paging).
- updated_min, updated_max
- The bounds on entry update dates. These query parameters are ignored unless the
orderby
parameter is set toupdated
.
For more information about query parameters, see the Blogger Data API Reference Guide and the Google Data APIs Reference Guide.
Updating posts
To update an existing blog post, first you retrieve the entry you want to
update, then you modify it, and then you send it to Blogger using the
Put
method. The following code snippet modifies the title of a blog
entry, assuming that you've already retrieved the entry from the server.
def UpdatePostTitle(blogger_service, entry_to_update, new_title='The REAL answer'): entry_to_update.title = atom.Title('xhtml', new_title) return blogger_service.Put(entry_to_update, entry_to_update.GetEditLink().href)
The above code returns a GDataEntry
containing the entire
newly-updated post. To update any other properties, simply set them in the
GDataEntry
instance before calling Put
.
Note: Modifying the author data associated with posts is currently not supported.
Deleting posts
To delete a post, pass the post's edit URL to the Delete
method
on your GDataService
object, like this:
def DeletePost(blogger_service, edit_link_href): blogger_service.Delete(edit_link_href)
Comments
The Blogger Data API allows for creating, retrieving, and deleting comments. Updating comments is not supported (nor is it available in the web interface).
Creating comments
To post a comment, create a GDataEntry
object and insert it as follows:
def CreateComment(blogger_service, blog_id, post_id, comment_text='Mostly harmless'): feed_uri = '/feeds/' + blog_id + '/' + post_id + '/comments/default' entry = gdata.GDataEntry() entry.content = atom.Content(content_type='xhtml', text=comment_text) return blogger_service.Post(entry, feed_uri)
Note: Currently, you can only post comments to a blog owned by the authenticated user.
Note: Setting a custom author for comments is currently not supported. All new comments will appear as if they were created by the currently authenticated user.
Retrieving comments
You can retrieve the comments for a particular post from the post's comments feed URL:
def PrintAllComments(blogger_service, blog_id, post_id): feed_url = '/feeds/' + blog_id + '/' + post_id + '/comments/default' feed = blogger_service.Get(feed_url) print feed.title.text for entry in feed.entry: print "\t" + entry.title.text print "\t" + entry.updated.text print
Or you can get the comments from all posts by using the blog's comments feed URL:
http://www.blogger.com/feeds/blogID/comments/default
Deleting comments
To delete a comment, pass the comment's edit URL to the Delete
method on your GDataService
object like this:
def DeleteComment(blogger_service, post_id, comment_id): feed_url = '/feeds/' + post_id + '/comments/default/' + comment_id blogger_service.Delete(feed_url)