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
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', })
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', }
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
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/'
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)
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': {
import flask_restplus route = flask_restplus.Namespace(name='Auth', description='Manage Auth API')
# 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", {
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,
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': {
# -*- 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')
# 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,
# -*- 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
# 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,
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')
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
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',
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)
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.",
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
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': {
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
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(
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'''
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
import flask_restplus route = flask_restplus.Namespace(name='User', description='Manage User API')