APIFlask
¶
The Flask
object with some web API support.
Examples:
from apiflask import APIFlask
app = APIFlask(__name__)
Attributes:
Name | Type | Description |
---|---|---|
openapi_version |
str |
The version of OpenAPI Specification (openapi.openapi).
This attribute can also be configured from the config with the
|
description |
Optional[str] |
The description of the API (openapi.info.description).
This attribute can also be configured from the config with the
|
tags |
Union[List[str], List[Dict[str, str]]] |
The tags of the OpenAPI spec documentation (openapi.tags), accepts a list of dicts. You can also pass a simple list contains the tag name:
A standard OpenAPI tags list will look like this:
If not set, the blueprint names will be used as tags. This attribute can also be configured from the config with the
|
contact |
Optional[Dict[str, str]] |
The contact information of the API (openapi.info.contact). Example:
This attribute can also be configured from the config with the
|
license |
Optional[Dict[str, str]] |
The license of the API (openapi.info.license). Example:
This attribute can also be configured from the config with the
|
servers |
Optional[List[Dict[str, str]]] |
The servers information of the API (openapi.servers), accepts multiple server dicts. Example value:
This attribute can also be configured from the config with the
|
external_docs |
Optional[Dict[str, str]] |
The external documentation information of the API (openapi.externalDocs). Example:
This attribute can also be configured from the config with the
|
terms_of_service |
Optional[str] |
The terms of service URL of the API (openapi.info.termsOfService). Example:
This attribute can also be configured from the config with the
|
spec_callback |
Optional[SpecCallbackType] |
It stores the function object registerd by
|
error_callback |
ErrorCallbackType |
It stores the function object registerd by
|
spec: Union[dict, str]
property
readonly
¶
Get the current OAS document file.
This property will call get_spec method.
__init__(self, import_name, title='APIFlask', version='0.1.0', spec_path='/openapi.json', docs_path='/docs', docs_oauth2_redirect_path='/docs/oauth2-redirect', redoc_path='/redoc', json_errors=True, enable_openapi=True, static_url_path=None, static_folder='static', static_host=None, host_matching=False, subdomain_matching=False, template_folder='templates', instance_path=None, instance_relative_config=False, root_path=None)
special
¶
Make a Flask app instance.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
import_name |
str |
The name of the application package, usually
|
required |
title |
str |
The title of the API (openapi.info.title), defaults to "APIFlask". You can change it to the name of your API (e.g. "Pet API"). |
'APIFlask' |
version |
str |
The version of the API (openapi.info.version), defaults to "0.1.0". |
'0.1.0' |
spec_path |
str |
The path to OpenAPI Spec documentation. It
defaults to |
'/openapi.json' |
docs_path |
str |
The path to Swagger UI documentation, defaults to |
'/docs' |
docs_oauth2_redirect_path |
str |
The path to Swagger UI OAuth redirect. |
'/docs/oauth2-redirect' |
redoc_path |
str |
The path to Redoc documentation, defaults to |
'/redoc' |
json_errors |
bool |
If True, APIFlask will return a JSON response for HTTP errors. |
True |
enable_openapi |
bool |
If False, will disable OpenAPI spec and API docs views. |
True |
Other keyword arguments are directly pass to flask.Flask
.
Source code in apiflask/app.py
def __init__(
self,
import_name: str,
title: str = 'APIFlask',
version: str = '0.1.0',
spec_path: str = '/openapi.json',
docs_path: str = '/docs',
docs_oauth2_redirect_path: str = '/docs/oauth2-redirect',
redoc_path: str = '/redoc',
json_errors: bool = True,
enable_openapi: bool = True,
static_url_path: Optional[str] = None,
static_folder: str = 'static',
static_host: Optional[str] = None,
host_matching: bool = False,
subdomain_matching: bool = False,
template_folder: str = 'templates',
instance_path: Optional[str] = None,
instance_relative_config: bool = False,
root_path: Optional[str] = None
) -> None:
"""Make a Flask app instance.
Arguments:
import_name: The name of the application package, usually
`__name__`. This helps locate the `root_path` for the
application.
title: The title of the API (openapi.info.title), defaults to "APIFlask".
You can change it to the name of your API (e.g. "Pet API").
version: The version of the API (openapi.info.version), defaults to "0.1.0".
spec_path: The path to OpenAPI Spec documentation. It
defaults to `/openapi.json`, if the path end with `.yaml`
or `.yml`, the YAML format of the OAS will be returned.
docs_path: The path to Swagger UI documentation, defaults to `/docs`.
docs_oauth2_redirect_path: The path to Swagger UI OAuth redirect.
redoc_path: The path to Redoc documentation, defaults to `/redoc`.
json_errors: If True, APIFlask will return a JSON response for HTTP errors.
enable_openapi: If False, will disable OpenAPI spec and API docs views.
Other keyword arguments are directly pass to `flask.Flask`.
"""
super(APIFlask, self).__init__(
import_name,
static_url_path=static_url_path,
static_folder=static_folder,
static_host=static_host,
host_matching=host_matching,
subdomain_matching=subdomain_matching,
template_folder=template_folder,
instance_path=instance_path,
instance_relative_config=instance_relative_config,
root_path=root_path
)
# Set default config
self.config.from_object('apiflask.settings')
self.title = title
self.version = version
self.spec_path = spec_path
self.docs_path = docs_path
self.redoc_path = redoc_path
self.docs_oauth2_redirect_path = docs_oauth2_redirect_path
self.enable_openapi = enable_openapi
self.json_errors = json_errors
self.spec_callback: Optional[SpecCallbackType] = None
self.error_callback: ErrorCallbackType = default_error_handler # type: ignore
self._spec: Optional[Union[dict, str]] = None
self._register_openapi_blueprint()
self._register_error_handlers()
delete(self, rule, **options)
¶
Shortcut for app.route(methods=['DELETE'])
.
Source code in apiflask/app.py
def delete(self, rule: str, **options: Any):
"""Shortcut for `app.route(methods=['DELETE'])`."""
return cls_route(self, rule, methods=['DELETE'], **options)
dispatch_request(self)
¶
Overwrite the default dispatch method in Flask.
With this overwrite, view arguments are passed as positional arguments so that the view function can intuitively accept the parameters (i.e. from top to bottom, from left to right).
Examples:
@app.get('/pets/<name>/<int:pet_id>/<age>') # -> name, pet_id, age
@input(QuerySchema) # -> query
@output(PetSchema) # -> pet
def get_pet(name, pet_id, age, query, pet):
pass
From Flask, see NOTICE file for license informaiton.
Version added: 0.2.0
Source code in apiflask/app.py
def dispatch_request(self) -> ResponseType:
"""Overwrite the default dispatch method in Flask.
With this overwrite, view arguments are passed as positional
arguments so that the view function can intuitively accept the
parameters (i.e. from top to bottom, from left to right).
Examples:
```python
@app.get('/pets/<name>/<int:pet_id>/<age>') # -> name, pet_id, age
@input(QuerySchema) # -> query
@output(PetSchema) # -> pet
def get_pet(name, pet_id, age, query, pet):
pass
```
From Flask, see NOTICE file for license informaiton.
*Version added: 0.2.0*
"""
req = _request_ctx_stack.top.request
if req.routing_exception is not None:
self.raise_routing_exception(req)
rule = req.url_rule
# if we provide automatic options for this URL and the
# request came with the OPTIONS method, reply automatically
if ( # pragma: no cover
getattr(rule, "provide_automatic_options", False)
and req.method == "OPTIONS"
):
return self.make_default_options_response() # pragma: no cover
# otherwise dispatch to the handler for that endpoint
return self.view_functions[rule.endpoint](*req.view_args.values())
error_processor(self, f)
¶
A decorator to register a error handler callback function.
The callback function will be called when validation error hanppend when
parse a request or an exception triggerd with exceptions.HTTPError or
:func:exceptions.abort
. It must accept four positional arguments (i.e.
status_code, message, detail, headers
) and return a valid response.
Examples:
@app.error_processor
def my_error_handler(status_code, message, detail, headers):
return {
'status_code': status_code,
'message': message,
'detail': detail
}, status_code, headers
The arguments are:
- status_code: If the error triggerd by validation error, the value will be
400 (default) or the value you passed in config
VALIDATION_ERROR_STATUS_CODE
. If the error triggerd by HTTP, it will be the status code you passed. Otherwise, it will be the status code set by Werkzueg when processing the request. - message: The error description for this error, either you passed or grab from Werkzeug.
-
detail: The detail of the error, it will be filled when validation error happaned, the structure will be:
"<location>": { "<field_name>": ["<error_message>", ...], "<field_name>": ["<error_message>", ...], ... }, "<location>": { ... }, ...
The value of
location
can bejson
(i.e. request body) orquery
(i.e. query string) depend on the palace the validation error happened. - headers: The value will be None unless you pass it in HTTPError or abort.
If you want, you can rewrite the whole response body to anything you like:
@app.errorhandler_callback
def my_error_handler(status_code, message, detail, headers):
return {'error_detail': detail}, status_code, headers
However, I would recommend to keep the detail
since it contains the detail
information about the validation error.
Source code in apiflask/app.py
def error_processor(
self,
f: ErrorCallbackType
) -> ErrorCallbackType:
"""A decorator to register a error handler callback function.
The callback function will be called when validation error hanppend when
parse a request or an exception triggerd with exceptions.HTTPError or
:func:`exceptions.abort`. It must accept four positional arguments (i.e.
`status_code, message, detail, headers`) and return a valid response.
Examples:
```python
@app.error_processor
def my_error_handler(status_code, message, detail, headers):
return {
'status_code': status_code,
'message': message,
'detail': detail
}, status_code, headers
```
The arguments are:
- status_code: If the error triggerd by validation error, the value will be
400 (default) or the value you passed in config `VALIDATION_ERROR_STATUS_CODE`.
If the error triggerd by HTTP, it will be the status code you passed.
Otherwise, it will be the status code set by Werkzueg when processing the request.
- message: The error description for this error, either you passed or grab from Werkzeug.
- detail: The detail of the error, it will be filled when validation error happaned, the
structure will be:
```python
"<location>": {
"<field_name>": ["<error_message>", ...],
"<field_name>": ["<error_message>", ...],
...
},
"<location>": {
...
},
...
```
The value of `location` can be `json` (i.e. request body) or `query`
(i.e. query string) depend on the palace the validation error happened.
- headers: The value will be None unless you pass it in HTTPError or abort.
If you want, you can rewrite the whole response body to anything you like:
```python
@app.errorhandler_callback
def my_error_handler(status_code, message, detail, headers):
return {'error_detail': detail}, status_code, headers
```
However, I would recommend to keep the `detail` since it contains the detail
information about the validation error.
"""
self.error_callback = f
return f
get(self, rule, **options)
¶
Shortcut for app.route()
.
Source code in apiflask/app.py
def get(self, rule: str, **options: Any):
"""Shortcut for `app.route()`."""
return cls_route(self, rule, methods=['GET'], **options)
get_spec(self, spec_format='json')
¶
Get the current OAS document file.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
spec_format |
str |
The format of the spec file, one of |
'json' |
Source code in apiflask/app.py
def get_spec(self, spec_format: str = 'json') -> Union[dict, str]:
"""Get the current OAS document file.
Arguments:
spec_format: The format of the spec file, one of `'json'`, `'yaml'`
and `'yml'`, defaults to `'json'`.
"""
if self._spec is None:
if spec_format == 'json':
self._spec = self._generate_spec().to_dict()
else:
self._spec = self._generate_spec().to_yaml()
if self.spec_callback:
self._spec = self.spec_callback(self._spec)
return self._spec
patch(self, rule, **options)
¶
Shortcut for app.route(methods=['PATCH'])
.
Source code in apiflask/app.py
def patch(self, rule: str, **options: Any):
"""Shortcut for `app.route(methods=['PATCH'])`."""
return cls_route(self, rule, methods=['PATCH'], **options)
post(self, rule, **options)
¶
Shortcut for app.route(methods=['POST'])
.
Source code in apiflask/app.py
def post(self, rule: str, **options: Any):
"""Shortcut for `app.route(methods=['POST'])`."""
return cls_route(self, rule, methods=['POST'], **options)
put(self, rule, **options)
¶
Shortcut for app.route(methods=['PUT'])
.
Source code in apiflask/app.py
def put(self, rule: str, **options: Any):
"""Shortcut for `app.route(methods=['PUT'])`."""
return cls_route(self, rule, methods=['PUT'], **options)
spec_processor(self, f)
¶
A decorator to register a spec handler callback function.
You can register a function to update the spec. The callback function should accept the spec as argument and return it in the end. The callback function will be called when generating the spec file.
Examples:
@app.spec_processor
def update_spec(spec):
spec['title'] = 'Updated Title'
return spec
Notice the format of the spec is depends on the the value of configuration
variable SPEC_FORMAT
(defaults to 'json'
):
'json'
-> dictionary'yaml'
-> string
Source code in apiflask/app.py
def spec_processor(self, f: SpecCallbackType) -> SpecCallbackType:
"""A decorator to register a spec handler callback function.
You can register a function to update the spec. The callback function
should accept the spec as argument and return it in the end. The callback
function will be called when generating the spec file.
Examples:
```python
@app.spec_processor
def update_spec(spec):
spec['title'] = 'Updated Title'
return spec
```
Notice the format of the spec is depends on the the value of configuration
variable `SPEC_FORMAT` (defaults to `'json'`):
- `'json'` -> dictionary
- `'yaml'` -> string
"""
self.spec_callback = f
return f