How to upload a picture to woocommerce with python/django POST request

I have created a woocommerce web page and I am trying to use Django/Python synchronized with my page. From the documentation woocomerce post request:

data = {
    "product": {
        "title": "Sample of Title through POST",
        "type": "simple",
        "regular_price": "21.99",
        "description": "Long description from Post Request",
        "short_description": "Short description from Post Request",
        "categories": [
            9,
            14
        ],
        "images": [
            {
                "src": "http://example.com/wp-content/uploads/2015/01/premium-quality-front.jpg",
                "position": 0
            },
            {
                "src": "http://example.com/wp-content/uploads/2015/01/premium-quality-back.jpg",
                "position": 1
            }
        ]
    }
}

print (wcapi.post("products", data).json())

I am using the Python wrapper for the WooCommerce REST API and it seems to be working with the get requests, I can not find a way to make it work with the post request.

Read More

I constantly getting this error:

TypeError: <open file 'test.jpg', mode 'rb' at 0x104b4ced0> is not JSON serializable

I have been searching over and over the web for possible solutions but I can not find one. Does anyone knows what is the correct way to upload an image from the local directory to the web page? I have tried to reformat the path from absolute path to url path, but it did not work.

Complete code:

import pprint
import urllib
import os.path
import urlparse
from woocommerce import API


def path2url(path):
    return urlparse.urljoin(
        'file:', urllib.pathname2url(path))

wcapi = API(
    url= '' # Your store URL
    consumer_key= '' # Your consumer key
    consumer_secret= '' # Your consumer secret
    version='v3'  # WooCommerce API version
)
# Get request    
pprint.pprint(wcapi.get("products").json())

# Post request
data = {
    "product": {
        "title": "Sample of Title through POST",
        "type": "simple",
        "regular_price": "21.99",
        "description": "Long description from Post Request",
        "short_description": "Short description from Post Request",
        "categories": [
            9,
            14
        ],
        "images": [
            {
                "src": open('test.jpg', 'rb'),
                "position": 0
            },
            {
                "src": open('test.jpg', 'rb'),
                "position": 1
            }
        ]
    }
}

print (wcapi.post("products", data).json())

Update: I have tried to use the exact path for images from my local host e.g. ” http://localhost:8888/wordpress/wp-content/uploads/2016/04/test.jpg ” where on the browser it works fine, I can see the picture. When I use this path on the post request, it produces the same error. I also tried to use relative path e.g. ” file:///Users/tinyOS/Sites/wordpress/wp-content/uploads/2016/04/test.jpg ” still same error code.

Related posts

1 comment

  1. So I manage to find the solution to my problem. Just in case someone else in the future might need it.

    In order to be able to upload a picture to woocommerce you need to have a valid url path (e.g. http://localhost:8888/wordpress/wp-content/uploads/2016/04/test.jpg)

    In order to get that url, you need to upload a file first to woocommerce with the relative path and as a second step to retrieve the path and add it to the secondary post request with all the data of the product that you want to post.

    The tool for python is python-wordpress-xmlrpc. I also found the manual that contains more analytical examples that I have found more useful than just the documentation: python-wordpress-xmlrpc, Documentation, Release 2.3.

    The example below demonstrates the process to upload the image. The code is taken from the manual:

    from wordpress_xmlrpc import Client, WordPressPost
    from wordpress_xmlrpc.compat import xmlrpc_client
    from wordpress_xmlrpc.methods import media, posts
    
    client = Client('http://mysite.wordpress.com/xmlrpc.php', 'username', 'password')
    
    # set to the path to your file
    filename = '/path/to/my/picture.jpg'
    
    # prepare metadata
    data = {
    'name': 'picture.jpg',
    'type': 'image/jpeg', # mimetype
    }
    
    # read the binary file and let the XMLRPC library encode it into base64
    with open(filename, 'rb') as img:
        data['bits'] = xmlrpc_client.Binary(img.read())
    
    response = client.call(media.UploadFile(data))
    
    # response == {
    # 'id': 6,
    # 'file': 'picture.jpg'
    # 'url': 'http://www.example.com/wp-content/uploads/2012/04/16/picture.jpg',
    # 'type': 'image/jpeg',
    # }
    attachment_id = response['id']
    

    As a second step you can create a function that post all the information to the woocommerce store of yours. Sample of code taken from Create a Product, WooCommerce 2.1, the REST API. You simply need to create a dictionary with all the data:

    data = {
        "product": {
            "title": "Premium Quality",
            "type": "simple",
            "regular_price": "21.99",
            "description": "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",
            "short_description": "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.",
            "categories": [
                9,
                14
            ],
            "images": [
                {
                    "src": "http://example.com/wp-content/uploads/2015/01/premium-quality-front.jpg",
                    "position": 0
                },
                {
                    "src": "http://example.com/wp-content/uploads/2015/01/premium-quality-back.jpg",
                    "position": 1
                }
            ]
        }
    }
    
    print(wcapi.post("products", data).json())
    

    The src: needs to be replaced with the retrieved url from the upload request and voila. Very simple if you know which tools to use, complicated if you do not.

    I hope this helps.

Comments are closed.