Using Python and WordPress REST API, Post CURD example with Custom Field and Yoast Data - Quick Reference

In this article, I am going to cover how you can connect Python using WordPress Rest API in order to create a post along with custom fields and Yoast data.

Authorization

To connect with your WordPress site, you need to implement authorization in your code.


# aurthorization code
url = "path to wordpress rest api"
user = "your wordpress user name"
password = "your application password"
credentials = user + ':' + password
token = base64.b64encode(credentials.encode())
header = {'Authorization': 'Basic ' + token.decode('utf-8')}

Let's see what are url, user, and password fields and how to find it

url

This is your WordPress Rest API URL
https://your-wordpress-site/wp-json/wp/v2/posts/

user

your WordPress user name

password

This is not a WordPress user password, you can create an application password by editing the user in WordPress. At the bottom, you can find an option to create WordPress application password.

Creating Post with WordPress Rest API


import requests
import json
import base64

#header = {'Authorization': 'Basic ' + token.decode('utf-8'),
#              "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
#    }

url = "https://your-wordpress-blog.comm/wp-json/wp/v2/posts/"
user = "sunil"
password = "xxx xxx xxxx xxx xxx xxxx"
credentials = user + ':' + password
token = base64.b64encode(credentials.encode())
header = {'Authorization': 'Basic ' + token.decode('utf-8')}

#show response
#response = requests.get(url , headers=header)
#print(response)

#add new post

content = '''
<!-- wp:paragraph -->

hello brother

<!-- /wp:paragraph --> ''' post = { 'title' : 'Sunil testing wordpress rest api', 'status' : 'publish', 'content' : content, 'categories': [7,12], # category ID # 'date' : '2020-01-05T10:00:00' 'meta' : { 'mycustom_field' : 'hellooo i am custom field', '_yoast_wpseo_focuskw' :'i am yoast focus keyword', '_yoast_wpseo_title' :'i am yoast title', '_yoast_wpseo_metadesc' : 'i am yoast meta description' } } response = requests.post(url, headers=header, json=post) print(response)

The above code creates a post on WordPress. But wait custom field mycustom_field and Yoast SEO data will not be updated.

Step 1: Custom Fields and Yoast SEO Meta Data

To update the custom field, you need to create it by installing the Advanced Custom Fields plugin, and for Yoast SEO metadata you need to install Yoast SEO Plugin.

Step 2: Update functions.php File

Once you create a custom field and have a Yoast installed. Now time to register these fields as meta, so that we can pass them as meta as the WordPress Rest API default object doesn't have the option to pass ACF or Yoast data. we can do it by using the register_meta function in the functions.php file.


function my_function() {   
    register_meta('post', 'mycustom_field',
        [
            'object_subtype' => 'post',
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string'/*,
            'auth_callback' => function() {
                return current_user_can( 'edit_posts' );
            }*/
        ]
    );
	register_meta('post', '_yoast_wpseo_focuskw',
        [
            'object_subtype' => 'post',
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string'/*,
            'auth_callback' => function() {
                return current_user_can( 'edit_posts' );
            }*/
        ]
    );
	register_meta('post', '_yoast_wpseo_metadesc',
        [
            'object_subtype' => 'post',
            'show_in_rest' => true,
            'single' => true,
            'type' => 'string'/*,
            'auth_callback' => function() {
                return current_user_can( 'edit_posts' );
            }*/
        ]
    );
	
	
}

add_action( 'rest_api_init', 'my_function' );

Update Post

Below is code to update the wordpress post.


import requests
import json
import base64


url = "https://your-wordpress-blog.com/wp-json/wp/v2/posts/"
postID = 1077
user = "sunil"
password = "xxx xxx xxxx xxx xxx xxxx"
credentials = user + ':' + password
token = base64.b64encode(credentials.encode())
header = {'Authorization': 'Basic ' + token.decode('utf-8')}
post = {
 'title'    : 'Sunil updating wordpress rest api',
 'content'  : 'This is my updated post using rest API Updated'
}
response = requests.post(url + str(postID) , headers=header, json=post)
print(response)

To update a post just pass the post id in the request.post function.

Delete Post


import requests
import json
import base64


url = "https://www.your-wordpress-blog.com/wp-json/wp/v2/posts/"
postID = 1077
user = "sunil"
password = "xxx xxx xxxx xxx xxx xxxx"
credentials = user + ':' + password
token = base64.b64encode(credentials.encode())
header = {'Authorization': 'Basic ' + token.decode('utf-8')}
response = requests.delete(url + str(postID) , headers=header)
print(response)

By passing post id in requests.delete function will delete the Post.

Get All Categories


def get_categories():
    url = "https://www.your-wordpress-blog.com/wp-json/wp/v2/categories"
    response = requests.get(url)
    response_json = response.json()
    for ele in response_json:
        print(str(ele["id"]) + " - " + ele["name"])
    

get_categories()

Pagination

By default wp-json/wp/v2/posts/returns 10 post data. Here are some more functions needed if dealing with n number of posts.


def read_wordpress_posts():
    response = requests.get(url)
    response_json = response.json()
    print(response_json)

#read_wordpress_posts() // show all post
def get_total_pagecount():
    api_url = 'https://your-wordpress-blog.com/wp-json/wp/v2/posts/?page=1&per_page=10'
    response = requests.get(api_url)
    pages_count = response.headers['X-WP-TotalPages']
    return int(pages_count)

#this show total number of pages
#print(get_total_pagecount())


def read_wordpress_post_with_pagination():
    total_pages = get_total_pagecount()
    current_page = 1
    all_page_items_json = []
    while current_page <= total_pages:
        api_url = "https://your-wordpress-blog.com/wp-json/wp/v2/posts?page=" + str(current_page) + "&per_page=10"
        page_items = requests.get(api_url)
        page_items_json = page_items.json()
        all_page_items_json.extend(page_items_json)
        current_page = current_page + 1
        return all_page_items_json

#print(read_wordpress_post_with_pagination())