Enhancement: Validate request body parameters and use defaults

This commit is contained in:
Kyle Hornberg
2018-02-06 07:10:41 -06:00
parent 13d1ea539e
commit a707d38e25
2 changed files with 55 additions and 9 deletions
+12 -9
View File
@@ -10,7 +10,7 @@ __version__ = '0.1.0'
class Base(object):
headers = {}
headers = {} # TODO default headers
base_url = 'https://api.github.com'
def _get_headers(self, definition):
@@ -21,8 +21,10 @@ class Base(object):
for p in required_params:
assert p in kwargs # has all required
for kwarg, value in kwargs.items():
param = params.get(kwarg)
assert param # is a valid param but not necessarily required
param_value = params.get(kwarg)
assert param_value # is a valid param but not necessarily required
if param_value.get('enum'):
assert value in param_value.get('enum') # is a valid option of the enum
if kwarg in required_params:
assert value # required param has a value
@@ -31,12 +33,16 @@ class Base(object):
for name, value in values.items():
_url, subs = re.subn(f':{name}', str(value), _url)
if subs != 0:
# TODO
# it seems like params not in the url are in the body data
data_values.pop(name)
url = f'{self.base_url}{_url}'
return url, data_values
def _get_data(self, kwargs, params):
for param, value in params.items():
if value.get('default') and not kwargs.get(param):
kwargs[param] = value.get('default')
return json.dumps(kwargs) if kwargs else None
class Octokit(Base):
@@ -65,10 +71,7 @@ class Octokit(Base):
def _api_call(*args, **kwargs):
self._validate(kwargs, definition.get('params'))
url, data_kwargs = self._form_url(kwargs, definition['url'])
# TODO for post, put, patch data
# use defaults for params
# data = json.dumps(o_kwargs) if o_kwargs else None
data = None
data = self._get_data(data_kwargs, definition.get('params'))
return getattr(requests, definition['method'].lower())(
url, headers=self._get_headers(definition), data=data
)
+43
View File
@@ -1,6 +1,7 @@
from octokit import Octokit
import requests
import pytest
import json
class TestClientMethods(object):
@@ -35,3 +36,45 @@ class TestClientMethods(object):
mocker.patch('requests.get')
Octokit().authorization.get(id=100)
requests.get.assert_called_once_with('https://api.github.com/authorizations/100', data=None, headers={})
def test_request_has_body_parameters(self, mocker):
mocker.patch('requests.post')
data = {
'scopes': [
'public_repo'
],
'note': 'admin script'
}
Octokit().authorization.create(**data)
requests.post.assert_called_once_with(
'https://api.github.com/authorizations', data=json.dumps(data), headers={}
)
def test_must_include_required_body_parameters(self):
data = {
'gist_id': 'abc123',
}
with pytest.raises(AssertionError):
Octokit().authorization.create(**data)
def test_use_default_parameter_values(self, mocker):
mocker.patch('requests.patch')
headers = {'accept': 'application/vnd.github.squirrel-girl-preview'}
data = {'state': 'open'}
Octokit().issues.edit(owner='testUser', repo='testRepo', number=1)
requests.patch.assert_called_once_with(
'https://api.github.com/repos/testUser/testRepo/issues/1', data=json.dumps(data), headers=headers
)
def test_use_passed_value_instead_of_default_parameter_values(self, mocker):
mocker.patch('requests.patch')
headers = {'accept': 'application/vnd.github.squirrel-girl-preview'}
data = {'state': 'closed'}
Octokit().issues.edit(owner='testUser', repo='testRepo', number=1, **data)
requests.patch.assert_called_once_with(
'https://api.github.com/repos/testUser/testRepo/issues/1', data=json.dumps(data), headers=headers
)
def test_validate_enum_values(self):
with pytest.raises(AssertionError):
Octokit().issues.edit(owner='testUser', repo='testRepo', number=1, state='closeddddd')