APIFlask is a lightweight Python web API framework based on Flask and marshmallow-code projects

Overview

APIFlask

Build status codecov

APIFlask is a lightweight Python web API framework based on Flask and marshmallow-code projects. It's easy to use, highly customizable, ORM/ODM-agnostic, and 100% compatible with the Flask ecosystem. It starts as a fork of APIFairy and is inspired by flask-smorest and FastAPI (see Comparison and Motivations for the comparison between these projects).

With APIFlask, you will have:

  • More sugars for view function (@input(), @output(), @app.get(), @app.post() and more)
  • Automatic request validation and deserialization (with webargs)
  • Automatic response formatting and serialization (with marshmallow)
  • Automatic OpenAPI Specification (OAS, formerly Swagger Specification) document generation (with apispec)
  • Automatic interactive API documentation (with Swagger UI and Redoc)
  • API authentication support (with Flask-HTTPAuth)
  • Automatic JSON response for HTTP errors

Requirements

  • Python 3.7+
  • Flask 1.1.0+

Installation

For Linux and macOS:

$ pip3 install apiflask

For Windows:

> pip install apiflask

Links

Example

from apiflask import APIFlask, Schema, input, output, abort
from apiflask.fields import Integer, String
from apiflask.validators import Length, OneOf

app = APIFlask(__name__)

pets = [
    {'id': 0, 'name': 'Kitty', 'category': 'cat'},
    {'id': 1, 'name': 'Coco', 'category': 'dog'}
]


class PetInSchema(Schema):
    name = String(required=True, validate=Length(0, 10))
    category = String(required=True, validate=OneOf(['dog', 'cat']))


class PetOutSchema(Schema):
    id = Integer()
    name = String()
    category = String()


@app.get('/')
def say_hello():
    # returning a dict equals to use jsonify()
    return {'message': 'Hello!'}


@app.get('/pets/
    
     '
    )
@output(PetOutSchema)
def get_pet(pet_id):
    if pet_id > len(pets) - 1:
        abort(404)
    # you can also return an ORM/ODM model class instance directly
    # APIFlask will serialize the object into JSON format
    return pets[pet_id]


@app.patch('/pets/
    
     '
    )
@input(PetInSchema(partial=True))
@output(PetOutSchema)
def update_pet(pet_id, data):
    # the validated and parsed input data will
    # be injected into the view function as a dict
    if pet_id > len(pets) - 1:
        abort(404)
    for attr, value in data.items():
        pets[pet_id][attr] = value
    return pets[pet_id]
You can also use class-based views with MethodView
') class Pet(MethodView): @output(PetOutSchema) def get(self, pet_id): """Get a pet""" if pet_id > len(pets) - 1: abort(404) return pets[pet_id] @input(PetInSchema(partial=True)) @output(PetOutSchema) def patch(self, pet_id, data): """Update a pet""" if pet_id > len(pets) - 1: abort(404) for attr, value in data.items(): pets[pet_id][attr] = value return pets[pet_id] ">
from apiflask import APIFlask, Schema, input, output, abort
from apiflask.fields import Integer, String
from apiflask.validators import Length, OneOf
from flask.views import MethodView

app = APIFlask(__name__)

pets = [
    {'id': 0, 'name': 'Kitty', 'category': 'cat'},
    {'id': 1, 'name': 'Coco', 'category': 'dog'}
]


class PetInSchema(Schema):
    name = String(required=True, validate=Length(0, 10))
    category = String(required=True, validate=OneOf(['dog', 'cat']))


class PetOutSchema(Schema):
    id = Integer()
    name = String()
    category = String()


# use the "route" decorator to decorate the view class
@app.route('/')
class Hello(MethodView):

    # use HTTP method name as class method name
    def get(self):
        return {'message': 'Hello!'}


@app.route('/pets/
      
       '
      )
class Pet(MethodView):

    @output(PetOutSchema)
    def get(self, pet_id):
        """Get a pet"""
        if pet_id > len(pets) - 1:
            abort(404)
        return pets[pet_id]

    @input(PetInSchema(partial=True))
    @output(PetOutSchema)
    def patch(self, pet_id, data):
        """Update a pet"""
        if pet_id > len(pets) - 1:
            abort(404)
        for attr, value in data.items():
            pets[pet_id][attr] = value
        return pets[pet_id]
Or use async def with Flask 2.0
$ pip install -U flask[async]
import asyncio

from apiflask import APIFlask

app = APIFlask(__name__)


@app.get('/')
async def say_hello():
    await asyncio.sleep(1)
    return {'message': 'Hello!'}

See Using async and await for the details of the async support in Flask 2.0.

Save this as app.py, then run it with :

$ flask run --reload

Now visit the interactive API documentation (Swagger UI) at http://localhost:5000/docs:

Or you can visit the alternative API documentation (Redoc) at http://localhost:5000/redoc:

