Exemplo n.º 1
0
class SettingsToTest(settings.Settings):
    schema: settings.SettingsSchema = {
        'one': fields.Dictionary({
            'a': fields.ClassConfigurationSchema(base_class=ClassUsingAttrs27HintsToTest, description='Nifty schema.'),
            'b': fields.PythonPath(value_schema=fields.UnicodeString(), description='Must be a path, yo.'),
            'c': fields.TypeReference(base_classes=ClassHoldingSigsToTest, description='Refer to that thing!'),
        }),
        'two': fields.SchemalessDictionary(key_type=fields.UnicodeString(), value_type=fields.Boolean()),
        'three': fields.List(fields.Integer()),
        'four': fields.Nullable(fields.Set(fields.ByteString())),
        'five': fields.Any(fields.Integer(), fields.Float()),
        'six': fields.ObjectInstance(valid_type=ClassUsingAttrs27HintsToTest, description='Y u no instance?'),
        'seven': fields.Polymorph(
            'thing',
            {
                'thing1': fields.Dictionary({'z': fields.Boolean()}, allow_extra_keys=True),
                'thing2': fields.Dictionary({'y': fields.Boolean()}, allow_extra_keys=True, optional_keys=('y', )),
            },
        ),
    }

    defaults: settings.SettingsData = {
        'one': {
            'b': 'foo.bar:Class',
        },
        'three': [1, 5, 7],
    }
Exemplo n.º 2
0
 def test_schema_correct(self):
     assert SettingsOneTwoThree.schema == {
         'foo':
         fields.UnicodeString(),
         'bar':
         fields.Boolean(),
         'baz':
         fields.Dictionary(
             {
                 'inner_foo':
                 fields.UnicodeString(),
                 'inner_bar':
                 fields.Boolean(),
                 'inner_baz':
                 fields.List(fields.Integer()),
                 'inner_qux':
                 fields.Dictionary(
                     {
                         'most_inner_foo': fields.Boolean(),
                         'most_inner_bar': fields.UnicodeString(),
                     }, ),
             }, ),
         'qux':
         fields.Float(),
     }
Exemplo n.º 3
0
class SettingsTwo(Settings):
    schema = {
        'bar':
        fields.Integer(),
        'baz':
        fields.Dictionary(
            {
                'inner_foo':
                fields.UnicodeString(),
                'inner_bar':
                fields.Boolean(),
                'inner_baz':
                fields.List(fields.Integer()),
                'inner_qux':
                fields.Dictionary(
                    {
                        'most_inner_foo': fields.Boolean(),
                        'most_inner_bar': fields.UnicodeString(),
                    }, ),
            }, ),
    }  # type: SettingsSchema

    defaults = {
        'bar': 1,
        'baz': {
            'inner_foo': 'Default inner',
            'inner_qux': {
                'most_inner_bar': 'Default most inner'
            }
        },
    }  # type: SettingsData
Exemplo n.º 4
0
 def test_schema_correct(self):
     assert SettingsTwoFour.schema == {
         'bar':
         fields.Integer(),
         'baz':
         fields.Dictionary(
             {
                 'inner_foo':
                 fields.UnicodeString(),
                 'inner_bar':
                 fields.Boolean(),
                 'inner_baz':
                 fields.List(fields.Integer()),
                 'inner_qux':
                 fields.Dictionary(
                     {
                         'most_inner_foo': fields.Boolean(),
                         'most_inner_bar': fields.UnicodeString(),
                     }, ),
             }, ),
         'qux':
         fields.Decimal(),
         'new':
         fields.ByteString(),
         'old':
         fields.UnicodeString(),
     }
