def test_api_payload(self, app, client):
        api = restplus.Api(app, validate=True)
        ns = restplus.Namespace('apples')
        api.add_namespace(ns)

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

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

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

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

        client.post_json('/apples/validation/', data)

        assert Payload.payload == data
Example #2
0
    def test_errorhandler_with_namespace(self):
        api = restplus.Api(self.app)

        ns = restplus.Namespace("ExceptionHandler", path="/")

        class CustomException(RuntimeError):
            pass

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

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

        api.add_namespace(ns)

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

            data = json.loads(response.data.decode('utf8'))
            self.assertEqual(data, {
                'message': 'error',
                'test': 'value',
            })
Example #3
0
    def test_errorhandler_with_namespace(self, app, client):
        api = restplus.Api(app)

        ns = restplus.Namespace("ExceptionHandler", path="/")

        class CustomException(RuntimeError):
            pass

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

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

        api.add_namespace(ns)

        response = client.get('/test/')
        assert response.status_code == 400
        assert response.content_type == 'application/json'

        data = json.loads(response.data.decode('utf8'))
        assert data == {
            'message': 'error',
            'test': 'value',
        }
Example #4
0
    def test_multiple_ns_with_authorizations(self, app):
        api = restplus.Api()
        a1 = {
            'apikey': {
                'type': 'apiKey',
                'in': 'header',
                'name': 'X-API'
            }
        }
        a2 = {
            'oauth2': {
                'type': 'oauth2',
                'flow': 'accessCode',
                'tokenUrl': 'https://somewhere.com/token',
                'scopes': {
                    'read': 'Grant read-only access',
                    'write': 'Grant read-write access',
                }
            }
        }
        ns1 = restplus.Namespace('ns1', authorizations=a1)
        ns2 = restplus.Namespace('ns2', authorizations=a2)

        @ns1.route('/')
        class Ns1(restplus.Resource):
            @ns1.doc(security='apikey')
            def get(self):
                pass

        @ns2.route('/')
        class Ns2(restplus.Resource):
            @ns1.doc(security='oauth2')
            def post(self):
                pass

        api.add_namespace(ns1, path='/ns1')
        api.add_namespace(ns2, path='/ns2')
        api.init_app(app)

        assert {"apikey": []} in api.__schema__["paths"]["/ns1/"]["get"]["security"]
        assert {"oauth2": []} in api.__schema__["paths"]["/ns2/"]["post"]["security"]
        unified_auth = copy.copy(a1)
        unified_auth.update(a2)
        assert api.__schema__["securityDefinitions"] == unified_auth
Example #5
0
    def test_ns_path_prefixes(self, app):
        api = restplus.Api()
        ns = restplus.Namespace('test_ns', description='Test namespace')

        @ns.route('/test/', endpoint='test_resource')
        class TestResource(restplus.Resource):
            pass

        api.add_namespace(ns, '/api_test')
        api.init_app(app)

        with app.test_request_context():
            assert url_for('test_resource') == '/api_test/test/'
Example #6
0
import logging

import flask_restplus

import synonyms.models.synonym as synonym

__all__ = ['api']

api = flask_restplus.Namespace('Synonyms',
                               description='Work with synonyms used in Solr')


@api.route('/<term>', methods=['GET'])
class _Synonyms(flask_restplus.Resource):
    @staticmethod
    def get(term):
        term = term.strip()
        logging.debug('Doing synonym search for "{}"'.format(term))

        results = synonym.Synonym.find(term)

        if not results:
            return {
                'message':
                'Term \'{}\' not found in any synonyms list'.format(term)
            }, 404

        response_list = []
        for result in results:
            response_list.append(result.synonyms_text)
Example #7
0
import flask_restplus as fr
from flask_jwt_extended import (
    create_access_token,
    get_jwt_identity,  # noqa
    jwt_optional,
    jwt_required)
from werkzeug.security import generate_password_hash

from app.errors.exceptions import BadRequest, NotFound  # noqa
from app.repositories import adv_repo  # noqa

from ..utils.decorator import authorized, consumes, use_args  # noqa

ns = fr.Namespace('advs', description='Advs related operations')


