Working towards #1709
I think we're almost there, some tests I did are now working properly.
Would love to get some feedback/ideas on the implementation and the
tests :)
Fixes#1697
Because of a wrong comparison against the position `Enum`, middleware
was not actually being added to the stack via `add_middleware`. This PR
fixes this, adds a warning when the middleware position cannot be found,
and adds a test.
Registering error handlers on the async app leads to an error on 3.0.0a5
because the error handlers are not unpacked correctly when being
registered internally.
Fixes#1682
This PR inspects the parameters of a Middleware class before passing in
the `lifespan` keyword argument. I was doubting to check the class
instead (`isinstance(LifespanMiddleware)`), but that's less flexible if
users want to write custom middleware to handle the lifespan.
This PR adds an `add_middleware` method to the apps and
`ConnexionMiddleware` to easily add middleware to the stack. Before, the
only way to do this was to pass in a complete middleware stack.
The default position to add the new middleware is right before the
`ContextMiddleware`, which is the final middleware in the stack. Another
position can be selected by passing in a `MiddlewarePosition` enum,
which defines some positions which make sense.
Since we can no longer assume that the whole middleware stack is defined
when initializing the `ConnexionMiddleware`, we need to delay building
the middleware stack until the `ConnexionMiddleware` is actually called.
This also means we need to delay registering the APIs and error
handlers. This is now all done in the `_build_middleware_stack` method.
Continues on the work of #1077 by moving the test fixtures into the
`secure_endpoint` fixture and adding a test for it in
`test_secure_api.py`.
The test will check whether an api key in the query will not lead to an
error when `strict_validation` is enabled.
Make security pluggable
- [x] Solution for standard security handlers: `security_deny`,
`security_passthrough`, `verify_none`
- [x] HTTP security handlers & overlap with basic from swagger 2
- [x] Do we need a separate handler for each `oauth2` flow?
The current implementation of replaying the stream will always replay
the first message. This PR fixes this by progressing through the
messages with each call.
This PR adds a new middleware to handle lifespan events.
I added this as a separate middleware so it is encapsulated and aligned
for both the `FlaskApp` and `AsyncApp`. It leverages a Starlette
`Router` to register and call the lifespan handler.
This PR delays import errors for the optional Flask dependency, so you
can use the AsyncApp without Flask installed.
This issue is hidden in our tests since we install all extras. To
prevent this, we need to address
https://github.com/spec-first/connexion/issues/1389.
This PR adds a `jsonifier` argument to the app and api to align it with
other customization options. We also no longer pass it via the operation
object, which brings us closer to operations as data class only.
Fixes#942
No longer return 400 if a read-only property is provided, as discussed
in the issue. We still raise an error if write-only properties are
included in the response and response validation is enabled.
I also changed how read-/write-only works in combination with
`required`. Previously, `required` would not be overwritten by
read-/write-only. Now we just follow the spec to the letter:
- required and read-only: must be included but must be ignored by the
server
- required and write-only: impossible to achieve, but I also don't see
how this combination could make sense
- read-only: may be included but must be ignored by server
- write-only: must not be included by server
Fixes#254Fixes#967
This PR fixes the very long-standing issue of being able to handle
relative references, which allows users to split their specification
into multiple files.
This PR fixes 'outside of Flask context' errors in our test suite and
contains the following changes:
- `Connexion.request` is now a Connexion `ASGIRequest` instead of a
Flask `request`
- All other tests with a Flask dependency have been updated or split
Failing tests are down to 11.
This PR refactors our tests to prepare the activation of our tests for
our AsyncApp.
The separate commits are atomic, which can be useful for reviewing.
---------
Co-authored-by: Ruwann <ruwanlambrichts@gmail.com>
This PR adds an interface for the ConnexionMiddleware, similar to the
interface of the Connexion Apps.
The Connexion Apps are now a simple wrapper around the
ConnexionMiddleware and framework app, delegating the work to the
middleware. This enables a similar interface and behavior for users when
using either the middleware or apps.
The arguments are repeated everywhere there is a user interface, but are
parsed in a central place. Repeating the arguments is not DRY, but
needed to provide users with IDE autocomplete, typing, etc. They are
parsed in a single `_Options` class, which also provides a mechanism to
set default options on an App level, and override them on the more
granular API level.
This makes the long list of provided parameters a lot more manageable,
so I would like to use it for the `Jsonifier` as well, and re-add the
`debug` and `extra_files` arguments which I have dropped in previous
PRs. I'll submit a separate PR for this.
I renamed the `options` parameter to `swagger_ui_options` since it only
contains swagger UI options. This is a breaking change though, and we'll
need to highlight this upon release.
We still have quite a lot of `App`, `MiddlewareApp`, and abstract
classes. It would be great if we could find a way to reduce those
further, or at least find better naming to make it more clear what each
one does 🙂 .
Finally, I added examples on how the middleware can be used with third
party frameworks under `examples/frameworks`. Currently there's an
example for Starlette and Quart, but this should be easy to extend. They
also show how the `ASGIDecorator` and `StarletteDecorator` from my
previous PR can be used.
This PR contains 2 main changes:
- Expose additional context. We now expose the scope, operation,
connexion context, and receive channel as context aware globals. This
makes them available to the decorators independent of the framework in
between. The user will also be able to use these.
I also implemented a `TestContext` class which can be used to populate
the context during testing. It's minimal, but can be extended towards
the future.
- Rename the decorators to be framework specific. This is part of a
bigger change for which I'll submit a follow up PR. I was working on
this first when it became clear that the context would need to be
extended, which is why this is already included.
This PR updates the examples for Connexion 3.0 and merges them for
OpenAPI and Swagger.
2 examples required some changes to make them work:
- The reverse proxy example required some fixes to the
SwaggerUIMiddleware to leverage the `root_path` correctly. This is
included in the PR.
- The enforced defaults example requires the json validator to adapt the
body and pass it on. We currently pass on the original body after
validation, and I'm not sure if we should change this. I'll submit a
separate PR to discuss this.