コード例 #1
0
 def _parse_data(self, schema, request, *args, **kwargs):
     """Deserializes from a Flask request to a dict with valid
     data. It a ``Marshmallow.Schema`` instance to perform the
     deserialization
     """
     return FlaskParser().parse(schema, request, locations=('json',),
                                *args, **kwargs)
コード例 #2
0
class ArgumentsMixin:
    """Extend Blueprint to add arguments parsing feature"""

    ARGUMENTS_PARSER = FlaskParser()

    def arguments(
            self, schema, *, location='json', required=True,
            example=None, examples=None, **kwargs
    ):
        """Decorator specifying the schema used to deserialize parameters

        :param type|Schema schema: Marshmallow ``Schema`` class or instance
            used to deserialize and validate the argument.
        :param str location: Location of the argument.
        :param bool required: Whether argument is required (default: True).
            This only affects `body` arguments as, in this case, the docs
            expose the whole schema as a `required` parameter.
            For other locations, the schema is turned into an array of
            parameters and their required value is inferred from the schema.
        :param dict example: Parameter example.
        :param list examples: List of parameter examples.
        :param dict kwargs: Keyword arguments passed to the webargs
            :meth:`use_args <webargs.core.Parser.use_args>` decorator used
            internally.

        The `example` and `examples` parameters are mutually exclusive and
        should only be used with OpenAPI 3 and when location is `json`.

        See :doc:`Arguments <arguments>`.
        """
        # At this stage, put schema instance in doc dictionary. Il will be
        # replaced later on by $ref or json.
        parameters = {
            'in': location,
            'required': required,
            'schema': schema,
        }
        if example is not None:
            parameters['example'] = example
        if examples is not None:
            parameters['examples'] = examples

        def decorator(func):

            @wraps(func)
            def wrapper(*f_args, **f_kwargs):
                return func(*f_args, **f_kwargs)

            # Add parameter to parameters list in doc info in function object
            # The deepcopy avoids modifying the wrapped function doc
            wrapper._apidoc = deepcopy(getattr(wrapper, '_apidoc', {}))
            wrapper._apidoc.setdefault('parameters', []).append(parameters)

            # Call use_args (from webargs) to inject params in function
            return self.ARGUMENTS_PARSER.use_args(
                schema, locations=[location], **kwargs)(wrapper)

        return decorator
コード例 #3
0
class OdataMixin:
    """Extend Blueprint to add Odata feature"""

    ODATA_ARGUMENTS_PARSER = FlaskParser()

    def odata(self, session: Session, default_orderby: str = None):
        """Decorator adding odata capability to endpoint."""

        parameters = {
            'in': 'query',
            'schema': OdataSchema,
        }

        error_status_code = (
            self.ODATA_ARGUMENTS_PARSER.DEFAULT_VALIDATION_STATUS)

        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                odata_params = self.ODATA_ARGUMENTS_PARSER.parse(
                    OdataSchema, request, location='query')
                # Execute decorated function
                model, status, headers = unpack_tuple_response(
                    func(*args, **kwargs))
                # Apply Odata
                query = Odata(
                    session=session,
                    model=model,
                    odata_parameters=odata_params,
                    default_orderby=default_orderby,
                ).query
                return query, status, headers

            # Add odata params to doc info in wrapper object
            wrapper._apidoc = deepcopy(getattr(wrapper, '_apidoc', {}))
            wrapper._apidoc['odata'] = {
                'parameters': parameters,
                'response': {
                    error_status_code: HTTPStatus(error_status_code).name,
                }
            }

            return wrapper

        return decorator

    def _prepare_odata_doc(self, doc, doc_info, *, spec, **kwargs):
        operation = doc_info.get('odata')
        if operation:
            doc.setdefault('parameters', []).append(operation['parameters'])
            doc.setdefault('responses', {}).update(operation['response'])
        return doc
コード例 #4
0
    def __init__(self, import_name, name, prefix, template_folder=None):
        self.blueprint = Blueprint(import_name=import_name,
                                   name=name,
                                   url_prefix=prefix,
                                   template_folder=template_folder)
        self.prefix = prefix
        self.name = name
        self.parser = FlaskParser()
        self.apidoc = {}

        @self.parser.error_handler
        def _handle_error(err):
            raise err
