Skip to content

Instantly share code, notes, and snippets.

@joefozmans
Created February 12, 2015 23:40
Show Gist options
  • Save joefozmans/e297db7eeecdeac6e56a to your computer and use it in GitHub Desktop.
Save joefozmans/e297db7eeecdeac6e56a to your computer and use it in GitHub Desktop.
post and authenticate to ghost
# Posts to Ghost via its API, given a piece of Markdown
# Markdown attachments are not yet supported
# (i.e: images must be linked to, not added inline)
# Import dependencies
import urllib2
import json
# Global constants
BASE_API_URL = 'https://joe.fo/ghost/api/v0.1'
CLIENT_ID = 'ghost-admin' # testing - pretend to be the ghost web-client
USER_AGENT = 'joefo/ghostclient'
# There are a few steps in order to post to Ghost:
# Step 1: Authenticate yourself
#
# Authentication is acheived using OAuth.
# You are required to send a POST request to
# BASE_API_URL/authentication/token
# From the docs at
# https://github.com/TryGhost/Ghost/wiki/How-does-oAuth-work-with-Ghost%3F
# POST BASE_API_URL/authentication/token
# Content-Type: application/x-www-form-urlencoded
# grant_type=password&username=<username>&password=<password>\
# &client_id=ghost-admin
# (no line-break)
# where <username> actually refers to the users' email address.
def get_oauth_token(username, password, url):
"""Requests a new OAuth token from a given URL.
Faliures return None.
This will return:
a) None - if wrong username, password, or if
no username / password / url was supplied
b) A Dictionary (from a JSON object returned
by the server, where json_object['access_token']
is the OAuth token
c) An error in various cases.
"""
if not (username and password and url):
# we need all of these things, so just return None
# there is no way of authenticating with missing info.
print('[OAuth]: username or password or url was missing')
return None
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': USER_AGENT
}
data = 'grant_type=password&username=' + username + \
'&password=' + password + '&client_id=' + CLIENT_ID
request = urllib2.Request(url, data=data, headers=headers)
try:
response = urllib2.urlopen(request)
returned_json = response.read()
oauth_object = json.loads(returned_json)
return oauth_object
except urllib2.HTTPError as e:
if e.code == 401: # unauthorized (wrong username / pass)
return None
else:
return e
except ValueError as e:
# JSON had an issue decoding the response.
# Pass this exception down the chain.
return e
# Step 2: Access the Ghost endpoints
#
# We specifically need to interface with the posts API
# https://github.com/TryGhost/Ghost/wiki/%5BWIP%5D-API-Documentation#posts
def make_new_post(md, title, access_token, url, tags=None, status='published'):
"""Creates a new post on the server from the API url supplied.
Returns post object if successful, raises some error otherwise.
"""
if not (md and title and access_token and url):
raise ValueError('Expected 3 arguments: (markdown, token, url)')
headers = {
'Content-Type': 'application/json',
'User-Agent': USER_AGENT,
'Authorization': 'Bearer ' + access_token
}
data = json.dumps({
'posts': [
{
'status': status, # should be either 'published' or 'draft'
'author': '1', # the default user
'title': title,
'markdown': md,
'tags': tags
}]
})
request = urllib2.Request(url, data=data, headers=headers)
response = urllib2.urlopen(request)
return json.loads(response.read())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment