示例#1
0
    async def test_marshal_does_not_hit_unrequired_attributes(
            self, app, client):
        api = Api(app)

        model = api.model(
            'Person', {
                'name': fields.String,
                'age': fields.Integer,
                'boolean': fields.Boolean,
            })

        class Person(object):
            def __init__(self, name, age):
                self.name = name
                self.age = age

            @property
            def boolean(self):
                raise Exception()

        @api.route('/test/')
        class TestResource(Resource):
            @api.marshal_with(model)
            def get(self):
                return Person('John Doe', 42)

        data = await client.get_json('/test/',
                                     headers={'X-Fields': '{name,age}'})
        assert data == {'name': 'John Doe', 'age': 42}
示例#2
0
    def test_marshal_handle_inheritance(self, app):
        api = Api(app)

        person = api.model('Person', {
            'name': fields.String,
            'age': fields.Integer,
        })

        child = api.inherit('Child', person, {
            'extra': fields.String,
        })

        data = {'name': 'John Doe', 'age': 42, 'extra': 'extra'}

        values = (
            ('name', {
                'name': 'John Doe'
            }),
            ('name,extra', {
                'name': 'John Doe',
                'extra': 'extra'
            }),
            ('extra', {
                'extra': 'extra'
            }),
        )

        for value, expected in values:
            result = marshal(data, child, mask=value)
            assert result == expected
示例#3
0
    async def test_marshal_with_honour_field_mask_list(self, app, client):
        api = Api(app)

        model = api.model(
            'Test', {
                'name': fields.String,
                'age': fields.Integer,
                'boolean': fields.Boolean,
            })

        @api.route('/test/')
        class TestResource(Resource):
            @api.marshal_with(model)
            def get(self):
                return [{
                    'name': 'John Doe',
                    'age': 42,
                    'boolean': True
                }, {
                    'name': 'Jane Doe',
                    'age': 33,
                    'boolean': False
                }]

        data = await client.get_json('/test/',
                                     headers={'X-Fields': '{name,age}'})
        assert data == [{
            'name': 'John Doe',
            'age': 42,
        }, {
            'name': 'Jane Doe',
            'age': 33,
        }]
示例#4
0
    async def test_marshal_with_expose_custom_mask_header(self, app, client):
        api = Api(app)

        model = api.model(
            'Test', {
                'name': fields.String,
                'age': fields.Integer,
                'boolean': fields.Boolean,
            })

        @api.route('/test/')
        class TestResource(Resource):
            @api.marshal_with(model)
            async def get(self):
                return {'name': 'John Doe', 'age': 42, 'boolean': True}

        app.config['RESTPLUS_MASK_HEADER'] = 'X-Mask'
        specs = await client.get_specs()

        op = specs['paths']['/test/']['get']
        assert 'parameters' in op
        assert len(op['parameters']) == 1

        param = op['parameters'][0]
        assert param['name'] == 'X-Mask'
示例#5
0
    async def test_marshal_with_expose_mask_header(self, app, client):
        api = Api(app)

        model = api.model(
            'Test', {
                'name': fields.String,
                'age': fields.Integer,
                'boolean': fields.Boolean,
            })

        @api.route('/test/')
        class TestResource(Resource):
            @api.marshal_with(model)
            async def get(self):
                return {'name': 'John Doe', 'age': 42, 'boolean': True}

        specs = await client.get_specs()
        op = specs['paths']['/test/']['get']

        assert 'parameters' in op
        assert len(op['parameters']) == 1

        param = op['parameters'][0]

        assert param['name'] == 'X-Fields'
        assert param['type'] == 'string'
        assert param['format'] == 'mask'
        assert param['in'] == 'header'
        assert 'required' not in param
        assert 'default' not in param
示例#6
0
 def test_with_readonly(self, app):
     api = Api(app)
     nested_fields = api.model('NestedModel', {'name': fields.String})
     field = fields.Nested(nested_fields, readonly=True)
     assert field.__schema__ == {
         'readOnly': True,
         'allOf': [{
             '$ref': '#/definitions/NestedModel'
         }]
     }
示例#7
0
async def test_no_crossdomain(app, client):
    class Foo(Resource):
        async def get(self):
            return "data"

    api = Api(app)
    api.add_resource(Foo, '/test/')

    res = await client.get('/test/')
    assert res.status_code == 200
    assert 'Access-Control-Allow-Origin' not in res.headers
    assert 'Access-Control-Allow-Methods' not in res.headers
    assert 'Access-Control-Max-Age' not in res.headers
