Saturday, April 09, 2016

How to Post to Blogger - Blogspot using Google API in Python automatically

This blog explains the end-to-end of the steps needed to write a Python program that will write a "post" to a blog on Google's blogger.com
Why? This is part of a step to automate writing blog posts. For example, you want to post a blog every minute to say:
    Today - at this exact minute 12:05:00, the temperature is 27'C
In this example the time and temperature data are obtained somewhere and you can programmatically construct the sentence above.
However, it will be very tedious to login to blogger, click on many buttons, write the content and publish the post every minute.
A program can be setup to login automatically and post the sentence above to the blog automatically - that is the goal here.

GOAL:
To write a Python program that will automatically publish blogger/blogspot post

METHOD:
The combination of the following technologies are used:
- Python programming language
- Blogger/Blogspot blog providers
- Google API for Python
- OAuth 2.0 Google Authorization


PREREQUISITE:
1. Python v2.x - assume you have this installed - instructions on how to install and use python is beyond the scope of this post.
2. Blogger.com / blogspot.com account - These two names are the same free Blog site owned by Google. It is assumed you already have an account and know how to post blogs by logging in and posting a blog manually. Instructions on how to setup and use a blog the normal ways are not covered here.


PREPARATION:

1. On a CMD prompt / terminal, do:
pip install --upgrade oauth2client
pip install --upgrade google-api-python-client
https://developers.google.com/api-client-library/python/apis/blogger/v3#sample
https://developers.google.com/blogger/docs/3.0/api-lib/python#sample

2. Go to website below to get 'api_name', 'api_version'
Supported Google APIs: https://developers.google.com/api-client-library/python/apis/
api_name=blogger    api_version=v3
api_name=drive      api_version=v3




OAUTH AUTHORIZATION:

These two websites are good to get a reasonable understanding, but ultimately does not provide direct instructions.
    https://developers.google.com/blogger/docs/3.0/using#auth
    https://developers.google.com/identity/protocols/OAuth2#basicsteps

The three main types of Credentials are:
1. API Keys
2. OAuth 2.0 client IDs
3. Service account keys

Go to https://console.developers.google.com
The interface is not very good at directing what to do next.
On the left panel are: Overview,  Credentials
On the top right horizontal menu of items, there is a Drop-Down icon
--- Click on the Drop-Down icon to "Manage all projects" or "Create Project"
--- If new here, then choose Create Project,
--- Note that you can enter quite different values for Project Name and Project ID.

Coming back to the main page, click Overview
--- Now the main area has: "Google APIs" and "Enabled APIs"
--- Click on the "Google APIs" to show a list of popular APIs.
--- If Blogger API is not listed, type Blogger on the search text field.
--- Then click Blogger and click Enable (if not enabled already)
--- Going back some pages, now click "Enabled APIs". On this page, check that "Blogger API v3" is listed.

