Skip to content

Commit 77acda4

Browse files
authored
Merge pull request #20 from QuickPay/feature/request_options
API: supporting body, headers, query as arguments
2 parents f66a9d9 + 1e387cb commit 77acda4

File tree

4 files changed

+77
-15
lines changed

4 files changed

+77
-15
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## UNRELEASED
6+
7+
### Breaking
8+
- [Sending request with body, headers, and query](https://github.com/QuickPay/quickpay-python-client/issues/16#issuecomment-474115554)
9+
610
### Fixed
711
- [Callback header typo fix](https://github.com/QuickPay/quickpay-python-client/issues/16)
812

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,21 @@ else:
7373
print "Error", body
7474
```
7575

76+
Beyond the endpoint, the client accepts the following options (default values shown):
77+
78+
* `body: ""` ( valid for POST, PATCH and PUT)
79+
* `headers: {}`
80+
* `query: {}`
81+
* `raw: false`
82+
83+
```python
84+
response = client.post("/payments/1/capture",
85+
body={ 'amount': 100 },
86+
query={ "synchronized" : "" },
87+
raw=False
88+
)
89+
```
90+
7691
Handling API exceptions
7792
----------------------
7893

quickpay_api_client/api.py

+22-9
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
from quickpay_api_client import exceptions
1111
import quickpay_api_client
1212

13+
1314
class QPAdapter(HTTPAdapter):
1415
def init_poolmanager(self, connections, maxsize, block=False):
1516
self.poolmanager = PoolManager(num_pools=connections,
1617
maxsize=maxsize,
1718
block=block,
1819
ssl_version=ssl.PROTOCOL_TLSv1_1)
1920

21+
2022
class QPApi(object):
2123
api_version = '10'
2224
base_url = 'https://api.quickpay.net'
@@ -43,32 +45,43 @@ def fulfill(self, method, *args, **kwargs):
4345

4446
def perform(self, method, path, **kwargs):
4547
raw = kwargs.pop('raw', False)
48+
ssl_verify = kwargs.pop("verify", True)
4649
url = "{0}{1}".format(self.base_url, path)
4750

4851
headers = {
4952
"Accept-Version": 'v%s' % self.api_version,
5053
"User-Agent": "quickpay-python-client, v%s" % quickpay_api_client.__version__
5154
}
5255

53-
callback_url = kwargs.pop("callback_url", None)
54-
if callback_url:
55-
headers["QuickPay-Callback-Url"] = callback_url
56+
body = kwargs.get("body", {})
57+
query = kwargs.get("query", {})
58+
59+
for key in kwargs.get("headers", {}):
60+
headers[key] = kwargs['headers'][key]
5661

5762
if self.secret:
58-
headers["Authorization"
59-
] = "Basic {0}".format(_base64_encode(self.secret))
63+
headers["Authorization"] = "Basic {0}".format(
64+
_base64_encode(self.secret))
6065

6166
if method in ['put', 'post', 'patch']:
6267
headers['content-type'] = 'application/json'
68+
69+
# The bytes class isn't considered a string type in Python 3
70+
if not isinstance(body, (str, bytes)):
71+
body = json.dumps(body)
72+
6373
response = self.fulfill(method, url,
64-
data=json.dumps(kwargs),
74+
data=body,
75+
params=query,
6576
headers=headers,
66-
timeout=self.timeout)
77+
timeout=self.timeout,
78+
verify=ssl_verify)
6779
else:
6880
response = self.fulfill(method, url,
69-
params=kwargs,
81+
params=query,
7082
headers=headers,
71-
timeout=self.timeout)
83+
timeout=self.timeout,
84+
verify=ssl_verify)
7285

7386
if response.headers.get('content-type') == 'application/json':
7487
body = response.json()

quickpay_api_client/tests/api_tests.py

+36-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import base64, json
1+
import base64
2+
import json
23
from nose.tools import assert_equal, assert_raises
34
import requests
45
from quickpay_api_client.api import QPApi
@@ -12,8 +13,8 @@ def setup(self):
1213

1314
def setup_request(self):
1415
responses.add(responses.GET, self.url,
15-
json={'id': 123},
16-
headers={"x-quickpay-server" : "QP-TEST"})
16+
json={'id': 123},
17+
headers={"x-quickpay-server": "QP-TEST"})
1718

1819
@responses.activate
1920
def test_perform_success(self):
@@ -24,8 +25,8 @@ def test_perform_success(self):
2425
@responses.activate
2526
def test_perform_failure(self):
2627
responses.add(responses.GET, self.url,
27-
status=500,
28-
json={'message': 'dummy'})
28+
status=500,
29+
json={'message': 'dummy'})
2930

3031
try:
3132
self.api.perform("get", "/test")
@@ -47,11 +48,40 @@ def test_headers(self):
4748
def test_callback_url_headers(self):
4849
self.setup_request()
4950
callback_url = "https://foo.bar"
50-
res = self.api.perform("get", "/test", callback_url=callback_url)
51+
self.api.perform(
52+
"get", "/test", headers={'QuickPay-Callback-Url': callback_url})
5153

5254
req_headers = responses.calls[0].request.headers
5355
assert_equal(req_headers['QuickPay-Callback-Url'], callback_url)
5456

57+
@responses.activate
58+
def test_query_params(self):
59+
self.setup_request()
60+
self.api.perform("get", "/test", query={'foo': 'bar'})
61+
62+
url = responses.calls[0].request.url
63+
assert(url.endswith('?foo=bar'))
64+
65+
@responses.activate
66+
def test_post_body(self):
67+
responses.add(responses.POST, self.url,
68+
status=200,
69+
json={'message': 'dummy'})
70+
71+
self.api.perform("post", "/test", query={"foo": "baz"},
72+
body={'foo': 'bar'})
73+
74+
last_request = responses.calls[0].request
75+
body = last_request.body
76+
parsed_body = json.loads(body)
77+
headers = last_request.headers
78+
79+
assert_equal(parsed_body["foo"], "bar")
80+
assert(headers["Authorization"])
81+
assert(headers["Accept-Version"])
82+
assert(headers["User-Agent"])
83+
assert(last_request.url.endswith('?foo=baz'))
84+
5585
@responses.activate
5686
def test_perform_when_raw(self):
5787
self.setup_request()

0 commit comments

Comments
 (0)