コード例 #5
0
class ArgumentsMixin:
    """Extend Blueprint to add arguments parsing feature"""

    ARGUMENTS_PARSER = FlaskParser()

    def arguments(self, schema, *, location='json', required=True, **kwargs):
        """Decorator specifying the schema used to deserialize parameters

        :param type|Schema schema: Marshmallow ``Schema`` class or instance
            used to deserialize and validate the argument.
        :param str location: Location of the argument.
        :param bool required: Whether argument is required (default: True).
            This only affects `body` arguments as, in this case, the docs
            expose the whole schema as a `required` parameter.
            For other locations, the schema is turned into an array of
            parameters and their required value is inferred from the schema.
        :param dict kwargs: Keyword arguments passed to the webargs
            :meth:`use_args <webargs.core.Parser.use_args>` decorator used
            internally.

        See :doc:`Arguments <arguments>`.
        """
        # TODO: This shouldn't be needed. I think I did this because apispec
        # worked better with instances, but this should have been solved since.
        if isinstance(schema, type):
            schema = schema()

        try:
            openapi_location = __location_map__[location]
        except KeyError:
            raise InvalidLocation(
                "{} is not a valid location".format(location))

        # At this stage, put schema instance in doc dictionary. Il will be
        # replaced later on by $ref or json.
        parameters = {
            'in': openapi_location,
            'required': required,
            'schema': schema,
        }

        def decorator(func):
            # Add parameter to parameters list in doc info in function object
            func._apidoc = getattr(func, '_apidoc', {})
            func._apidoc.setdefault('parameters', []).append(parameters)
            # Call use_args (from webargs) to inject params in function
            return self.ARGUMENTS_PARSER.use_args(schema,
                                                  locations=[location],
                                                  **kwargs)(func)

        return decorator
コード例 #6
0
ファイル: pagination.py プロジェクト: thisissoon/FM-API
        def wrapper(self, *args, **kwargs):

            args = FlaskParser().parse(
                {
                    'page': Arg(int, default=1),
                    'limit': Arg(int, default=limit)
                }, request)

            if args['limit'] > maximum:
                args['limit'] = maximum

            response = function(self,
                                limit=args['limit'],
                                page=args['page'],
                                offset=(args['page'] - 1) * args['limit'],
                                *args,
                                **kwargs)

            return response
コード例 #7
0
    def _get_args(cls, **kwargs):
        """Parse style and locale.

        Argument location precedence: kwargs > view_args > query
        """
        csl_args = {'style': cls._default_style, 'locale': cls._default_locale}

        if has_request_context():
            parser = FlaskParser(locations=('view_args', 'query'))
            csl_args.update(parser.parse(cls._user_args, request))

        csl_args.update(
            {k: kwargs[k]
             for k in ('style', 'locale') if k in kwargs})

        try:
            csl_args['style'] = get_style_filepath(csl_args['style'].lower())
        except StyleNotFoundError:
            if has_request_context():
                raise StyleNotFoundRESTError(csl_args['style'])
            raise
        return csl_args
