Skip to content

Commit ce70e4d

Browse files
committed
Added a bunch of new endpoints
1 parent 8e5fec7 commit ce70e4d

3 files changed

Lines changed: 230 additions & 22 deletions

File tree

python_wpapi/errors.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def factory(response):
1313
code = payload.get('code')
1414
message = payload.get('message')
1515
data = payload.get('data')
16+
print('status code', status_code)
1617
if status_code == 400:
1718
return BadRequestWpApiError(code, message, data)
1819
elif status_code == 401:
@@ -21,6 +22,8 @@ def factory(response):
2122
return ForbiddenWpApiError(code, message, data)
2223
elif status_code == 404:
2324
return NotFoundWpApiError(code, message, data)
25+
elif status_code == 500:
26+
return InternalErrorWpApiError(code, message, data)
2427
else:
2528
return WpApiError(status_code, code, message, data)
2629

@@ -43,3 +46,8 @@ def __init__(self, code='', message='', data={}):
4346
class NotFoundWpApiError(WpApiError):
4447
def __init__(self, code='', message='', data={}):
4548
super(NotFoundWpApiError, self).__init__(404, code, message, data)
49+
50+
51+
class InternalErrorWpApiError(WpApiError):
52+
def __init__(self, code='', message='', data={}):
53+
super(InternalErrorWpApiError, self).__init__(500, code, message, data)

python_wpapi/python_wpapi.py

Lines changed: 82 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def __init__(self, base_url, user=None, password=None):
1111
self.auth = (user, password)
1212
self.base_url = base_url.strip('/') + '/wp-json/wp/v2'
1313

14-
def _request(self, endpoint, method='GET', headers={}, **kwargs):
14+
def _request(self, endpoint, method='GET', files=None, headers={}, **kwargs):
1515
data = {}
1616
params = {}
1717
if method == 'GET':
@@ -24,7 +24,8 @@ def _request(self, endpoint, method='GET', headers={}, **kwargs):
2424
auth=self.auth,
2525
params=params,
2626
json=data,
27-
headers=headers
27+
headers=headers,
28+
files=files
2829
)
2930
if not response.status_code // 100 == 2:
3031
error = WpApiError.factory(response)
@@ -35,9 +36,9 @@ def get_posts(self):
3536
endpoint = '{}/posts'.format(self.base_url)
3637
return self._request(endpoint)
3738

38-
def get_post(self, id):
39+
def get_post(self, id, context='view'):
3940
endpoint = '{}/posts/{}'.format(self.base_url, id)
40-
return self._request(endpoint)
41+
return self._request(endpoint, context=context)
4142

4243
def create_post(self, **data):
4344
endpoint = '{}/posts'.format(self.base_url)
@@ -47,21 +48,53 @@ def update_post(self, id, **data):
4748
endpoint = '{}/posts/{}'.format(self.base_url, id)
4849
return self._request(endpoint, method='POST', **data)
4950

51+
def delete_post(self, id, force=False):
52+
endpoint = '{}/posts/{}'.format(self.base_url, id)
53+
return self._request(endpoint, method='DELETE', force=force)
54+
5055
def get_medias(self):
5156
endpoint = '{}/media'.format(self.base_url)
5257
return self._request(endpoint)
5358

54-
def get_media(self, id):
59+
def get_media(self, id, context='view'):
5560
endpoint = '{}/media/{}'.format(self.base_url, id)
56-
return self._request(endpoint)
57-
61+
return self._request(endpoint, context=context)
62+
63+
def create_media(self, filename, content_type, file_data, **data):
64+
headers = {'Content-Disposition': 'attachment; filename="{}"'.format(filename)}
65+
files = {'file': (filename, file_data, content_type, {'Expires': '0'})}
66+
endpoint = '{}/media'.format(self.base_url)
67+
return self._request(endpoint, method='POST',
68+
headers=headers, files=files, **data)
69+
70+
def update_media(self, id, **data):
71+
endpoint = '{}/media/{}'.format(self.base_url, id)
72+
return self._request(endpoint, method='POST', **data)
73+
74+
def delete_media(self, id, force=False):
75+
endpoint = '{}/media/{}'.format(self.base_url, id)
76+
return self._request(endpoint, method='DELETE', force=force)
77+
5878
def get_users(self):
5979
endpoint = '{}/users'.format(self.base_url)
6080
return self._request(endpoint)
6181

