A note from the author: I no longer do Wordpress work, so I won't have the time to adequately maintain this repo. If you would like to maintain a fork of this repo, and want me to link to your fork here, please let me know <mailto:derwentx@gmail.com>
_.
One such fork is https://github.com/Synoptik-Labs/wp-api-python
thanks!
.. image:: https://travis-ci.org/derwentx/wp-api-python.svg?branch=master :target: https://travis-ci.org/derwentx/wp-api-python
.. image:: https://api.codeclimate.com/v1/badges/4df627621037b2df7e5d/maintainability :target: https://codeclimate.com/github/derwentx/wp-api-python/maintainability :alt: Maintainability
.. image:: https://api.codeclimate.com/v1/badges/4df627621037b2df7e5d/test_coverage :target: https://codeclimate.com/github/derwentx/wp-api-python/test_coverage :alt: Test Coverage
.. image:: https://snyk.io/test/github/derwentx/wp-api-python/badge.svg?targetFile=requirements.txt :target: https://snyk.io/test/github/derwentx/wp-api-python?targetFile=requirements.txt
.. image:: https://badge.fury.io/py/wordpress-api.svg :target: https://badge.fury.io/py/wordpress-api
A Python wrapper for the Wordpress and WooCommerce REST APIs with oAuth1a 3leg support.
Supports the Wordpress REST API v1-2, WooCommerce REST API v1-3 and WooCommerce WP-API v1-2 (with automatic OAuth3a handling). Forked from the excellent WooCommerce API written by Claudio Sanches and modified to work with Wordpress: https://github.com/woocommerce/wc-api-python
I created this fork because I prefer the way that the wc-api-python client interfaces with the Wordpress API compared to the existing python client, https://pypi.python.org/pypi/wordpress_json which does not support OAuth authentication, only Basic Authentication (very unsecure)
Any comments about how you're using the API and suggestions about how this repository could be improved are welcome :). You can find my contact info in my GitHub profile.
Wordpress version 4.7+ comes pre-installed with REST API v2, so you don't need to have the WP REST API plugin if you have the latest Wordpress.
You should have the following plugins installed on your wordpress site:
The following python packages are also used by the package
Install with pip
.. code-block:: bash
pip install wordpress-api
Download this repo and use setuptools to install the package
.. code-block:: bash
pip install setuptools
git clone https://github.com/derwentx/wp-api-python
python setup.py install
Some of the tests make API calls to a dockerized woocommerce container. Don't worry! It's really simple to set up. You just need to install docker and run
.. code-block:: bash
docker-compose up -d
# this just waits until the docker container is set up and exits
docker exec -it wpapipython_woocommerce_1 bash -c 'until [ -f .done ]; do sleep 1; done; echo "complete"'
Then you can test with:
.. code-block:: bash
pip install -r requirements-test.txt
python setup.py test
Note to self because I keep forgetting how to use Twine >_<
.. code-block:: bash
python setup.py sdist bdist_wheel
# Check that you've updated changelog
twine upload dist/wordpress-api-$(python setup.py --version) -r pypitest
twine upload dist/wordpress-api-$(python setup.py --version) -r pypi
Generate API credentials (Consumer Key & Consumer Secret) following these instructions: http://v2.wp-api.org/guide/authentication/
Simply go to Users -> Applications and create an Application, e.g. "REST API". Enter a callback URL that you will be able to remember later such as "http://example.com/oauth1_callback" (not really important for this client). Store the resulting Key and Secret somewhere safe.
Check out the Wordpress API endpoints and data that can be manipulated in http://v2.wp-api.org/reference/.
(Note: requires Basic Authentication plugin)
.. code-block:: python
from wordpress import API
wpapi = API(
url="http://example.com",
api="wp-json",
version='wp/v2',
wp_user="XXXX",
wp_pass="XXXX",
basic_auth = True,
user_auth = True,
)
(Note: the username and password are required so that it can fill out the oauth request token form automatically for you. Requires OAuth 1.0a plugin. )
.. code-block:: python
#...
wpapi = API(
url="http://example.com",
consumer_key="XXXXXXXXXXXX",
consumer_secret="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
api="wp-json",
version="wp/v2",
wp_user="XXXX",
wp_pass="XXXX",
oauth1a_3leg=True,
creds_store="~/.wc-api-creds.json"
)
.. code-block:: python
#...
wcapi = API(
url="http://example.com",
consumer_key="ck_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
consumer_secret="cs_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
api="wc-api",
version="v3"
)
Note: oauth1a 3legged works with Wordpress but not with WooCommerce. However oauth1a signing still works. If you try to do oauth1a_3leg with WooCommerce it just says "consumer_key not valid", even if it is valid.
.. code-block:: python
#...
wcapi = API(
url="http://example.com",
consumer_key="ck_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
consumer_secret="cs_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
api="wp-json",
version="wc/v2",
callback='http://127.0.0.1/oauth1_callback'
)
Options
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
| Option | Type | Required | Description |
+=======================+=============+==========+==================================================================================================================+
| ``url`` | ``string`` | yes | Your Store URL, example: http://wp.dev/ |
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
| ``consumerKey`` | ``string`` | yes | Your API consumer key |
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
| ``consumerSecret`` | ``string`` | yes | Your API consumer secret |
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
| ``api`` | ``string`` | no | Determines which api to use, defaults to ``wp-json``, can be arbitrary: ``wc-api``, ``oembed`` |
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
| ``version`` | ``string`` | no | API version, default is ``wp/v2``, can be ``v3`` or ``wc/v1`` if using ``wc-api`` |
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
| ``timeout`` | ``integer`` | no | Connection timeout, default is ``5`` |
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
| ``verify_ssl`` | ``bool`` | no | Verify SSL when connect, use this option as ``False`` when need to test with self-signed certificates |
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
| ``basic_auth`` | ``bool`` | no | Force Basic Authentication, can be through query string or headers (default) |
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
| ``query_string_auth`` | ``bool`` | no | Use query string for Basic Authentication when ``True`` and using HTTPS, default is ``False`` which uses header |
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
| ``oauth1a_3leg`` | ``string`` | no | use oauth1a 3-legged authentication |
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
| ``creds_store`` | ``string`` | no | JSON file where oauth verifier is stored (only used with OAuth_3Leg) |
+-----------------------+-------------+----------+------------------------------------------------------------------------------------------------------------------+
Methods
-------
+--------------+----------------+------------------------------------------------------------------+
| Params | Type | Description |
+==============+================+==================================================================+
| ``endpoint`` | ``string`` | API endpoint, example: ``posts`` or ``user/12`` |
+--------------+----------------+------------------------------------------------------------------+
| ``data`` | ``dictionary`` | Data that will be converted to JSON |
+--------------+----------------+------------------------------------------------------------------+
GET
.get(endpoint)
POST
- ``.post(endpoint, data)``
PUT
.put(endpoint, data)
DELETE
- ``.delete(endpoint)``
OPTIONS
.options(endpoint)
(Note: this only works on WP API with the Basic Auth plugin enabled: https://github.com/WP-API/Basic-Auth )
.. code-block:: python
assert os.path.exists(img_path), "img should exist"
data = open(img_path, 'rb').read()
filename = os.path.basename(img_path)
_, extension = os.path.splitext(filename)
headers = {
'cache-control': 'no-cache',
'content-disposition': 'attachment; filename=%s' % filename,
'content-type': 'image/%s' % extension
}
endpoint = "/media"
return wpapi.post(endpoint, data, headers=headers)
All methods will return Response <http://docs.python-requests.org/en/latest/api/#requests.Response>
_ object.
Example of returned data:
.. code-block:: bash
>>> from wordpress import api as wpapi
>>> r = wpapi.get("posts")
>>> r.status_code
200
>>> r.headers['content-type']
'application/json; charset=UTF-8'
>>> r.encoding
'UTF-8'
>>> r.text
u'{"posts":[{"title":"Flying Ninja","id":70,...' // Json text
>>> r.json()
{u'posts': [{u'sold_individually': False,... // Dictionary data
The extra keyword arguments passed to the function of a __request
call (such as .delete()
) to a wordpress.API
object are used to modify a Requests.request
call, this is to allow you to specify custom parameters to modify how the request is made such as headers
. At the moment it only passes the headers
parameter to requests, but if I see a use case for it, I can forward more of the parameters to Requests
.
The delete
function doesn’t accept a data object because a HTTP DELETE request does not typically have a payload, and some implementations of a HTTP server would reject a DELETE request that has a payload.
You can still pass api request parameters in the query string of the URL. I would suggest using a library like urlparse
/ urllib.parse
to modify the query string if you are automatically deleting users.
According the the documentation for deleting a user, you need to pass the force
and reassign
parameters to the API, which can be done by appending them to the endpoint URL.
.. code-block:: python
response = wpapi.delete(‘/users/
?reassign= &force=true’) response.json() {“deleted”:true, ... }
In Python2, make sure to only POST
unicode string objects or strings that
have been correctly encoded as utf-8. Serializing objects containing non-utf8
byte strings in Python2 is broken by importing unicode_literals
from
__future__
because of a bug in json.dumps
. You may be able to get around
this problem by serializing the data yourself.
1.2.8 - 2018/10/13
- Much better python3 support
- really good tests
- added NoAuth option for adding custom headers (like JWT)
1.2.7 - 2018/06/18
1.2.6 - 2018/01/29
- Better Python3 support
- Tested on Python v3.6.2 and v2.7.13
1.2.5 - 2017/12/07
1.2.4 - 2017/10/01
- Support for image upload
- More accurate documentation of WP authentication methods
1.2.3 - 2017/09/07
1.2.2 - 2017/06/16
- support basic auth without https
- rename oauth module to auth (since auth covers oauth and basic auth)
- tested with latest versions of WP and WC
1.2.1 - 2016/12/13
1.2.0 - 2016/09/28
- Initial fork
- Implemented 3-legged OAuth
- Tested with pagination