Skip to content

Commit 69d6685

Browse files
authored
Merge pull request #5 from akreisman-epam/master
Extend with absent endpoints
2 parents 6a227ab + 67000ff commit 69d6685

10 files changed

Lines changed: 158 additions & 71 deletions

File tree

.coveragerc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[run]
22
source = hyperwallet
3-
omit = venv/*
4-
omit = hyperwallet/tests/*
3+
omit =
4+
venv/*
5+
hyperwallet/tests/*

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ htmlcov
1717
# Other
1818
.DS_Store
1919
.coverage
20+
.idea/

CHANGELOG.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
Changelog
22
=========
33

4+
1.1.2 (current)
5+
------------------
6+
7+
- Added bank card endpoint
8+
49
1.1.1 (2017-10-11)
510
------------------
611

hyperwallet/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
__email__ = 'devsupport@hyperwallet.com'
77
__copyright__ = 'Copyright (c) 2017 Hyperwallet'
88
__license__ = 'MIT'
9-
__version__ = '1.1.1'
9+
__version__ = '1.1.2'
1010
__url__ = 'https://github.com/hyperwallet/python-sdk'
1111
__download_url__ = 'https://pypi.python.org/pypi/hyperwallet-sdk'
1212
__description__ = 'A Python wrapper around the Hyperwallet API'

hyperwallet/api.py

Lines changed: 72 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
import os
44

5-
from config import SERVER
6-
from exceptions import HyperwalletException
7-
from utils import ApiClient
5+
from .config import SERVER
6+
from .exceptions import HyperwalletException
7+
from .utils import ApiClient
88

99
from hyperwallet import (
1010
User,
@@ -155,37 +155,6 @@ def listUsers(self,
155155

156156
return [User(x) for x in response.get('data', [])]
157157

158-
def createUserStatusTransition(self,
159-
userToken=None,
160-
data=None):
161-
'''
162-
Create a User Status Transition.
163-
164-
:param userToken:
165-
A token identifying the User. **REQUIRED**
166-
:param data:
167-
A dictionary containing User Status Transition information. **REQUIRED**
168-
:returns:
169-
A User Status Transition.
170-
'''
171-
172-
if not userToken:
173-
raise HyperwalletException('userToken is required')
174-
175-
if not data:
176-
raise HyperwalletException('data is required')
177-
178-
response = self.apiClient.doPost(
179-
os.path.join(
180-
'users',
181-
userToken,
182-
'status-transitions'
183-
),
184-
data
185-
)
186-
187-
return StatusTransition(response)
188-
189158
def getUserStatusTransition(self,
190159
userToken=None,
191160
statusTransitionToken=None):
@@ -821,6 +790,44 @@ def createPrepaidCard(self,
821790

822791
return PrepaidCard(response)
823792

793+
def updatePrepaidCard(self,
794+
userToken=None,
795+
prepaidCardToken=None,
796+
data=None):
797+
'''
798+
Update a Prepaid Card.
799+
800+
:param userToken:
801+
A token identifying the User. **REQUIRED**
802+
:param prepaidCardToken:
803+
A token identifying the Prepaid Card. **REQUIRED**
804+
:param data:
805+
A dictionary containing Prepaid Card information. **REQUIRED**
806+
:returns:
807+
A Prepaid Card.
808+
'''
809+
810+
if not userToken:
811+
raise HyperwalletException('userToken is required')
812+
813+
if not prepaidCardToken:
814+
raise HyperwalletException('prepaidCardToken is required')
815+
816+
if not data:
817+
raise HyperwalletException('data is required')
818+
819+
response = self.apiClient.doPut(
820+
os.path.join(
821+
'users',
822+
userToken,
823+
'prepaid-cards',
824+
prepaidCardToken
825+
),
826+
data
827+
)
828+
829+
return PrepaidCard(response)
830+
824831
def getPrepaidCard(self,
825832
userToken=None,
826833
prepaidCardToken=None):
@@ -1560,6 +1567,37 @@ def listPaymentStatusTransitions(self,
15601567

15611568
return [StatusTransition(x) for x in response.get('data', [])]
15621569

1570+
def createPaymentStatusTransition(self,
1571+
paymentToken=None,
1572+
data=None):
1573+
'''
1574+
Create Payment Status Transition.
1575+
1576+
:param paymentToken:
1577+
A token identifying the Payment. **REQUIRED**
1578+
:param data:
1579+
A dictionary containing User Status Transition information. **REQUIRED**
1580+
:returns:
1581+
A Payment Status Transition.
1582+
'''
1583+
1584+
if not paymentToken:
1585+
raise HyperwalletException('paymentToken is required')
1586+
1587+
if not data:
1588+
raise HyperwalletException('data is required')
1589+
1590+
response = self.apiClient.doPost(
1591+
os.path.join(
1592+
'payments',
1593+
paymentToken,
1594+
'status-transitions'
1595+
),
1596+
data
1597+
)
1598+
1599+
return StatusTransition(response)
1600+
15631601
'''
15641602
15651603
Balances

hyperwallet/exceptions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,16 @@ class HyperwalletException(Exception):
66
An Exception raised when the SDK is used incorrectly.
77
'''
88

9+
@property
10+
def message(self):
11+
return self.__dict__.get('message', None) or getattr(self, 'args')[0]
12+
913

1014
class HyperwalletAPIException(Exception):
1115
'''
1216
An Exception raised when the API response is an error.
1317
'''
18+
19+
@property
20+
def message(self):
21+
return self.__dict__.get('message', None) or getattr(self, 'args')[0]

hyperwallet/tests/test_api.py

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -131,28 +131,6 @@ def test_list_users_success(self, mock_get):
131131

132132
self.assertEqual(response[0].token, self.data.get('token'))
133133

134-
def test_create_user_status_transition_fail_need_user_token(self):
135-
136-
with self.assertRaises(HyperwalletException) as exc:
137-
self.api.createUserStatusTransition()
138-
139-
self.assertEqual(exc.exception.message, 'userToken is required')
140-
141-
def test_create_user_status_transition_fail_need_data(self):
142-
143-
with self.assertRaises(HyperwalletException) as exc:
144-
self.api.createUserStatusTransition('token')
145-
146-
self.assertEqual(exc.exception.message, 'data is required')
147-
148-
@mock.patch('hyperwallet.utils.ApiClient._makeRequest')
149-
def test_create_user_status_transition_success(self, mock_post):
150-
151-
mock_post.return_value = self.data
152-
response = self.api.createUserStatusTransition('token', self.data)
153-
154-
self.assertTrue(response.token, self.data.get('token'))
155-
156134
def test_get_user_status_transition_fail_need_user_token(self):
157135

158136
with self.assertRaises(HyperwalletException) as exc:
@@ -632,6 +610,35 @@ def test_create_prepaid_card_success(self, mock_post):
632610

633611
self.assertTrue(response.token, self.data.get('token'))
634612

613+
def test_update_prepaid_card_fail_need_user_token(self):
614+
615+
with self.assertRaises(HyperwalletException) as exc:
616+
self.api.updatePrepaidCard()
617+
618+
self.assertEqual(exc.exception.message, 'userToken is required')
619+
620+
def test_update_prepaid_card_fail_need_card_token(self):
621+
622+
with self.assertRaises(HyperwalletException) as exc:
623+
self.api.updatePrepaidCard('token')
624+
625+
self.assertEqual(exc.exception.message, 'prepaidCardToken is required')
626+
627+
def test_update_prepaid_card_fail_need_data(self):
628+
629+
with self.assertRaises(HyperwalletException) as exc:
630+
self.api.updatePrepaidCard('token', 'token')
631+
632+
self.assertEqual(exc.exception.message, 'data is required')
633+
634+
@mock.patch('hyperwallet.utils.ApiClient._makeRequest')
635+
def test_update_prepaid_card_success(self, mock_put):
636+
637+
mock_put.return_value = self.data
638+
response = self.api.updatePrepaidCard('token', 'token', self.data)
639+
640+
self.assertTrue(response.token, self.data.get('token'))
641+
635642
def test_get_prepaid_card_fail_need_user_token(self):
636643

637644
with self.assertRaises(HyperwalletException) as exc:
@@ -1235,6 +1242,28 @@ def test_list_payment_status_transitions_success(self, mock_get):
12351242

12361243
self.assertTrue(response[0].token, self.data.get('token'))
12371244

1245+
def test_create_payment_status_transition_fail_need_payment_token(self):
1246+
1247+
with self.assertRaises(HyperwalletException) as exc:
1248+
self.api.createPaymentStatusTransition()
1249+
1250+
self.assertEqual(exc.exception.message, 'paymentToken is required')
1251+
1252+
def test_create_payment_status_transition_fail_need_data(self):
1253+
1254+
with self.assertRaises(HyperwalletException) as exc:
1255+
self.api.createPaymentStatusTransition('token')
1256+
1257+
self.assertEqual(exc.exception.message, 'data is required')
1258+
1259+
@mock.patch('hyperwallet.utils.ApiClient._makeRequest')
1260+
def test_create_payment_status_transition_success(self, mock_post):
1261+
1262+
mock_post.return_value = self.data
1263+
response = self.api.createPaymentStatusTransition('token', self.data)
1264+
1265+
self.assertTrue(response.token, self.data.get('token'))
1266+
12381267
'''
12391268
12401269
Balances

hyperwallet/tests/test_client.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,13 @@ def test_receive_valid_json_response(self, session_mock):
9191
content=json.dumps(data)
9292
)
9393

94+
encoded = json.dumps(data)
95+
if hasattr(encoded, 'decode'): # Python 2
96+
encoded = encoded.decode('utf-8')
97+
9498
self.assertEqual(
9599
self.client._makeRequest(),
96-
json.loads(json.dumps(data).decode('utf-8'))
100+
json.loads(encoded)
97101
)
98102

99103

hyperwallet/tests/test_models.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
import json
44
import unittest
5-
import hyperwallet
6-
7-
from hyperwallet.exceptions import HyperwalletException
85

96
from hyperwallet import (
107
HyperwalletModel,
@@ -374,7 +371,7 @@ def test_transfer_method_configuration_model(self):
374371
transfer_method_configuration_data
375372
)
376373

377-
print transfer_method_configuration_data.get('countries')
374+
print(transfer_method_configuration_data.get('countries'))
378375
self.assertEqual(
379376
test_transfer_method_configuration.__repr__(),
380377
'TransferMethodConfiguration({country}, {type})'.format(

hyperwallet/utils/apiclient.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
#!/usr/bin/env python
22

3-
import sys
43
import ssl
54
import json
6-
import urlparse
75
import requests
86

97
from hyperwallet.exceptions import HyperwalletAPIException
108
from requests_toolbelt.adapters.ssl import SSLAdapter
119
from hyperwallet import __version__
10+
try:
11+
from urllib.parse import urljoin
12+
except ImportError:
13+
from urlparse import urljoin # Python 2
1214

1315

1416
class ApiClient(object):
@@ -42,7 +44,7 @@ def __init__(self, username, password, server):
4244
self.server = server
4345

4446
# The complete base URL of the API.
45-
self.baseUrl = urlparse.urljoin(self.server, '/rest/v3/')
47+
self.baseUrl = urljoin(self.server, '/rest/v3/')
4648

4749
# The default connection to persist authentication and SSL settings.
4850
defaultSession = requests.Session()
@@ -81,7 +83,7 @@ def _makeRequest(self,
8183
try:
8284
response = self.session.request(
8385
method=method,
84-
url=urlparse.urljoin(self.baseUrl, url),
86+
url=urljoin(self.baseUrl, url),
8587
data=data,
8688
headers=headers,
8789
params=params
@@ -93,15 +95,17 @@ def _makeRequest(self,
9395
'code': 'COMMUNICATION_ERROR',
9496
'message': 'Connection to {} failed: {}'.format(
9597
self.server,
96-
e.message
98+
e.args[0]
9799
)
98100
}]
99101
})
100102

101103
if response.status_code is 204:
102104
return {}
103105

104-
content = response.content.decode('utf-8')
106+
content = response.content
107+
if hasattr(content, 'decode'): # Python 2
108+
content = content.decode('utf-8')
105109

106110
try:
107111
json_body = json.loads(content)
@@ -110,7 +114,7 @@ def _makeRequest(self,
110114
raise HyperwalletAPIException({
111115
'errors': [{
112116
'code': 'GARBAGE_RESPONSE',
113-
'message': 'Invalid response: {}'.format(e.message)
117+
'message': 'Invalid response: {}'.format(e.args[0])
114118
}]
115119
})
116120

0 commit comments

Comments
 (0)