示例#8
0
async def test_access_control_expose_headers(app, client):
    class Foo(Resource):
        @cors.crossdomain(origin='*',
                          expose_headers=['X-My-Header', 'X-Another-Header'])
        async def get(self):
            return 'data'

    api = Api(app)
    api.add_resource(Foo, '/test/')

    res = await client.get('/test/')
    assert res.status_code == 200
    assert 'X-MY-HEADER' in res.headers['Access-Control-Expose-Headers']
    assert 'X-ANOTHER-HEADER' in res.headers['Access-Control-Expose-Headers']
    assert (await res.get_data(False)) == 'data'
示例#9
0
async def test_crossdomain(app, client):
    class Foo(Resource):
        @cors.crossdomain(origin='*')
        async def get(self):
            return 'data'

    api = Api(app)
    api.add_resource(Foo, '/test/')

    res = await client.get('/test/')
    assert res.status_code == 200
    assert res.headers['Access-Control-Allow-Origin'] == '*'
    assert res.headers['Access-Control-Max-Age'] == '21600'
    assert 'HEAD' in res.headers['Access-Control-Allow-Methods']
    assert 'OPTIONS' in res.headers['Access-Control-Allow-Methods']
    assert 'GET' in res.headers['Access-Control-Allow-Methods']
示例#10
0
    async def test_marshal_with_honour_default_model_mask(self, app, client):
        api = Api(app)

        model = api.model('Test', {
            'name': fields.String,
            'age': fields.Integer,
            'boolean': fields.Boolean,
        },
                          mask='{name,age}')

        @api.route('/test/')
        class TestResource(Resource):
            @api.marshal_with(model)
            def get(self):
                return {'name': 'John Doe', 'age': 42, 'boolean': True}

        data = await client.get_json('/test/')
        assert data == {'name': 'John Doe', 'age': 42}
示例#11
0
    def test_marshal_honour_field_mask(self, app):
        api = Api(app)

        model = api.model(
            'Test', {
                'name': fields.String,
                'age': fields.Integer,
                'boolean': fields.Boolean,
            })

        data = {'name': 'John Doe', 'age': 42, 'boolean': True}

        result = api.marshal(data, model, mask='{name,age}')

        assert result == {
            'name': 'John Doe',
            'age': 42,
        }
示例#12
0
    async def test_raise_400_on_invalid_mask(self, app, client):
        api = Api(app)

        model = api.model('Test', {
            'name': fields.String,
            'age': fields.Integer,
        })

        @api.route('/test/')
        class TestResource(Resource):
            @api.marshal_with(model)
            async def get(self):
                pass

        response = await client.get('/test/',
                                    headers={'X-Fields': 'name{,missing}'})
        assert response.status_code == 400
        assert response.content_type == 'application/json'
示例#13
0
    def test_list_fields_with_nested_inherited(self, app):
        api = Api(app)

        person = api.model('Person', {
            'name': fields.String,
            'age': fields.Integer
        })
        child = api.inherit('Child', person, {'attr': fields.String})

        family = api.model('Family',
                           {'children': fields.List(fields.Nested(child))})

        result = mask.apply(family.resolved, 'children{name,attr}')

        data = {
            'children': [
                {
                    'name': 'John',
                    'age': 5,
                    'attr': 'value-john'
                },
                {
                    'name': 'Jane',
                    'age': 42,
                    'attr': 'value-jane'
                },
            ]
        }
        expected = {
            'children': [
                {
                    'name': 'John',
                    'attr': 'value-john'
                },
                {
                    'name': 'Jane',
                    'attr': 'value-jane'
                },
            ]
        }

        assert_data(marshal(data, result), expected)
        # Should leave th original mask untouched
        assert_data(marshal(data, family), data)
示例#14
0
    async def test_marshal_with_skip_missing_fields(self, app, client):
        api = Api(app)

        model = api.model('Test', {
            'name': fields.String,
            'age': fields.Integer,
        })

        @api.route('/test/')
        class TestResource(Resource):
            @api.marshal_with(model)
            def get(self):
                return {
                    'name': 'John Doe',
                    'age': 42,
                }

        data = await client.get_json('/test/',
                                     headers={'X-Fields': '{name,missing}'})
        assert data == {'name': 'John Doe'}
示例#15
0
    async def test_marshal_with_honour_custom_field_mask(self, app, client):
        api = Api(app)

        model = api.model(
            'Test', {
                'name': fields.String,
                'age': fields.Integer,
                'boolean': fields.Boolean,
            })

        @api.route('/test/')
        class TestResource(Resource):
            @api.marshal_with(model)
            def get(self):
                return {'name': 'John Doe', 'age': 42, 'boolean': True}

        app.config['RESTPLUS_MASK_HEADER'] = 'X-Mask'
        data = await client.get_json('/test/',
                                     headers={'X-Mask': '{name,age}'})

        assert data == {'name': 'John Doe', 'age': 42}