コード例 #8
0
class ArgumentsMixin:
    """Extend Blueprint to add arguments parsing feature"""

    ARGUMENTS_PARSER = FlaskParser()

    def arguments(self,
                  schema,
                  *,
                  location='json',
                  content_type=None,
                  required=True,
                  description=None,
                  example=None,
                  examples=None,
                  **kwargs):
        """Decorator specifying the schema used to deserialize parameters

        :param type|Schema schema: Marshmallow ``Schema`` class or instance
            used to deserialize and validate the argument.
        :param str location: Location of the argument.
        :param str content_type: Content type of the argument.
            Should only be used in conjunction with ``json``, ``form`` or
            ``files`` location.
            The default value depends on the location and is set in
            ``Blueprint.DEFAULT_LOCATION_CONTENT_TYPE_MAPPING``.
            This is only used for documentation purpose.
        :param bool required: Whether argument is required (default: True).
        :param str description: Argument description.
        :param dict example: Parameter example.
        :param list examples: List of parameter examples.
        :param dict kwargs: Keyword arguments passed to the webargs
            :meth:`use_args <webargs.core.Parser.use_args>` decorator used
            internally.

        The `required` and `description` only affect `body` arguments
        (OpenAPI 2) or `requestBody` (OpenAPI 3), because the docs expose the
        whole schema. For other locations, the schema is turned into an array
        of parameters and the required/description value of each parameter item
        is taken from the corresponding field in the schema.

        The `example` and `examples` parameters are mutually exclusive and
        should only be used with OpenAPI 3 and when location is ``json``.

        See :doc:`Arguments <arguments>`.
        """
        # At this stage, put schema instance in doc dictionary. Il will be
        # replaced later on by $ref or json.
        parameters = {
            'in': location,
            'required': required,
            'schema': schema,
        }
        if content_type is not None:
            parameters['content_type'] = content_type
        if example is not None:
            parameters['example'] = example
        if examples is not None:
            parameters['examples'] = examples
        if description is not None:
            parameters['description'] = description

        error_status_code = kwargs.get(
            'error_status_code',
            self.ARGUMENTS_PARSER.DEFAULT_VALIDATION_STATUS)

        def decorator(func):
            @wraps(func)
            def wrapper(*f_args, **f_kwargs):
                return func(*f_args, **f_kwargs)

            # Add parameter to parameters list in doc info in function object
            # The deepcopy avoids modifying the wrapped function doc
            wrapper._apidoc = deepcopy(getattr(wrapper, '_apidoc', {}))
            docs = wrapper._apidoc.setdefault('arguments', {})
            docs.setdefault('parameters', []).append(parameters)
            docs.setdefault('responses',
                            {})[error_status_code] = http.HTTPStatus(
                                error_status_code).name

            # Call use_args (from webargs) to inject params in function
            return self.ARGUMENTS_PARSER.use_args(schema,
                                                  location=location,
                                                  **kwargs)(wrapper)

        return decorator

    def _prepare_arguments_doc(self, doc, doc_info, spec, **kwargs):
        # This callback should run first as it overrides existing parameters
        # in doc. Following callbacks should append to parameters list.
        operation = doc_info.get('arguments', {})

        parameters = [
            p for p in operation.get('parameters', [])
            if isinstance(p, abc.Mapping)
        ]

        # OAS 2
        if spec.openapi_version.major < 3:
            for param in parameters:
                if param['in'] in (self.DEFAULT_LOCATION_CONTENT_TYPE_MAPPING):
                    content_type = (
                        param.pop('content_type', None) or
                        self.DEFAULT_LOCATION_CONTENT_TYPE_MAPPING[param['in']]
                    )
                    if content_type != DEFAULT_REQUEST_BODY_CONTENT_TYPE:
                        operation['consumes'] = [
                            content_type,
                        ]
                    # body and formData are mutually exclusive
                    break
        # OAS 3
        else:
            for param in parameters:
                if param['in'] in (self.DEFAULT_LOCATION_CONTENT_TYPE_MAPPING):
                    request_body = {
                        x: param[x]
                        for x in ('description', 'required') if x in param
                    }
                    fields = {
                        x: param.pop(x)
                        for x in ('schema', 'example', 'examples')
                        if x in param
                    }
                    content_type = (
                        param.pop('content_type', None) or
                        self.DEFAULT_LOCATION_CONTENT_TYPE_MAPPING[param['in']]
                    )
                    request_body['content'] = {content_type: fields}
                    operation['requestBody'] = request_body
                    # There can be only one requestBody
                    operation['parameters'].remove(param)
                    if not operation['parameters']:
                        del operation['parameters']
                    break
        doc = deepupdate(doc, operation)
        return doc
コード例 #9
0
ファイル: _schemas.py プロジェクト: iCodeIN/crowdsorter
import logging

from webargs import core
from webargs.flaskparser import FlaskParser
from marshmallow import Schema, fields, pre_load, post_load

from ._exceptions import UnprocessableEntity

parser = FlaskParser(('query', 'form', 'data'))
log = logging.getLogger(__name__)


@parser.location_handler('data')
def parse_data(request, name, field):
    return core.get_value(request.data, name, field)