62-
def get_user(self, id):
82+
def get_user(self, id, context='view'):
6383
endpoint = '{}/users/{}'.format(self.base_url, id)
64-
return self._request(endpoint)
84+
return self._request(endpoint, context=context)
85+
86+
def create_user(self, username, email, password, **data):
87+
endpoint = '{}/users'.format(self.base_url)
88+
return self._request(endpoint, method='POST',
89+
username=username, email=email, password=password, **data)
90+
91+
def update_user(self, id, **data):
92+
endpoint = '{}/users/{}'.format(self.base_url, id)
93+
return self._request(endpoint, method='POST', **data)
94+
95+
def delete_user(self, id):
96+
endpoint = '{}/users/{}'.format(self.base_url, id)
97+
return self._request(endpoint, method='DELETE', force=True)
6598

6699
def get_taxonomies(self, type=None):
67100
endpoint = '{}/taxonomies'.format(self.base_url)
@@ -70,3 +103,43 @@ def get_taxonomies(self, type=None):
70103
def get_taxonomy(self, slug):
71104
endpoint = '{}/taxonomies/{}'.format(self.base_url, slug)
72105
return self._request(endpoint)
106+
107+
def get_categories(self):
108+
endpoint = '{}/categories'.format(self.base_url)
109+
return self._request(endpoint)
110+
111+
def get_category(self, id, context='view'):
112+
endpoint = '{}/categories/{}'.format(self.base_url, id)
113+
return self._request(endpoint, context=context)
114+
115+
def create_category(self, name, **data):
116+
endpoint = '{}/categories'.format(self.base_url)
117+
return self._request(endpoint, method='POST', name=name, **data)
118+
119+
def update_category(self, id, **data):
120+
endpoint = '{}/categories/{}'.format(self.base_url, id)
121+
return self._request(endpoint, method='POST', **data)
122+
123+
def delete_category(self, id):
124+
endpoint = '{}/categories/{}'.format(self.base_url, id)
125+
return self._request(endpoint, method='DELETE', force=True)
126+
127+
def get_tags(self):
128+
endpoint = '{}/tags'.format(self.base_url)
129+
return self._request(endpoint)
130+
131+
def get_tag(self, id, context='view'):
132+
endpoint = '{}/tags/{}'.format(self.base_url, id)
133+
return self._request(endpoint, context=context)
134+
135+
def create_tag(self, name, **data):
136+
endpoint = '{}/tags'.format(self.base_url)
137+
return self._request(endpoint, method='POST', name=name, **data)
138+
139+
def update_tag(self, id, **data):
140+
endpoint = '{}/tags/{}'.format(self.base_url, id)
141+
return self._request(endpoint, method='POST', **data)
142+
143+
def delete_tag(self, id):
144+
endpoint = '{}/tags/{}'.format(self.base_url, id)
145+
return self._request(endpoint, method='DELETE', force=True)

tests/test_python_wpapi.py

Lines changed: 140 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,26 +52,27 @@ def test_get_posts(mock, api):
5252
@patch.object(python_wpapi.WpApi, '_request')
5353
def test_get_post(mock, api):
5454
api.get_post(3)
55-
mock.assert_called_with('http://base.url/wp-json/wp/v2/posts/3')
55+
mock.assert_called_with('http://base.url/wp-json/wp/v2/posts/3',
56+
context='view')
5657

5758
@patch.object(python_wpapi.WpApi, '_request')
5859
def test_create_post(mock, api):
5960
api.create_post(title='Title Here', content='Content Here')
60-
kws = {
61-
'title': 'Title Here',
62-
'content': 'Content Here'
63-
}
6461
mock.assert_called_with('http://base.url/wp-json/wp/v2/posts',
65-
method='POST', **kws)
62+
method='POST', title='Title Here', content='Content Here')
6663

