Search code examples
pythonpython-requestswordpress-rest-api

Wordpress REST API remove all posts and images (media) via Python


I feel like this should be something several other people already accomplished... to write a script that removes all sample data from a dev webpage using the Wordpress Rest API. Right now I try to automate posting images and posts, which works and leads to several of hundreds posts and images blowing up my database. Looking for a script doing that, neither ChatGPT nor browsing the web has provided any good answers.

Any ideas where to look for scripts like that or how to write it yourself?


Solution

  • I hope this helps someone else out in the future!!

    Minimum Working Example (MWE)

    1. Configure everything to connect to Wordpress Backend

    import requests
    import base64
    
    def generate_auth_header():
        """Generate the authentication header for the Wordpress API."""
        try:
            user = "admin" # Set your username here
            password = "iTef fMhJ Rcij Azj3 Uban TeST" # Set your Appllication password here
    
            credentials = user + ":" + password
    
            token = base64.b64encode(credentials.encode())
    
            header = {"Authorization": "Basic " + token.decode("utf-8")}
    
            return header
    
        except IOError as e:
             raise IOError(f"Error connecting to Wordpress backend: {e}") from e
    
    # Create header and wordpress URL
    wordpress_url = 'http://localhost:10014/wp-json/wp/v2/' # Set your domain here
    header = generate_auth_header()
    

    Note: If you haven't set an Application Password yet, read this

    2. Get all posts to delete each post by iterating

    # Function to get all posts
    def get_all_posts():
        posts_url = f'{wordpress_url}posts?per_page=100'
        response = requests.get(posts_url, headers=header, timeout=5)
        return response.json()
    
    # Function to delete a post by ID
    def delete_post(post_id):
        delete_url = f'{wordpress_url}posts/{post_id}'
        response = requests.delete(delete_url, headers=header, timeout=5)
        return response.status_code
    
    # Get first 100 posts
    posts = get_all_posts()
    print(f"posts: {posts}")
    
    # Delete all posts iterating over 100 posts at a time
    while posts != []:
        for post in posts:
            post_id = post['id']
            delete_status = delete_post(post_id)
            if delete_status in [200, 201]:
                print(f"Post {post_id} deleted successfully.")
            else:
                print(f"Failed to delete post {post_id}, status code: {delete_status}")
    
        posts = get_all_posts()
    

    Note: The query string ?per_page=100 in the GET-posts URL makes things easier instead of iterating over the default 10 posts at a time.

    3. Get all images to delete each image by iterating

    # Function to get all images
    def get_all_media():
        media_url = f'{wordpress_url}media?per_page=100'
        response = requests.get(media_url, headers=header, timeout=5)
        return response.json()
    
    # Function to delete each image by ID
    def delete_media(media_id):
        delete_url = f'{wordpress_url}media/{media_id}?force=1'
        response = requests.delete(delete_url, headers=header, timeout=5)
        return response.status_code
    
    # Get and delete all media (images)
    media = get_all_media()
    print(f"media: {media}")
    
    # Delete all media (images) iterating over 100 images at a time
    while media != []:
        for media_item in media:
            media_id = media_item['id']
            delete_status = delete_media(media_id)
            if delete_status in [200, 201]:
                print(f"Media {media_id} deleted successfully.")
            else:
                print(f"Failed to delete media {media_id}, status code: {delete_status}")
    
        media = get_all_media()
    

    Note: Without the query string ?force=1 deleting images did not work for me.