示例#16
0
    async def test_marshal_with_expose_default_model_mask_header(
            self, app, client):
        api = Api(app)

        model = api.model('Test', {
            'name': fields.String,
            'age': fields.Integer,
            'boolean': fields.Boolean,
        },
                          mask='{name,age}')

        @api.route('/test/')
        class TestResource(Resource):
            @api.marshal_with(model)
            async def get(self):
                pass

        specs = await client.get_specs()
        definition = specs['definitions']['Test']
        assert 'x-mask' in definition
        assert definition['x-mask'] == '{name,age}'
示例#17
0
    async def test_marshal_with_disabling_mask_header(self, app, client):
        api = Api(app)

        model = api.model(
            'Test', {
                'name': fields.String,
                'age': fields.Integer,
                'boolean': fields.Boolean,
            })

        @api.route('/test/')
        class TestResource(Resource):
            @api.marshal_with(model)
            async def get(self):
                return {'name': 'John Doe', 'age': 42, 'boolean': True}

        app.config['RESTPLUS_MASK_SWAGGER'] = False
        specs = await client.get_specs()

        op = specs['paths']['/test/']['get']

        assert 'parameters' not in op
示例#18
0
    async def test_is_only_exposed_on_marshal_with(self, app, client):
        api = Api(app)

        model = api.model(
            'Test', {
                'name': fields.String,
                'age': fields.Integer,
                'boolean': fields.Boolean,
            })

        @api.route('/test/')
        class TestResource(Resource):
            async def get(self):
                return api.marshal(
                    {
                        'name': 'John Doe',
                        'age': 42,
                        'boolean': True
                    }, model)

        specs = await client.get_specs()
        op = specs['paths']['/test/']['get']

        assert 'parameters' not in op
示例#19
0
    async def test_marshal_with_handle_polymorph(self, app, client):
        api = Api(app)

        parent = api.model('Person', {
            'name': fields.String,
        })

        child1 = api.inherit('Child1', parent, {
            'extra1': fields.String,
        })

        child2 = api.inherit('Child2', parent, {
            'extra2': fields.String,
        })

        class Child1(object):
            name = 'child1'
            extra1 = 'extra1'

        class Child2(object):
            name = 'child2'
            extra2 = 'extra2'

        mapping = {Child1: child1, Child2: child2}

        thing = api.model('Thing', {
            'owner': fields.Polymorph(mapping),
        })

        @api.route('/thing-1/')
        class Thing1Resource(Resource):
            @api.marshal_with(thing)
            async def get(self):
                return {'owner': Child1()}

        @api.route('/thing-2/')
        class Thing2Resource(Resource):
            @api.marshal_with(thing)
            async def get(self):
                return {'owner': Child2()}

        data = await client.get_json('/thing-1/',
                                     headers={'X-Fields': 'owner{name}'})
        assert data == {'owner': {'name': 'child1'}}

        data = await client.get_json('/thing-1/',
                                     headers={'X-Fields': 'owner{extra1}'})
        assert data == {'owner': {'extra1': 'extra1'}}

        data = await client.get_json('/thing-2/',
                                     headers={'X-Fields': 'owner{name}'})
        assert data == {'owner': {'name': 'child2'}}
示例#20
0
from quart_restplus import Api

from .cat import api as cat_api
from .dog import api as dog_api

api = Api(
    title='Zoo API',
    version='1.0',
    description='A simple demo API',
)

api.add_namespace(cat_api)
api.add_namespace(dog_api)
示例#21
0
from quart import Quart
from quart_restplus import Api, Resource, fields

app = Quart(__name__)
api = Api(
    app,
    version='1.0',
    title='TodoMVC API',
    description='A simple TodoMVC API',
)

ns = api.namespace('todos', description='TODO operations')

todo = api.model(
    'Todo', {
        'id':
        fields.Integer(readonly=True,
                       description='The task unique identifier'),
        'task':
        fields.String(required=True, description='The task details')
    })


class TodoDAO(object):
    def __init__(self):
        self.counter = 0
        self.todos = []

    def get(self, id):
        for todo in self.todos:
            if todo['id'] == id:
示例#22
0
from quart import Quart, request
from quart_restplus import Resource, Api

app = Quart(__name__)
api = Api(app)

todos = {}