6764
@patch.object(python_wpapi.WpApi, '_request')
6865
def test_update_post(mock, api):
6966
api.update_post(id=5, title='Updated')
70-
kws = {
71-
'title': 'Updated',
72-
}
7367
mock.assert_called_with('http://base.url/wp-json/wp/v2/posts/5',
74-
method='POST', **kws)
68+
method='POST', title='Updated')
69+
70+
@patch.object(python_wpapi.WpApi, '_request')
71+
def test_delete_post(mock, api):
72+
api.delete_post(28)
73+
mock.assert_called_with('http://base.url/wp-json/wp/v2/posts/28',
74+
force=False,
75+
method='DELETE')
7576

7677
@patch.object(python_wpapi.WpApi, '_request')
7778
def test_get_medias(mock, api):
@@ -81,7 +82,35 @@ def test_get_medias(mock, api):
8182
@patch.object(python_wpapi.WpApi, '_request')
8283
def test_get_media(mock, api):
8384
api.get_media(5)
84-
mock.assert_called_with('http://base.url/wp-json/wp/v2/media/5')
85+
mock.assert_called_with('http://base.url/wp-json/wp/v2/media/5',
86+
context='view')
87+
88+
@patch.object(python_wpapi.WpApi, '_request')
89+
def test_create_media(mock, api):
90+
api.create_media(filename='file.png',
91+
content_type='image/png',
92+
file_data=b'123')
93+
expected_headers = {'Content-Disposition': 'attachment; filename="file.png"'}
94+
expected_files = {'file': ('file.png', b'123', 'image/png',
95+
{'Expires': '0'})}
96+
mock.assert_called_with('http://base.url/wp-json/wp/v2/media',
97+
method='POST',
98+
headers=expected_headers,
99+
files=expected_files)
100+
101+
@patch.object(python_wpapi.WpApi, '_request')
102+
def test_update_media(mock, api):
103+
api.update_media(6, email='john@smith')
104+
mock.assert_called_with('http://base.url/wp-json/wp/v2/media/6',
105+
method='POST',
106+
email='john@smith')
107+
108+
@patch.object(python_wpapi.WpApi, '_request')
109+
def test_delete_media(mock, api):
110+
api.delete_media(7)
111+
mock.assert_called_with('http://base.url/wp-json/wp/v2/media/7',
112+
force=False,
113+
method='DELETE')
85114

86115
@patch.object(python_wpapi.WpApi, '_request')
87116
def test_get_users(mock, api):
@@ -91,7 +120,31 @@ def test_get_users(mock, api):
91120
@patch.object(python_wpapi.WpApi, '_request')
92121
def test_get_user(mock, api):
93122
res = api.get_user(1)
94-
mock.assert_called_with('http://base.url/wp-json/wp/v2/users/1')
123+
mock.assert_called_with('http://base.url/wp-json/wp/v2/users/1',
124+
context='view')
125+
126+
@patch.object(python_wpapi.WpApi, '_request')
127+
def test_create_user(mock, api):
128+
api.create_user(username='johndoe', email='john@doe', password='123')
129+
mock.assert_called_with('http://base.url/wp-json/wp/v2/users',
130+
method='POST',
131+
username='johndoe',
132+
email='john@doe',
133+
password='123')
134+
135+
@patch.object(python_wpapi.WpApi, '_request')
136+
def test_update_user(mock, api):
137+
api.update_user(2, email='john@smith')
138+
mock.assert_called_with('http://base.url/wp-json/wp/v2/users/2',
139+
method='POST',
140+
email='john@smith')
141+
142+
@patch.object(python_wpapi.WpApi, '_request')
143+
def test_delete_user(mock, api):
144+
api.delete_user(3)
145+
mock.assert_called_with('http://base.url/wp-json/wp/v2/users/3',
146+
force=True,
147+
method='DELETE')
95148

96149
@patch.object(python_wpapi.WpApi, '_request')
97150
def test_get_taxonomies(mock, api):
@@ -102,10 +155,74 @@ def test_get_taxonomies(mock, api):
102155
mock.assert_called_with('http://base.url/wp-json/wp/v2/taxonomies', type='slug')
103156

104157
@patch.object(python_wpapi.WpApi, '_request')
105-
def test_get_taxonomie(mock, api):
158+
def test_get_taxonomy(mock, api):
106159
api.get_taxonomy('slug')
107160
mock.assert_called_with('http://base.url/wp-json/wp/v2/taxonomies/slug')
108161