class ValidatorMixin(object):
    @pre_load
    def log_input(self, data):  # pylint: disable=no-self-use
        log.debug("Input data: %r", data)

    @post_load
    def log_parsed(self, data):  # pylint: disable=no-self-use
        log.debug("Parsed data: %r", data)

    def handle_error(self, error, data):  # pylint: disable=no-self-use
        log.error("Unable to parse: %r", data)

        missing = []
        for field in sorted(error.messages):
コード例 #10
0
class PaginationMixin:
    """Extend Blueprint to add Pagination feature"""

    PAGINATION_ARGUMENTS_PARSER = FlaskParser()

    # Name of field to use for pagination metadata response header
    # Can be overridden. If None, no pagination header is returned.
    PAGINATION_HEADER_FIELD_NAME = 'X-Pagination'

    # Global default pagination parameters
    # Can be overridden to provide custom defaults
    DEFAULT_PAGINATION_PARAMETERS = {
        'page': 1,
        'page_size': 10,
        'max_page_size': 100
    }

    PAGINATION_HEADER_DOC = {
        'description': 'Pagination metadata',
        'schema': PaginationHeaderSchema,
    }

    def paginate(self,
                 pager=None,
                 *,
                 page=None,
                 page_size=None,
                 max_page_size=None):
        """Decorator adding pagination to the endpoint

        :param Page pager: Page class used to paginate response data
        :param int page: Default requested page number (default: 1)
        :param int page_size: Default requested page size (default: 10)
        :param int max_page_size: Maximum page size (default: 100)

        If a :class:`Page <Page>` class is provided, it is used to paginate the
        data returned by the view function, typically a lazy database cursor.

        Otherwise, pagination is handled in the view function.

        The decorated function may return a tuple including status and/or
        headers, like a typical flask view function. It may not return a
        ``Response`` object.

        See :doc:`Pagination <pagination>`.
        """
        if page is None:
            page = self.DEFAULT_PAGINATION_PARAMETERS['page']
        if page_size is None:
            page_size = self.DEFAULT_PAGINATION_PARAMETERS['page_size']
        if max_page_size is None:
            max_page_size = self.DEFAULT_PAGINATION_PARAMETERS['max_page_size']
        page_params_schema = _pagination_parameters_schema_factory(
            page, page_size, max_page_size)

        parameters = {
            'in': 'query',
            'schema': page_params_schema,
        }

        error_status_code = (
            self.PAGINATION_ARGUMENTS_PARSER.DEFAULT_VALIDATION_STATUS)

        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):

                page_params = self.PAGINATION_ARGUMENTS_PARSER.parse(
                    page_params_schema, request, location='query')

                # Pagination in resource code: inject page_params as kwargs
                if pager is None:
                    kwargs['pagination_parameters'] = page_params

                # Execute decorated function
                result, status, headers = unpack_tuple_response(
                    func(*args, **kwargs))

                # Post pagination: use pager class to paginate the result
                if pager is not None:
                    result = pager(result, page_params=page_params).items

                # Add pagination metadata to headers
                if self.PAGINATION_HEADER_FIELD_NAME is not None:
                    if page_params.item_count is None:
                        current_app.logger.warning(
                            'item_count not set in endpoint {}'.format(
                                request.endpoint))
                    else:
                        page_header = self._make_pagination_header(
                            page_params.page, page_params.page_size,
                            page_params.item_count)
                        if headers is None:
                            headers = {}
                        headers[
                            self.PAGINATION_HEADER_FIELD_NAME] = page_header

                return result, status, headers

            # Add pagination params to doc info in wrapper object
            wrapper._apidoc = deepcopy(getattr(wrapper, '_apidoc', {}))
            wrapper._apidoc['pagination'] = {
                'parameters': parameters,
                'response': {
                    error_status_code: http.HTTPStatus(error_status_code).name,
                }
            }
            wrapper._paginated = True

            return wrapper

        return decorator

    @staticmethod
    def _make_pagination_header(page, page_size, item_count):
        """Build pagination header from page, page size and item count

        This method returns a json representation of a default pagination
        metadata structure. It can be overridden to use another structure.
        """
        page_header = OrderedDict()
        page_header['total'] = item_count
        if item_count == 0:
            page_header['total_pages'] = 0
        else:
            # First / last page, page count
            page_count = ((item_count - 1) // page_size) + 1
            first_page = 1
            last_page = page_count
            page_header['total_pages'] = page_count
            page_header['first_page'] = first_page
            page_header['last_page'] = last_page
            # Page, previous / next page
            if page <= last_page:
                page_header['page'] = page
                if page > first_page:
                    page_header['previous_page'] = page - 1
                if page < last_page:
                    page_header['next_page'] = page + 1
        header = PaginationHeaderSchema().dumps(page_header)
        if MARSHMALLOW_VERSION_MAJOR < 3:
            header = header.data
        return header

    @staticmethod
    def _prepare_pagination_doc(doc, doc_info, **kwargs):
        operation = doc_info.get('pagination')
        if operation:
            parameters = operation.get('parameters')
            doc.setdefault('parameters', []).append(parameters)
            response = operation.get('response')
            doc.setdefault('responses', {}).update(response)
        return doc
コード例 #11
0
class PaginationMixin:
    """Extend Blueprint to add Pagination feature"""

    PAGINATION_ARGUMENTS_PARSER = FlaskParser()

    # Name of field to use for pagination metadata response header
    # Can be overridden. If None, no pagination header is returned.
    PAGINATION_HEADER_NAME = "X-Pagination"

    # Global default pagination parameters
    # Can be overridden to provide custom defaults
    DEFAULT_PAGINATION_PARAMETERS = {
        "page": 1,
        "page_size": 10,
        "max_page_size": 100
    }

    def paginate(self,
                 pager=None,
                 *,
                 page=None,
                 page_size=None,
                 max_page_size=None):
        """Decorator adding pagination to the endpoint

        :param Page pager: Page class used to paginate response data
        :param int page: Default requested page number (default: 1)
        :param int page_size: Default requested page size (default: 10)
        :param int max_page_size: Maximum page size (default: 100)

        If a :class:`Page <Page>` class is provided, it is used to paginate the
        data returned by the view function, typically a lazy database cursor.

        Otherwise, pagination is handled in the view function.

        The decorated function may return a tuple including status and/or
        headers, like a typical flask view function. It may not return a
        ``Response`` object.

        See :doc:`Pagination <pagination>`.
        """
        if page is None:
            page = self.DEFAULT_PAGINATION_PARAMETERS["page"]
        if page_size is None:
            page_size = self.DEFAULT_PAGINATION_PARAMETERS["page_size"]
        if max_page_size is None:
            max_page_size = self.DEFAULT_PAGINATION_PARAMETERS["max_page_size"]
        page_params_schema = _pagination_parameters_schema_factory(
            page, page_size, max_page_size)

        parameters = {
            "in": "query",
            "schema": page_params_schema,
        }

        error_status_code = self.PAGINATION_ARGUMENTS_PARSER.DEFAULT_VALIDATION_STATUS

        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):

                page_params = self.PAGINATION_ARGUMENTS_PARSER.parse(
                    page_params_schema, request, location="query")

                # Pagination in resource code: inject page_params as kwargs
                if pager is None:
                    kwargs["pagination_parameters"] = page_params

                # Execute decorated function
                result, status, headers = unpack_tuple_response(
                    func(*args, **kwargs))

                # Post pagination: use pager class to paginate the result
                if pager is not None:
                    result = pager(result, page_params=page_params).items

                # Set pagination metadata in response
                if self.PAGINATION_HEADER_NAME is not None:
                    if page_params.item_count is None:
                        warnings.warn(
                            "item_count not set in endpoint {}.".format(
                                request.endpoint))
                    else:
                        result, headers = self._set_pagination_metadata(
                            page_params, result, headers)

                return result, status, headers

            # Add pagination params to doc info in wrapper object
            wrapper._apidoc = deepcopy(getattr(wrapper, "_apidoc", {}))
            wrapper._apidoc["pagination"] = {
                "parameters": parameters,
                "response": {
                    error_status_code: http.HTTPStatus(error_status_code).name,
                },
            }

            return wrapper

        return decorator

    @staticmethod
    def _make_pagination_metadata(page, page_size, item_count):
        """Build pagination metadata from page, page size and item count

        Override this to use another pagination metadata structure
        """
        page_metadata = {}
        page_metadata["total"] = item_count
        if item_count == 0:
            page_metadata["total_pages"] = 0
        else:
            # First / last page, page count
            page_count = ((item_count - 1) // page_size) + 1
            first_page = 1
            last_page = page_count
            page_metadata["total_pages"] = page_count
            page_metadata["first_page"] = first_page
            page_metadata["last_page"] = last_page
            # Page, previous / next page
            if page <= last_page:
                page_metadata["page"] = page
                if page > first_page:
                    page_metadata["previous_page"] = page - 1
                if page < last_page:
                    page_metadata["next_page"] = page + 1
        return PaginationMetadataSchema().dump(page_metadata)

    def _set_pagination_metadata(self, page_params, result, headers):
        """Add pagination metadata to headers

        Override this to set pagination data another way
        """
        if headers is None:
            headers = {}
        headers[self.PAGINATION_HEADER_NAME] = json.dumps(
            self._make_pagination_metadata(page_params.page,
                                           page_params.page_size,
                                           page_params.item_count))
        return result, headers

    def _document_pagination_metadata(self, spec, resp_doc):
        """Document pagination metadata header

        Override this to document custom pagination metadata
        """
        resp_doc["headers"] = {
            self.PAGINATION_HEADER_NAME:
            "PAGINATION"
            if spec.openapi_version.major >= 3 else PAGINATION_HEADER
        }

    def _prepare_pagination_doc(self, doc, doc_info, *, spec, **kwargs):
        operation = doc_info.get("pagination")
        if operation:
            doc.setdefault("parameters", []).append(operation["parameters"])
            doc.setdefault("responses", {}).update(operation["response"])
            success_status_codes = doc_info.get("success_status_codes", [])
            for success_status_code in success_status_codes:
                self._document_pagination_metadata(
                    spec, doc["responses"][success_status_code])
        return doc
コード例 #12
0
from flask import Blueprint, jsonify, abort, url_for, current_app, render_template, request, redirect
from flask.ext.login import login_required, current_user

from webargs import fields
from webargs.flaskparser import FlaskParser

from chess.chess import Chess
from .database import Game, User

from tests.factories import UserFactory  # TODO: remove

blueprint = Blueprint("chess", __name__, url_prefix='/chess/')
parser = FlaskParser(('query', 'json'))

move_args = {
    'start': fields.Str(required=True),
    'end': fields.Str(required=True),
}

game_args = {
    'color': fields.Str(required=False, missing=None),
}

create_user_args = {
    'password': fields.Str(required=True),
    'email': fields.Str(required=True),
    'name': fields.Str()
}


def get_requested_index(request):
コード例 #13
0
ファイル: article.py プロジェクト: weiguoyu/jinjia2
# -*- coding: utf-8 -*-

from flask import (request, session, redirect, url_for, abort, render_template,
                   flash, Blueprint)

from database import (Entries)

from webargs.flaskparser import (
    FlaskParser, )

from webargs import fields
from settings import config

from async_tasks import add_log

args_parser = FlaskParser()
article_blueprint = Blueprint('article', __name__)


@article_blueprint.route('/')
def show_entries():
    entries = Entries.get(0, 0)
    return render_template('show_entries.html', entries=entries)


@article_blueprint.route('/add', methods=['POST'])
def add_entry():
    if not session.get('logged_in'):
        abort(401)
    Entries.add(title=request.form['title'], text=request.form['text'])
    add_log.delay("New entry {0} was successfully posted".\
コード例 #14
0
def parser():
    return FlaskParser()
コード例 #15
0
ファイル: base.py プロジェクト: PortSwigger/faraday_old
 def _parse_data(self, schema, request, *args, **kwargs):
     return FlaskParser().parse(schema, request, locations=('json',),
                                *args, **kwargs)
コード例 #16
0
ファイル: test_flaskparser.py プロジェクト: venuatu/webargs
from werkzeug.datastructures import ImmutableMultiDict
import pytest

from webargs import Arg, Missing
from webargs.core import ValidationError
from webargs.flaskparser import FlaskParser, use_args, use_kwargs, abort

from .compat import text_type


class TestAppConfig:
    TESTING = True
    DEBUG = True


parser = FlaskParser()

hello_args = {
    'name': Arg(text_type, default='World'),
}


@pytest.fixture
def testapp():
    app = Flask(__name__)
    app.config.from_object(TestAppConfig)

    @app.route('/handleform', methods=['post'])
    def handleform():
        """View that just returns the jsonified args."""
        args = parser.parse(hello_args, targets=('form', ))
コード例 #17
0
ファイル: arguments.py プロジェクト: cleano01/Loja_de_Aluguel
class ArgumentsMixin:
    """Extend Blueprint to add arguments parsing feature"""

    ARGUMENTS_PARSER = FlaskParser()

    def arguments(self,
                  schema,
                  *,
                  location='json',
                  content_type=None,
                  required=True,
                  description=None,
                  example=None,
                  examples=None,
                  **kwargs):
        """Decorator specifying the schema used to deserialize parameters

        :param type|Schema schema: Marshmallow ``Schema`` class or instance
            used to deserialize and validate the argument.
        :param str location: Location of the argument.
        :param str content_type: Content type of the argument.
            Should only be used in conjunction with ``json``, ``form`` or
            ``files`` location.
            The default value depends on the location and is set in
            ``Blueprint.DEFAULT_LOCATION_CONTENT_TYPE_MAPPING``.
            This is only used for documentation purpose.
        :param bool required: Whether argument is required (default: True).
        :param str description: Argument description.
        :param dict example: Parameter example.
        :param list examples: List of parameter examples.
        :param dict kwargs: Keyword arguments passed to the webargs
            :meth:`use_args <webargs.core.Parser.use_args>` decorator used
            internally.

        The `required` and `description` only affect `body` arguments
        (OpenAPI 2) or `requestBody` (OpenAPI 3), because the docs expose the
        whole schema. For other locations, the schema is turned into an array
        of parameters and the required/description value of each parameter item
        is taken from the corresponding field in the schema.

        The `example` and `examples` parameters are mutually exclusive and
        should only be used with OpenAPI 3 and when location is ``json``.

        See :doc:`Arguments <arguments>`.
        """
        # At this stage, put schema instance in doc dictionary. Il will be
        # replaced later on by $ref or json.
        parameters = {
            'in': location,
            'required': required,
            'schema': schema,
        }
        if content_type is not None:
            parameters['content_type'] = content_type
        if example is not None:
            parameters['example'] = example
        if examples is not None:
            parameters['examples'] = examples
        if description is not None:
            parameters['description'] = description

        def decorator(func):
            @wraps(func)
            def wrapper(*f_args, **f_kwargs):
                return func(*f_args, **f_kwargs)

            # Add parameter to parameters list in doc info in function object
            # The deepcopy avoids modifying the wrapped function doc
            wrapper._apidoc = deepcopy(getattr(wrapper, '_apidoc', {}))
            wrapper._apidoc.setdefault('parameters', []).append(parameters)

            # Call use_args (from webargs) to inject params in function
            return self.ARGUMENTS_PARSER.use_args(schema,
                                                  locations=[location],
                                                  **kwargs)(wrapper)

        return decorator
コード例 #18
0
import json
from datetime import datetime
from webargs import fields
from webargs.flaskparser import use_args, FlaskParser

from . import main
from .. import socketio
from .config import ferm_active_sessions_path
from .model import PicoFermSession
from .session_parser import active_ferm_sessions

arg_parser = FlaskParser()

# Register: /API/PicoFerm/isRegistered?uid={uid}&token={token}
# Response: '#{0}#' where {0} : 1 = Registered, 0 = Not Registered
ferm_registered_args = {
    'uid':
    fields.Str(required=True),  # 12 character alpha-numeric serial number
    'token': fields.Str(required=True),  # 8 character alpha-numberic number
}


@main.route('/API/PicoFerm/isRegistered')
@use_args(ferm_registered_args, location='querystring')
def process_ferm_registered(args):
    return '#1#'


# Check Firmware: /API/PicoFerm/checkFirmware?uid={UID}&version={VERSION}
#           Response: '#{0}#' where {0} : 1 = Update Available, 0 = No Updates
check_ferm_firmware_args = {
コード例 #19
0
from webargs import core
from webargs.flaskparser import FlaskParser

parser = FlaskParser(('form', 'data'))


@parser.location_handler('data')
def parse_data(request, name, field):
    return core.get_value(request.data, name, field)