APIFlask


NameAPIFlask JSON
Version 2.1.1 PyPI version JSON
download
home_pagehttps://apiflask.com
SummaryA lightweight web API framework based on Flask and marshmallow-code projects.
upload_time2024-03-10 14:42:48
maintainer
docs_urlNone
authorGrey Li
requires_python>=3.8
licenseMIT
keywords flask marshmallow openapi
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
![](https://apiflask.com/_assets/apiflask-logo.png)

# APIFlask

[![Build status](https://github.com/apiflask/apiflask/actions/workflows/tests.yml/badge.svg)](https://github.com/apiflask/apiflask/actions) [![codecov](https://codecov.io/gh/apiflask/apiflask/branch/main/graph/badge.svg?token=2CFPCZ1DMY)](https://codecov.io/gh/apiflask/apiflask)

APIFlask is a lightweight Python web API framework based on [Flask](https://github.com/pallets/flask) and [marshmallow-code](https://github.com/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](https://github.com/OAI/OpenAPI-Specification) (OAS, formerly Swagger Specification) document generation
- Automatic interactive API documentation
- API authentication support (with [Flask-HTTPAuth](https://github.com/miguelgrinberg/flask-httpauth))
- Automatic JSON response for HTTP errors


## Requirements

- Python 3.8+
- Flask 2.0+


## Installation

For Linux and macOS:

```bash
$ pip3 install apiflask
```

For Windows:

```bash
> pip install apiflask
```


## Links

- Website: <https://apiflask.com>
- Documentation: <https://apiflask.com/docs>
- PyPI Releases: <https://pypi.python.org/pypi/APIFlask>
- Change Log: <https://apiflask.com/changelog>
- Source Code: <https://github.com/apiflask/apiflask>
- Issue Tracker: <https://github.com/apiflask/apiflask/issues>
- Discussion: <https://github.com/apiflask/apiflask/discussions>
- Twitter: <https://twitter.com/apiflask>
- Open Collective: <https://opencollective.com/apiflask>


## Donate

If you find APIFlask useful, please consider [donating](https://opencollective.com/apiflask) today. Your donation keeps APIFlask maintained and evolving.

Thank you to all our backers and sponsors!

### Backers

[![](https://opencollective.com/apiflask/backers.svg?width=890)](https://opencollective.com/apiflask)

### Sponsors

[![](https://opencollective.com/apiflask/sponsors.svg?width=890)](https://opencollective.com/apiflask)

## Example

```python
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))  # -> json_data
@app.output(PetOut)
def update_pet(pet_id, json_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 json_data.items():
        pets[pet_id][attr] = value
    return pets[pet_id]
```

<details>
<summary>You can also use class-based views based on <code>MethodView</code></summary>

```python
from apiflask import APIFlask, Schema, 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 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, json_data):
        """Update a pet"""
        if pet_id > len(pets) - 1:
            abort(404)
        for attr, value in json_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'))
```
</details>

<details>
<summary>Or use <code>async def</code></summary>

```bash
$ pip install -U "apiflask[async]"
```

```python
import asyncio

from apiflask import APIFlask

app = APIFlask(__name__)


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

See <em><a href="https://flask.palletsprojects.com/async-await">Using async and await</a></em> for the details of the async support in Flask 2.0.

</details>

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

```bash
$ flask run --reload
```

Or run in debug mode:

```bash
$ flask run --debug
```

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

![](https://apiflask.com/_assets/swagger-ui.png)

Or you can change the API documentation UI when creating the APIFlask instance with the `docs_ui` parameter:

```py
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:

- `swagger-ui` (default value): [Swagger UI](https://github.com/swagger-api/swagger-ui)
- `redoc`: [Redoc](https://github.com/Redocly/redoc)
- `elements`: [Elements](https://github.com/stoplightio/elements)
- `rapidoc`: [RapiDoc](https://github.com/rapi-doc/RapiDoc)
- `rapipdf`: [RapiPDF](https://github.com/mrin9/RapiPdf)

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](https://apiflask.com/openapi/#the-flask-spec-command):

```bash
$ flask spec
```

For some complete examples, see [/examples](https://github.com/apiflask/apiflask/tree/main/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](https://apiflask.com/migrating)* 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.

For a minimal Flask application:

```python
from flask import Flask, request
from markupsafe import escape

app = Flask(__name__)

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

Now change to APIFlask:

```python
from apiflask import APIFlask  # step one
from flask import request
from markupsafe import 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.
- `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.

```python
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](https://github.com/miguelgrinberg/APIFairy) and is inspired by [flask-smorest](https://github.com/marshmallow-code/flask-smorest) and [FastAPI](https://github.com/tiangolo/fastapi) (see *[Comparison and Motivations](https://apiflask.com/comparison)* for the comparison between these projects).

            

Raw data

            {
    "_id": null,
    "home_page": "https://apiflask.com",
    "name": "APIFlask",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "",
    "keywords": "flask,marshmallow,openapi",
    "author": "Grey Li",
    "author_email": "withlihui@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/6e/65/1b3f8cc644c8853a6f4a07dff6635843ef9377cd9f0a46557798d5014e0c/APIFlask-2.1.1.tar.gz",
    "platform": "any",
    "description": "\n![](https://apiflask.com/_assets/apiflask-logo.png)\n\n# APIFlask\n\n[![Build status](https://github.com/apiflask/apiflask/actions/workflows/tests.yml/badge.svg)](https://github.com/apiflask/apiflask/actions) [![codecov](https://codecov.io/gh/apiflask/apiflask/branch/main/graph/badge.svg?token=2CFPCZ1DMY)](https://codecov.io/gh/apiflask/apiflask)\n\nAPIFlask is a lightweight Python web API framework based on [Flask](https://github.com/pallets/flask) and [marshmallow-code](https://github.com/marshmallow-code) projects. It's easy to use, highly customizable, ORM/ODM-agnostic, and 100% compatible with the Flask ecosystem.\n\nWith APIFlask, you will have:\n\n- More sugars for view function (`@app.input()`, `@app.output()`, `@app.get()`, `@app.post()` and more)\n- Automatic request validation and deserialization\n- Automatic response formatting and serialization\n- Automatic [OpenAPI Specification](https://github.com/OAI/OpenAPI-Specification) (OAS, formerly Swagger Specification) document generation\n- Automatic interactive API documentation\n- API authentication support (with [Flask-HTTPAuth](https://github.com/miguelgrinberg/flask-httpauth))\n- Automatic JSON response for HTTP errors\n\n\n## Requirements\n\n- Python 3.8+\n- Flask 2.0+\n\n\n## Installation\n\nFor Linux and macOS:\n\n```bash\n$ pip3 install apiflask\n```\n\nFor Windows:\n\n```bash\n> pip install apiflask\n```\n\n\n## Links\n\n- Website: <https://apiflask.com>\n- Documentation: <https://apiflask.com/docs>\n- PyPI Releases: <https://pypi.python.org/pypi/APIFlask>\n- Change Log: <https://apiflask.com/changelog>\n- Source Code: <https://github.com/apiflask/apiflask>\n- Issue Tracker: <https://github.com/apiflask/apiflask/issues>\n- Discussion: <https://github.com/apiflask/apiflask/discussions>\n- Twitter: <https://twitter.com/apiflask>\n- Open Collective: <https://opencollective.com/apiflask>\n\n\n## Donate\n\nIf you find APIFlask useful, please consider [donating](https://opencollective.com/apiflask) today. Your donation keeps APIFlask maintained and evolving.\n\nThank you to all our backers and sponsors!\n\n### Backers\n\n[![](https://opencollective.com/apiflask/backers.svg?width=890)](https://opencollective.com/apiflask)\n\n### Sponsors\n\n[![](https://opencollective.com/apiflask/sponsors.svg?width=890)](https://opencollective.com/apiflask)\n\n## Example\n\n```python\nfrom apiflask import APIFlask, Schema, abort\nfrom apiflask.fields import Integer, String\nfrom apiflask.validators import Length, OneOf\n\napp = APIFlask(__name__)\n\npets = [\n    {'id': 0, 'name': 'Kitty', 'category': 'cat'},\n    {'id': 1, 'name': 'Coco', 'category': 'dog'}\n]\n\n\nclass PetIn(Schema):\n    name = String(required=True, validate=Length(0, 10))\n    category = String(required=True, validate=OneOf(['dog', 'cat']))\n\n\nclass PetOut(Schema):\n    id = Integer()\n    name = String()\n    category = String()\n\n\n@app.get('/')\ndef say_hello():\n    # returning a dict or list equals to use jsonify()\n    return {'message': 'Hello!'}\n\n\n@app.get('/pets/<int:pet_id>')\n@app.output(PetOut)\ndef get_pet(pet_id):\n    if pet_id > len(pets) - 1:\n        abort(404)\n    # you can also return an ORM/ODM model class instance directly\n    # APIFlask will serialize the object into JSON format\n    return pets[pet_id]\n\n\n@app.patch('/pets/<int:pet_id>')\n@app.input(PetIn(partial=True))  # -> json_data\n@app.output(PetOut)\ndef update_pet(pet_id, json_data):\n    # the validated and parsed input data will\n    # be injected into the view function as a dict\n    if pet_id > len(pets) - 1:\n        abort(404)\n    for attr, value in json_data.items():\n        pets[pet_id][attr] = value\n    return pets[pet_id]\n```\n\n<details>\n<summary>You can also use class-based views based on <code>MethodView</code></summary>\n\n```python\nfrom apiflask import APIFlask, Schema, abort\nfrom apiflask.fields import Integer, String\nfrom apiflask.validators import Length, OneOf\nfrom flask.views import MethodView\n\napp = APIFlask(__name__)\n\npets = [\n    {'id': 0, 'name': 'Kitty', 'category': 'cat'},\n    {'id': 1, 'name': 'Coco', 'category': 'dog'}\n]\n\n\nclass PetIn(Schema):\n    name = String(required=True, validate=Length(0, 10))\n    category = String(required=True, validate=OneOf(['dog', 'cat']))\n\n\nclass PetOut(Schema):\n    id = Integer()\n    name = String()\n    category = String()\n\n\nclass Hello(MethodView):\n\n    # use HTTP method name as class method name\n    def get(self):\n        return {'message': 'Hello!'}\n\n\nclass Pet(MethodView):\n\n    @app.output(PetOut)\n    def get(self, pet_id):\n        \"\"\"Get a pet\"\"\"\n        if pet_id > len(pets) - 1:\n            abort(404)\n        return pets[pet_id]\n\n    @app.input(PetIn(partial=True))\n    @app.output(PetOut)\n    def patch(self, pet_id, json_data):\n        \"\"\"Update a pet\"\"\"\n        if pet_id > len(pets) - 1:\n            abort(404)\n        for attr, value in json_data.items():\n            pets[pet_id][attr] = value\n        return pets[pet_id]\n\n\napp.add_url_rule('/', view_func=Hello.as_view('hello'))\napp.add_url_rule('/pets/<int:pet_id>', view_func=Pet.as_view('pet'))\n```\n</details>\n\n<details>\n<summary>Or use <code>async def</code></summary>\n\n```bash\n$ pip install -U \"apiflask[async]\"\n```\n\n```python\nimport asyncio\n\nfrom apiflask import APIFlask\n\napp = APIFlask(__name__)\n\n\n@app.get('/')\nasync def say_hello():\n    await asyncio.sleep(1)\n    return {'message': 'Hello!'}\n```\n\nSee <em><a href=\"https://flask.palletsprojects.com/async-await\">Using async and await</a></em> for the details of the async support in Flask 2.0.\n\n</details>\n\nSave this as `app.py`, then run it with:\n\n```bash\n$ flask run --reload\n```\n\nOr run in debug mode:\n\n```bash\n$ flask run --debug\n```\n\nNow visit the interactive API documentation (Swagger UI) at <http://localhost:5000/docs>:\n\n![](https://apiflask.com/_assets/swagger-ui.png)\n\nOr you can change the API documentation UI when creating the APIFlask instance with the `docs_ui` parameter:\n\n```py\napp = APIFlask(__name__, docs_ui='redoc')\n```\n\nNow <http://localhost:5000/docs> will render the API documentation with Redoc.\n\nSupported `docs_ui` values (UI libraries) include:\n\n- `swagger-ui` (default value): [Swagger UI](https://github.com/swagger-api/swagger-ui)\n- `redoc`: [Redoc](https://github.com/Redocly/redoc)\n- `elements`: [Elements](https://github.com/stoplightio/elements)\n- `rapidoc`: [RapiDoc](https://github.com/rapi-doc/RapiDoc)\n- `rapipdf`: [RapiPDF](https://github.com/mrin9/RapiPdf)\n\nThe auto-generated OpenAPI spec file is available at <http://localhost:5000/openapi.json>. You can also get the spec with [the `flask spec` command](https://apiflask.com/openapi/#the-flask-spec-command):\n\n```bash\n$ flask spec\n```\n\nFor some complete examples, see [/examples](https://github.com/apiflask/apiflask/tree/main/examples).\n\n\n## Relationship with Flask\n\nAPIFlask is a thin wrapper on top of Flask. You only need to remember the following differences (see *[Migrating from Flask](https://apiflask.com/migrating)* for more details):\n\n- When creating an application instance, use `APIFlask` instead of `Flask`.\n- When creating a blueprint instance, use `APIBlueprint` instead of `Blueprint`.\n- The `abort()` function from APIFlask (`apiflask.abort`) returns JSON error response.\n\nFor a minimal Flask application:\n\n```python\nfrom flask import Flask, request\nfrom markupsafe import escape\n\napp = Flask(__name__)\n\n@app.route('/')\ndef hello():\n    name = request.args.get('name', 'Human')\n    return f'Hello, {escape(name)}'\n```\n\nNow change to APIFlask:\n\n```python\nfrom apiflask import APIFlask  # step one\nfrom flask import request\nfrom markupsafe import escape\n\napp = APIFlask(__name__)  # step two\n\n@app.route('/')\ndef hello():\n    name = request.args.get('name', 'Human')\n    return f'Hello, {escape(name)}'\n```\n\nIn 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.\n\n\n## Relationship with marshmallow\n\nAPIFlask 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.\n\nYou can build marshmallow schemas just like before, but APIFlask also exposes some marshmallow APIs for convenience:\n\n- `apiflask.Schema`: The base marshmallow schema class.\n- `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.\n- `apiflask.validators`: The marshmallow validators.\n\n```python\nfrom apiflask import Schema\nfrom apiflask.fields import Integer, String\nfrom apiflask.validators import Length, OneOf\nfrom marshmallow import pre_load, post_dump, ValidationError\n```\n\n## Credits\n\nAPIFlask starts as a fork of [APIFairy](https://github.com/miguelgrinberg/APIFairy) and is inspired by [flask-smorest](https://github.com/marshmallow-code/flask-smorest) and [FastAPI](https://github.com/tiangolo/fastapi) (see *[Comparison and Motivations](https://apiflask.com/comparison)* for the comparison between these projects).\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A lightweight web API framework based on Flask and marshmallow-code projects.",
    "version": "2.1.1",
    "project_urls": {
        "Changelog": "https://apiflask.com/changelog",
        "Documentation": "https://apiflask.com/docs",
        "Donate": "https://opencollective.com/apiflask",
        "Homepage": "https://apiflask.com",
        "Issue Tracker": "https://github.com/apiflask/apiflask/issues",
        "Source": "https://github.com/apiflask/apiflask"
    },
    "split_keywords": [
        "flask",
        "marshmallow",
        "openapi"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6060ed757d562b2e243fc6f0530a5da6431d73967eaab82211823802015e4a05",
                "md5": "b55cda84116dfcb6a03b96f2ee3af18f",
                "sha256": "8586c1f845f6b17f948ecbc6ea26837532cc32953379553c4a78bf9498b2c082"
            },
            "downloads": -1,
            "filename": "APIFlask-2.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b55cda84116dfcb6a03b96f2ee3af18f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 42025,
            "upload_time": "2024-03-10T14:42:45",
            "upload_time_iso_8601": "2024-03-10T14:42:45.979121Z",
            "url": "https://files.pythonhosted.org/packages/60/60/ed757d562b2e243fc6f0530a5da6431d73967eaab82211823802015e4a05/APIFlask-2.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6e651b3f8cc644c8853a6f4a07dff6635843ef9377cd9f0a46557798d5014e0c",
                "md5": "8947fdc98ccb6c2414a5508d1ad76828",
                "sha256": "88db5a539cc155e35d9636d99b434d00ca6c0b23e7c87c8321ec9dc980535366"
            },
            "downloads": -1,
            "filename": "APIFlask-2.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "8947fdc98ccb6c2414a5508d1ad76828",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 84544,
            "upload_time": "2024-03-10T14:42:48",
            "upload_time_iso_8601": "2024-03-10T14:42:48.888831Z",
            "url": "https://files.pythonhosted.org/packages/6e/65/1b3f8cc644c8853a6f4a07dff6635843ef9377cd9f0a46557798d5014e0c/APIFlask-2.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-10 14:42:48",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "apiflask",
    "github_project": "apiflask",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "apiflask"
}
        
Elapsed time: 0.20926s