コード例 #1
0
    def test_method_security_headers(self):
        api = restplus.Api(self.app,
                           authorizations={
                               'apikey': {
                                   'type': 'apiKey',
                                   'in': 'header',
                                   'name': 'X-API'
                               }
                           })

        @api.route('/secure/')
        class Secure(restplus.Resource):
            @api.doc('secure', security='apikey')
            def get(self):
                pass

        @api.route('/unsecure/')
        class Unsecure(restplus.Resource):
            @api.doc('unsecure')
            def get(self):
                pass

        data = api.as_postman()

        validate(data, schema)
        requests = dict((r['name'], r['headers']) for r in data['requests'])

        self.assertEqual(requests['unsecure'], '')
        self.assertEqual(requests['secure'], 'X-API:')
コード例 #2
0
    def test_url_variables_enabled(self):
        api = restplus.Api(self.app)

        parser = api.parser()
        parser.add_argument('int', type=int)
        parser.add_argument('default', type=int, default=5)
        parser.add_argument('str', type=str)

        @api.route('/test/')
        class Test(restplus.Resource):
            @api.doc(parser=parser)
            def get(self):
                pass

        data = api.as_postman(urlvars=True)

        validate(data, schema)

        self.assertEqual(len(data['requests']), 1)
        request = data['requests'][0]
        qs = parse_qs(urlparse(request['url']).query, keep_blank_values=True)

        self.assertIn('int', qs)
        self.assertEqual(qs['int'][0], '0')

        self.assertIn('default', qs)
        self.assertEqual(qs['default'][0], '5')

        self.assertIn('str', qs)
        self.assertEqual(qs['str'][0], '')
コード例 #3
0
    def test_root_endpoint(self):
        api = restplus.Api(self.app, version='1.0')

        with self.context():
            url = url_for('root')
            self.assertEqual(url, '/')
            self.assertEqual(api.base_url, 'http://localhost/')
コード例 #4
0
    def test_export_with_namespace(self):
        api = restplus.Api(self.app)
        ns = api.namespace('test', 'A test namespace')

        @ns.route('/test')
        class Test(restplus.Resource):
            @api.doc('test_post')
            def post(self):
                '''A test post'''
                pass

        data = api.as_postman()

        validate(data, schema)

        self.assertEqual(len(data['requests']), 1)
        request = data['requests'][0]
        self.assertEqual(request['name'], 'test_post')
        self.assertEqual(request['description'], 'A test post')

        self.assertEqual(len(data['folders']), 2)
        folder = data['folders'][1]
        self.assertEqual(folder['name'], 'test')
        self.assertEqual(folder['description'], 'A test namespace')

        self.assertEqual(request['folder'], folder['id'])
コード例 #5
0
    def test_errorhandler_lazy(self):
        api = restplus.Api()

        class CustomException(RuntimeError):
            pass

        @api.route('/test/', endpoint='test')
        class TestResource(restplus.Resource):
            def get(self):
                raise CustomException('error')

        @api.errorhandler(CustomException)
        def handle_custom_exception(error):
            return {'message': str(error), 'test': 'value'}, 400

        api.init_app(self.app)

        with self.app.test_client() as client:
            response = client.get('/test/')
            self.assertEquals(response.status_code, 400)
            self.assertEquals(response.content_type, 'application/json')

            data = json.loads(response.data.decode('utf8'))
            self.assertEqual(data, {
                'message': 'error',
                'test': 'value',
            })
コード例 #6
0
    def test_validation_on_list(self):
        '''It should perform validation on lists'''
        api = restplus.Api(self.app, validate=True)

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

        family = api.model('Family', {
            'name': restplus.fields.String(required=True),
            'members': restplus.fields.List(restplus.fields.Nested(person))
        })

        @api.route('/validation/')
        class List(restplus.Resource):
            @api.expect(family)
            def post(self):
                return {}

        response = self.post('/validation/', {
            'name': 'Doe',
            'members': [{'name': 'Jonn'}, {'age': 42}]
        })

        self.assert_errors(response, 'members.0.age', 'members.1.name')