The auto-generated OpenAPI spec file is available at http://localhost:5000/openapi.json. You can also get the spec with the flask spec command:

$ flask spec

For some complete examples, see /examples.

Relationship with Flask

APIFlask is a thin wrapper on top of Flask. You only need to remember four differences (see Migrating from Flask for more details):

  • When creating an application instance, use APIFlask instead of Flask.
  • When creating a blueprint instance, use APIBlueprint instead of Blueprint.
  • The abort() function from APIFlask (apiflask.abort) returns JSON error response.
  • The view class should be registered with the route decorator.

For a minimal Flask application:

from flask import Flask, request, escape

app = Flask(__name__)

@app.route('/')
def hello():
    name = request.args.get('name', 'Human')
    return f'Hello, {escape(name)}'

Now change to APIFlask:

from apiflask import APIFlask  # step one
from flask import request, escape

app = APIFlask(__name__)  # step two

@app.route('/')
def hello():
    name = request.args.get('name', 'Human')
    return f'Hello, {escape(name)}'

In a word, to make Web API development in Flask more easily, APIFlask provides APIFlask and APIBlueprint to extend Flask's Flask and Blueprint objects and it also ships with some helpful utilities. Other than that, you are actually using Flask.

Relationship with marshmallow

APIFlask accepts marshmallow schema as data schema, uses webargs to validate the request data against the schema, and uses apispec to generate the OpenAPI representation from the schema.