@ns.route('')
class APIAdvCreateAndList(fr.Resource):
    @jwt_required
    @authorized()
    @use_args(
        **{
            'type': 'object',
            'properties': {
                'username': {
                    'type': 'string'
                },
                'password': {
                    'type': 'string'
                },
                'email': {
Example #8
0
import flask_restplus

route = flask_restplus.Namespace(name='Auth', description='Manage Auth API')
Example #9
0
# limitations under the License.
"""BigGraphite API."""

from __future__ import absolute_import

from flask import request
import flask_restplus as rp

from biggraphite import metric as bg_metric
from biggraphite.cli.web import context

# TODO:
# - Add the equivalent of what the accessor provides
# - Add the ability to get/set points.

api = rp.Namespace("biggraphite", description="BigGraphite API")

metric_metadata = api.model(
    "MetricMetadata",
    {
        "aggregator": rp.fields.String(description="The metric aggregator"),
        "retention": rp.fields.String(description="The metric retention"),
        "carbon_xfilesfactor": rp.fields.Float(
            description="The metric carbon xfiles factor"
        ),
    },
)

metric = api.model(
    "Metric",
    {
Example #10
0
            return ["This url does not belong to the app.".encode()]


app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/api')

api = flask_restplus.Api(
    app,
    title='bcforms JSON REST API',
    description='JSON REST API for calculating properties of biocomplex forms',
    contact='*****@*****.**',
    version=bcforms.__version__,
    license='MIT',
    license_url='https://github.com/KarrLab/bcforms/blob/master/LICENSE',
    doc='/')

bcform_ns = flask_restplus.Namespace(
    'bcform', description='Calculate properties of biocomplex forms')
api.add_namespace(bcform_ns)

# define model

# if encoding, structure defined -> ignore formula, mol_wt, charge, and define them based on structure
# if neither encoding, structure set and formula is defined -> ignore mol_wt, and define mol_wt based on formula
subunit_fields = {}
subunit_fields['name'] = flask_restplus.fields.String(required=True,
                                                      title='Subunit name',
                                                      example='abc_a')
# encoding can be smiles, bpforms.ProteinForm, bpforms.DnaForm, bpforms.RnaForm
subunit_fields['encoding'] = flask_restplus.fields.String(
    required=False, title='Structure encoding', example='bpforms.ProteinForm')
subunit_fields['structure'] = flask_restplus.fields.String(
    required=False, title='Structure string', example='AAA')
import logging

import flask_restplus
import webargs.flaskparser

from minesweeper.errors import HttpError
from minesweeper.schema.game import GameListPostRequestSchema, GameModelSchema, \
    GameListGetRequestSchema, GamePutRequestSchema
from minesweeper.services.game import create_game, get_games, get_game_by_id, \
    delete_game_by_id, set_cell_action

logger = logging.getLogger(__name__)

game_ns = flask_restplus.Namespace("game", description="Game endpoints")


@game_ns.route("/<int:game_id>")
class Game(flask_restplus.Resource):
    @staticmethod
    def get(game_id):
        game = get_game_by_id(game_id)
        if not game:
            raise HttpError(code=404,
                            message=f"Game with ID {game_id} not found")
        return GameModelSchema().dump(game)

    @staticmethod
    def delete(game_id):
        game = delete_game_by_id(game_id)
        if not game:
            raise HttpError(code=404,
Example #12
0
import flask_restplus as fr
from flask_jwt_extended import (
    create_access_token,
    get_jwt_identity,  # noqa
    jwt_optional,
    jwt_required)

from app.errors.exceptions import BadRequest, NotFound
from app.repositories import user_repo

from ..utils.decorator import authorized, consumes, use_args

ns = fr.Namespace('users', description='Users related operations')


@ns.route('/profile')
class APIUserProfile(fr.Resource):
    @jwt_required
    @authorized()
    def get(self, current_user):
        return {
            'item': current_user.to_model(),
            'message': 'Get UserInfo Successfully'
        }, 200

    @jwt_required
    @authorized()
    @use_args(**{
        'type': 'object',
        'properties': {
            'postback_url': {
Example #13
0
# -*- coding: utf-8 -*-
import flask_restplus as fr
from flask_jwt_extended import (create_access_token, get_jwt_identity,  # noqa
                                jwt_optional, jwt_required)

from app.errors.exceptions import BadRequest, NotFound  # noqa
from app.repositories import user_repo, domain_repo

from ..utils.decorator import authorized, consumes, use_args  # noqa

ns = fr.Namespace('domains', description='Domains related operations')


@ns.route('')
class APIUserAddDomainAndList(fr.Resource):
    @jwt_required
    @authorized()
    @use_args(**{
        'type': 'object',
        'properties': {
            'url': {
                'type': 'string',
            },
        },
        'required': ['url'],
    })
    def post(self, current_user, args):
        url = args.get('url')
        domain = domain_repo.find_domain_by_url(url)
        if domain is not None:
            raise BadRequest(message='Domain is existed')
Example #14
0
# See the License for the specific language governing permissions and
# limitations under the License.
"""bgutil API."""

from __future__ import absolute_import

import argparse
import logging

import flask_restplus as rp

from biggraphite.cli.web import context
from biggraphite.cli.web.capture import Capture
from biggraphite import settings as bg_settings

api = rp.Namespace("bgutil", description="bgutil as a service")

command = api.model(
    "Command",
    {
        "arguments":
        rp.fields.List(rp.fields.String(), description="command arguments")
    },
)


class UnknownCommandException(Exception):
    """Unknown command exception."""
    def __init__(self, command_name):
        """Init UnknownCommandException."""
        super(UnknownCommandException,
Example #15
0
# -*- coding: utf-8 -*-
import flask_restplus as fr
from flask_jwt_extended import (create_access_token, get_jwt_identity,  # noqa
                                jwt_optional, jwt_required)

from app.errors.exceptions import BadRequest, NotFound  # noqa
from app.repositories import category_repo  # noqa

from ..utils.decorator import authorized, consumes, use_args  # noqa

ns = fr.Namespace('categories', description='Category related operations')


@ns.route('')
class APICategoryCreateAndList(fr.Resource):
    @jwt_required
    @authorized()
    @use_args(**{
        'type': 'object',
        'properties': {
            'name': {'type': 'string'},
            'description': {'type': 'string'},
        },
        'required': ['name'],
    })
    def post(self, current_user, args):
        category = category_repo.create(args)
        if category is None:
            raise BadRequest(message='Could not created category')
        return {'item': category.to_model(), 'message': 'Create category successfully'}, 201
Example #16
0
            # numpy
            # tensorflow
            # etc.
        }
        return flask.jsonify(versions)


###############################################################################
###############################################################################
# flask_restplus namespace
###############################################################################
###############################################################################

ns2 = flask_restplus.Namespace(
    name='Flask-Restplus-Namespace-Subsystem-Service-v2',
    description='A set of services for the Subsytem v2.',
    path='/v2',
)

###############################################################################
# route: /get, version in namespace
# usage: curl -i -X GET http://localhost:5000/subsys/v2/get
###############################################################################


@ns2.route('/get')
class Get3(flask_restplus.Resource):
    def get(self):
        payload = flask.request.json
        versions = {
            'flask.request.url': flask.request.url,
Example #17
0
import flask_restplus as fr
from flask import current_app, render_template

from app.decorators import use_args
from app.email import send_email
from app.errors.exceptions import BadRequest
from app.repositories.user import user_repo
from app.utils import to_json

ns = fr.Namespace(name="password",
                  description="Password reset and verification")


@ns.route('/request_token')
class APIPasswordRequestToken(fr.Resource):
    @use_args(
        **{
            'type': 'object',
            'properties': {
                'email': {
                    'type': 'string'
                },
            },
            'required': ['email']
        })
    def post(self, args):
        user = user_repo.get_by_email(args.get('email'))
        if not user:
            raise BadRequest(message='Email is not exist')
        if not user.emailVerified:
            raise BadRequest(message='Email is not verified')
Example #18
0
import flask_restplus

__all__ = ['api']

api = flask_restplus.Namespace(
    'Probes',
    description='Operations probes to determine liveness and readiness')


# If we are reachable, we consider ourselves to be live.
@api.route('/liveness')
class _Liveness(flask_restplus.Resource):
    @staticmethod
    def get():
        return {'message': 'Liveness checks passed'}, 200


# If we are reachable, we consider ourselves to be ready.
@api.route('/readiness')
class _Readiness(flask_restplus.Resource):
    @staticmethod
    def get():
        return {'message': 'Readiness checks passed'}, 200
Example #19
0
            return ["This url does not belong to the app.".encode()]


app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/api')

api = flask_restplus.Api(
    app,
    title='Bpforms JSON REST API',
    description='JSON REST API for calculating properties of biopolymer forms',
    contact='*****@*****.**',
    version=bpforms.__version__,
    license='MIT',
    license_url='https://github.com/KarrLab/bpforms/blob/master/LICENSE',
    doc='/')

bpform_ns = flask_restplus.Namespace(
    'bpform', description='Calculate properties of biopolymer forms')
api.add_namespace(bpform_ns)

bpforms_model = bpform_ns.model(
    'BpForm', {
        'alphabet':
        flask_restplus.fields.String(
            enum=list(bpforms.util.get_alphabets().keys()),
            required=True,
            title='Alphabet',
            description='Id of the alphabet of the biopolymer form'),
        'seq':
        flask_restplus.fields.String(
            required=True,
            title='Sequence of monomeric forms',
            description='Sequence of monomeric forms of the biopolymer form',
Example #20
0
    def add_restful_api(self,
                        name: str,
                        backend: object,
                        endpoint: str = None):
        """
        Creates a flask_restplus restful api from the
        routines available in given class
        """
        if endpoint is None:
            endpoint = name.replace(" ", "_").lower()
        ns = flask_restplus.Namespace(name, inspect.getdoc(backend),
                                      f"/{endpoint}")

        def isempty(o):
            "Checks if an annotation or a default value is empty"
            return o == inspect.Parameter.empty

        def build_resource(callable, post_parser, get_parser, is_post, is_get):
            "Instantiates an ApiMember in closure"

            def invoke_callable(parser, *args, **kwargs):
                for key, value in parser.parse_args().items():
                    kwargs[key] = value
                return callable(*args, **kwargs)

            if is_post:
                if is_get:

                    class ApiMember(flask_restplus.Resource):
                        @ns.expect(post_parser)
                        def post(self, *args, **kwargs):
                            return invoke_callable(post_parser, *args,
                                                   **kwargs)

                        @ns.expect(get_parser)
                        def get(self, *args, **kwargs):
                            return invoke_callable(get_parser, *args, **kwargs)

                else:

                    class ApiMember(flask_restplus.Resource):
                        @ns.expect(post_parser)
                        def post(self, *args, **kwargs):
                            return invoke_callable(post_parser, *args,
                                                   **kwargs)

            else:

                class ApiMember(flask_restplus.Resource):
                    @ns.expect(get_parser)
                    def get(self, *args, **kwargs):
                        return invoke_callable(get_parser, *args, **kwargs)

            return ApiMember

        member_resources = {}
        for name, value in inspect.getmembers(backend, inspect.ismethod):
            if name.startswith("_"):
                continue
            is_post = hasattr(value, "is_post") and value.is_post
            is_get = hasattr(value, "is_get") and value.is_get
            if not (is_post or is_get):
                is_post = True
            signature = inspect.signature(value)
            post_parser = ns.parser()
            get_parser = ns.parser()
            for p in signature.parameters.values():
                param_type = str if isempty(p.annotation) else p.annotation
                param_action = "store"
                param_location = {"get": "args", "post": "form"}
                param_choices = ()
                if isinstance(param_type, listof):
                    param_type = param_type.subtype
                    param_action = "append"
                try:
                    if issubclass(param_type, file):
                        is_get = False
                        is_post = True
                        param_type = FileStorage
                        param_location = {"get": "files", "post": "files"}
                except:
                    pass
                if isinstance(param_type, enum):
                    param_choices = tuple(param_type.entries.keys())
                    param_type = str
                post_parser.add_argument(
                    p.name,
                    location=param_location["post"],
                    type=param_type,
                    action=param_action,
                    choices=param_choices,
                    required=isempty(p.default),
                    default=None if isempty(p.default) else p.default,
                )
                get_parser.add_argument(
                    p.name,
                    location=param_location["get"],
                    type=param_type,
                    action=param_action,
                    choices=param_choices,
                    required=isempty(p.default),
                    default=None if isempty(p.default) else p.default,
                )

            resource = build_resource(value, post_parser, get_parser, is_post,
                                      is_get)
            member_resources[value] = resource
            ns.route("/" + name)(resource)

        self.add_namespace(ns)

        def backend_url_for(backend, method):
            "Provide the backend with a means to get urls for its methods"
            if method not in backend.member_resources:
                return
            return self.url_for(backend.member_resources[method])

        backend.member_resources = member_resources
        backend.url_for = MethodType(backend_url_for, backend)
Example #21
0
import copy

import flask
import flask_restplus
from flask_restplus import fields
import werkzeug
import werkzeug.exceptions as exceptions

from deepaas import model

# Get the models (this is a singleton, so it is safe to call it multiple times
model.register_models()

api = flask_restplus.Namespace(
    'models',
    description='Model information, inference and training operations')

# This should be removed with marshmallow whenever flask-restplus is ready
data_parser = api.parser()

# FIXME(aloga): currently we allow only to upload one file. There is a bug in
# the Swagger UI that makes impossible to upload several files, although this
# works if the request is not done through swagger. Since providing a UI and an
# API that behave differently is incoherent, only allow one file for the time
# being.
#
# See https://github.com/noirbizarre/flask-restplus/issues/491 for more details
# on the bug.
data_parser.add_argument('data',
                         help="Data file to perform inference.",
Example #22
0
import flask
import flask_restplus

from cmp_rbac.service import common
from flask import render_template
from cmp_rbac.service.v1 import user_service
from cmp_rbac import app
import cmp_rbac.models.user
from flask_security import roles_required, auth_token_required, login_required

api = flask_restplus.Namespace('user', description='User Details')

user_api_model = api.model('user', cmp_rbac.models.user.api_model)

# @app.route('/')
# @login_required
# def home():
#     return render_template('index.html')


@api.route('/user_details')
@api.response(500, 'Something went wrong.')
class UserView(flask_restplus.Resource):
    @api.doc('Lists all users')
    @api.response(200, 'User Data')
    # @auth_token_required
    # @roles_required('admin')
    # @roles_required('end-user')
    def get(self):
        return common.get_return_envelope(data=api.marshal(
            user_service.get_all_users(), user_api_model)), 200
Example #23
0
import flask_restplus as fr
from flask_jwt_extended import (
    create_access_token,
    get_jwt_identity,  # noqa
    jwt_optional,
    jwt_required)

from app.errors.exceptions import BadRequest, NotFound  # noqa
from app.repositories import offer_repo  # noqa

from ..utils.decorator import authorized, consumes, use_args  # noqa

ns = fr.Namespace('offers', description='Offer related operations')


@ns.route('')
class APIOfferCreateAndList(fr.Resource):
    @jwt_required
    @authorized()
    @use_args(
        **{
            'type':
            'object',
            'properties': {
                'alias': {
                    'type': 'string'
                },
                'description': {
                    'type': 'string'
                },
                'short_desc': {
Example #24
0
import logging

import flask
import flask_restplus

from solr_feeder import solr

__all__ = ['api']

api = flask_restplus.Namespace(
    'Feeds', description='Feed updates from legacy databases')


# Feed the specified core with the given data.
@api.route('')
class _Names(flask_restplus.Resource):
    solr_request_model = api.model(
        'Solr Request', {
            'solr_core': flask_restplus.fields.String(),
            'request': flask_restplus.fields.String()
        })

    @api.expect(solr_request_model)
    def post(self):
        logging.debug('request raw data: {}'.format(flask.request.data))
        json_data = flask.request.get_json()

        if 'solr_core' not in json_data:
            return {
                'message': 'Required parameter "solr_core" not defined'
            }, 400
Example #25
0
import logging
import typing
import uuid

import flask_restplus
from sqlalchemy.orm import exc

from service.models import database
from service.models import user

LOG = logging.getLogger(__name__)

api = flask_restplus.Namespace('users', description='Users related operations')

USER_MODEL = api.model(user.USER_FILEDS.name, user.USER_FILEDS)


@api.route('')
class Users(flask_restplus.Resource):
    @api.doc(
        description='Gets users', )
    @api.param('lastName',
               description='User last name to filter by',
               _in='query')
    @api.marshal_with(USER_MODEL, code=200)
    def get(self
            ) -> typing.Tuple[typing.List[typing.Dict[str, typing.Any]], int]:
        arguments = user.USER_FILTER.parse_args()
        LOG.info('Received request to list users')
        if arguments['lastName']:
            users = user.User.query.filter(
Example #26
0
import uuid

from flask import jsonify, request, Response
import flask.wrappers as FLW
import flask_restplus as FRP

from redis import Redis, StrictRedis
from rq import Queue
from tasks import RQueues

strict_redis: Redis = StrictRedis()


API = FRP.Namespace(
    name='Demo',
    path="/demo",
    description='Root route; used for demo-ing the API is up and running, etc.'
)

logger: logging.Logger = logging.getLogger(__name__)


@API.route("/")
class DemoRoutes(FRP.Resource):
    """Controller class for demo-routes"""

    @API.doc('--demo--')
    @FRP.cors.crossdomain(origin='*')
    def get(self: 'DemoRoutes') -> typing.Any:
        '''Returns trivial json object'''
Example #27
0
import typing

import flask_restplus

api = flask_restplus.Namespace('status', description='Check service status')


@api.route('')
class Status(flask_restplus.Resource):
    @api.doc(
        'Gets service status',
        responses={
            '200': 'Service is operational',
            '500': 'Service is unable to handle the request',
        },
    )
    def get(self) -> typing.Tuple[typing.Any, int]:
        return '', 200
Example #28
0
import flask_restplus

route = flask_restplus.Namespace(name='User', description='Manage User API')