Speed up rororo applications#
There are several known ways of improving performance for rororo applications.
[startup] Custom schema loader#
In most cases you may ignore speeding up startup of aiohttp.web application,
the place where rororo.openapi.setup_openapi()
called. But, as loading
schema dict from file is time consuming operation (especially when OpenAPI
schema file is large or disk, where file is stored, is slow) there are several
techniques on how to faster load OpenAPI schema.
YAML files#
Ensure that libyaml is installed in your
system. After, yaml.CSafeLoader
will be used instead of
yaml.SafeLoader
, which might increase load time up to 10 times.
In [1]: import yaml
In [2]: from api.constants import PROJECT_PATH
In [3]: schema_path = PROJECT_PATH / "openapi.yaml"
In [4]: %timeit yaml.load(schema_path.read_text(), Loader=yaml.SafeLoader)
164 ms ± 10.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [5]: %timeit yaml.load(schema_path.read_text(), Loader=yaml.CSafeLoader)
14.6 ms ± 339 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
JSON files#
rororo.openapi.setup_openapi()
allows to pass custom schema loader
function, as by default, for JSON files, it uses standard json.loads()
,
which is not the fastest way of loading JSON files into the Python.
Example below illustrates how to use ujson
for loading schema from openapi.json
file,
from pathlib import Path
import ujson
from aiohttp import web
from rororo import setup_openapi
from .views import operations
app = setup_openapi(
web.Application(),
Path(__file__) / "openapi.json",
operations,
schema_loader=ujson.loads,
)
[runtime] Disable validating responses#
To satisfy that OpenAPI hander provides proper response rororo internally
run ResponseValidator.validate(...)
function.
In most cases this fact is OK as it will ensure that all responses conform OpenAPI schema and client will receive expected result. However, it also results in extra deserializing / validation calls, which will slow down process of getting response from OpenAPI handler.
To “fix” this, there is a possibility to entirely turn off validation of responses in rororo,
app = setup_openapi(
web.Application(),
Path(__file__) / "openapi.yaml",
operations,
is_validate_response=False,
)
Danger
Turning off response validation may cause unexpected results for application consumers.
[testing] Cache reading schema and spec creation#
If you have a lot of tests and many of them calling
rororo.openapi.setup_openapi()
before supplying web.Application
to
aiohttp_client
you might want to speed up things, by caching calls for,
rororo.openapi.openapi.read_openapi_schema()
openapi_core.shortcuts.create_spec()
To enable this behaviour use next snippet,
from pathlib import Path
from rororo import (
BaseSettings,
setup_openapi,
setup_settings_from_environ,
)
app = setup_settings_from_environ(
web.Application(), BaseSettings
)
setup_openapi(
app,
Path(__file__) / "openapi.yaml",
operations,
cache_create_schema_and_spec=settings.is_dev,
)