2009-06-21

Using the Blogger API from Python

Blogger exposes a Google Data API. Using this API, you can access all parts of your blog using simple HTTP requests. The REST-style API is based on the Atom Publishing Protocol.

It is very easy to access the blogger API (or any Google Data API) from Python using the Google Data APIs Python Client Library (gdata-python-client). This library is easy to use, has great documentation and great sample code included.

Using reStructuredText and gdata-python-client I created a simple application (blogger.py) that takes a rst file, converts it to HTML and publishes the HTML on my blog.

Using this approach, I can edit blog posts in a my editor of choice, using an easy-to-read plaintext markup syntax.

Example use:

# first, get the blog id
(vanilla)[~/misc/blogger]
$ python blogger.py --username my.email@gmail.com --listblogs
Password:
nnnnnnnnnnnnnnnnnnn: Code Monkey Do

# then create a new blog post
(vanilla)[~/misc/blogger]
$ python blogger.py --username my.email@gmail.com --blog nnnnnnnnnnnnnnnnnnn post1.rst
Password:

$ python blogger.py --help
...

blogger.py source code (on github):

import rstdirective

def login(username, password):
    import gdata.service
    service = gdata.service.GDataService(username, password)
    service.service = 'blogger'
    service.server = 'www.blogger.com'
    service.ProgrammaticLogin()
    return service

def create_entry(title, content, draft=False):
    import atom
    import gdata
    entry = gdata.GDataEntry()
    entry.title = atom.Title(title_type='text', text=title)
    entry.content = atom.Content(content_type='html', text=content.encode('utf8'))
    if draft:
        control = atom.Control()
        control.draft = atom.Draft(text='yes')
        entry.control = control
    return entry

def listblogs(service):
    feed = service.Get('/feeds/default/blogs')
    for blog in feed.entry:
        print "%s: %s" % (blog.GetSelfLink().href.split('/')[-1],
            blog.title.text)

def listposts(service, blogid):
    feed = service.Get('/feeds/' + blogid + '/posts/default')
    for post in feed.entry:
        print post.GetEditLink().href.split('/')[-1], post.title.text, "[DRAFT]" if is_draft(post) else ""

# ... see full source code on github: http://github.com/codeape2/python-blogger/tree/master/blogger.py

If you are not familiar with the reStructuredText format, have a look at this example, the rst source for this post.

You can download the entire source code from github.

2 comments:

Daren Thomas said...

You sir rule! I was able to get blogger.py working for me and am now happy with blogger again (I just hated their editor). Note that adding additional headers (apart from the first one) results in weird formatting, as blogger starts with h3 - so blogger.py should somehow tell docutils to create h4, h5 etc?

brbrenna said...

It is probably possible to make docutils start with another header level, I'll look into it one day.

I have, however not had any formatting problems on my own blog. Probably depends on the "skin" used on the blog.