Exemplo n.º 5
0
class MockingTestAction(Action):
    request_schema = fields.Dictionary({
        'min': fields.Integer(),
        'max': fields.Integer(),
        'kwargs': fields.SchemalessDictionary(key_type=fields.UnicodeString()),
    })

    response_schema = fields.Dictionary({
        'random': fields.Integer(),
        'response': fields.SchemalessDictionary(),
        'extra': fields.UnicodeString(),
    })

    def run(self, request):
        try:
            # noinspection PyUnresolvedReferences
            return {
                'random': random.randint(request.body['min'], request.body['max']),
                'response': function_which_shall_be_mocked(
                    request.body['max'],
                    request.body['min'],
                    **request.body['kwargs']
                ),
                'extra': function_which_shall_be_mocked.extra.value().for_me,
            }
        except AttributeError:
            raise ActionError(errors=[Error('ATTRIBUTE_ERROR', 'An attribute error was raised')])
        except BytesWarning:
            raise ActionError(errors=[Error('BYTES_WARNING', 'A bytes warning was raised')])
        except ExpectedException:
            raise ActionError(errors=[Error('EXPECTED_EXCEPTION', 'An expected exception was raised')])
Exemplo n.º 6
0
class TypesEchoAction(Action):
    request_schema = fields.Dictionary(
        {
            'an_int': fields.Integer(),
            'a_float': fields.Float(),
            'a_bool': fields.Boolean(),
            'a_bytes': fields.ByteString(),
            'a_string': fields.UnicodeString(),
            'a_datetime': fields.DateTime(),
            'a_date': fields.Date(),
            'a_time': fields.Time(),
            'a_list': fields.List(fields.Anything(), max_length=0),
            'a_dict': fields.Nullable(fields.Dictionary({})),
        },
        optional_keys=(
            'an_int', 'a_float', 'a_bool', 'a_bytes', 'a_string', 'a_datetime', 'a_date', 'a_time', 'a_list', 'a_dict',
        ),
    )

    response_schema = fields.Dictionary(
        {'r_{}'.format(k): v for k, v in six.iteritems(request_schema.contents)},
        optional_keys=('r_{}'.format(k) for k in request_schema.optional_keys),
    )

    def run(self, request):
        return {'r_{}'.format(k): v for k, v in six.iteritems(request.body)}
Exemplo n.º 7
0
class SquareAction(Action):
    """
    This is an example of a simple action which takes a single input argument - a number to square - and returns the
    square of it.
    """

    # The SOA library enables validation of both requests and responses using the "conformity" library. Simple schemas
    # can be specified inline like this; more complex ones should live in a separate schemas/ package (see other
    # examples).
    request_schema = fields.Dictionary({
        # Request bodies are always dictionaries. Here we say we want a dict with exactly one input - a float called
        # "number"
        'number': fields.Float(),
    })

    response_schema = fields.Dictionary({
        'square': fields.Float(),
    })

    def run(self, request):
        """
        When an action is run, the request is validated, and then passed to you here in the run() method, where you can
        perform the business logic.
        """
        # Request body is a dictionary, so it's easy to pull out fields.
        square = request.body['number'] ** 2
        # Return the result
        return {
            'square': square,
        }
Exemplo n.º 8
0
class SettingsWithDefaults(Settings):
    schema = {
        'complex_property':
        fields.Dictionary({
            'string_property':
            fields.UnicodeString(),
            'int_property':
            fields.Integer(),
            'kwargs':
            fields.Dictionary({
                'foo': fields.Integer(),
                'bar': fields.UnicodeString(),
            }),
        }),
        'simple_property':
        fields.Integer(),
    }

    defaults = {
        'simple_property': 0,
        'complex_property': {
            'string_property': 'default_string',
            'kwargs': {
                'foo': 1,
            },
        },
    }
Exemplo n.º 9
0
class LoginAction(Action):
    request_schema = fields.Dictionary({'username': fields.UnicodeString()})

    response_schema = fields.Dictionary(
        {'session': fields.Dictionary({'session_id': fields.UnicodeString(), 'user': fields.UnicodeString()})},
    )

    def run(self, request):
        return {'session': {'session_id': six.text_type(uuid.uuid4().hex), 'user': request.body['username']}}
