Skip to content

Commit edba01d

Browse files
committed
improved put request
1 parent 702e64e commit edba01d

File tree

3 files changed

+149
-10
lines changed

3 files changed

+149
-10
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11

22
Unreleased
33
----------
4+
**Changes**
5+
- `put` request will take an `item` parameter that's used to automatically populate headers for updates.
6+
47
**Bugfixes**
58
- Convert NaN values to null (None) when calling `microanalytic_score.execute_module_step`.
69

10+
711
v1.2.2 (2019-8-21)
812
------------------
913
**Bugfixes**

src/sasctl/core.py

Lines changed: 95 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -632,30 +632,115 @@ def is_uuid(id):
632632
return False
633633

634634

635-
def get(*args, **kwargs):
635+
def get(path, **kwargs):
636+
"""Send a GET request.
637+
638+
Parameters
639+
----------
640+
path : str
641+
The path portion of the URL.
642+
kwargs : any
643+
Passed to `request`.
644+
645+
Returns
646+
-------
647+
RestObj or None
648+
The results or None if the resource was not found.
649+
650+
"""
636651
try:
637-
return request('get', *args, **kwargs)
652+
return request('get', path, **kwargs)
638653
except HTTPError as e:
639654
if e.code == 404:
640655
return None # Resource not found
641656
else:
642657
raise e
643658

644659

645-
def head(*args, **kwargs):
646-
return request('head', *args, **kwargs)
660+
def head(path, **kwargs):
661+
"""Send a HEAD request.
662+
663+
Parameters
664+
----------
665+
path : str
666+
The path portion of the URL.
667+
kwargs : any
668+
Passed to `request`.
669+
670+
Returns
671+
-------
672+
RestObj
647673
674+
"""
675+
return request('head', path, **kwargs)
648676

649-
def post(*args, **kwargs):
650-
return request('post', *args, **kwargs)
651677

678+
def post(path, **kwargs):
679+
"""Send a POST request.
652680
653-
def put(*args, **kwargs):
654-
return request('put', *args, **kwargs)
681+
Parameters
682+
----------
683+
path : str
684+
The path portion of the URL.
685+
kwargs : any
686+
Passed to `request`.
655687
688+
Returns
689+
-------
690+
RestObj
656691
657-
def delete(*args, **kwargs):
658-
return request('delete', *args, **kwargs)
692+
"""
693+
return request('post', path, **kwargs)
694+
695+
696+
def put(path, item=None, **kwargs):
697+
"""Send a PUT request.
698+
699+
Parameters
700+
----------
701+
path : str
702+
The path portion of the URL.
703+
item : RestObj, optional
704+
A existing object to PUT. If provided, ETag and Content-Type headers
705+
will automatically be specified.
706+
kwargs : any
707+
Passed to `request`.
708+
709+
Returns
710+
-------
711+
RestObj
712+
713+
"""
714+
# If call is in the format put(url, RestObj), automatically fill in header
715+
# information
716+
if item is not None and isinstance(item, RestObj):
717+
get_headers = getattr(item, '_headers', None)
718+
if get_headers is not None:
719+
# Update the headers param if it was specified
720+
headers = kwargs.pop('headers', {})
721+
headers.setdefault('If-Match', get_headers.get('etag'))
722+
headers.setdefault('Content-Type', get_headers.get('content-type'))
723+
return request('put', path, json=item, headers=headers)
724+
725+
return request('put', path, **kwargs)
726+
727+
728+
def delete(path, **kwargs):
729+
"""Send a DELETE request.
730+
731+
Parameters
732+
----------
733+
path : str
734+
The path portion of the URL.
735+
kwargs : any
736+
Passed to `request`.
737+
738+
Returns
739+
-------
740+
RestObj
741+
742+
"""
743+
return request('delete', path, **kwargs)
659744

660745

661746
def request(verb, path, session=None, raw=False, **kwargs):

tests/unit/test_core.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,53 @@ def test_update_item():
111111
assert ('put', '/widget/12345') == request.call_args[0]
112112
assert target == resp
113113

114+
115+
def test_put_restobj():
116+
from sasctl.core import put, RestObj
117+
118+
url = "/jobDefinitions/definitions/717331fa-f650-4e31-b9e2-6e6d49f66bf9"
119+
obj = RestObj({
120+
'_headers': {'etag': 123, 'content-type': 'spam'}
121+
})
122+
123+
# Base case
124+
with mock.patch('sasctl.core.request') as req:
125+
put(url, obj)
126+
127+
assert req.called
128+
args = req.call_args[0]
129+
kwargs = req.call_args[1]
130+
131+
assert args == ('put', url)
132+
assert kwargs['json'] == obj
133+
assert kwargs['headers']['If-Match'] == 123
134+
assert kwargs['headers']['Content-Type'] == 'spam'
135+
136+
# Should merge with explicit headers
137+
with mock.patch('sasctl.core.request') as req:
138+
put(url, obj, headers={'encoding': 'spammy'})
139+
140+
assert req.called
141+
args = req.call_args[0]
142+
kwargs = req.call_args[1]
143+
144+
assert args == ('put', url)
145+
assert kwargs['json'] == obj
146+
assert kwargs['headers']['If-Match'] == 123
147+
assert kwargs['headers']['Content-Type'] == 'spam'
148+
assert kwargs['headers']['encoding'] == 'spammy'
149+
150+
# Should not overwrite explicit headers
151+
with mock.patch('sasctl.core.request') as req:
152+
put(url, obj, headers={'Content-Type': 'notspam',
153+
'encoding': 'spammy'})
154+
155+
assert req.called
156+
args = req.call_args[0]
157+
kwargs = req.call_args[1]
158+
159+
assert args == ('put', url)
160+
assert kwargs['json'] == obj
161+
assert kwargs['headers']['If-Match'] == 123
162+
assert kwargs['headers']['Content-Type'] == 'notspam'
163+
assert kwargs['headers']['encoding'] == 'spammy'

0 commit comments

Comments
 (0)