Coming back to the main page, click Credentials (just below Overview)
--- The top submenu has: "Credentials", "OAuth consent Screen", "Domain Verification"
--- Click on Credentials.
--- for OAuth 2.0 client IDs
------ To create manually, click on "Create Credentials", choose OAuth Client ID, choose Other as Application type.
------ To create automatically, click on "Create Credentials", choose "Help Me Choose".
--------- Then in the drop down, choose Blogger API, choose calling the API from "Other UI(Windows)", choose "User Data"
------ At the end, the credentials is downloaded, eg client_secret_<client_id>.json, and the content is like:
                 {"installed":{"client_id":"
--- for Service Account Keys
------ To create manually, click on "Service Account Keys", choose a service account (create one if needed), choose JSON, click Create.
------ To create automatically, click on "Create Credentials", choose "Help Me Choose".
--------- Then in the drop down, choose Blogger API, choose calling the API from "Other UI(Windows)", choose "Application Data"
------ At the end, the credentials is downloaded, eg <project>-<keyID>.json, and the content is like:
{
  "type": "service_account",
  "project_id": ".......",
  "private_key_id": "..................",
  "private_key": "-----BEGIN PRIVATE

Since this project is about automated program that writes to the blog, the credentials should not involve any interaction - in this case, create and use the "Service account keys"
The "OAuth 2.0 client IDs" also works but requires clicking a button and copying a "code" to the python program. This is shown to work - but this is less suitable for our goals.


SCOPE:
Before the actual coding to use the APIs, the authorization process also need to know the scopes of your program.
Here are some scopes for the Blogger API and the Google Drive API:

Blogger API, v3
https://www.googleapis.com/auth/blogger Manage your Blogger account
https://www.googleapis.com/auth/blogger.readonly View your Blogger account
Drive API, v3
https://www.googleapis.com/auth/drive View and manage the files in your Google Drive
https://www.googleapis.com/auth/drive.appdata View and manage its own configuration data in your Google Drive
https://www.googleapis.com/auth/drive.file View and manage Google Drive files and folders that you have opened or created with this app
https://www.googleapis.com/auth/drive.metadata View and manage metadata of files in your Google Drive
https://www.googleapis.com/auth/drive.metadata.readonly View metadata for files in your Google Drive
https://www.googleapis.com/auth/drive.photos.readonly View the photos, videos and albums in your Google Photos
https://www.googleapis.com/auth/drive.readonly View the files in your Google Drive
https://www.googleapis.com/auth/drive.scripts Modify your Google Apps Script scripts' behavior

*** A Complete list of scopes for all Google APIs (not just Blogger and Drive), can be found in:
https://developers.google.com/identity/protocols/googlescopes
- title "OAuth 2.0 Scopes for Google APIs"


CODE in Python:
1. The code below is complete end to end. When run, it will handle the authorization, then send some text, to be posted to a blogger site and the json response is captured.
2. There may be more import statements than necessary.
3. The code will NOT work as is because the __blogID__ is not real and the <blah>.json files is not the real filenames. If these values are replaced with proper values, the code should work.
4. The code also shows to options of OAuth. The first uses "OAuth 2.0 for Server to Server Applications" which does not need interaction. The second, which is commented out, uses "Client Secrets", which pops-up a browser, then the operator needs to copy the code and paste it on the terminal where the python code is running.

<code><pre>
import os
# OAuth 2.0 for Installed Applications
from oauth2client.client import flow_from_clientsecrets
# OAuth 2.0 for Server to Server Applications
from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
from oauth2client.client import flow_from_clientsecrets
import json
import webbrowser
import httplib2

from apiclient import discovery
from oauth2client import client
from apiclient.discovery import build
from googleapiclient import sample_tools

__blogID__='99999999999999999999'

# Using OAuth 2.0 for Server to Server Applications
# https://developers.google.com/api-client-library/python/auth/service-accounts#authorizingrequests

scopes = ['https://www.googleapis.com/auth/blogger.readonly']
credentials = ServiceAccountCredentials.from_json_keyfile_name('<project>-<keyID>.json', scopes)
http_auth = credentials.authorize(Http())
# THis returns no errors - so what's next????

"""
# Client Secrets
# https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
flow = flow_from_clientsecrets('client_secret_<client_ID>.json',
                               scope='https://www.googleapis.com/auth/blogger',
                               redirect_uri='urn:ietf:wg:oauth:2.0:oob')
# This section copied from https://developers.google.com/api-client-library/python/auth/installed-app#example
auth_uri = flow.step1_get_authorize_url()
webbrowser.open(auth_uri)
auth_code = raw_input('Enter the auth code: ')
credentials = flow.step2_exchange(auth_code)
http_auth = credentials.authorize(httplib2.Http())
# THis returns no errors - so what's next????
"""

service = build('blogger', 'v3', http=http_auth)   # (api_name, api_version)

text = \
'{ \
    "kind": "blogger#post", \
    "blog": { \
        "id": "999999999999999" \
    }, \
    "title": "A new post", \
    "content": "With <b>new</b> content..." \
}'

parsed = json.loads(text)
print json.dumps(parsed , indent=4, separators=(',', ': '))

request = service.posts().insert(blogId=__blogID__, body=parsed )
response = request.execute()
print json.dumps(response , indent=4, separators=(',', ': '))
</pre></code>





APPENDIXES:
There is a lot of information on this subject, to the extent that it has become confusing and difficult to understand.
The instructions in this blog post just give the minimum steps without too much explanations with the aim of reducing the confusion.
However, to gain an understanding after the fact, the list of websites is given here as a reference:

https://developers.google.com/api-client-library/python/guide/aaa_oauth#oauth-20-explained
- EXCELLENT page - title "OAuth 2.0" - part of "API Client Library for Python"
- examples of Python code to use OAuth 2.0 to connect to Google APIs.

https://developers.google.com/identity/protocols/OAuth2InstalledApp#choosingredirecturi
- talks about "redirect_uri" in the code. The main page is called "Using OAuth 2.0 for Installed Applications"

https://support.google.com/cloud/answer/6158849?hl=en#serviceaccounts
- not that useful

https://developers.google.com/api-client-library/python/auth/service-accounts
- title "Using OAuth 2.0 for Server to Server Applications", part of the "API Client Library for Python"
- OAuth 2.0 can be for "Web Server Application", "Installed Applications", "Server to Server Applications".
- For this goal of automatically posting to Blogger, the "Server to Server Applications" is the most relevant.

https://developers.google.com/blogger/
- Intro to the Blogger API

https://developers.google.com/blogger/docs/3.0/reference/#Pages
- Blogger API reference

About accessing Google APIs for Blogger
https://developers.google.com/blogger/docs/3.0/libraries
https://developers.google.com/resources/api-libraries/documentation/blogger/v3/python/latest/
https://developers.google.com/api-client-library/python/
https://developers.google.com/apis-explorer/#p/blogger/v3/

3 comments:

Bui Van Quy said...

I run your example code but receive error message when call service.posts().insert()

"We're sorry, but you don't have permission to access this resource."

I have search about message but no information about this message.

Unknown said...

Great :D ... and it works !

1) However not in the first go though. Following thing does not work for some reason:
service = build('blogger', 'v3', http=credentials.authorize(Http()))

While downloading credentials file using "Service account key" method, it asks me to select the service account. I had selected "App engine default service account". Is this correct?


2) How to upoload images? :)

Thanks.

Jabir Shaik said...

Nice Article, This technology is having good reputation and growth in the market. By using python we can create our own software's according to our business strategies. We are offering you an advance level of Python online training by experts who worked in top MNC's with 100% placement assistance. For details visit our website Advanced Python Training Online