コード例 #1
0
ファイル: meta.py プロジェクト: by46/coffee
    def __new__(cls, name, bases, attributes):
        model = attributes.get(Meta.MODEL_NAME)
        resource_fields = {}
        if model:
            ignore_fields = attributes.get(Meta.IGNORE_FIELDS, [])
            raw_fields = [x for x in model.__dict__ if x not in ignore_fields and not x.startswith('_')]
            for field in raw_fields:
                value = getattr(model, field)
                if isinstance(value, InstrumentedAttribute):
                    field_type = value.comparator.type
                    if isinstance(field_type, (sqltypes.String, sqltypes.Text)):
                        resource_fields[field] = fields.String
                    elif isinstance(field_type, sqltypes.Integer):
                        resource_fields[field] = fields.Integer
                    elif isinstance(field_type, sqltypes.Boolean):
                        resource_fields[field] = fields.Boolean
                    elif isinstance(field_type, sqltypes.DateTime):
                        resource_fields[field] = fields.DateTime(dt_format='iso8601')
                    elif isinstance(field_type, sqltypes.DECIMAL):
                        resource_fields[field] = fields.MyDecimal
                    else:
                        resource_fields[field] = fields.String

        # add extra fields
        extra_fields = attributes.get(Meta.EXTRA_FIELDS, {})
        if isinstance(extra_fields, dict):
            resource_fields.update(extra_fields)
        attributes['resource_fields'] = resource_fields
        meta = type.__new__(cls, name, bases, attributes)
        swagger.add_model(meta)
        return meta
コード例 #2
0
    def __new__(cls, name, bases, attributes):
        if name == 'Serializer':
            return type.__new__(cls, name, bases, attributes)

        model = attributes.pop('__model__', None)  # type: User
        exclude_fields = attributes.pop('__exclude_fields__', [])
        include_fields = attributes.pop('__include_fields__', {})
        new_entity_fields = attributes.pop('__new_entity_fields__', [])
        class_dict = attributes.copy()
        class_dict['resource_fields'] = resource_fields = {}
        class_dict['exclude_fields'] = exclude_fields
        class_dict['include_fields'] = include_fields
        class_dict['new_entity_fields'] = new_entity_fields
        if model:
            for column in model.__table__.columns:
                if column.name in exclude_fields:
                    continue
                field_type_name = column.type.__visit_name__
                field_type = MAPPING.get(field_type_name)
                if not field_type:
                    field_type = fields.String
                resource_fields[column.name] = field_type

            if include_fields:
                resource_fields.update(include_fields)
        s = type.__new__(cls, name, bases, class_dict)
        swagger.add_model(s)
        return s
コード例 #3
0
def test_add_model_with_resource_fields_nested_swagger_metadata(model_class, ):
    """Test for model with resource fields, nested subclass, swagger metadata

    * resource_fields: YES
    * nested subclass: YES
    * __init__: NO
    * swagger_metadata:YES
    """
    pdst = patch_deduce_swagger_type
    pr = patch_registry
    ppd = patch_parse_doc
    pha = patch_hasattr

    with pr(), ppd(), patch_isinstance(True) as mock_isinstance:
        with pha() as mock_hasattr:
            with patch_dir(["resource_fields"]) as mock_dir:
                with pdst() as mock_deduce_swagger_type:
                    swagger.add_model(model_class)

                    mock_dir.assert_called_with(model_class)
                    assert mock_dir.call_count == 2
                    mock_hasattr.assert_called_once_with(
                        model_class, "required")
                    mock_isinstance.assert_called_with(model_class,
                                                       swagger._Nested)
                    assert mock_deduce_swagger_type.call_count == len(
                        model_class.resource_fields.items())
コード例 #4
0
ファイル: parser.py プロジェクト: by46/coffee
    def __new__(cls, name, bases, attributes):
        if name == 'EntityBase':
            return type.__new__(cls, name, bases, attributes)

        parser = RequestParser()
        fields = [(name, field) for name, field in iteritems(attributes)
                  if isinstance(field, Field)]

        field_names = set()
        resource_fields = dict()
        for name, field in fields:
            if inspect.isclass(field.type) and issubclass(
                    field.type, EntityBase):
                field.type = field.type.parse
                field.location = 'json'
            parser.add_argument(field)
            field_names.add(name)
            resource_fields[name] = get_field_type(field.type)
            del attributes[name]
        attributes['entity_parser'] = parser
        attributes['entity_fields'] = field_names
        attributes['resource_fields'] = resource_fields

        schema = type.__new__(cls, name, bases, attributes)
        # support swagger
        swagger.add_model(schema)
        return schema