Exemplo n.º 10
0
class StubClientTransportSchema(BasicClassSchema):
    contents = {
        'path':
        fields.UnicodeString(
            description=
            'The path to the stub client transport, in the format `module.name:ClassName`',
        ),
        'kwargs':
        fields.Dictionary(
            {
                'action_map':
                fields.SchemalessDictionary(
                    key_type=fields.UnicodeString(
                        description='The name of the action to stub', ),
                    value_type=fields.Dictionary(
                        {
                            'body':
                            fields.SchemalessDictionary(
                                description=
                                'The body with which the action should respond',
                            ),
                            'errors':
                            fields.List(
                                fields.Any(
                                    fields.ObjectInstance(Error),
                                    fields.Dictionary(
                                        {
                                            'code':
                                            fields.UnicodeString(),
                                            'message':
                                            fields.UnicodeString(),
                                            'field':
                                            fields.UnicodeString(),
                                            'traceback':
                                            fields.UnicodeString(),
                                            'variables':
                                            fields.SchemalessDictionary(),
                                            'denied_permissions':
                                            fields.List(
                                                fields.UnicodeString()),
                                        }, ),
                                ),
                                description='The ',
                            ),
                        },
                        description=
                        'A dictionary containing either a body dict or an errors list, providing an '
                        'instruction on how the stub action should respond to requests',
                        optional_keys=('body', 'errors'),
                    ),
                ),
            }, ),
    }

    optional_keys = ()

    description = 'The settings for the local transport'
Exemplo n.º 11
0
class RootAction(Action):
    request_schema = fields.Dictionary(
        {'number': fields.Integer(), 'base': fields.Integer()},
        optional_keys=('base', ),
    )

    response_schema = fields.Dictionary({'number_root': fields.Integer()})

    def run(self, request):
        base = request.body.get('base', 2)
        return {'number_root': int(round(request.body['number'] ** (1 / float(base))))}
Exemplo n.º 12
0
class StubbingTwoCallsTestAction(Action):
    request_schema = fields.Dictionary({'one': fields.SchemalessDictionary(), 'two':  fields.SchemalessDictionary()})
    response_schema = fields.Dictionary({'one': fields.SchemalessDictionary(), 'two':  fields.SchemalessDictionary()})

    def run(self, request):
        try:
            return {
                'one': request.client.call_action('examiner', 'roll', body=request.body['one']).body,
                'two': request.client.call_action('player', 'pitch', body=request.body['two']).body,
            }
        except request.client.CallActionError as e:
            raise ActionError(errors=e.actions[0].errors)
Exemplo n.º 13
0
class ActionOne(Action):
    request_schema = fields.Dictionary({'planet': fields.UnicodeString()})

    response_schema = fields.Dictionary({
        'planet_response':
        fields.UnicodeString(),
        'settings':
        fields.Anything()
    })

    def run(self, request):
        return {
            'planet_response': request.body['planet'],
            'settings': self.settings
        }
Exemplo n.º 14
0
class TestAction(Action):
    __test__ = False  # So that PyTest doesn't try to collect this and spit out a warning

    request_schema = fields.Dictionary({
        'string_field': fields.UnicodeString(),
    })

    response_schema = fields.Dictionary({
        'boolean_field': fields.Boolean(),
    })

    _return = None

    def run(self, request):
        return self._return
Exemplo n.º 15
0
class TestAction(Action):
    __test__ = False  # So that PyTest doesn't try to collect this and spit out a warning

    request_schema = fields.Dictionary({
        'string_field': fields.UnicodeString(),
    })  # type: Optional[fields.Dictionary]

    response_schema = fields.Dictionary({
        'boolean_field': fields.Boolean(),
    })  # type: Optional[fields.Dictionary]

    _return = None  # type: Optional[Dict[six.text_type, Any]]

    def run(self, request):
        return self._return
Exemplo n.º 16
0
class GetTinyImageAction(Action):
    response_schema = fields.Dictionary({'tiny_image': fields.ByteString()})

    def run(self, request):
        with open(os.path.dirname(__file__) + '/tiny-image.gif',
                  'rb') as file_input:
            return {'tiny_image': file_input.read()}
Exemplo n.º 17
0
class LocalClientTransportSchema(BasicClassSchema):
    contents = {
        'path': fields.UnicodeString(
            description='The path to the local client transport, in the format `module.name:ClassName`',
        ),
        'kwargs': fields.Dictionary({
            # server class can be an import path or a class object
            'server_class': fields.Any(
                fields.UnicodeString(
                    description='The path to the `Server` class, in the format `module.name:ClassName`',
                ),
                fields.ObjectInstance(
                    six.class_types,
                    description='A reference to the `Server`-extending class/type',
                ),
                description='The path to the `Server` class to use locally (as a library), or a reference to the '
                            '`Server`-extending class/type itself',
            ),
            # No deeper validation because the Server will perform its own validation
            'server_settings': fields.SchemalessDictionary(
                key_type=fields.UnicodeString(),
                description='The settings to use when instantiating the `server_class`'
            ),
        }),
    }

    optional_keys = ()

    description = 'The settings for the local client transport'