コード例 #7
0
    def test_validation_with_inheritance(self):
        '''It should perform validation with inheritance (allOf/$ref)'''
        api = restplus.Api(self.app, validate=True)

        fields = api.model('Parent', {
            'name': restplus.fields.String(required=True),
        })

        child_fields = api.inherit('Child', fields, {
            'age': restplus.fields.Integer,
        })

        @api.route('/validation/')
        class Inheritance(restplus.Resource):
            @api.expect(child_fields)
            def post(self):
                return {}

        response = self.post('/validation/', {
            'name': 'John Doe',
            'age': 15,
        })
        self.assertEquals(response.status_code, 200)

        response = self.post('/validation/', {
            'age': '15',
        })
        self.assert_errors(response, 'name', 'age')
コード例 #8
0
    def test_api_payload(self):
        api = restplus.Api(self.app, validate=True)

        fields = api.model('Person', {
            'name': restplus.fields.String(required=True),
            'age': restplus.fields.Integer,
            'birthdate': restplus.fields.DateTime,
        })

        @api.route('/validation/')
        class Payload(restplus.Resource):
            payload = None

            @api.expect(fields)
            def post(self):
                Payload.payload = api.payload
                return {}

        data = {
            'name': 'John Doe',
            'age': 15,
        }

        response = self.post('/validation/', data)

        self.assertEquals(response.status_code, 200)
        self.assertEquals(Payload.payload, data)
コード例 #9
0
    def test_default_apidoc_on_root(self):
        restplus.Api(self.app, version='1.0')

        with self.context(), self.app.test_client() as client:
            response = client.get(url_for('root'))
            self.assertEquals(response.status_code, 200)
            self.assertEquals(response.content_type,
                              'text/html; charset=utf-8')
コード例 #10
0
    def test_id_is_the_same(self):
        api = restplus.Api(self.app)

        first = api.as_postman()

        second = api.as_postman()

        self.assertEqual(first['id'], second['id'])
コード例 #11
0
    def test_basic_export(self):
        api = restplus.Api(self.app)

        data = api.as_postman()

        validate(data, schema)

        self.assertEqual(len(data['requests']), 0)
コード例 #12
0
    def test_root_endpoint_with_blueprint(self):
        blueprint = Blueprint('api', __name__, url_prefix='/api')
        api = restplus.Api(blueprint, version='1.0')
        # api.init_app(self.app)
        self.app.register_blueprint(blueprint)

        with self.context():
            url = url_for('api.root')
            self.assertEqual(url, '/api/')
            self.assertEqual(api.base_url, 'http://localhost/api/')
コード例 #13
0
    def test_default_apidoc_on_root_with_blueprint(self):
        blueprint = Blueprint('api', __name__, url_prefix='/api')
        restplus.Api(blueprint, version='1.0')
        self.app.register_blueprint(blueprint)

        with self.context(), self.app.test_client() as client:
            response = client.get(url_for('api.root'))
            self.assertEquals(response.status_code, 200)
            self.assertEquals(response.content_type,
                              'text/html; charset=utf-8')
コード例 #14
0
    def test_doc_decorator(self):
        api = restplus.Api(self.app, prefix='/api', version='1.0')
        params = {'q': {'description': 'some description'}}

        @api.doc(params=params)
        class TestResource(restplus.Resource):
            pass

        self.assertTrue(hasattr(TestResource, '__apidoc__'))
        self.assertEqual(TestResource.__apidoc__, {'params': params})
コード例 #15
0
    def test_disabled_apidoc(self):
        restplus.Api(self.app, version='1.0', doc=False)

        with self.context():
            with self.app.test_client() as client:
                with self.assertRaises(BuildError):
                    url_for('doc')

                response = client.get(url_for('root'))
                self.assertEquals(response.status_code, 404)
コード例 #16
0
    def test_apidoc_with_custom_validator(self):
        self.app.config['SWAGGER_VALIDATOR_URL'] = 'http://somewhere.com/validator'
        restplus.Api(self.app, version='1.0')

        with self.context():
            with self.app.test_client() as client:
                response = client.get(url_for('doc'))
                self.assertEquals(response.status_code, 200)
                self.assertEquals(response.content_type, 'text/html; charset=utf-8')
                self.assertIn('validatorUrl: "http://somewhere.com/validator" || null,', str(response.data))
コード例 #17
0
    def test_default_apidoc_on_root_lazy(self):
        api = restplus.Api(version='1.0')
        api.init_app(self.app)

        with self.context():
            self.assertEqual(url_for('doc'), url_for('root'))
            with self.app.test_client() as client:
                response = client.get(url_for('doc'))
                self.assertEquals(response.status_code, 200)
                self.assertEquals(response.content_type, 'text/html; charset=utf-8')