コード例 #5
0
def test_integration_test_add_model(test_input, properties, required,
                                    defaults):
    """Integration test for `add_model(...)` method.

    Ensures models are added to `registry["models"]` with expected structure.
    Example each model should have 'description', 'id','notes', 'properties',
    etc.
    Example `registry["models"]`:
        # print(registry["models"])
        {   'models': {   .....
              'MockTodoItem': {   'description': 'This is an example of a '
                                             'model class that has '
                                             'parameters in its '
                                             'constructor',
                              'id': 'MockTodoItem',
                              'notes': 'and the fields in the swagger spec '
                                       'are derived from the '
                                       'parameters<br/>to __init__.<br/>In '
                                       'this case we would have args, arg2 '
                                       'as required parameters and arg3 '
                                       'as<br/>optional parameter.',
                              'properties': {   'arg1': {'type': 'string'},
                                                'arg2': {'type': 'string'},
                                                'arg3': {   'default': '123',
                                                            'type': 'string'}},
                              'required': ['arg1', 'arg2']},
                                ..........
    """
    with patch_registry() as registry:
        swagger.add_model(test_input)

        assert test_input.__name__ in registry["models"]
        assert "description" in registry["models"][test_input.__name__]
        assert "notes" in registry["models"][test_input.__name__]

        if "resource_fields" not in dir(test_input) and "__init__" not in dir(
                test_input):
            # in py2, classes without __init__ or resource_fields defined
            # will cause issues.
            # note, no issue in PY3.
            pytest.fail(
                "do not call without resource_fields or __init__ defined.")

        if "resource_fields" in dir(test_input):
            if hasattr(test_input, "required"):
                assert "required" in registry["models"][test_input.__name__]
        elif "__init__" in dir(test_input):
            assert "required" in registry["models"][test_input.__name__]

        assert "properties" in registry["models"][test_input.__name__]
コード例 #6
0
def test_add_model_init_parsing_args(model_class, required, defaults):
    """Test to verify args parsed correctly
    """
    with patch_registry() as registry, patch_parse_doc(), patch_dir(
        ["__init__"]):
        swagger.add_model(model_class)

        assert model_class.__name__ in registry["models"]
        assert registry["models"][model_class.__name__]["required"] == required
        for key, default_value in defaults:
            _name = model_class.__name__
            assert key in registry["models"][_name]["properties"]
            assert (default_value == registry["models"][_name]["properties"]
                    [key]["default"])
コード例 #7
0
 def wrapper(func):
     attr = func.__dict__['__swagger_attr']
     params = attr.get('parameters', [])
     resource_fields = {}
     for field in cls.new_entity_fields:
         if isinstance(field, tuple):
             name, schema_type = field
         else:
             name, schema_type = field, cls.resource_fields.get(field)
         resource_fields[name] = schema_type
     attributes = {
         'resource_fields': resource_fields,
         '__doc__': 'create new entity'
     }
     entity_model = type(entity_name, (object, ), attributes)
     swagger.add_model(entity_model)
     params.append(post_parameter(entity_model))
     attr['parameters'] = params
     return func
コード例 #8
0
def test_add_model_no_init(model_class):
    """Test for model with only init

    * resource_fields: NO
    * nested subclass: NO
    * __init__: NO
    * swagger_metadata: NO
    """
    pdst = patch_deduce_swagger_type
    pr = patch_registry
    ppd = patch_parse_doc
    pgas = patch_getargspec
    pha = patch_hasattr

    with pdst() as mock_deduce_swagger_type:
        with pr(), ppd(), pgas() as mock_getargspec:
            with pha() as mock_hasattr:
                swagger.add_model(model_class)
                mock_getargspec.assert_not_called()
                mock_hasattr.assert_not_called()
                mock_deduce_swagger_type.assert_not_called()
コード例 #9
0
def test_add_model_with_resource_fields_without_swagger_metadata(
    mock_nested,
    mock_model_class,
):
    """Test adding model with resource fields, no init, without swagger metadata.
    """
    pdst = patch_deduce_swagger_type
    pr = patch_registry
    ppd = patch_parse_doc
    pha = patch_hasattr

    with pr(), ppd(), patch_isinstance(False) as mock_isinstance:
        with pha() as mock_hasattr, patch_dir(["resource_fields"]) as mock_dir:
            with pdst() as mock_deduce_swagger_type:

                swagger.add_model(mock_model_class)
                mock_dir.assert_called_with(mock_model_class)
                assert mock_dir.call_count == 2
                mock_hasattr.assert_called_once_with(mock_model_class,
                                                     "required")
                mock_isinstance.assert_called_with(mock_model_class,
                                                   mock_nested)
                assert mock_deduce_swagger_type.call_count == len(
                    mock_model_class.resource_fields.items())
