diff --git a/examples/petstore_blueprint.py b/examples/petstore_blueprint.py new file mode 100644 index 0000000..f29c71e --- /dev/null +++ b/examples/petstore_blueprint.py @@ -0,0 +1,55 @@ +import logging + +import flask.views +import marshmallow as ma + +from flask_apispec import FlaskApiSpec, MethodResource +from flask_apispec import doc, marshal_with, use_kwargs +from flask_apispec.blueprint import Blueprint + +app = flask.Flask(__name__) +docs = FlaskApiSpec(app) + +blueprint = Blueprint(docs, name='pet', import_name=__name__) + +logging.basicConfig(level=logging.DEBUG) + + +class Pet: + def __init__(self, name, type): + self.name = name + self.type = type + + +class PetSchema(ma.Schema): + name = ma.fields.Str() + type = ma.fields.Str() + + +@blueprint.route('/pets/') +@doc(params={'pet_id': {'description': 'pet id'}}) +@marshal_with(PetSchema) +@use_kwargs({'breed': ma.fields.Str()}, location='query') +def get_pet(pet_id,breed): + return Pet('calici', 'cat') + + +@blueprint.route('/cat/') +@doc( + tags=['pets'], + params={'pet_id': {'description': 'the pet name'}}, +) +class CatResource(MethodResource): + + @marshal_with(PetSchema) + def get(self, pet_id): + return Pet('calici', 'cat') + + @marshal_with(PetSchema) + def put(self, pet_id): + return Pet('calici', 'cat') + + +if __name__ == '__main__': + app.register_blueprint(blueprint) + app.run(debug=True) diff --git a/flask_apispec/annotations.py b/flask_apispec/annotations.py index 9812267..8120c52 100644 --- a/flask_apispec/annotations.py +++ b/flask_apispec/annotations.py @@ -37,7 +37,6 @@ def wrapper(func): return activate(func) return wrapper - def marshal_with(schema, code='default', description='', inherit=None, apply=None): """Marshal the return value of the decorated view function using the specified schema. diff --git a/flask_apispec/blueprint.py b/flask_apispec/blueprint.py new file mode 100644 index 0000000..5740d69 --- /dev/null +++ b/flask_apispec/blueprint.py @@ -0,0 +1,30 @@ +from flask import Blueprint as FlaskBlueprint +from flask.blueprints import BlueprintSetupState +from flask_apispec import MethodResource, FlaskApiSpec +import logging +import inspect + +log = logging.getLogger(__name__) + + +class DocsBlueprintSetupState(BlueprintSetupState): + + def add_url_rule(self, rule, endpoint=None, view_func=None, **options): + log.debug('add url rule:%s' % rule) + doc_view_func = view_func + if inspect.isclass(view_func) and issubclass(view_func, MethodResource): + view_func = view_func.as_view(endpoint or view_func.__name__) + super().add_url_rule(rule, endpoint, view_func, **options) + docs = self.blueprint.docs + log.debug('register %s' % doc_view_func.__name__) + docs.register(doc_view_func, endpoint=endpoint, blueprint=self.blueprint.name) + + +class Blueprint(FlaskBlueprint): + + def __init__(self, docs: FlaskApiSpec, name: str, import_name: str, **kwargs): + super().__init__(name, import_name, **kwargs) + self.docs = docs + + def make_setup_state(self, app, options, first_registration=False): + return DocsBlueprintSetupState(self, app, options, first_registration) \ No newline at end of file