コード例 #18
0
    def test_custom_apidoc_page(self):
        api = restplus.Api(self.app, version='1.0')
        content = 'My Custom API Doc'

        @api.documentation
        def api_doc():
            return content

        with self.context():
            with self.app.test_client() as client:
                response = client.get(url_for('doc'))
                self.assertEquals(response.status_code, 200)
                self.assertEquals(response.data.decode('utf8'), content)
コード例 #19
0
    def test_export_with_swagger(self):
        api = restplus.Api(self.app)

        data = api.as_postman(swagger=True)

        validate(data, schema)

        self.assertEqual(len(data['requests']), 1)
        request = data['requests'][0]
        self.assertEqual(request['name'], 'Swagger specifications')
        self.assertEqual(request['description'],
                         'The API Swagger specifications as JSON')
        self.assertEqual(request['url'], 'http://localhost/swagger.json')
コード例 #20
0
    def test_export_infos(self):
        api = restplus.Api(
            self.app,
            version='1.0',
            title='My API',
            description='This is a testing API',
        )

        data = api.as_postman()

        validate(data, schema)

        self.assertEqual(data['name'], 'My API 1.0')
        self.assertEqual(data['description'], 'This is a testing API')
コード例 #21
0
    def test_abort_on_exception(self):
        api = restplus.Api(self.app)

        @api.route('/test/', endpoint='test')
        class TestResource(restplus.Resource):
            def get(self):
                raise ValueError()

        with self.app.test_client() as client:
            response = client.get('/test/')
            self.assertEquals(response.status_code, 500)
            self.assertEquals(response.content_type, 'application/json')

            data = json.loads(response.data.decode('utf8'))
            self.assertIn('message', data)
コード例 #22
0
    def test_abort_with_message(self):
        api = restplus.Api(self.app)

        @api.route('/test/', endpoint='test')
        class TestResource(restplus.Resource):
            def get(self):
                api.abort(403, 'A message')

        with self.app.test_client() as client:
            response = client.get('/test/')
            self.assertEquals(response.status_code, 403)
            self.assertEquals(response.content_type, 'application/json')

            data = json.loads(response.data.decode('utf8'))
            self.assertEqual(data['message'], 'A message')
コード例 #23
0
    def test_content_type_header(self):
        api = restplus.Api(self.app)
        form_parser = api.parser()
        form_parser.add_argument('param',
                                 type=int,
                                 help='Some param',
                                 location='form')

        file_parser = api.parser()
        file_parser.add_argument('in_files',
                                 type=FileStorage,
                                 location='files')

        @api.route('/json/')
        class TestJson(restplus.Resource):
            @api.doc('json')
            def post(self):
                pass

        @api.route('/form/')
        class TestForm(restplus.Resource):
            @api.doc('form', parser=form_parser)
            def post(self):
                pass

        @api.route('/file/')
        class TestFile(restplus.Resource):
            @api.doc('file', parser=file_parser)
            def post(self):
                pass

        @api.route('/get/')
        class TestGet(restplus.Resource):
            @api.doc('get')
            def get(self):
                pass

        data = api.as_postman(urlvars=True)

        validate(data, schema)
        requests = dict((r['name'], r['headers']) for r in data['requests'])

        self.assertEqual(requests['json'], 'Content-Type:application/json')
        self.assertEqual(requests['form'], 'Content-Type:multipart/form-data')
        self.assertEqual(requests['file'], 'Content-Type:multipart/form-data')

        # No content-type on get
        self.assertEqual(requests['get'], '')
コード例 #24
0
    def test_custom_apidoc_page_lazy(self):
        blueprint = Blueprint('api', __name__, url_prefix='/api')
        api = restplus.Api(blueprint, version='1.0')
        content = 'My Custom API Doc'

        @api.documentation
        def api_doc():
            return content

        self.app.register_blueprint(blueprint)

        with self.context():
            with self.app.test_client() as client:
                response = client.get(url_for('api.doc'))
                self.assertEquals(response.status_code, 200)
                self.assertEquals(response.data.decode('utf8'), content)
