Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_call_local_action_super_enriched_request(self):
action = mock.MagicMock()
action.return_value.return_value = ActionResponse(action='another_foo', body={'sweet': 'success'})
server = mock.MagicMock()
server.settings = {'a_setting': 'a_value'}
server.action_class_map = {'another_foo': action}
logger = logging.getLogger('test')
r = SuperEnrichedActionRequest(
action='foo',
body={'bar': 'baz'},
context={'auth_token': 'def456'},
control={'repeat': True},
metrics='A custom object',
analytics_logger=logger,
)
r._server = server
def test_returns_action_response_true(self):
response = self.action(self.action_request)
self.assertIsInstance(response, ActionResponse)
self.assertEqual(self.action_request.action, response.action)
self.assertEqual({'boolean_field': True}, response.body)
'conformity': '1.2.3',
'pysoa': '1.0.2',
'python': '3.7.4',
'version': '9.7.8',
}
with stub_action('foo', 'status') as foo_stub,\
stub_action('bar', 'status', errors=[Error('BAR_ERROR', 'Bar error')]),\
stub_action('baz', 'status', body=baz_body),\
stub_action('qux', 'status') as qux_stub:
foo_stub.return_value = JobResponse(errors=[Error('FOO_ERROR', 'Foo error')])
qux_stub.side_effect = MessageReceiveTimeout('Timeout calling qux')
response = _CheckOtherServicesAction()(action_request)
self.assertIsInstance(response, ActionResponse)
self.assertEqual(six.text_type(conformity.__version__), response.body['conformity'])
self.assertEqual(six.text_type(pysoa.__version__), response.body['pysoa'])
self.assertEqual(six.text_type(platform.python_version()), response.body['python'])
self.assertEqual('8.71.2', response.body['version'])
self.assertIn('healthcheck', response.body)
self.assertEqual([], response.body['healthcheck']['warnings'])
self.assertIn(
('FOO_CALL_ERROR', six.text_type([Error('FOO_ERROR', 'Foo error')])),
response.body['healthcheck']['errors'],
)
self.assertIn(
('BAR_STATUS_ERROR', six.text_type([Error('BAR_ERROR', 'Bar error')])),
response.body['healthcheck']['errors'],
)
self.assertIn(
('QUX_TRANSPORT_ERROR', 'Timeout calling qux'),
def action_logic(request): # type: (EnrichedActionRequest) -> ActionResponse
return ActionResponse(action='one', body={'animal_response': request.body['animal'], 'settings': settings})
return action_logic
pass
__all__ = (
'HarakiriInterrupt',
'Server',
'ServerMiddlewareActionTask',
'ServerMiddlewareJobTask',
)
# A hack to make documentation generation work properly, otherwise there are errors (see `if TYPE_CHECKING`)
middleware.EnrichedActionRequest = EnrichedActionRequest # type: ignore
middleware.EnrichedJobRequest = EnrichedJobRequest # type: ignore
ServerMiddlewareJobTask = Callable[[EnrichedJobRequest], JobResponse]
ServerMiddlewareActionTask = Callable[[EnrichedActionRequest], ActionResponse]
_MT = TypeVar('_MT', ServerMiddlewareActionTask, ServerMiddlewareJobTask)
_RT = TypeVar('_RT', JobResponse, ActionResponse)
def _replace_fid(d, fid): # type: (Dict[Any, Any], six.text_type) -> None
for k, v in six.iteritems(d):
if isinstance(v, six.text_type):
d[k] = v.replace('{{fid}}', fid).replace('[[fid]]', fid).replace('%%fid%%', fid)
elif isinstance(v, dict):
_replace_fid(v, fid)
class HarakiriInterrupt(BaseException):
"""
Raised internally to notify the server code about interrupts due to harakiri. You should never, ever, ever, ever
catch this exception in your service code. As such, it inherits from `BaseException` so that even
def _convert_action_responses(actions):
# type: (Union[Iterable[Mapping[six.text_type, Any]], Iterable[ActionResponse]]) -> List[ActionResponse]
value = [] # type: List[ActionResponse]
for a in actions:
value.append(a if isinstance(a, ActionResponse) else ActionResponse(**a))
return value
response_body = self.run(action_request)
# Validate the response body. Errors in a response are the problem of
# the service, and so we just raise a Python exception and let error
# middleware catch it. The server will return a SERVER_ERROR response.
if self.response_schema:
errors = self.response_schema.errors(response_body)
if errors:
raise ResponseValidationError(action=action_request.action, errors=errors)
# Make an ActionResponse and return it
if response_body is not None:
return ActionResponse(
action=action_request.action,
body=response_body,
)
else:
return ActionResponse(action=action_request.action)
)]
if raise_action_errors:
raise ActionError(errors, set_is_caller_error_to=None)
return ActionResponse(action=action, errors=errors)
if action not in server.action_class_map:
# This is never a caller error, because it can only happen due to a bug in the service calling itself.
errors = [Error(
code=ERROR_CODE_UNKNOWN,
message='The action "{}" was not found on this server.'.format(action),
field='action',
is_caller_error=False,
)]
if raise_action_errors:
raise ActionError(errors, set_is_caller_error_to=None)
return ActionResponse(action=action, errors=errors)
action_type = server.action_class_map[action] # type: ActionType
action_callable = action_type(server.settings)
request = self.__class__(
action=action,
body=body,
# Dynamically copy all Attrs attributes so that subclasses introducing other Attrs can still work properly
**{
a.name: getattr(self, a.name)
for a in getattr(self, '__attrs_attrs__')
if a.name not in ('action', 'body')
}
)
request._server = server
errors = self.response_schema.errors(response_body)
if errors:
raise ResponseValidationError(action=action_request.action, errors=errors)
# Make an ActionResponse and return it
if response_body is not None:
return ActionResponse(
action=action_request.action,
body=response_body,
)
else:
return ActionResponse(action=action_request.action)
ActionType = Union[
Type[Action],
Callable[[ServerSettings], Callable[[EnrichedActionRequest], ActionResponse]],
]
"""
@abc.abstractmethod
def __call__(self, action_request): # type: (EnrichedActionRequest) -> ActionResponse
"""
Execute the action.
:param action_request: The action request
:return: The action response
"""
ActionType = Union[
Type[ActionInterface],
Callable[[Optional[ServerSettings]], Callable[[EnrichedActionRequest], ActionResponse]],
]
"""A type used for annotating attributes and arguments that represent any valid action class or callable."""