You can build marshmallow schemas just like before, but APIFlask also exposes some marshmallow APIs for convenience (it's optional, you can still import everything from marshamallow directly):

  • apiflask.Schema: The base marshmallow schema class.
  • apiflask.fields: The marshmallow fields, contain the fields from both marshmallow and Flask-Marshmallow. Beware that the aliases (Url, Str, Int, Bool, etc.) were removed (vote in marshmallow #1828 to remove these aliases from marshmallow).
  • apiflask.validators: The marshmallow validators (vote in marshmallow #1829 for better names for validate-related APIs in marshmallow).
from apiflask import Schema
from apiflask.fields import Integer, String
from apiflask.validators import Length, OneOf
from marshmallow import pre_load, post_dump, ValidationError
Comments
  • Add example for using dataclasses with marshmallow-dataclass

    Add example for using dataclasses with marshmallow-dataclass

    • fixes #242

    Checklist:

    • [x] Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
    • [x] Add or update relevant docs, in the docs folder and in code docstring.
    • [ ] Add an entry in CHANGES.md summarizing the change and linking to the issue and your username.
    • [ ] Add *Version changed* or *Version added* note in any relevant docs and docstring.
    • [x] Run pytest and tox, no tests failed.
    opened by mmdbalkhi 10
  • explicitly check if view_func.view_class is MethodViewType in add_url_rule

    explicitly check if view_func.view_class is MethodViewType in add_url_rule

    • fixes #379

    Checklist:

    • [X] Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
    • [ ] Add or update relevant docs, in the docs folder and in code docstring.
    • [X] Add an entry in CHANGES.md summarizing the change and linking to the issue and your username.
    • [ ] Add *Version changed* or *Version added* note in any relevant docs and docstring.
    • [X] Run pytest and tox, no tests failed.
    opened by rod7760 6
  • Simplify the async-related tests

    Simplify the async-related tests

    Implemented a fixture for the "skip async test" function since all test in that file will requires Flask > 2.0 suggested by jonasps and greyli apiflask/tests/test_async.py Before

    def skip_flask1(app):
        if not hasattr(app, 'ensure_sync'):
            pytest.skip('This test requires Flask 2.0 or higher')
    

    After

    @pytest.fixture(autouse=True)
    def skip_async_test(app):
        if not hasattr(app, 'ensure_sync'):
            pytest.skip('This test requires Flask 2.0 or higher')
    

    To improve it

    • fixes #318

    Checklist:

    • [x] Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
    • [ ] Add or update relevant docs, in the docs folder and in code docstring.
    • [ ] Add an entry in CHANGES.md summarizing the change and linking to the issue and your username.
    • [ ] Add *Version changed* or *Version added* note in any relevant docs and docstring.
    • [ ] Run pytest and tox, no tests failed.
    opened by glunkad 6
  • Consider moving APIFlask back to an extension

    Consider moving APIFlask back to an extension

    See this discussion where Grey says:

    Glad to see this finally merged! After I proposed this idea and was declined in the first pallets meeting, I started to make the REST API extension I'm developing to become a framework so that I can inherit the Flask class and add these route shortcuts, now I may consider making it back to an extension...

    Motivation

    So that we can healthily mix different extensions and not make APIFlask our main point of entry.

    improvement 
    opened by Abdur-rahmaanJ 6
  • RFC: Import and rename decorators from Marshmallow

    RFC: Import and rename decorators from Marshmallow

    I have some doubt about these changes, so I keep it as a undocumentated features so far. Basically, I change the name of the following decorators from Marshamallow:

    • validates -> validate
    • validates_schema -> validate_schema
    • ~~pre_load -> before_load~~
    • ~~post_load -> after_load~~
    • ~~pre_dump -> before_dump~~
    • ~~post_dump -> after_dump~~

    Some ideas behind these changes:

    • validate and validate_schema are short and clear than validates and validates_schema. It also matches the validate keyword in field classes.
    • ~~The change from pre_ to before_ and from post_ to after_ was trying to follow the name convention in Flask (before_request, etc.).~~

    IMO, the new names are easier to understand and intuitive. However, this will definitely introduce "breaking" changes between APIFlask and Marshmallow. I can add a warning in the docs to inform users that they can continue to import everything from marshmallow, but notice the name changes if they want to import from APIFlask.

    Is it a good or bad idea? Feel free to leave any thoughts.

    request for comment 
    opened by greyli 5
  • Using class-based views with Flask 2.2 causes TypeError: view() takes 0 positional arguments but 1 was given

    Using class-based views with Flask 2.2 causes TypeError: view() takes 0 positional arguments but 1 was given

    Error when using class-based views for compliance documentation

    from flask.views import MethodView
    from apiflask import APIFlask
    
    app = APIFlask(__name__)
    
    
    @app.route('/pets/<int:pet_id>', endpoint='pet')
    class Pet(MethodView):
    
        def get(self, pet_id):
            return {'message': 'OK'}
    
        def delete(self, pet_id):
            return '', 204
    
    app.run(debug=True)
    

    Environment:

    • Python version: 3.10
    • Flask version: 2.2.2
    • APIFlask version: 1.1.2
    bug help wanted 
    opened by NimaQu 4
  • Add support of separate schema per status code

    Add support of separate schema per status code

    Now apiflask supports multiple @app.output decorators

    • fixes #327

        @app.route("/lessons", methods=['GET'])
        @app.input(LessonsRequestSchema, location="querystring")
        @app.output(LessonSchema, 201, description="Single lesson")
        @app.output(LessonsResponseSchema, 244, description="list of lessons")
        def lessons(query):
            #implementation goes here
            pass
      
    opened by victorcrimea 4
  • YAML generation return incorrect tags definition

    YAML generation return incorrect tags definition

    When I generate the specs without specifying any tags the output yaml format get inconsistent. In particular, in many case is correct:

          tags:
          - Supercon
    

    with Supercon as the name of the application

    However, for certain cases (see the whole method):

    @bp.route('/record/<id>/flag', methods=['PUT', 'PATCH'])
    @output(Flag)
    def flag_record(id):
        object_id = validateObjectId(id)
        connection = connect_mongo(config=config)
        db_name = config['mongo']['db']
        db = connection[db_name]
        tabular_collection = db.get_collection("tabular")
        record = tabular_collection.find_one({"_id": object_id})
        if record is None:
            return 404
        else:
            new_status = 'invalid'
            new_type = 'manual'
    
            changes = {'status': new_status, 'type': new_type}
    
            tabular_collection.update_one({'_id': record['_id']}, {'$set': changes})
            return changes, 200
    

    the array is invalidated:

      /supercon/record/{id}/flag:
        patch:
          parameters:
          - &id001
            in: path
            name: id
            required: true
            schema:
              type: string
          responses:
            '200':
              content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/Flag'
              description: Successful response
            '404':
              content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/HTTPError'
              description: Not found
          summary: Flag Record
          tags: &id002
          - Supercon
        put:
          parameters:
          - *id001
          responses:
            '200':
              content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/Flag'
              description: Successful response
            '404':
              content:
                application/json:
                  schema:
                    $ref: '#/components/schemas/HTTPError'
              description: Not found
          summary: Flag Record
          tags: *id002
    

    if I define the app.tags("supercon") the problem disappears..

    Environment:

    • Python version: 3.8.12
    • Flask version: 2.0.2
    • APIFlask version: 0.11.0
    bug need more info 
    opened by lfoppiano 4
  • BASE_RESPONSE_SCHEMA not use in APIBlueprint

    BASE_RESPONSE_SCHEMA not use in APIBlueprint

    the BASE_RESPONSE_SCHEMA not use in APIBlueprint

    class BaseResponseSchema(Schema):
        message = String()
        status_code = Integer()
        data = Field()  # the data key
    
    app.config['BASE_RESPONSE_SCHEMA'] = BaseResponseSchema
    app.config['BASE_RESPONSE_DATA_KEY '] = 'data'
    

    just return the data, like this

    {
        "data": {
            "category": "dog",
            "id": 3,
            "name": "admin13"
        }
    }
    
    

    I can’t determine whether it’s a bug or a problem with my settings

    need more info 
    opened by zhibeen 4
  • Spec output is non-deterministic

    Spec output is non-deterministic

    Running flask spec --output openapi.yaml repeatedly results in output files with diffs when working on a large project. This is problematic when consuming the output file to generate an HTTP client.

    Environment:

    • Python version: 3.9.13
    • Flask version: 2.0.3
    • APIFlask version: 1.1.3
    bug 
    opened by crmilsap 3
  • fix a compat bug with some flask extension

    fix a compat bug with some flask extension

    • fixes #344

    Checklist:

    • [ ] Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
    • [x] Add or update relevant docs, in the docs folder and in code docstring.
    • [ ] Add an entry in CHANGES.md summarizing the change and linking to the issue and your username.
    • [ ] Add *Version changed* or *Version added* note in any relevant docs and docstring.
    • [x] Run pytest and tox, no tests failed.
    opened by hjlarry 3
  • Cannot return non-dictlike object from handler if BASE_RESPONSE_SCHEMA is set

    Cannot return non-dictlike object from handler if BASE_RESPONSE_SCHEMA is set

    If BASE_RESPONSE_SCHEMA is set and a non-dict like object is returned from a route, an exception TypeError: argument of type '<type of object>' is not iterable is thrown from scaffold.py when checking if data_key not in obj (the in keyword doesn't work on all objects).

    Environment:

    • Python version:
    • Flask version:
    • APIFlask version:
    bug 
    opened by lorenyu 2
  • Cannot provide requestInterceptor option in SWAGGER_UI_CONFIG

    Cannot provide requestInterceptor option in SWAGGER_UI_CONFIG

    I tried to provide the "requestInterceptor" option to Swagger UI via SWAGGER_UI_CONFIG, but it did not work. The basic problem seems to be that apiflask assumes that all such options should be strings, but this is not the case for this option. If only some of the options are supported, this should be documented.

    To reproduce, take your own example program and add the lines

    app.config['SWAGGER_UI_CONFIG'] = {
       'requestInterceptor': "(req) => { console.log('intercepted!'); return req; }"
    }
    

    Navigate to the docs page and it fails with the error "r.requestInterceptor is not a function /openapi.json" But there does not seem to be any way to make it into a function in my Python code. I have done something similar in C# with Swashbuckle, where it works fine to provide it as a string in this way.

    In ui_templates.py in apiflask are the lines

    var userConfig = {{ config.SWAGGER_UI_CONFIG | tojson }}
       for (var attr in userConfig) {
         baseConfig[attr] = userConfig[attr]
       }
    

    which seems to just assume that all options are meant to be strings. If I change this to eval(userConfig[attr]) then it works (but would then not work for options that are meant to be strings rather than javascript code, so some kind of conditional logic would be needed. )

    Environment:

    • Python 3.10.6
    • Flask version 2.1.3
    • APIFlask version: 1.1.3
    bug help wanted 
    opened by gjb1002 0
  • Redirect the request of openapi.json when using nginx

    Redirect the request of openapi.json when using nginx

    Code

    from apiflask import APIFlask
    
    app = APIFlask(__name__)
    
    
    @app.get('/')
    def ping():
        return 'pong\n'
    
    
    if __name__ == '__main__':
        app.run()
    

    nginx.conf

    http {
        server {
            listen       80;
            server_name  localhost;
    
            location ^~ /project/v1/ {
                proxy_pass http://127.0.0.1:5000/;
            }
        }
    }
    

    Correct:http://127.0.0.1/project/v1/

    Error:http://127.0.0.1/project/v1/docs

    image

    help wanted feature 
    opened by vba34520 2
  • ImportError: module 'apiflask' has no attribute 'settings'

    ImportError: module 'apiflask' has no attribute 'settings'

    pyinstaller

    Traceback (most recent call last): File "werkzeug\utils.py", line 556, in import_string AttributeError: module 'apiflask' has no attribute 'settings'

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last): File "werkzeug\utils.py", line 558, in import_string ImportError: module 'apiflask' has no attribute 'settings'

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last): File "manage.py", line 22, in File "apiflask\app.py", line 338, in init File "flask\config.py", line 174, in from_object File "werkzeug\utils.py", line 563, in import_string File "werkzeug_compat.py", line 147, in reraise File "werkzeug\utils.py", line 558, in import_string werkzeug.utils.ImportStringError: import_string() failed for 'apiflask.settings'. Possible reasons are:

    • missing init.py in a package;
    • package or module path not included in sys.path;
    • duplicated package or module name taking precedence in sys.path;
    • missing module, class, function or variable;

    Debugged import:

    • 'apiflask' found in 'C:\Users\ADMINI~1\AppData\Local\Temp\_MEI324362\apiflask\init.pyc'.
    • 'apiflask.settings' not found.

    Original exception:

    ImportError: module 'apiflask' has no attribute 'settings' [24324] Failed to execute script manage Environment:

    • Python version:3.7.4
    • Flask version:1.1.1
    • APIFlask version:1.1.3
    bug need more info 
    opened by chongjing001 1
  • Allow iteration of input list

    Allow iteration of input list

    Reading the docs I can't tell if this is currently supported; so apologies if this can already be accomplished.

    It would be great if this lib supported iterating over a list of inputs. A single querystring key can have multiple values (if its specified more than once in the URL: e.g. http://localhost/api/myendpoint?ids[]=id_1&ids[]=id_2). But there doesn't seem to be a way to access the individual values of the input list within the API method.

    class DeleteQuery(Schema):
        ids = List(String(required=True, data_key='ids[]'))
    
    @app.input(DeleteQuery, location='query')
    @app.output({}, status_code=204)
    def delete(self, query: DeleteQuery):
    
        for id in query.ids: #ERROR -> List is not iterable  __iter__ method not defined",
            db.delete(id)
    
        return "", 204
    
    feature 
    opened by ryder-gillen-ltk 0
  • different documentation instances based on blueprints

    different documentation instances based on blueprints

    My application employs multiple blueprints which i would like to generate separate documentation for. I don't want the customers to see the endpoints i use in the internal frontend.

    Currently i use workaround with DispatcherMiddleware so i can have multiple app instances, instead of using blueprints. That solution is really cumbersome and creates other issues with debugging, readability, extensions and so on. It would be nice to have option to have multiple endpoints based on Blueprints.

    improvement 
    opened by AdamVerner 0
Releases(1.2.0)
  • 1.2.0(Jan 8, 2023)

    Breaking changes

    • Add apiflask.views.MethodView to replace flask.views.MethodView, raise error if using flask.views.MethodView (#341)
    from apiflask.views import MethodView
    
    • Change the status code of request validation error from 400 to 422 in OpenAPI docs (#345). Thanks @hjlarry

    You can control this with the config key VALIDATION_ERROR_STATUS_CODE:

    app.config['VALIDATION_ERROR_STATUS_CODE'] = 422
    

    Bugfixes and enhancements

    • Add Enum field from marshmallow 3.18.
    • Fix OpenAPI spec generating for path parameters when path schema is provided (#350). Thanks @ndawn
    • Add spec_plugins param to APIFlask class to support using custom apispec plugins (#349). Thanks @ndawn
    • Improve the default bypassing rules to support bypass blueprint's static endpoint and Flask-DebugToolbar (#344, #369).
    • Explicitly check if view_func.view_class is MethodViewType in add_url_rule (#379). Thanks @rod7760
    • The schema fields are now in order by default, which ensures the output of flask spec is deterministic (#373).

    Translation

    Thanks @mmdbalkhi for working on the Persian translation of APIFlask docs.

    Source code(tar.gz)
    Source code(zip)
  • 1.1.3(Sep 4, 2022)

    One more bugfix release.

    • Fix some tests and import statements for Flask 2.2 (#343). Thanks @hjlarry
    • Pin Flask < 2.2 as a temp fix for the breaking changes of class-based view support (#341).

    We still need to make a real fix for #341, any help will be appreciated.

    Source code(tar.gz)
    Source code(zip)
  • 1.1.2(Aug 13, 2022)

  • 1.1.1(Aug 3, 2022)

    A bugfix release for Flask 2.2.

    • Improve CI setup and test again Python 3.10 and 3.11 (#331).
    • Fix the typing of APIFlask path parameters (#329). Thanks @jeamland
    • Update MethodViewType usages for Flask 2.2 (#335). Thanks @z-t-y
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Jul 3, 2022)

    A new feature release!

    • Support more API docs: RapiDoc, Elements, and RapiPDF. Now the docs UI is controlled by the docs_ui parameter (#308):
    from apiflask import APIFlask
    
    # available docs_ui values: swagger-ui, redoc, elements, rapidoc, rapipdf
    app = APIFlask(__name__, docs_ui='elements')
    
    • The API docs will be available at /docs by default, and the /redoc path and the redoc_path parameter were deprecated and will be removed in 2.0.
    • Allow the view function to return list as JSON (#322):
    @app.route('/')
    def index():
        return ['this', 'will', 'become', 'JSON']
    

    P.S. This feature will also be available in Flask 2.2.

    See the full changelog for more details: https://apiflask.com/changelog/#version-110

    Source code(tar.gz)
    Source code(zip)
  • 1.0.2(May 21, 2022)

    Another bugfix release.

    • Combine custom security schemes (app.security_schemes) with existing values (issue #293).
    • Add the missing path (view_args) to the valid request location list (issue #301)
    • Fix the security scheme values to lowercase.
    Source code(tar.gz)
    Source code(zip)
  • 1.0.1(May 17, 2022)

  • 1.0.0(May 4, 2022)

    APIFlask 1.0 is finally released! 🎉

    • The changelog: https://apiflask.com/changelog/#version-100
    • The milestone: https://github.com/greyli/apiflask/milestone/3
    • Check out the complete documentation: https://apiflask.com/docs/

    Retweet the announcement on Twitter to tell your friends this news:

    https://twitter.com/apiflask/status/1521869484746702849

    Thanks for all your support!

    Source code(tar.gz)
    Source code(zip)
  • 0.12.0(Mar 2, 2022)

    This version brings a breaking change:

    The four standalone API decorators (i.e. input, output, doc, and auth_required) were moved to APIFlask and APIBlueprint classes. Now access them with your application or blueprint instance:

    from apiflask import APIFlask
    
    app = APIFlask(__name__)
    
    @app.get('/')
    @app.input(FooSchema)  # <-
    @app.output(BarSchema)  # <-
    def hello():
        return {'message': 'Hello'}
    

    This makes it possible to access app instance in these decorators so we can support changing corresponding behaviors based on application attributes or configuration variables.

    The old standalone decorators were deprecated since 0.12, and will be removed in the 1.0 version. Notice all the usage in the docs/examples are updated, you may want to upgrade APIFlask to update the usage in your app.

    The next version will be 1.0.0. Stay tuned!

    Source code(tar.gz)
    Source code(zip)
  • 0.11.0(Dec 6, 2021)

    This version improves the error handling system, you can now write custom error classes based on HTTPError:

    from apiflask import HTTPError
    
    class PetNotFound(HTTPError):
        status_code = 404
        message = 'This pet is missing.'
        extra_data = {
            'error_code': '2323',
            'error_docs': 'https://example.com/docs/missing'
        }
    
    
    @app.get('/pets/<pet_id>')
    def get_pet(pet_id):
        pets = [1, 2, 3]
        if pet_id not in pets:
            raise PetNotFound
        return {'message': 'Pet'}
    

    See more details in the newly added docs for error handling.

    Source code(tar.gz)
    Source code(zip)
  • 0.10.1(Nov 26, 2021)

  • 0.10.0(Sep 19, 2021)

    Features:

    • Add parameter extra_data to abort and HTTPError, it accepts a dict that will be added to the error response (#125).
    from apiflask import abort
    
    @app.get('/')
    def missing():
        abort(404, message='nothing', extra_data={'code': '123', 'status': 'not_found'})
    
    • Support passing operation_id in the doc decorator (docs).
    @app.get('/')
    @doc(operation_id='myCustomHello')
    def hello():
        pass
    
    • Support setting response links via @output(links=...) (docs).
    pet_links = {
        'getAddressByUserId': {
            'operationId': 'getUserAddress',
            'parameters': {
                'userId': '$request.path.id'
            }
        }
    }
    
    @app.post('/pets')
    @output(PetOutSchem, links=pet_links)
    def new_pet(data):
        pass
    
    • Support using add_url_rule method on view classes.

    Undocumented breaking changes:

    • Only expose marshmallow fields, validators, and Schema in APIFlask.
    • Remove the status_code field from the default error response (#124).
    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Aug 10, 2021)

    Breaking change:

    • Custom error processor now should accept an HTTPError object instead of individual error information:
    @app.error_processor
    def my_error_processor(error):
        return {
            'status_code': error.status_code,
            'message': error.message,
            'errors': error.detail
        }, error.status_code, error.headers
    
    

    Features:

    • Support base response schema customization (docs). See a full example at here.
    • Support setting custom schema name resolver via the APIFlask.schema_name_resolver attribute (docs).
    • Support to config Redoc via the configuration variable REDOC_CONFIG:
    app.config['REDOC_CONFIG'] = {'disableSearch': True, 'hideLoading': True}
    

    There are also some improvements on error handling, see the full changelog for more details: https://apiflask.com/changelog/#version-090

    Source code(tar.gz)
    Source code(zip)
  • 0.8.0(Jul 7, 2021)

    This is the first stable version. From this version, all breaking changes will start with a deprecated warning.

    Some major changes in this version:

    • Automatically add a 404 response in OpenAPI spec for routes contains URL variables:
    @app.get('/pets/<id>')
    def get_pet(id):
        pass
    

    So user don't need to set a 404 response manually:

    @app.get('/pets/<id>')
    @doc(responses=[404])
    def get_pet(id):
        pass
    
    • The app.spec property now will always return the latest spec instead of the cached one (docs):
    >>> from apiflask import APIFlask
    >>> app = APIFlask(__name__)
    >>> app.spec
    {'info': {'title': 'APIFlask', 'version': '0.1.0'}, 'tags': [], 'paths': OrderedDict(), 'openapi': '3.0.3'}
    >>> @app.get('/')
    ... def hello():
    ...     return {'message': 'Hello'}
    ...
    >>> app.spec
    {'info': {'title': 'APIFlask', 'version': '0.1.0'}, 'tags': [], 'paths': OrderedDict([('/', {'get': {'parameters': [], 'responses': OrderedDict([('200', {'content': {'application/json': {'schema': {}}}, 'description': 'Successful response'})]), 'summary': 'Hello'}})]), 'openapi': '3.0.3'}
    >>>
    
    • Add configration variable INFO (and app.info attribute), it can be used to set the following info fields: description, termsOfService, contact, license (docs):
    app.info = {
        'description': '...',
        'termsOfService': 'http://example.com',
        'contact': {
            'name': 'API Support',
            'url': 'http://www.example.com/support',
            'email': '[email protected]'
        },
        'license': {
            'name': 'Apache 2.0',
            'url': 'http://www.apache.org/licenses/LICENSE-2.0.html'
        }
    }
    
    
    • Rename the following configuration variables:
      • AUTO_PATH_SUMMARY -> AUTO_OPERATION_SUMMARY
      • AUTO_PATH_DESCRIPTION -> AUTO_OPERATION_DESCRIPTION

    See details in the changelog: https://github.com/greyli/apiflask/blob/main/CHANGES.md#version-080

    Source code(tar.gz)
    Source code(zip)
  • 0.7.0(Jun 24, 2021)

    Some major changes in this version:

    • Add a flask spec command to output the OpenAPI spec to stdout or a file (docs).
    • Support keeping the local spec in sync automatically (docs).
    • Re-add the SPEC_FORMAT config. Remove the auto-detection of the format from APIFlask(spec_path=...) (docs).
    • Fix auto-tag support for nesting blueprint.
    • Add a new docs chapter for OpenAPI generating: https://apiflask.com/openapi/

    See more in the changelog: https://github.com/greyli/apiflask/blob/main/CHANGES.md#version-070

    Source code(tar.gz)
    Source code(zip)
  • 0.6.3(May 17, 2021)

  • 0.6.2(May 16, 2021)

  • 0.6.1(May 15, 2021)

    A bugfix release for Flask 2.0:

    • Fix various type annotation issues.
    • Fix async support.

    See the changelog for the details:

    https://github.com/greyli/apiflask/blob/master/CHANGES.md#version-061

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0(May 11, 2021)

  • 0.5.2(Apr 29, 2021)

    A bugfix release.

    • Allow returning a Response object in a view function decorated with output decorator. In this case, APIFlask will do nothing but return it directly.
    • Skip Flask's Blueprint objects when generating the OpenAPI spec
    Source code(tar.gz)
    Source code(zip)
  • 0.5.1(Apr 28, 2021)

    A bugfix release.

    • Add a temp fix for https://github.com/pallets/flask/issues/3981.
    • Change the default endpoint of the view class to the original class name.
    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Apr 27, 2021)

    The core feature added in this version is class-based views support. Check out the example application or documentation for more details.

    This version also introduces some breaking changes:

    • Remove the configuration variable DOCS_HIDE_BLUEPRINTS, add APIBlueprint.enable_openapi as a replacement.
    • Remove the support to generate info.description and tag description from the module docstring, and also remove the AUTO_DESCRIPTION config.
    • No longer support mix the use of flask.Bluerpint and apiflask.APIBluerpint.

    See the changelog for more details.

    0.5.0 Changelog: https://github.com/greyli/apiflask/blob/master/CHANGES.md#version-050

    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Apr 20, 2021)

    This version introduces some breaking changes:

    • Rename abort_json() to abort().
    • Some undocumented configuration variables were deleted.

    There are also some bug fixes and new features. Check out the changelog for the details.

    0.4.0 Changelog: https://github.com/greyli/apiflask/blob/master/CHANGES.md#version-040

    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Mar 31, 2021)

    This is the first public version.

    This version has some API change, public API changes including:

    • Rename function api_abort() to abort_json().
    • Change decorator attribute @doc(tags) to @doc(tag).

    Besides, this version has basic type annotations for the package, the tests will be updated in the next version.

    Check out the changelog for the details.

    0.3.0 Changelog: https://github.com/greyli/apiflask/blob/master/CHANGES.md#version-030

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Mar 27, 2021)

    From version 0.2.0, this project became a framework instead of a Flask extension. It provided two classes to replace the one in Flask:

    • flask.Flask -> apiflask.APIFlask
    • flask.Blueprint -> apiflask.APIBlueprint

    This version also added some more useful features, a bunch of configuration variables, and changed almost all the APIs. Check out the changelog for the details.

    Changelog: https://github.com/greyli/apiflask/blob/master/CHANGES.md#version-020

    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Jan 27, 2021)

    Based on APIFairy 0.6.3dev, version 0.1.0 added some useful features, check out the changelog for the details.

    • Changelog: https://github.com/greyli/apiflask/blob/master/CHANGES.md#version-010
    Source code(tar.gz)
    Source code(zip)
Owner
Grey Li
Web developer, member of @pallets, creator of @helloflask.
Grey Li
CherryPy is a pythonic, object-oriented HTTP framework. https://docs.cherrypy.org/

Welcome to the GitHub repository of CherryPy! CherryPy is a pythonic, object-oriented HTTP framework. It allows building web applications in much the

CherryPy 1.6k Dec 29, 2022
An easy-to-use high-performance asynchronous web framework.

An easy-to-use high-performance asynchronous web framework.

Aber 264 Dec 31, 2022
The core of a service layer that integrates with the Pyramid Web Framework.

pyramid_services The core of a service layer that integrates with the Pyramid Web Framework. pyramid_services defines a pattern and helper methods for

Michael Merickel 78 Apr 15, 2022
cirrina is an opinionated asynchronous web framework based on aiohttp

cirrina cirrina is an opinionated asynchronous web framework based on aiohttp. Features: HTTP Server Websocket Server JSON RPC Server Shared sessions

André Roth 32 Mar 05, 2022
A minimal, extensible, fast and productive API framework for Python 3.

molten A minimal, extensible, fast and productive API framework for Python 3. Changelog: https://moltenframework.com/changelog.html Community: https:/

Bogdan Popa 980 Nov 28, 2022
Web framework based on type hint。

Hint API 中文 | English 基于 Type hint 的 Web 框架 hintapi 文档 hintapi 实现了 WSGI 接口,并使用 Radix Tree 进行路由查找。是最快的 Python web 框架之一。一切特性都服务于快速开发高性能的 Web 服务。 大量正确的类型

Aber 19 Dec 02, 2022
Asynchronous HTTP client/server framework for asyncio and Python

Async http client/server framework Key Features Supports both client and server side of HTTP protocol. Supports both client and server Web-Sockets out

aio-libs 13.2k Jan 05, 2023
A simple todo app using flask and sqlachemy

TODO app This is a simple TODO app made using Flask. Packages used: DoodleCSS Special thanks to Chris McCormick (@mccrmx) :) Flask Flask-SQLAlchemy Fl

Lenin 1 Dec 26, 2021
Library for building WebSocket servers and clients in Python

What is websockets? websockets is a library for building WebSocket servers and clients in Python with a focus on correctness and simplicity. Built on

Aymeric Augustin 4.3k Dec 31, 2022
Fast⚡, simple and light💡weight ASGI micro🔬 web🌏-framework for Python🐍.

NanoASGI Asynchronous Python Web Framework NanoASGI is a fast ⚡ , simple and light 💡 weight ASGI micro 🔬 web 🌏 -framework for Python 🐍 . It is dis

Kavindu Santhusa 8 Jun 16, 2022
Microservice example with Python, Faust-Streaming and Kafka (Redpanda)

Microservices Orchestration with Python, Faust-Streaming and Kafka (Redpanda) Example project for PythonBenin meetup. It demonstrates how to use Faust

Lé 3 Jun 13, 2022
Web-frameworks-benchmark

Web-frameworks-benchmark

Nickolay Samedov 4 May 13, 2021
Phoenix LiveView but for Django

Reactor, a LiveView library for Django Reactor enables you to do something similar to Phoenix framework LiveView using Django Channels. What's in the

Eddy Ernesto del Valle Pino 526 Jan 02, 2023
Free & open source Rest API for YTDislike

RestAPI Free & open source Rest API for YTDislike, read docs.ytdislike.com for implementing. Todo Add websockets Installation Git clone git clone http

1 Nov 25, 2021
Pyrin is an application framework built on top of Flask micro-framework to make life easier for developers who want to develop an enterprise application using Flask

Pyrin A rich, fast, performant and easy to use application framework to build apps using Flask on top of it. Pyrin is an application framework built o

Mohamad Nobakht 10 Jan 25, 2022
A beginners course for Django

The Definitive Django Learning Platform. Getting started with Django This is the code from the course "Getting Started With Django", found on YouTube

JustDjango 288 Jan 08, 2023
Persistent remote applications for X11; screen sharing for X11, MacOS and MSWindows.

Table of Contents About Installation Usage Help About Xpra is known as "screen for X" : its seamless mode allows you to run X11 programs, usually on a

xpra.org 785 Dec 30, 2022
Dazzler is a Python async UI/Web framework built with aiohttp and react.

Dazzler is a Python async UI/Web framework built with aiohttp and react. Create dazzling fast pages with a layout of Python components and bindings to update from the backend.

Philippe Duval 17 Oct 18, 2022
Web3.py plugin for using Flashbots' bundle APIs

This library works by injecting a new module in the Web3.py instance, which allows submitting "bundles" of transactions directly to miners. This is done by also creating a middleware which captures c

Georgios Konstantopoulos 294 Jan 04, 2023
A micro web-framework using asyncio coroutines and chained middleware.

Growler master ' dev Growler is a web framework built atop asyncio, the asynchronous library described in PEP 3156 and added to the standard library i

687 Nov 27, 2022