Skip to main content

A lightweight web API framework based on Flask and marshmallow-code projects.

Project description

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.

With APIFlask, you will have:

  • More sugars for view function (@app.input(), @app.output(), @app.get(), @app.post() and more)
  • Automatic request validation and deserialization
  • Automatic response formatting and serialization
  • Automatic OpenAPI Specification (OAS, formerly Swagger Specification) document generation
  • Automatic interactive API documentation
  • 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, 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 PetIn(Schema):
    name = String(required=True, validate=Length(0, 10))
    category = String(required=True, validate=OneOf(['dog', 'cat']))


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


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


@app.get('/pets/<int:pet_id>')
@app.output(PetOut)
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/<int:pet_id>')
@app.input(PetIn(partial=True))
@app.output(PetOut)
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 based on MethodView
from apiflask import APIFlask, Schema, abort
from apiflask.fields import Integer, String
from apiflask.validators import Length, OneOf
from apiflask.views import MethodView

app = APIFlask(__name__)

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


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


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


class Hello(MethodView):

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


class Pet(MethodView):

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

    @app.input(PetIn(partial=True))
    @app.output(PetOut)
    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]


app.add_url_rule('/', view_func=Hello.as_view('hello'))
app.add_url_rule('/pets/<int:pet_id>', view_func=Pet.as_view('pet'))
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 change the API documentation UI when creating the APIFlask instance with the docs_ui parameter:

app = APIFlask(__name__, docs_ui='redoc')

Now http://localhost:5000/docs will render the API documentation with Redoc.

Supported docs_ui values (UI libraries) include:

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 the following 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.
  • When creating a class-based view, use apiflask.views.MethodView instead of flask.views.MethodView.
  • The abort() function from APIFlask (apiflask.abort) returns JSON error response.

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:

  • apiflask.Schema: The base marshmallow schema class. Notice it sets the set_class to OrderedSet by default.
  • 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.
  • apiflask.validators: The marshmallow validators.
from apiflask import Schema
from apiflask.fields import Integer, String
from apiflask.validators import Length, OneOf
from marshmallow import pre_load, post_dump, ValidationError

Credits

APIFlask starts as a fork of APIFairy and is inspired by flask-smorest and FastAPI (see Comparison and Motivations for the comparison between these projects).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

APIFlask-1.2.1.tar.gz (80.9 kB view details)

Uploaded Source

Built Distribution

APIFlask-1.2.1-py3-none-any.whl (44.4 kB view details)

Uploaded Python 3

File details

Details for the file APIFlask-1.2.1.tar.gz.

File metadata

  • Download URL: APIFlask-1.2.1.tar.gz
  • Upload date:
  • Size: 80.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.10

File hashes

Hashes for APIFlask-1.2.1.tar.gz
Algorithm Hash digest
SHA256 505431a2c61ec3fc7e8fdb81f653d09c1ccec5b1e4e94f878f730af70a31be54
MD5 74cf64802c423b85812b657817afe048
BLAKE2b-256 04909c74699da88651f40fff6fa4c5b3a03b037d7a99990011cad10d5927ba38

See more details on using hashes here.

Provenance

File details

Details for the file APIFlask-1.2.1-py3-none-any.whl.

File metadata

  • Download URL: APIFlask-1.2.1-py3-none-any.whl
  • Upload date:
  • Size: 44.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.10

File hashes

Hashes for APIFlask-1.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 71452cb2dee41053f8cd1e7dd7d976ba9deb54f1a76845e375c1ca5af3c7c794
MD5 3ab6e17c1ceb6a05c7370c03124c8b8f
BLAKE2b-256 b226d3ab2bbe78215d180242097852a7223501fa1017d85def4fa17f4501100a

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page