Commit Graph

1352 Commits

Author SHA1 Message Date
Robbe Sneyders
15e985e864 Introduce poetry (#1628) 2023-02-07 20:17:38 +01:00
Robbe Sneyders
022bb8f34a Coerce types only in uri parser (#1627)
This PR moves all type coercing into the URI parsers and makes sure it's
only done once for each code path.
2023-01-30 08:49:49 +01:00
Robbe Sneyders
769120e5a0 Cache operation body definition (#1626)
Fixes a small todo I left in the code before to cache the body
definition on the operation.
2023-01-26 15:41:50 +01:00
Robbe Sneyders
1211d1b655 Enable enforcing defaults (#1616)
This PR is a proposal to enforce defaults in json bodies.

The standard JsonRequestBodyValidator does not adapt the body. Instead, I added a DefaultsJsonRequestBodyValidator which does. The user can easily activate enforcing default by passing this Validator in a validator_map.

I would have liked connexion to have an enforce_defaults flag, but it would be hard to make this compatible with the validator_map argument.
2023-01-26 15:08:27 +01:00
Robbe Sneyders
edb0381af3 Implement user facing interface for ConnexionMiddleware (#1621)
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.
2023-01-26 14:40:29 +01:00
Robbe Sneyders
2bf18f6629 Expose additional context (#1620)
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.
2023-01-13 22:01:08 +01:00
Robbe Sneyders
f064fd04b7 Switch to own maintained version of swagger-ui (#1619)
Fixes #1412
Fixes #1516 

Since [swagger-ui-bundle](https://github.com/dtkav/swagger_ui_bundle) is
no longer maintained, I forked it under the spec-first organization as
[py-swagger-ui](https://github.com/spec-first/py-swagger-ui). This PR
updates connexion to use it instead.
2023-01-09 18:57:15 +01:00
Robbe Sneyders
90672873c4 Refactor decorators (#1618)
This PR refactors the decorators so they can be used independently of an
API, which will allow them to be used by other wrapped frameworks as
well.
2023-01-08 00:30:44 +01:00
Robbe Sneyders
de3b6f6895 Extract framework specific functionality into framework module & class 2023-01-03 22:38:33 +01:00
Robbe Sneyders
6fdb807567 Extract response parsing into decorator 2023-01-03 22:29:21 +01:00
Robbe Sneyders
2c7f83dd4a Refactor parameter decorator into sync and async version 2023-01-03 22:29:21 +01:00
Robbe Sneyders
073f0d446e Update examples for Connexion 3.0 (#1615)
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.
2022-12-30 20:34:19 +01:00
Robbe Sneyders
e5784c5741 Add async app (#1613)
Fixes #1534

Changes proposed in this pull request:
- Adds a "native" async app based on lower level Starlette tools. It
leverages the routing already done in the middleware.
- Extracts code related to the parameter decorator out of the Operation
objects

There's some more work to be done, but this PR is already quite huge, so
I wanted to stop at a point where I got all the tests and a simple
example working.
- Still some general refactoring. I left some TODOs, and the Operation
classes are still relied on in too many places.
- Sync routes on an Async app should receive async decorators, so they
can access the body using `await`. The decorators should then run the
sync route in a threadpool to prevent blocking.
- We should be able to reuse the parameter decorator for all ASGI apps
since we're working with a Starlette Request which we can get directly
from the scope and receive channel, which we can make available as
context. This means we'll pass Starlette Datastructures to the view
functions (eg. FormData, UploadFiles, ...), but if this is opt-in, I
don't see any issue with this.
- We should be able to reuse the response parsing for Starlette apps as
well since it returns a StarletteResponse.
- We should test the AsyncApp as well. I'm hoping we can do this quite
quickly by generating a test client for it in the fixtures as well, but
in the long term some more work will be needed.
2022-12-28 18:36:36 +01:00
Robbe Sneyders
0add539f4c Add custom WSGIMiddleware 2022-12-26 20:51:46 +01:00
Robbe Sneyders
5a0c292b44 Add async app 2022-12-26 20:51:46 +01:00
Robbe Sneyders
db6ebecc8a Drop deprecated response serialization 2022-12-23 11:15:10 +01:00
Robbe Sneyders
7acbad0691 Move parameter decorator related methods out of operation classes 2022-12-23 11:15:10 +01:00
Robbe Sneyders
2438114b71 Rename and move decorators 2022-12-23 11:12:22 +01:00
Robbe Sneyders
32bb8db462 Remove empty decorators 2022-12-23 11:12:22 +01:00
Robbe Sneyders
1af47335ed Move parameter validation to middleware (#1610)
Fixes https://github.com/spec-first/connexion/issues/1525

This PR follows up on #1588 and #1591 and moves the last part of
validation, the parameter validation, to the middleware,
2022-12-23 11:03:50 +01:00
enerqi
a8295361e3 Flask apps only signal an exception on real server errors (#1611)
Fixes the problem of non-exceptional "exceptions" being recorded by
telemetry systems as a serious error. This expands on the changes made
in #1326. The intention of that other change seems to be making
telemetry systems like Sentry record serious errors. Diving into the
Sentry implementation even shows that the signalled exception is
recorded at "level" = "error".

The root of the problem is that exceptions are being used for control
flow, which is not ideal - convenient for app writers but not always for
library maintainers. The connexion BadRequestProblem and
NotFoundProblem, for example, should not be recorded as an error in a
telemetry system. In my case
[elastic-apm-python](https://github.com/elastic/apm-agent-python) is
receiving these signals and recording 4xx events as serious errors.

This pull request only propagates an exception signal to flask if it's a
serious error.

Aiohttp applications have a similar problem with exceptions being used
for control flow - the problems middleware will convert the exception
into an appropriate problem response but things like the elastic apm
python telemetry middleware will see that exception and record it as a
serious error. Interestingly aiohttp also uses exceptions for control
flow and the elastic apm agent was patched to specifically ignore aio
web exceptions below the 5xx status response range. Elastic apm and
sentry cannot be expected to be aware of non-serious control flow
exceptions used by various libraries though. So, a solution for Aiohttp
applications is a separate problem.

Co-authored-by: Enerqi <>
2022-12-07 07:59:08 +01:00
Robbe Sneyders
825c682086 Remove strict_validation and validate_responses from API and Operation classes 2022-11-14 23:31:09 +01:00
Robbe Sneyders
2581a7e4c4 Move parameter validation to middleware 2022-11-14 23:15:31 +01:00
Robbe Sneyders
53621d0db8 Move validators into separate directory 2022-11-11 21:55:45 +01:00
Robbe Sneyders
670bee920b Merge pull request #1595 from spec-first/feature/form-validation
Add form data validator for validation middleware
2022-11-04 19:14:44 +01:00
Robbe Sneyders
a1b1f53076 Polish form validation (#1604)
* Create MediaTypeDict class for range matching

* Extract parsing instead of using jsonifier

* Add default validator class as parameter defaults

* Clean up form validation
2022-11-04 11:07:03 +01:00
Robbe Sneyders
9d7258c25d Create MediaTypeDict class for range matching (#1603) 2022-11-04 11:07:03 +01:00
Robbe Sneyders
b8bdcc999d Move Swagger 2 form validation to middleware (#1599)
* Move Swagger 2 form validation to middleware

* Add unit test for form transformation
2022-11-04 11:07:03 +01:00
Ruwann
68d5b4fe91 Add form parsing via URIParser (#1596) 2022-11-04 00:43:02 +01:00
Robbe Sneyders
269ea2c4fe Add form data validator for OpenAPI 3
Add python-multipart dependency to setup.py

Copy validator map so it remains unchanged
2022-11-04 00:42:59 +01:00
gaetano-guerriero
c899132e17 Avoid warning with jsonschema 4.16.0 (#1601)
Accessing jsonschema.draftN_format_checker is now deprecated
2022-10-07 08:00:47 +02:00
Robbe Sneyders
59f619c9a5 Remove support for deprecated x-body-name position (#1600) 2022-10-04 23:18:41 +02:00
Robbe Sneyders
1ab5400c0b Move JSON response body validation to middleware (#1591)
* Extract boilerplate code into Routed base classes

* Use typing_extensions for Python 3.7 Protocol support

* Use Mock instead of AsyncMock

* Extract response validation to middleware

* Refactor Request validation to match Response validation

* Factor out shared functionality

* Fix typo in TextResponseBodyValidator class name

* Fix string formatting

* Use correct schema to check nullability in response validation
2022-10-03 23:01:21 +02:00
Robbe Sneyders
181c61bfb6 Extract boilerplate code into Routed base classes (#1590)
* Extract boilerplate code into Routed base classes

* Use typing_extensions for Python 3.7 Protocol support

* Use Mock instead of AsyncMock

* Turn properties into class attributes
2022-09-26 20:33:58 +02:00
Robbe Sneyders
024666de89 Explicitly support Flask async routes (#1592) 2022-09-26 20:04:23 +02:00
Leonardo Festa
fc003ca140 Removed internal variable pass_context_arg_name (#1568)
* Removed internal variable pass_context_arg_name

* fixed issue with personalized context name in tests

* restored code from pr suggestion

* restore decorator functionality

now the function accept a pass_context_arg boolean parameter,
instead of the pass_context_arg_name value

* Fixed security test checks, now passes tests

* Removed pass_context_arg, fixed security handler

fixed security handler as suggested
removed pass_context_arg as before

* Fix context injection test

Co-authored-by: Niels Dewulf <87133686+nielsbox@users.noreply.github.com>
Co-authored-by: Robbe Sneyders <robbe.sneyders@ml6.eu>
2022-09-22 22:53:25 +02:00
Robbe Sneyders
7ab4180111 Remove AbstractSwaggerUIAPI class (#1589) 2022-09-18 19:50:48 +02:00
Robbe Sneyders
fb071ea56f Extract JSON request body validation to middleware (#1588)
* Set up code skeleton for validation middleware

* Add more boilerplate code

* WIP

* Add ASGI JSONBodyValidator

* Revert example changes

* Remove incorrect content type test

Co-authored-by: Ruwan <ruwanlambrichts@gmail.com>
2022-09-18 10:55:16 +02:00
John Vandenberg
e4b7827b6d setup.py: Update url (#1586) 2022-09-13 18:57:42 +02:00
Robbe Sneyders
3e52c782eb Use Flask request_ctx instead of _request_ctx_stack (#1583)
* Use Flask request_ctx instead of _request_ctx_stack

* Suppress first party warnings
2022-09-07 08:35:34 +02:00
Robbe Sneyders
45468a14e6 Update json for Flask 2.3 (#1582)
* Update json for Flask 2.3

* Update docstrings
2022-09-06 22:57:13 +02:00
Yasunobu Chiba
5a71737c68 Resolve $ref referring to another $ref (#1584)
* Resolve $ref referring to another $ref.

* Fix issues detected by black.
2022-09-05 17:51:50 +02:00
Florian Greinacher
390c2e355d fix: don't interpret simple parameter as deepObject (#1570)
* fix: don't interpret simple parameter as deepObject

* Fix flake8 issues

Co-authored-by: Robbe Sneyders <robbe.sneyders@ml6.eu>
2022-08-30 18:02:11 +02:00
Robbe Sneyders
e39c255217 Fix tests for Flask 2.2 (#1572) 2022-08-30 18:02:11 +02:00
Motti Lanzkron
5cc9b0e787 Only warn about the schema's x-body-name being deprecated if it's used. (#1554)
Co-authored-by: Motti Lanzkron <motti@microfocus.com>
2022-08-30 18:02:11 +02:00
Ricardo Piro-Rael
a2c679f5a3 Fix OpenAPI parameters containing other parameters (#1523)
* Fix OpenAPI parameters containing other parameters

OpenAPI parameters can be unspecified and sometimes contain other
parameters. The current behavior is to assume it's a bracket parameter
and nest the containing parameter within the contained parameter, which
breaks the schema as the original parameter now seems to contain a
nested object.

We can avert this by checking for the presence of a '[' in the
parameter.

* Trigger Github workflow

Co-authored-by: Ricardo Piro-Rael <rpiro-rael@ironox.com>
2022-08-30 18:02:11 +02:00
Christian Clauss
5f2aaba1fb Remove "type: ignore" by using list(dict), not dict.keys() (#1575)
In Python 3, `list(dict)` is often a better way to express `dict.keys()`

Related to #1560 -- @RobbeSneyders @nielsbox Your review, please.
2022-08-23 11:18:21 +02:00
Robbe Sneyders
67bd37fe77 Activate mypy check in pre-commit (#1560) 2022-08-23 09:02:14 +02:00
Nico Braun
64f42547dc rename method view resolver and pass class args and kwargs to it (#1564)
Signed-off-by: Nico Braun <rainbowstack@gmail.com>
2022-07-05 00:27:05 +02:00
Robbe Sneyders
1aa0567457 Add .git-blame-ignore-revs file with black commit (#1561) 2022-06-29 23:45:20 +02:00