@api.route('/<string:todo_id>')
class TodoSimple(Resource):
    """
    You can try this example as follow:
        $ curl http://localhost:5000/todo1 -d "data=Remember the milk" -X PUT
        $ curl http://localhost:5000/todo1
        {"todo1": "Remember the milk"}
        $ curl http://localhost:5000/todo2 -d "data=Change my breakpads" -X PUT
        $ curl http://localhost:5000/todo2
        {"todo2": "Change my breakpads"}

    Or from python if you have requests :
     >>> from requests import put, get
     >>> put('http://localhost:5000/todo1', data={'data': 'Remember the milk'}).json
     {u'todo1': u'Remember the milk'}
     >>> get('http://localhost:5000/todo1').json
     {u'todo1': u'Remember the milk'}
     >>> put('http://localhost:5000/todo2', data={'data': 'Change my breakpads'}).json
     {u'todo2': u'Change my breakpads'}
     >>> get('http://localhost:5000/todo2').json
     {u'todo2': u'Change my breakpads'}
示例#23
0
# needs: pip install python-simplexml
from simplexml import dumps
from quart import make_response, Quart
from quart_restplus import Api, Resource, fields


async def output_xml(data, code, headers=None):
    """Makes a Quart response with a XML encoded body"""
    resp = await make_response(dumps({'response': data}), code)
    resp.headers.extend(headers or {})
    return resp


app = Quart(__name__)
api = Api(app, default_mediatype='application/xml')
api.representations['application/xml'] = output_xml

hello_fields = api.model('Hello', {'entry': fields.String})


@api.route('/<string:entry>')
class Hello(Resource):
    """
        # you need requests
        >>> from requests import get
        >>> get('http://localhost:5000/me').content # default_mediatype
        '<?xml version="1.0" ?><response><hello>me</hello></response>'
        >>> get('http://localhost:5000/me', headers={"accept":"application/json"}).content
        '{"hello": "me"}'
        >>> get('http://localhost:5000/me', headers={"accept":"application/xml"}).content
        '<?xml version="1.0" ?><response><hello>me</hello></response>'
示例#24
0
 def test_api_shortcut(self, app):
     api = Api(app)
     parser = api.parser()
     assert isinstance(parser, RequestParser)
示例#25
0
import pytest

from quart_restplus import fields, Api, Resource
from quart_restplus.swagger import Swagger

api = Api()

person = api.model('Person', {
    'name': fields.String,
    'age': fields.Integer
})

family = api.model('Family', {
    'name': fields.String,
    'father': fields.Nested(person),
    'mother': fields.Nested(person),
    'children': fields.List(fields.Nested(person))
})


@api.route('/families', endpoint='families')
class Families(Resource):
    @api.marshal_with(family)
    def get(self):
        """List all families"""
        pass

    @api.marshal_with(family)
    @api.response(201, 'Family created')
    def post(self):
        """Create a new family"""
示例#26
0
from quart import Quart, Blueprint
from quart_restplus import Api, Resource, fields

api_v1 = Blueprint('api', __name__, url_prefix='/api/1')

api = Api(
    api_v1,
    version='1.0',
    title='Todo API',
    description='A simple TODO API',
)

ns = api.namespace('todos', description='TODO operations')

TODOS = {
    'todo1': {
        'task': 'build an API'
    },
    'todo2': {
        'task': '?????'
    },
    'todo3': {
        'task': 'profit!'
    },
}

todo = api.model(
    'Todo',
    {'task': fields.String(required=True, description='The task details')})

listed_todo = api.model(
示例#27
0
 def api(self, app):
     blueprint = Blueprint('api', __name__)
     api = Api(blueprint)
     app.register_blueprint(blueprint)
     yield api
示例#28
0
    async def test_marshal_with_honour_complex_field_mask_header(
            self, app, client):
        api = Api(app)

        person = api.model('Person', person_fields)
        child = api.inherit('Child', person, {'attr': fields.String})

        family = api.model(
            'Family', {
                'father': fields.Nested(person),
                'mother': fields.Nested(person),
                'children': fields.List(fields.Nested(child)),
                'free': fields.List(fields.Raw),
            })

        house = api.model(
            'House', {'family': fields.Nested(family, attribute='people')})

        @api.route('/test/')
        class TestResource(Resource):
            @api.marshal_with(house)
            def get(self):
                return {
                    'people': {
                        'father': {
                            'name': 'John',
                            'age': 42
                        },
                        'mother': {
                            'name': 'Jane',
                            'age': 42
                        },
                        'children': [
                            {
                                'name': 'Jack',
                                'age': 5,
                                'attr': 'value-1'
                            },
                            {
                                'name': 'Julie',
                                'age': 7,
                                'attr': 'value-2'
                            },
                        ],
                        'free': [
                            {
                                'key-1': '1-1',
                                'key-2': '1-2'
                            },
                            {
                                'key-1': '2-1',
                                'key-2': '2-2'
                            },
                        ]
                    }
                }

        data = await client.get_json(
            '/test/',
            headers={
                'X-Fields':
                'family{father{name},mother{age},children{name,attr},free{key-2}}'
            })
        assert data == {
            'family': {
                'father': {
                    'name': 'John'
                },
                'mother': {
                    'age': 42
                },
                'children': [{
                    'name': 'Jack',
                    'attr': 'value-1'
                }, {
                    'name': 'Julie',
                    'attr': 'value-2'
                }],
                'free': [{
                    'key-2': '1-2'
                }, {
                    'key-2': '2-2'
                }]
            }
        }