kountanis.com is a static site, generated by a Python script. I like it that way. It's flexibile, ages well, and experimentation is easy. But I want to add my instagram pics, tweets, and wordpress posts into it.

Luckily, these days I have a wordpress.com private blog acting as a quasi-PESOS bucket. Using ifttt, I collect my various content feeds into it.

More importantly, using WordPress.com's REST api, I can get the content of my private blog programmatically and add it to the static site generation pipeline.

Registering an app with WordPress.com#

To do that, I created a wpcom developer app here. Then, to perform API requests on a private blog, I need authorization. As client owner, I can authenticate with the password grant_type, to test things out.

Onward to the script bit (I assume Python 3, with pip and venv). Let's make a project folder and a virtual env:

mkdir -p wpcom_api_python_example
cd wpcom_api_python_example
python3 -m venv venv
source venv/bin/activate

And install some libraries

pip install --upgrade pip
pip install requests python-dotenv

Head over to app and note the client id and client secret. This also needs a username and password (or application password if using 2fa).

I am storing all this sensitive data either in the environment or in a .env file. Here is a script that distills getting posts from the private site. (NB: This will only work if you own the site).

import os
import sys
import json
import requests
from dotenv import load_dotenv


argv = sys.argv[1:]

usage = """\

        python wpcom_priv_get_posts.py <site>'

site: A valid wordpress.com site.

if len(argv) == 0 or not argv[0]:

site = argv[0]

access_token_url = 'https://public-api.wordpress.com/oauth2/token'

data = {
    'client_id': os.getenv('WPCOM_APP_CLIENT_ID'),
    'client_secret': os.getenv('WPCOM_APP_CLIENT_SECRET'),
    'grant_type': 'password',
    'username': os.getenv('WPCOM_APP_USERNAME'),
    'password': os.getenv('WPCOM_APP_PASSWORD'),

response = requests.post(access_token_url, data=data)

if response.status_code != 200:
    raise ValueError('failed authenticating')

auth_data = response.json()
access_token = auth_data['access_token']

posts_endpoint = f'https://public-api.wordpress.com/rest/v1.1/sites/{site}/posts'

headers = {
    'authorization': f'Bearer {access_token}'

response = requests.get(posts_endpoint, headers=headers)

if response.status_code != 200:
    print(f'HTTP Request failed with status {response.status_code}' )

response_data = response.json()
post_count = len(response_data['posts'])

print(f'got {post_count} posts.')