Exemplo n.º 18
0
 class MySettings(SettingsWithDefaults):
     schema = {
         'complex_property':
         fields.Dictionary({
             'another_property': fields.Integer(),
         }),
     }
Exemplo n.º 19
0
class WalkAction(Action):
    request_schema = fields.Dictionary({'value': fields.Any(fields.Integer(), fields.Float())})

    response_schema = request_schema

    add = 1

    def run(self, request):
        return {'value': request.body['value'] + self.add}
Exemplo n.º 20
0
class LocalServerTransportSchema(BasicClassSchema):
    contents = {
        'path': fields.UnicodeString(
            description='The path to the local server transport, in the format `module.name:ClassName`',
        ),
        'kwargs': fields.Dictionary({}),
    }

    description = 'The settings for the local client transport'
Exemplo n.º 21
0
class Http2TransportSchema(fields.Dictionary):
    contents = {
        'backend_layer_kwargs':
        fields.Dictionary(
            {
                'http_host': fields.UnicodeString(),
                'http_port': fields.UnicodeString(),
            },
            optional_keys=(),
            allow_extra_keys=False,
        ),
        'backend_type':
        fields.Constant(
            *HTTP2_BACKEND_TYPES,
            description=
            'Which backend (hyper-h2 or twisted) should be used for this Http2 transport'
        ),
        'message_expiry_in_seconds':
        fields.Integer(
            description=
            'How long after a message is sent that it is considered expired, dropped from queue',
        ),
        'queue_capacity':
        fields.Integer(
            description=
            'The capacity of the message queue to which this transport will send messages',
        ),
        'queue_full_retries':
        fields.Integer(
            description=
            'How many times to retry sending a message to a full queue before giving up',
        ),
        'receive_timeout_in_seconds':
        fields.Integer(
            description='How long to block waiting on a message to be received',
        ),
        'default_serializer_config':
        fields.ClassConfigurationSchema(
            base_class=BaseSerializer,
            description=
            'The configuration for the serializer this transport should use.',
        ),
    }

    optional_keys = (
        'backend_layer_kwargs',
        'message_expiry_in_seconds',
        'queue_capacity',
        'queue_full_retries',
        'receive_timeout_in_seconds',
        'default_serializer_config',
    )

    description = 'The constructor kwargs for the Http2 client and server transports.'
Exemplo n.º 22
0
class StubbingOneCallTestAction(Action):
    request_schema = fields.SchemalessDictionary()
    response_schema = fields.Dictionary({'forwarded_response': fields.SchemalessDictionary()})

    def run(self, request):
        try:
            return {
                'forwarded_response': request.client.call_action('examiner', 'magnify', body=request.body).body
            }
        except request.client.CallActionError as e:
            raise ActionError(errors=e.actions[0].errors)
Exemplo n.º 23
0
class FakeActionTwo(object):
    """Test action documentation"""

    request_schema = fields.UnicodeString(description='Be weird.')

    response_schema = fields.Dictionary({
        'okay':
        fields.Boolean(description='Whether it is okay'),
        'reason':
        fields.Nullable(
            fields.UnicodeString(description='Why it is not okay')),
    })
Exemplo n.º 24
0
class ServerSettings(SOASettings):
    """
    Settings specific to servers
    """

    schema = {
        'transport':
        BasicClassSchema(BaseServerTransport),
        'middleware':
        fields.List(BasicClassSchema(ServerMiddleware)),
        'client_routing':
        fields.SchemalessDictionary(),
        'logging':
        fields.SchemalessDictionary(),
        'harakiri':
        fields.Dictionary({
            'timeout': fields.Integer(
                gte=0
            ),  # seconds of inactivity before harakiri is triggered, 0 to disable
            'shutdown_grace': fields.Integer(
                gte=0
            ),  # seconds to gracefully shutdown after harakiri is triggered
        }),
    }

    defaults = {
        'client_routing': {},
        'logging': {
            'version': 1,
            'formatters': {
                'console': {
                    'format': '%(asctime)s %(levelname)7s: %(message)s'
                },
            },
            'handlers': {
                'console': {
                    'level': 'INFO',
                    'class': 'logging.StreamHandler',
                    'formatter': 'console',
                },
            },
            'root': {
                'handlers': ['console'],
                'level': 'INFO',
            },
        },
        'harakiri': {
            'timeout': 300,
            'shutdown_grace': 30,
        },
    }
