Skip to content

Commit

Permalink
Merge pull request #3 from soda480/0.0.3
Browse files Browse the repository at this point in the history
Add log_request method
  • Loading branch information
soda480 authored Jun 7, 2020
2 parents dd4c67a + 93caf4f commit 110dd54
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 50 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.6.5-stretch
FROM python:3.6.5-slim

ENV PYTHONDONTWRITEBYTECODE 1

Expand Down
2 changes: 1 addition & 1 deletion build.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
]
summary = 'A Python class providing primitive methods for enabling consumption of REST APIs'
url = 'https://github.com/soda480/rest3client'
version = '0.0.2'
version = '0.0.3'
default_task = [
'clean',
'analyze',
Expand Down
60 changes: 32 additions & 28 deletions src/main/python/rest3client/restclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,31 +103,7 @@ def get_headers(self, **kwargs):

return headers

def request_handler(function):
""" decorator to process arguments and response for request method
"""
def _request_handler(self, *args, **kwargs):
""" decorator method to prepare and handle requests and responses
"""
noop = kwargs.pop('noop', False)
key_word_arguments = self.process_arguments(args, kwargs)

redacted_key_word_arguments = redact(key_word_arguments)
try:
redacted = json.dumps(redact(redacted_key_word_arguments), indent=2, sort_keys=True)
except TypeError:
redacted = redacted_key_word_arguments

logger.debug('\n{}: {} NOOP: {}\n{}'.format(
function.__name__.upper(), key_word_arguments['address'], noop, redacted))
if noop:
return
response = function(self, *args, **key_word_arguments)
return self.process_response(response, **kwargs)

return _request_handler

def process_arguments(self, args, kwargs):
def get_arguments(self, endpoint, kwargs):
""" return key word arguments to pass to requests method
"""
arguments = copy.deepcopy(kwargs)
Expand All @@ -141,10 +117,22 @@ def process_arguments(self, args, kwargs):
if 'verify' not in arguments or arguments.get('verify') is None:
arguments['verify'] = self.cabundle

arguments['address'] = 'https://{}{}'.format(self.hostname, args[0])
arguments['address'] = 'https://{}{}'.format(self.hostname, endpoint)
arguments.pop('raw_response', None)
return arguments

def log_request(self, function_name, arguments, noop):
""" log request function name and redacted arguments
"""
redacted_arguments = redact(arguments)
try:
redacted_arguments = json.dumps(redacted_arguments, indent=2, sort_keys=True)
except TypeError:
pass

logger.debug('\n{}: {} NOOP: {}\n{}'.format(
function_name, arguments['address'], noop, redacted_arguments))

def get_error_message(self, response):
""" return error message from response
"""
Expand Down Expand Up @@ -183,6 +171,22 @@ def process_response(self, response, **kwargs):
logger.debug('returning response text')
return response.text

def request_handler(function):
""" decorator to process arguments and response for request method
"""
def _request_handler(self, endpoint, **kwargs):
""" decorator method to prepare and handle requests and responses
"""
noop = kwargs.pop('noop', False)
arguments = self.get_arguments(endpoint, kwargs)
self.log_request(function.__name__.upper(), arguments, noop)
if noop:
return
response = function(self, endpoint, **arguments)
return self.process_response(response, **kwargs)

return _request_handler

@request_handler
def post(self, endpoint, **kwargs):
""" helper method to submit post requests
Expand All @@ -191,7 +195,7 @@ def post(self, endpoint, **kwargs):

@request_handler
def put(self, endpoint, **kwargs):
""" helper method to submit post requests
""" helper method to submit put requests
"""
return requests.put(kwargs.pop('address'), **kwargs)

Expand All @@ -209,7 +213,7 @@ def delete(self, endpoint, **kwargs):

@request_handler
def patch(self, endpoint, **kwargs):
""" helper method to submit delete requests
""" helper method to submit patch requests
"""
return requests.patch(kwargs.pop('address'), **kwargs)

Expand Down
69 changes: 49 additions & 20 deletions src/unittest/python/test_RESTclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,42 @@ def test__get_headers_Should_ReturnHeaders_When_BearerToken(self, *patches):
}
self.assertEqual(result, expected_result)

@patch('rest3client.restclient.os.access')
@patch('rest3client.restclient.redact')
@patch('rest3client.restclient.logger')
def test__log_request_Should_CallLogger_When_JsonNotSerializable(self, logger_patch, redact_patch, *patches):
redact_patch.return_value = '--redacted-arguments--'
client = RESTclient('hostname1.company.com', bearer_token='token')
arguments = {
'address': '--address--',
'data': Mock()
}
client.log_request('GET', arguments, True)
debug_call = call('\nGET: --address-- NOOP: True\n"--redacted-arguments--"')
self.assertTrue(debug_call in logger_patch.debug.mock_calls)

@patch('rest3client.restclient.os.access')
@patch('rest3client.restclient.redact')
@patch('rest3client.restclient.logger')
def test__log_request_Should_CallLogger_When_JsonSerializable(self, logger_patch, redact_patch, *patches):
arguments = {
'address': '--address--',
'data': 'data'
}
redact_patch.return_value = arguments
client = RESTclient('hostname1.company.com', bearer_token='token')

client.log_request('GET', arguments, True)
debug_call = call('\nGET: --address-- NOOP: True\n{\n "address": "--address--",\n "data": "data"\n}')
self.assertTrue(debug_call in logger_patch.debug.mock_calls)

@patch('rest3client.restclient.os.access')
def test__request_handler_Should_CallFunctionWithArgs_When_Args(self, *patches):
mock_function = Mock(__name__='mocked method')
client = RESTclient('hostname1.company.com')
decorated_function = RESTclient.request_handler(mock_function)
decorated_function(client, '/rest/endpoint', 'arg1', 'arg2')
expected_args = (client, '/rest/endpoint', 'arg1', 'arg2')
decorated_function(client, '/rest/endpoint', k1='arg1', k2='arg2')
expected_args = (client, '/rest/endpoint')
args, _ = mock_function.call_args_list[0]
self.assertEqual(args, expected_args)

Expand Down Expand Up @@ -162,27 +191,27 @@ def test__request_handler_Should_NotCallFunctionAndReturnNone_When_FunctionSetsN

@patch('rest3client.restclient.os.access')
@patch('rest3client.RESTclient.get_headers', return_value={'h1': 'v1'})
def test__get_standard_kwargs_Should_SetHeaders_When_NoHeadersSpecified(self, *patches):
def test__get_arguments_Should_SetHeaders_When_NoHeadersSpecified(self, *patches):
client = RESTclient('hostname1.company.com')
args = ['/endpoint']
endpoint = '/endpoint'
kwargs = {}
result = client.process_arguments(args, kwargs)
result = client.get_arguments(endpoint, kwargs)
expected_result = {
'h1': 'v1'
}
self.assertEqual(result['headers'], expected_result)

@patch('rest3client.restclient.os.access')
@patch('rest3client.RESTclient.get_headers', return_value={'h1': 'v1'})
def test__get_standard_kwargs_Should_UpdatedHeaders_When_HeadersSpecified(self, *patches):
def test__get_arguments_Should_UpdatedHeaders_When_HeadersSpecified(self, *patches):
client = RESTclient('hostname1.company.com')
args = ['/endpoint']
endpoint = '/endpoint'
kwargs = {
'headers': {
'h2': 'v2'
}
}
result = client.process_arguments(args, kwargs)
result = client.get_arguments(endpoint, kwargs)
expected_result = {
'h1': 'v1',
'h2': 'v2'
Expand All @@ -191,42 +220,42 @@ def test__get_standard_kwargs_Should_UpdatedHeaders_When_HeadersSpecified(self,

@patch('rest3client.restclient.os.access')
@patch('rest3client.RESTclient.get_headers', return_value={'h1': 'v1'})
def test__get_standard_kwargs_Should_SetVerifyToCabundle_When_VerifyNotSpecified(self, *patches):
def test__get_arguments_Should_SetVerifyToCabundle_When_VerifyNotSpecified(self, *patches):
client = RESTclient('hostname1.company.com')
args = ['/endpoint']
endpoint = '/endpoint'
kwargs = {}
result = client.process_arguments(args, kwargs)
result = client.get_arguments(endpoint, kwargs)
self.assertEqual(result['verify'], client.cabundle)

@patch('rest3client.restclient.os.access')
@patch('rest3client.RESTclient.get_headers', return_value={'h1': 'v1'})
def test__get_standard_kwargs_Should_SetVerifyToCabundle_When_VerifyIsNone(self, *patches):
def test__get_arguments_Should_SetVerifyToCabundle_When_VerifyIsNone(self, *patches):
client = RESTclient('hostname1.company.com')
args = ['/endpoint']
endpoint = '/endpoint'
kwargs = {
'verify': None
}
result = client.process_arguments(args, kwargs)
result = client.get_arguments(endpoint, kwargs)
self.assertEqual(result['verify'], client.cabundle)

@patch('rest3client.restclient.os.access')
@patch('rest3client.RESTclient.get_headers', return_value={'h1': 'v1'})
def test__get_standard_kwargs_Should_NotSetVerify_When_VerifyIsSet(self, *patches):
def test__get_arguments_Should_NotSetVerify_When_VerifyIsSet(self, *patches):
client = RESTclient('hostname1.company.com')
args = ['/endpoint']
endpoint = '/endpoint'
kwargs = {
'verify': False
}
result = client.process_arguments(args, kwargs)
result = client.get_arguments(endpoint, kwargs)
self.assertFalse(result['verify'])

@patch('rest3client.restclient.os.access')
@patch('rest3client.RESTclient.get_headers', return_value={'h1': 'v1'})
def test__get_standard_kwargs_Should_SetAddress_When_Called(self, *patches):
def test__get_arguments_Should_SetAddress_When_Called(self, *patches):
client = RESTclient('hostname1.company.com')
args = ['/endpoint']
endpoint = '/endpoint'
kwargs = {}
result = client.process_arguments(args, kwargs)
result = client.get_arguments(endpoint, kwargs)
expected_result = 'https://hostname1.company.com/endpoint'
self.assertEqual(result['address'], expected_result)

Expand Down

0 comments on commit 110dd54

Please sign in to comment.