Connexion 3.0: API-first for all¶
We are excited to announce the release of Connexion 3.0! 🎉
Connexion 3 fundamentally changes how Connexion is designed and implemented, and how it fits into the wider Python API ecosystem. We adopted the ASGI interface, which makes Connexion both modular and well-integrated with most modern Python API tooling.
It brings some major changes compared to 2.X:
The improved
App
and newAsyncApp
allow you to use Connexion as a stand-alone frameworkThe
App
interface was extended so you no longer have to care about the framework used underneath
Connexion can now be used as middleware to supercharge any ASGI or WSGI-compatible framework with its spec-based functionality
Connexion is now pluggable in many dimensions:
All Connexion functionality is pluggable by adding or removing middleware from its stack
Validation is now pluggable by content type, solving longstanding issues regarding endpoints with multiple content types and making it easy to add validation for additional content types
Authentication is now pluggable by security scheme, making it easy to customize the behavior or add support for additional security schemes.
Aiohttp support has been dropped due to lack of ASGI support
We spent a lot of effort on extending and improving our documentation
Read on below to discover more changes. 👇
Or read our in-depth blog post on the redesign.
Getting started with Connexion 3¶
Using stand-alone Connexion¶
You can use Connexion as a stand-alone web framework, using one of the available apps:
The
App
(aliasFlaskApp
), which is built on top of Flask as known from Connexion 2.X.The
AsyncApp
, which is built on top of starlette and provides native asynchronous functionality.
If you don’t require compatibility with the Flask ecosystem, we recommend to use the AsyncApp
.
Even when writing mostly synchronous code, as you can just use synchronous view functions.
Using Connexion with ASGI or WSGI frameworks¶
If you want to leverage Connexion functionality with third party ASGI frameworks, you can use the
ConnexionMiddleware
and wrap it around a third party application.
This provides all Connexion functionality except for automatic routing, automatic parameter injection,
and response serialization. You can add some of this functionality using Decorators
provided by
Connexion:
FlaskDecorator
: provides automatic parameter injection and response serialization for Flask applications.ASGIDecorator
: provides automatic parameter injection for ASGI applications. Note that this decorator injects Starlette datastructures (such asUploadFile
).StarletteDecorator
: provides automatic parameter injection and response serialization for Starlette applications.
For examples, see https://github.com/spec-first/connexion/tree/main/examples/frameworks.
Pluggable validation by content type¶
Validation is now pluggable by content type, which means that the VALIDATOR_MAP has been updated to accommodate this.
You can use the connexion.datastructures.MediaTypeDict
to support content type ranges.
VALIDATOR_MAP = {
"parameter": ParameterValidator,
"body": MediaTypeDict(
{
"*/*json": JSONRequestBodyValidator,
"application/x-www-form-urlencoded": FormDataValidator,
"multipart/form-data": MultiPartFormDataValidator,
}
),
"response": MediaTypeDict(
{
"*/*json": JSONResponseBodyValidator,
"text/plain": TextResponseBodyValidator,
}
),
}
You can pass it either to the app, or when registering an API.
app = connexion.App(__name__, validator_map=VALIDATOR_MAP)
app.add_api("openapi.yaml", validator_map=VALIDATOR_MAP)
An AbstractRequestBodyValidator
and AbstractResponseBodyValidator
class are available to
support the creation of custom validators.
ASGI Server¶
Connexion 3.0 needs to be run using an ASGI server instead of a WSGI server. While any ASGI server
should work, connexion comes with uvicorn
as an extra:
pip install connexion[uvicorn]
Smaller breaking changes¶
The
options
argument has been renamed toswagger_ui_options
and now takes an instance of theSwaggerUIOptions
. The naming of the options themselves have been changed to better represent their meaning.The
uri_parser_class
is now passed to theApp
or itsadd_api()
method directly instead of via theoptions
argument.The
jsonifier
is now passed to theApp
or itsadd_api()
method instead of setting it as an attribute on the Api.Drop Flask 1.X support and support Flask 2.X async routes
Drop Python 3.6 (and add Python 3.10) support
connexion.request
is now a StarletteRequest
instead of a FlaskRequest
Route priority changed. The most specific route should now be defined first in the specification.
We no longer guess a content type for response serialization if multiple are defined in the spec. We do take into account returned headers.
Don’t return 400 when read-only property is received
Content type is now validated for requests and responses if defined in the spec
The deprecated positions for
x-body-name
are no longer supportedThe parameter
pass_context_arg_name
has been removed. Context is now available as global request-level context, or can be passed in by defining acontext_
parameter in your view function.The
MethodViewResolver
has been renamed toMethodResolver
, and a newMethodViewResolver
has been added to work with Flask’sMethodView
specifically.Built-in support for uWSGI has been removed. You can re-add this functionality using a custom middleware.
The request body is now passed through for
GET
,HEAD
,DELETE
,CONNECT
andOPTIONS
methods as well.Error handlers registered on the on the underlying Flask app directly will be ignored. You should register them on the Connexion app directly.
Non-breaking changes¶
Relative and nested refs are now supported in OpenAPI / Swagger specifications
The
required
keyword is now supported for requestBodiesHTTP exceptions are now implemented as a hierarchy
Connexion now exposes
context
,operation
,receive
,scope
as global request-level contextConnexion now provides a
DefaultsJSONRequestBodyValidator
to fill in default values in received request bodies.
Full changelog¶
Consult our Github release page for an overview of all changes.
Feedback¶
We would really love to hear from you, so let us know if you have any feedback or questions. We’d like to make the migration for our users as easy and possible.
For questions, comments, and feedback, please comment on the discussion which will be created and pinned after the release.
For issues, please open an issue on our Github tracker