162+
@patch.object(python_wpapi.WpApi, '_request')
163+
def test_get_categories(mock, api):
164+
api.get_categories()
165+
mock.assert_called_with('http://base.url/wp-json/wp/v2/categories')
166+
167+
@patch.object(python_wpapi.WpApi, '_request')
168+
def test_get_category(mock, api):
169+
api.get_category(43)
170+
mock.assert_called_with('http://base.url/wp-json/wp/v2/categories/43',
171+
context='view')
172+
173+
@patch.object(python_wpapi.WpApi, '_request')
174+
def test_create_category(mock, api):
175+
api.create_category(name='Category Name')
176+
mock.assert_called_with('http://base.url/wp-json/wp/v2/categories',
177+
method='POST',
178+
name='Category Name')
179+
180+
@patch.object(python_wpapi.WpApi, '_request')
181+
def test_update_category(mock, api):
182+
api.update_category(44, description='desc')
183+
mock.assert_called_with('http://base.url/wp-json/wp/v2/categories/44',
184+
method='POST',
185+
description='desc')
186+
187+
@patch.object(python_wpapi.WpApi, '_request')
188+
def test_delete_category(mock, api):
189+
api.delete_category(45)
190+
mock.assert_called_with('http://base.url/wp-json/wp/v2/categories/45',
191+
force=True,
192+
method='DELETE')
193+
194+
@patch.object(python_wpapi.WpApi, '_request')
195+
def test_get_tags(mock, api):
196+
api.get_tags()
197+
mock.assert_called_with('http://base.url/wp-json/wp/v2/tags')
198+
199+
@patch.object(python_wpapi.WpApi, '_request')
200+
def test_get_tag(mock, api):
201+
api.get_tag(19)
202+
mock.assert_called_with('http://base.url/wp-json/wp/v2/tags/19',
203+
context='view')
204+
205+
@patch.object(python_wpapi.WpApi, '_request')
206+
def test_create_tag(mock, api):
207+
api.create_tag(name='Category Name')
208+
mock.assert_called_with('http://base.url/wp-json/wp/v2/tags',
209+
method='POST',
210+
name='Category Name')
211+
212+
@patch.object(python_wpapi.WpApi, '_request')
213+
def test_update_tag(mock, api):
214+
api.update_tag(20, description='desc')
215+
mock.assert_called_with('http://base.url/wp-json/wp/v2/tags/20',
216+
method='POST',
217+
description='desc')
218+
219+
@patch.object(python_wpapi.WpApi, '_request')
220+
def test_delete_tag(mock, api):
221+
api.delete_tag(21)
222+
mock.assert_called_with('http://base.url/wp-json/wp/v2/tags/21',
223+
force=True,
224+
method='DELETE')
225+
109226
@patch.object(python_wpapi.requests, 'request')
110227
def test__request_get(mock, api):
111228
mock.return_value.json.return_value = {}
@@ -117,6 +234,7 @@ def test__request_get(mock, api):
117234
auth=api.auth,
118235
params={'arg1': 'value'},
119236
json={},
237+
files=None,
120238
headers={}
121239
)
122240

@@ -132,6 +250,7 @@ def test__request_post(mock, api):
132250
auth=api.auth,
133251
params={},
134252
json={'arg1': 'value'},
253+
files=None,
135254
headers={'header1': 'header2'}
136255
)
137256

@@ -167,6 +286,14 @@ def test__request_404(mock, api):
167286
api._request('endpoint4')
168287
assert e.status_code == 404
169288

289+
@patch.object(python_wpapi.requests, 'request')
290+
def test__request_500(mock, api):
291+
mock.return_value.json.return_value = {}
292+
mock.return_value.status_code = 500
293+
with pytest.raises(errors.InternalErrorWpApiError) as e:
294+
api._request('endpoint4')
295+
assert e.status_code == 500
296+
170297
@patch.object(python_wpapi.requests, 'request')
171298
def test__request_generic(mock, api):
172299
mock.return_value.json.return_value = {}

0 commit comments

Comments
 (0)