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. 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

Currently, this project is in the active development stage; bugs and breaking changes are expected. Welcome to leave any suggestions or feedbacks in this issue or submit a pull request to improve it. Thank you!

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/<int:pet_id>')
@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/<int:pet_id>')
@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
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/<int:pet_id>')
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.

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.

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-0.6.2.tar.gz (769.1 kB view details)

Uploaded Source

Built Distribution

APIFlask-0.6.2-py3-none-any.whl (42.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: APIFlask-0.6.2.tar.gz
  • Upload date:
  • Size: 769.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.5.0.1 requests/2.25.1 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.55.1 CPython/3.8.0

File hashes

Hashes for APIFlask-0.6.2.tar.gz
Algorithm Hash digest
SHA256 41c7bb65c69011e460afe9dba5f6d7aa1f7497a392d46dc58ff45b3e7233356f
MD5 5836c9a863eab6e9641fbbdcfb7b4a73
BLAKE2b-256 210f53874359bc0b7702b410722bc880e9e616e7364fd9cff98dec7ac0166240

See more details on using hashes here.

File details

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

File metadata

  • Download URL: APIFlask-0.6.2-py3-none-any.whl
  • Upload date:
  • Size: 42.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.5.0.1 requests/2.25.1 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.55.1 CPython/3.8.0

File hashes

Hashes for APIFlask-0.6.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d2d37f975383cc6cb73ad8e1444d8527a2a402eb0ee41c6782316197cbe8ab69
MD5 bb0bf6e61f54acd0c11c252e8d272212
BLAKE2b-256 7812483f44293a43749985dbc94e618522153ae044eafb2d08720c54d679e480

See more details on using hashes here.

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