Exemplo n.º 25
0
class LocalTransportSchema(BasicClassSchema):
    contents = {
        'path':
        fields.UnicodeString(),
        'kwargs':
        fields.Dictionary({
            # server class can be an import path or a class object
            'server_class':
            fields.Any(fields.UnicodeString(),
                       fields.ObjectInstance(six.class_types)),
            # No deeper validation because the Server will perform its own validation
            'server_settings':
            fields.SchemalessDictionary(key_type=fields.UnicodeString()),
        }),
    }
Exemplo n.º 26
0
class HelloAction(Action):
    request_schema = fields.Dictionary(
        {
            'name': fields.UnicodeString(),
            'optional': fields.Integer(),
            'errors': fields.Integer()
        },
        optional_keys=('optional', 'errors'))

    def run(self, request):
        if request.body.get('errors') == 1:
            raise ActionError([Error('FOO', 'Foo error')])
        if request.body.get('errors') == 2:
            raise ActionError(
                [Error('BAZ', 'Baz error'),
                 Error('QUX', 'Qux error')])

        return {'salutation': 'Hello, {}'.format(request.body['name'])}
Exemplo n.º 27
0
class EchoAction(Action):
    request_schema = fields.SchemalessDictionary()

    response_schema = fields.Dictionary(
        {
            'request_body': fields.SchemalessDictionary(),
            'request_context': fields.SchemalessDictionary(),
            'request_switches': fields.List(fields.Integer()),
            'request_control': fields.SchemalessDictionary(),
        }, )

    def run(self, request):
        return {
            'request_body': request.body,
            'request_context': request.context,
            'request_switches': sorted(list(request.switches)),
            'request_control': request.control,
        }
Exemplo n.º 28
0
class MetricsSchema(BasicClassSchema):
    contents = {
        'path': fields.UnicodeString(
            description='The path to the class extending `MetricsRecorder`, in the format `module.name:ClassName`',
        ),
        'kwargs': fields.Dictionary(
            {
                'config': fields.SchemalessDictionary(description='Whatever metrics configuration is required'),
            },
            optional_keys=[
                'config',
            ],
            allow_extra_keys=True,
            description='The keyword arguments that will be passed to the constructed metrics recorder',
        ),
    }

    description = 'Configuration for defining a usage and performance metrics recorder'

    object_type = MetricsRecorder
Exemplo n.º 29
0
class MetricsSchema(BasicClassSchema):
    contents = {
        'path':
        fields.UnicodeString(
            description='The module.name:ClassName path to the metrics recorder'
        ),
        'kwargs':
        fields.Dictionary(
            {
                'config': fields.SchemalessDictionary(),
            },
            optional_keys=[
                'config',
            ],
            allow_extra_keys=True,
            description=
            'The keyword arguments that will be passed to the constructed metrics recorder',
        ),
    }

    object_type = MetricsRecorder
Exemplo n.º 30
0
class CallServiceAction(Action):
    """
    This is an example of a simple action which chains down to call another service; in this case, ourselves, which
    is unusual, but it's an easier example than creating another service.
    """

    response_schema = fields.Dictionary({
        'square': fields.Float(),
    })

    def run(self, request):
        """
        When an action is run, the request is validated, and then passed to you here in the run() method, where you can
        perform the business logic.
        """
        # The client, which lets us call other services, is always available on the request object if any client routing
        # settings are configured in the service settings. In this case, the service is calling itself, which can only
        # work if there are two or more server processes running.
        result = request.client.call_action('example', 'square', body={'number': 42})

        return {
            'square': result.body['square'],
        }