Files
connexion/docs/v3.rst
Julian Berman 5d7eb0bdab Fix two broken links in the docs. (#1854)
(One was enountered manually, the other found via Sphinx's builtin
linkcheck builder, which also confirms there aren't really any others.)

I often suggest using Sphinx's
[`default_role`](https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-default_role)
setting to make writing docs quite a bit less noisy in a fairly
uncontroversial way. A toxenv / docs setup in CI also seems like a
decent idea. As is, there is a small part of the docs which isn't being
rendered because it contains errors (in the output below it's the one
`CRITICAL`), and there are some other interlinks which are broken.
Essentially, IMHO, running Sphinx without `-n -T -W` is a recipe for
brokenness unfortunately. This is what one sees when doing so, even
after this PR:

<details>

```

/Users/julian/Development/connexion/docs/request.rst:194: CRITICAL: Unexpected section title.

Form data

/Users/julian/Development/connexion/connexion/lifecycle.py:docstring of connexion.lifecycle.ConnexionRequest.from_starlette_request:1: WARNING: py:class reference target not found: starlette.requests.Request
/Users/julian/Development/connexion/connexion/operations/openapi.py:docstring of connexion.operations.openapi.OpenAPIOperation:1: WARNING: py:class reference target not found: integer
/Users/julian/Development/connexion/connexion/operations/openapi.py:docstring of connexion.operations.openapi.OpenAPIOperation:1: WARNING: py:class reference target not found: AbstractURIParser
/Users/julian/Development/connexion/connexion/operations/openapi.py:docstring of connexion.operations.OpenAPIOperation.function:1: WARNING: py:class reference target not found: types.FunctionType
/Users/julian/Development/connexion/connexion/operations/swagger2.py:docstring of connexion.operations.swagger2.Swagger2Operation:1: WARNING: py:class reference target not found: integer
/Users/julian/Development/connexion/connexion/operations/swagger2.py:docstring of connexion.operations.swagger2.Swagger2Operation:1: WARNING: py:class reference target not found: AbstractURIParser
/Users/julian/Development/connexion/connexion/operations/swagger2.py:docstring of connexion.operations.Swagger2Operation.function:1: WARNING: py:class reference target not found: types.FunctionType
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/problem.py:docstring of connexion.problem.problem:14: WARNING: py:class reference target not found: type: str
/Users/julian/Development/connexion/connexion/problem.py:docstring of connexion.problem.problem:1: WARNING: py:class reference target not found: ConnexionResponse
/Users/julian/Development/connexion/connexion/exceptions.py:docstring of connexion.exceptions:1: WARNING: py:class reference target not found: jsonschema.exceptions.ValidationError
/Users/julian/Development/connexion/connexion/exceptions.py:docstring of connexion.exceptions:1: WARNING: py:class reference target not found: starlette.exceptions.HTTPException
/Users/julian/Development/connexion/connexion/exceptions.py:docstring of connexion.exceptions:1: WARNING: py:class reference target not found: starlette.exceptions.HTTPException
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp.add_wsgi_middleware:1: WARNING: py:class reference target not found: types.TracebackType
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.MiddlewarePosition:1: WARNING: py:class reference target not found: ExceptionMiddleware
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.MiddlewarePosition:1: WARNING: py:class reference target not found: SwaggerUIMiddleware
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.MiddlewarePosition:1: WARNING: py:class reference target not found: RoutingMiddleware
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.MiddlewarePosition:1: WARNING: py:class reference target not found: SecurityMiddleware
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.MiddlewarePosition:1: WARNING: py:class reference target not found: RequestValidationMiddleware
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.MiddlewarePosition:1: WARNING: py:class reference target not found: ContextMiddleware
/Users/julian/Development/connexion/docs/middleware.rst:121: WARNING: py:class reference target not found: SecurityMiddleware
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:3: WARNING: py:obj reference target not found: middleware.main.ConnexionMiddleware.default_middlewares
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:21: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:23: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:26: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:28: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:2: WARNING: py:obj reference target not found: middleware.main.ConnexionMiddleware.default_middlewares
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:12: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:23: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:25: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:28: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:30: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:1: WARNING: py:obj reference target not found: middleware.main.ConnexionmMiddleware.default_middlewares
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:19: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:21: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:24: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:26: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:3: WARNING: py:obj reference target not found: middleware.main.ConnexionMiddleware.default_middlewares
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:21: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:23: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:26: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:28: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:2: WARNING: py:obj reference target not found: middleware.main.ConnexionMiddleware.default_middlewares
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:12: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:23: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:25: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:28: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:30: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:1: WARNING: py:obj reference target not found: middleware.main.ConnexionmMiddleware.default_middlewares
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:19: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:21: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:24: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:26: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:11: WARNING: py:class reference target not found: resolver.Resolver
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:18: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:20: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:23: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:25: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:11: WARNING: py:class reference target not found: resolver.Resolver
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:18: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:20: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:23: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/apps/abstract.py:docstring of connexion.apps.abstract.AbstractApp.add_api:25: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_api:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_api:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_api:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_api:11: WARNING: py:class reference target not found: resolver.Resolver
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_api:18: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_api:20: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_api:23: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_api:25: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:4: WARNING: py:obj reference target not found: middleware.main.ConnexionMiddleware.default_middlewares
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:22: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:24: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:27: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:29: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:18: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:20: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:23: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp:25: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/apps/asynchronous.py:docstring of connexion.apps.asynchronous.AsyncApp.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:3: WARNING: py:obj reference target not found: middleware.main.ConnexionMiddleware.default_middlewares
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:13: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:24: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:26: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:29: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:31: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.abstract.AbstractApp.add_api:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:18: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:20: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:23: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp:25: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/apps/flask.py:docstring of connexion.apps.flask.FlaskApp.add_wsgi_middleware:1: WARNING: py:class reference target not found: types.TracebackType
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:2: WARNING: py:obj reference target not found: middleware.main.ConnexionmMiddleware.default_middlewares
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:20: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:22: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:25: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:27: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_api:1: WARNING: py:class reference target not found: pathlib.Path
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_api:1: WARNING: py:class reference target not found: connexion.jsonifier.Jsonifier
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_api:1: WARNING: py:class reference target not found: connexion.uri_parsing.AbstractURIParser
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:18: WARNING: py:class reference target not found: options.ConnexionOptions
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:20: WARNING: py:mod reference target not found: uri_parsing
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:23: WARNING: py:obj reference target not found: validators.VALIDATOR_MAP
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware:25: WARNING: py:obj reference target not found: security.SECURITY_HANDLERS
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/middleware/main.py:docstring of connexion.middleware.main.ConnexionMiddleware.add_error_handler:1: WARNING: py:class reference target not found: connexion.lifecycle.ConnexionResponse
/Users/julian/Development/connexion/connexion/lifecycle.py:docstring of connexion.lifecycle.ConnexionRequest.from_starlette_request:1: WARNING: py:class reference target not found: starlette.requests.Request
/Users/julian/Development/connexion/connexion/resolver.py:docstring of connexion.resolver.RelativeResolver:1: WARNING: py:class reference target not found: types.ModuleType
/Users/julian/Development/connexion/connexion/resolver.py:docstring of connexion.resolver.RelativeResolver:1: WARNING: py:class reference target not found: types.FunctionType
/Users/julian/Development/connexion/docs/testing.rst:29: WARNING: py:class reference target not found: TestContext
/Users/julian/Development/connexion/connexion/problem.py:docstring of connexion.problem.problem:14: WARNING: py:class reference target not found: type: str
/Users/julian/Development/connexion/connexion/problem.py:docstring of connexion.problem.problem:1: WARNING: py:class reference target not found: ConnexionResponse
/Users/julian/Development/connexion/docs/exceptions.rst:1: WARNING: broken link: about:blank ()
/Users/julian/Development/connexion/docs/context.rst:1: WARNING: broken link: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#componentsObject (Anchor 'componentsObject' not found)
/Users/julian/Development/connexion/docs/v3.rst:105: WARNING: broken link: https://github.com/abersheeran/a2wsgi#convert-asgi-app-to-wsgi-app (Anchor 'convert-asgi-app-to-wsgi-app' not found)
/Users/julian/Development/connexion/docs/context.rst:1: WARNING: broken link: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#security-definitions-object (Anchor 'security-definitions-object' not found)
/Users/julian/Development/connexion/docs/context.rst:1: WARNING: broken link: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#definitionsObject (Anchor 'definitionsObject' not found)
docs: exit 1 (5.40 seconds) /Users/julian/Development/connexion> .tox/docs/bin/python -m sphinx -n -T -q -b linkcheck docs /Users/julian/Development/connexion/.tox/docs/tmp/build pid=35935
.pkg: _exit> python /Users/julian/.dotfiles/.local/share/virtualenvs/tox/lib/python3.12/site-packages/pyproject_api/_backend.py True poetry.core.masonry.api
  docs: FAIL code 1 (7.91=setup[1.96]+cmd[0.55,5.40] seconds)
  evaluation failed :( (7.95 seconds)

```

</details>

I'm trying to actually use connexion for the first time, but if the
above sounds reasonable to y'all maintainers I can try to come back to
it and send a PR later.
2024-02-11 22:46:22 +01:00

323 lines
11 KiB
ReStructuredText

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 new ``AsyncApp`` allow you to use Connexion as a stand-alone framework
* The ``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.
.. _in-depth blog post: https://medium.com/@robbe.sneyders/a5dc17e81ff8?source=friends_link&sk=de5a7a67ccae8a03752f5e8e1dc68d48
.. _our documentation: https://connexion.readthedocs.io/en/stable/
Getting started with Connexion 3
--------------------------------
If you're getting started with Connexion 3 for a new project, follow the
:doc:`quickstart <quickstart>`. All documentation has been updated for Connexion 3.
Migrating from Connexion 2
--------------------------
The rest of this page will focus on how to migrate from Connexion 2 to Connexion 3.
This page will show examples migrating the ``connexion.FlaskApp``. However all Connexion 3 examples
should work for ``connexion.AsyncApp`` as well. If you are not relying on the underlying
Flask application, or you are coming from the old ``AiohttpApp``, we recommend migrating to the
``connexion.AsyncApp`` instead.
Running the application
'''''''''''''''''''''''
There have been 2 changes related to running the application:
- You now MUST run the Connexion application instead of the underlying Flask application.
- You should use an ASGI server instead of a WSGI server.
While the following would work on Connexion 2, it no longer works on Connexion 3:
.. code-block:: python
:caption: **hello.py**
import connexion
app = connexion.App(__name__)
flask_app = app.app
if __name__ == "__main__":
flask_app.run()
.. code-block:: bash
$ flask --app hello:flask_app
.. code-block:: bash
$ gunicorn hello:flask_app
Instead, you need to run the Connexion application using an ASGI server:
.. code-block:: python
:caption: **hello.py**
import connexion
app = connexion.App(__name__)
if __name__ == "__main__":
app.run()
.. code-block:: bash
$ uvicorn run:app
.. code-block:: bash
$ gunicorn -k uvicorn.workers.UvicornWorker run:app
.. warning::
You can wrap Connexion with the `ASGIMiddleware`_ offered by `a2wsgi`_ to run it with a WSGI
server. You will however lose the benefits offered by ASGI, and performance might be
impacted. You should only use this as a temporary workaround until you can switch to an ASGI
server.
For more information, check :ref:`Running your application <quickstart:Running your application>`.
.. _ASGIMiddleware: https://github.com/abersheeran/a2wsgi#convert-asgi-app-to-wsgi-app
.. _a2wsgi: https://github.com/abersheeran/a2wsgi
**Workers and threads**
You can still use workers as before, however you should not use threads with ASGI, since it
handles concurrency using an async event loop instead.
In the ``AsyncApp``, concurrency is completely handled by the async event loop.
The ``FlaskApp`` is more complex, since the underlying Flask app is WSGI instead of ASGI.
Concurrency in the middleware stack is handled by the async event loop, but once a request is
passed to the underlying Flask app, it is executed in a thread pool (of 10 workers) automatically.
Error handlers
``````````````
There have been 2 changes related to running the application:
- The interface of the error handlers changed, with a request now being injected as well
- The error handlers now should be registered on the Connexion App, not the underlying Flask App
Connexion 2:
.. code-block:: python
:caption: **hello.py**
import connexion
def not_found_handler(exc: Exception) -> flask.Response:
...
app = connexion.App(__name__)
flask_app = app.app
app.add_error_handler(404, not_found_handler) # either
flask_app.register_error_handler(404, not_found_handler) # or
Connexion 3:
.. code-block:: python
:caption: **hello.py**
import connexion
from connexion.lifecycle import ConnexionRequest, ConnexionResponse
def not_found_handler(request: ConnexionRequest, exc: Exception) -> ConnexionResponse:
...
app = connexion.App(__name__)
app.add_error_handler(404, not_found_handler)
You can easily generate Connexion responses adhering to the `Problem Details for HTTP APIs`_
standard by using the ``connexion.problem.problem`` module:
.. code-block:: python
from connexion.problem import problem
def not_found_handler(request: ConnexionRequest, exc: Exception) -> ConnexionResponse:
return problem(
title=http_facts.HTTP_STATUS_CODES.get(404),
detail="The resource was not found",
status=404,
)
.. dropdown:: View a detailed reference of the ``connexion.problem.problem`` function
:icon: eye
.. autofunction:: connexion.problem.problem
:noindex:
For more information, check the :doc:`exceptions` documentation.
.. _Problem Details for HTTP APIs: https://datatracker.ietf.org/doc/html/rfc7807
Flask extensions and WSGI middleware
````````````````````````````````````
Certain Flask extensions and WSGI middleware might no longer work, since some functionaity was
moved outside the scope of the Flask application. Extensions and middleware impacting the
following functionality should now be implemented as ASGI middleware instead:
- Exception handling
- Swagger UI
- Routing
- Security
- Validation
One such example is CORS support, since it impacts routing. It can no longer be added via the
``Flask-Cors`` extension. See :ref:`Connexion Cookbook: CORS <cookbook:CORS>` on how to use a
``CORSMiddleware`` instead.
See :doc:`middleware` for general documentation on ASGI middleware.
Custom validators
`````````````````
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.
.. code-block:: python
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.
.. code-block:: python
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.
Swagger UI Options
------------------
The ``options`` argument has been renamed to ``swagger_ui_options`` and now takes an instance
of the :class:`.SwaggerUIOptions`. The naming of the options themselves have been changed to
better represent their meaning.
.. code-block:: python
import connexion
from connexion.options import SwaggerUIOptions
swagger_ui_options = SwaggerUIOptions(
swagger_ui=True,
swagger_ui_path="docs",
)
app = connexion.FlaskApp(__name__, swagger_ui_options=swagger_ui_options) # either
app.add_api("openapi.yaml", swagger_ui_options=swagger_ui_options) # or
See :doc:`swagger_ui` for more information.
Smaller breaking changes
------------------------
* The ``uri_parser_class`` is now passed to the ``App`` or its ``add_api()`` method directly
instead of via the ``options`` argument.
* The ``jsonifier`` is now passed to the ``App`` or its ``add_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 Starlette ``Request`` instead of a Flask ``Request``
* 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 supported
* The parameter ``pass_context_arg_name`` has been removed. Context is now available as global
request-level context, or can be passed in by defining a ``context_`` parameter in your view function.
* The ``MethodViewResolver`` has been renamed to ``MethodResolver``, and a new ``MethodViewResolver``
has been added to work with Flask's ``MethodView`` 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`` and ``OPTIONS`` methods as well.
* The signature of error handlers has changed and default Flask error handlers are now replaced
with default Connexion error handlers which work the same for ``AsyncApp`` and
``ConnexionMiddleware``.
Non-breaking changes
--------------------
* Relative and nested refs are now supported in OpenAPI / Swagger specifications
* The ``required`` keyword is now supported for requestBodies
* HTTP exceptions are now implemented as a hierarchy
* Connexion now exposes ``context``, ``operation``, ``receive``, ``scope`` as global request-level context
* Connexion 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.
.. _Github release page: https://github.com/spec-first/connexion/releases/tag/3.0.0
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`_
.. _discussion: https://github.com/spec-first/connexion/discussions
.. _Github tracker: https://github.com/spec-first/connexion/issues