コード例 #10
0
class Exchanges(Resource):
    @swagger.operation(
        responseClass=StockMarket.__name__,
        nickname='get',
        parameters=[
            {
                "name": "Authorization",
                "required": True,
                "allowMultiple": False,
                "dataType": "string",
                "paramType": "header",
                "description": "Bearer <token>"

            }
        ],
        responseMessages=[
            {
                "code": 403,
                "message": "For this endpoint your need one of these permissions: {0}, {1}".format('exchanges',
                                                                                                   'exchanges_only_read')
            },
            {
                "code": 401,
                "message": "Token has expired"
            }
        ]
    )
    @jwt_required
    @roles_required('exchanges', 'exchanges_only_read')
    def get(self):
        """
        List Stock market endpoint
        :return:
        """
        stock_markets = []
        for stock in StockMarket.query.all():
            stock_markets.append(stock.to_json())
        return stock_markets, 200

    @jwt_required
    @roles_required('exchanges')
    def post(self):
        """
        :return: status
        """
        return Response(status=201)

    @jwt_required
    @roles_required('exchanges')
    def delete(self):
        """
        Delete endpoint method
        Remove from db Stock Market object by it's name
        :data_example:{"id":"1"}
        :return: status
        """
        json_data = request.get_json()
        try:
            delete_sm = StockMarket.query.filter_by(id=json_data['id']).first()
            create_action_log("{0} was removed".format(delete_sm.name), "Exchanges")
            delete_sm.delete()
            return Response(status=204)
        except:
            BadRequest(description="Can't delete the object with current name or id")

    @swagger.operation(
        responseClass=StockMarket.__name__,
        parameters=[
            {
                "name": "body",
                "required": True,
                "allowMultiple": False,
                "dataType": "json",
                "paramType": "body",
                "description": '{"leverage": integer, "balance_percentage": integer, "id":string}'
            },
            {
                "name": "Authorization",
                "required": True,
                "allowMultiple": False,
                "dataType": "string",
                "paramType": "header"
            }
        ],
        responseMessages=[
            {
                "code": 403,
                "message": "For this endpoint your need one of these permissions: {0}".format('exchanges')
            },
            {
                "code": 401,
                "message": "Token has expired"
            },
            {
                "message": 'ID is not in request',
                "code": 400
            },
            {
                "message": "Stock Market with current id is not found",
                "code": 204
            }
        ]
    )
    @jwt_required
    @roles_required('exchanges')
    def put(self):
        """
        The update Exchanges endpoint method
        :data_example:{"leverage": 11, "balance_percentage": 50, "id":"1"}
        :return: status code
        """
        json_data = request.get_json()
        if 'id' not in json_data:
            return 'ID is not in request', 400
        current_sm = StockMarket.query.filter_by(id=json_data['id']).first()
        if not current_sm:
            return "Stock Market with current id is not found", 204
        action = ""
        if 'balance_percentage' in json_data:
            balance_percentage = check_0_max(json_data['balance_percentage'], 100)
            if balance_percentage != current_sm.balance_percentage:
                action += "Balance percentage for {2} was changed from {0} to {1}.\n".format(
                    current_sm.balance_percentage, balance_percentage, current_sm.name)
                current_sm.balance_percentage = balance_percentage

        if 'leverage' in json_data:
            leverage = check_0_max(json_data['leverage'], current_sm.max_leverage)
            if leverage != current_sm.leverage:
                action += "Leverage for {2} was changed from {0} to {1}.".format(
                    current_sm.leverage, leverage, current_sm.name)
                current_sm.leverage = leverage

        current_sm.save()
        create_action_log(action, "Exchanges")
        return Response(status=200)

    swagger.add_model(StockMarket)
コード例 #11
0
def test_add_model_get_docs(input_model):
    """Ensure `_parse_doc(...)` is called without issues"""
    with patch_registry(), patch_parse_doc() as mock_parse_doc:
        swagger.add_model(input_model)
        mock_parse_doc.assert_called_once_with(input_model)