コード例 #25
0
def init(apis):
    """Module initialization."""

    blueprint = flask.Blueprint('v3', __name__, url_prefix='/v3')

    api = restplus.Api(blueprint,
                       version='3.0',
                       ui=False,
                       title="Treadmill's API Server - v3",
                       description="Treadmill's API server")

    @blueprint.route('/docs/', endpoint='docs')
    def _swagger_ui():
        """Swagger documentation route"""
        return restplus.apidoc.ui_for(api)

    rest.FLASK_APP.register_blueprint(blueprint)
    rest.FLASK_APP.register_blueprint(restplus.apidoc.apidoc)

    # TODO: origin must be configurable.
    cors = webutils.cors(origin='.*',
                         content_type='application/json',
                         credentials=True)

    def user_clbk():
        """Get current user from the request."""
        return flask.request.environ.get('REMOTE_USER')

    authorizer = authz.PluginAuthorizer(user_clbk)

    for apiname in apis:
        try:
            apimod = apiname.replace('-', '_')
            _LOGGER.info('Loading api: %s', apimod)

            api_restmod = importlib.import_module('treadmill.rest.v3.' +
                                                  apimod)
            api_implmod = importlib.import_module('treadmill.api.' + apimod)

            api_impl = api_implmod.init(authorizer)
            api_restmod.init(api, cors, api_impl)

        except ImportError as err:
            _LOGGER.warn('Unable to load %s api: %s', apimod, err)

    return ['/v3/' + apimod.replace('_', '-') for apimod in apis]
コード例 #26
0
    def test_custom_apidoc_url(self):
        restplus.Api(self.app, version='1.0', doc='/doc/')

        with self.context():
            with self.app.test_client() as client:
                doc_url = url_for('doc')
                root_url = url_for('root')

                self.assertNotEqual(doc_url, root_url)

                response = client.get(root_url)
                self.assertEquals(response.status_code, 404)

                self.assertEqual(doc_url, '/doc/')
                response = client.get(doc_url)
                self.assertEquals(response.status_code, 200)
                self.assertEquals(response.content_type, 'text/html; charset=utf-8')
コード例 #27
0
    def test_custom_apidoc_url(self):
        blueprint = Blueprint('api', __name__, url_prefix='/api')
        api = restplus.Api(blueprint, version='1.0', ui=False)

        @blueprint.route('/doc/', endpoint='doc')
        def swagger_ui():
            return restplus.apidoc.ui_for(api)

        self.app.register_blueprint(blueprint)

        with self.context(), self.app.test_client() as client:
            response = client.get(url_for('api.root'))
            self.assertEquals(response.status_code, 404)

            response = client.get(url_for('api.doc'))
            self.assertEquals(response.status_code, 200)
            self.assertEquals(response.content_type,
                              'text/html; charset=utf-8')
コード例 #28
0
    def test_apidoc_doc_expansion_parameter(self):
        restplus.Api(self.app)

        with self.context():
            with self.app.test_client() as client:
                response = client.get(url_for('doc'))
                self.assertIn('docExpansion: "none"', str(response.data))

        self.app.config['SWAGGER_UI_DOC_EXPANSION'] = 'list'
        with self.context():
            with self.app.test_client() as client:
                response = client.get(url_for('doc'))
                self.assertIn('docExpansion: "list"', str(response.data))

        self.app.config['SWAGGER_UI_DOC_EXPANSION'] = 'full'
        with self.context():
            with self.app.test_client() as client:
                response = client.get(url_for('doc'))
                self.assertIn('docExpansion: "full"', str(response.data))
コード例 #29
0
    def test_headers(self):
        api = restplus.Api(self.app)

        @api.route('/headers/')
        class TestHeaders(restplus.Resource):
            @api.doc('headers')
            @api.header('X-Header-1', default='xxx')
            @api.header('X-Header-2', required=True)
            def get(self):
                pass

        data = api.as_postman(urlvars=True)

        validate(data, schema)
        request = data['requests'][0]
        headers = dict(r.split(':') for r in request['headers'].splitlines())

        self.assertEqual(headers['X-Header-1'], 'xxx')
        self.assertEqual(headers['X-Header-2'], '')
コード例 #30
0
    def test_validation_true_on_constructor_with_override(self):
        api = restplus.Api(self.app, validate=True)

        fields = api.model('Person', {
            'name': restplus.fields.String(required=True),
            'age': restplus.fields.Integer,
            'birthdate': restplus.fields.DateTime,
        })

        @api.route('/validation/')
        class ValidationOff(restplus.Resource):
            @api.expect(fields, validate=False)
            def post(self):
                return {}

        data = {}

        response = self.post('/validation/', data)

        self.assert_errors(response, 'name')