Skip to content

Commit 44ea933

Browse files
authored
Connexion 2.0 (#619)
- App and Api options must be provided through the "options" argument (``old_style_options`` have been removed). - You must specify a form content-type in 'consumes' in order to consume form data. - The `Operation` interface has been formalized in the `AbstractOperation` class. - The `Operation` class has been renamed to `Swagger2Operation`. - Array parameter deserialization now follows the Swagger 2.0 spec more closely. In situations when a query parameter is passed multiple times, and the collectionFormat is either csv or pipes, the right-most value will be used. For example, `?q=1,2,3&q=4,5,6` will result in `q = [4, 5, 6]`. The old behavior is available by setting the collectionFormat to `multi`, or by importing `decorators.uri_parsing.AlwaysMultiURIParser` and passing `parser_class=AlwaysMultiURIParser` to your Api. - The spec validator library has changed from `swagger-spec-validator` to `openapi-spec-validator`. - Errors that previously raised `SwaggerValidationError` now raise the `InvalidSpecification` exception. All spec validation errors should be wrapped with `InvalidSpecification`. - Support for nullable/x-nullable, readOnly and writeOnly/x-writeOnly has been added to the standard json schema validator. - Custom validators can now be specified on api level (instead of app level). - Added support for basic authentication and apikey authentication - If unsupported security requirements are defined or ``x-tokenInfoFunc``/``x-tokenInfoUrl`` is missing, connexion now denies requests instead of allowing access without security-check. - Accessing ``connexion.request.user`` / ``flask.request.user`` is no longer supported, use ``connexion.context['user']`` instead
1 parent 08faf2a commit 44ea933

File tree

160 files changed

+4552
-39678
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

160 files changed

+4552
-39678
lines changed

README.rst

Lines changed: 72 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,12 @@ Connexion
2929
:target: https://github.com/zalando/connexion/blob/master/LICENSE
3030
:alt: License
3131

32-
Connexion is a framework on top of Flask_ that automagically handles
33-
HTTP requests based on `OpenAPI 2.0 Specification`_ (formerly known as
34-
Swagger Spec) of your API described in `YAML format`_. Connexion
35-
allows you to write a Swagger specification, then maps the
36-
endpoints to your Python functions; this makes it unique, as many
37-
tools generate the specification based on your Python
38-
code. You can describe your REST API in as much detail as
39-
you want; then Connexion guarantees that it will work as
40-
you specified.
32+
Connexion is a framework that automagically handles HTTP requests based on `OpenAPI Specification`_
33+
(formerly known as Swagger Spec) of your API described in `YAML format`_. Connexion allows you to
34+
write an OpenAPI specification, then maps the endpoints to your Python functions; this makes it
35+
unique, as many tools generate the specification based on your Python code. You can describe your
36+
REST API in as much detail as you want; then Connexion guarantees that it will work as you
37+
specified.
4138

4239
We built Connexion this way in order to:
4340

@@ -77,6 +74,25 @@ Other Sources/Mentions
7774
- Connexion listed on Swagger_'s website
7875
- Blog post: `Crafting effective Microservices in Python`_
7976

77+
New in Connexion 2.0:
78+
---------------------
79+
- App and Api options must be provided through the "options" argument (``old_style_options`` have been removed).
80+
- You must specify a form content-type in 'consumes' in order to consume form data.
81+
- The `Operation` interface has been formalized in the `AbstractOperation` class.
82+
- The `Operation` class has been renamed to `Swagger2Operation`.
83+
- Array parameter deserialization now follows the Swagger 2.0 spec more closely.
84+
In situations when a query parameter is passed multiple times, and the collectionFormat is either csv or pipes, the right-most value will be used.
85+
For example, `?q=1,2,3&q=4,5,6` will result in `q = [4, 5, 6]`.
86+
The old behavior is available by setting the collectionFormat to `multi`, or by importing `decorators.uri_parsing.AlwaysMultiURIParser` and passing `parser_class=AlwaysMultiURIParser` to your Api.
87+
- The spec validator library has changed from `swagger-spec-validator` to `openapi-spec-validator`.
88+
- Errors that previously raised `SwaggerValidationError` now raise the `InvalidSpecification` exception.
89+
All spec validation errors should be wrapped with `InvalidSpecification`.
90+
- Support for nullable/x-nullable, readOnly and writeOnly/x-writeOnly has been added to the standard json schema validator.
91+
- Custom validators can now be specified on api level (instead of app level).
92+
- Added support for basic authentication and apikey authentication
93+
- If unsupported security requirements are defined or ``x-tokenInfoFunc``/``x-tokenInfoUrl`` is missing, connexion now denies requests instead of allowing access without security-check.
94+
- Accessing ``connexion.request.user`` / ``flask.request.user`` is no longer supported, use ``connexion.context['user']`` instead
95+
8096
How to Use
8197
==========
8298

@@ -160,8 +176,8 @@ identify which Python function should handle each URL.
160176
If you provide this path in your specification POST requests to
161177
``http://MYHOST/hello_world``, it will be handled by the function
162178
``hello_world`` in the ``myapp.api`` module. Optionally, you can include
163-
``x-swagger-router-controller`` in your operation definition, making
164-
``operationId`` relative:
179+
``x-swagger-router-controller`` (or ``x-openapi-router-controller``) in your
180+
operation definition, making ``operationId`` relative:
165181

166182
.. code-block:: yaml
167183
@@ -249,8 +265,8 @@ function expects an argument named ``message`` and assigns the value
249265
of the endpoint parameter ``message`` to your view function.
250266

251267
.. warning:: When you define a parameter at your endpoint as *not* required, and
252-
this argument does not have default value in your Python view, you will get
253-
a "missing positional argument" exception whenever you call this endpoint
268+
this argument does not have default value in your Python view, you will get
269+
a "missing positional argument" exception whenever you call this endpoint
254270
WITHOUT the parameter. Provide a default value for a named argument or use
255271
``**kwargs`` dict.
256272

@@ -300,22 +316,25 @@ You can implement your own URI parsing behavior by inheriting from
300316
``connextion.decorators.uri_parsing.AbstractURIParser``.
301317

302318
There are three URI parsers included with connection.
303-
1. AlwaysMultiURIParser (default)
304-
This parser is backwards compatible, and joins together multiple instances
305-
of the same query parameter.
306-
2. Swagger2URIParser
307-
This parser adheres to the Swagger 2.0 spec, and will only join together
308-
multiple instance of the same query parameter if the ``collectionFormat``
309-
is set to ``multi``. Query parameters are parsed from left to right, so
310-
if a query parameter is defined twice, then the right-most definition wins.
311-
For example, if you provided a URI with the query string
312-
``?letters=a,b,c&letters=d,e,f``, and ``collectionFormat: csv``, then
313-
connexion will set ``letters = ['d', 'e', 'f']``
314-
3. FirstValueURIParser
315-
This parser behaves like the Swagger2URIParser, except that it prefers the
316-
first defined value. For example, if you provided a URI with the query
317-
string ``?letters=a,b,c&letters=d,e,f`` and ``collectionFormat: csv``
318-
then connexion will set ``letters = ['a', 'b', 'c']``
319+
320+
+----------------------+---------------------------------------------------------------------------+
321+
| AlwaysMultiURIParser | This parser is backwards compatible, and joins together multiple instances|
322+
| (default) | of the same query parameter. |
323+
+----------------------+---------------------------------------------------------------------------+
324+
| Swagger2URIParser | This parser adheres to the Swagger 2.0 spec, and will only join together |
325+
| | multiple instance of the same query parameter if the ``collectionFormat`` |
326+
| | is set to ``multi``. Query parameters are parsed from left to right, so |
327+
| | if a query parameter is defined twice, then the right-most definition |
328+
| | wins. For example, if you provided a URI with the query string |
329+
| | ``?letters=a,b,c&letters=d,e,f``, and ``collectionFormat: csv``, then |
330+
| | connexion will set ``letters = ['d', 'e', 'f']`` |
331+
+----------------------+---------------------------------------------------------------------------+
332+
| FirstValueURIParser | This parser behaves like the Swagger2URIParser, except that it prefers |
333+
| | the first defined value. For example, if you provided a URI with the query|
334+
| | string ``?letters=a,b,c&letters=d,e,f`` and ``collectionFormat: csv`` |
335+
| | hen connexion will set ``letters = ['a', 'b', 'c']`` |
336+
+----------------------+---------------------------------------------------------------------------+
337+
319338

320339
Parameter validation
321340
^^^^^^^^^^^^^^^^^^^^
@@ -400,15 +419,17 @@ parameters to the underlying `werkzeug`_ server.
400419
The Swagger UI Console
401420
----------------------
402421

403-
The Swagger UI for an API is available, by default, in
404-
``{base_path}/ui/`` where ``base_path`` is the base path of the API.
422+
The Swagger UI for an API is available through pip extras.
423+
You can install it with ``pip install connexion[swagger-ui]``.
424+
It will be served up at ``{base_path}/ui/`` where ``base_path`` is the
425+
base path of the API.
405426

406427
You can disable the Swagger UI at the application level:
407428

408429
.. code-block:: python
409430
410431
app = connexion.App(__name__, specification_dir='swagger/',
411-
swagger_ui=False)
432+
options={"swagger_ui": False})
412433
app.add_api('my_api.yaml')
413434
414435
@@ -417,28 +438,40 @@ You can also disable it at the API level:
417438
.. code-block:: python
418439
419440
app = connexion.App(__name__, specification_dir='swagger/')
420-
app.add_api('my_api.yaml', swagger_ui=False)
441+
app.add_api('my_api.yaml', options={"swagger_ui": False})
421442
422443
If necessary, you can explicitly specify the path to the directory with
423-
swagger-ui to not use the connexion-embedded swagger-ui distro.
444+
swagger-ui to not use the connexion[swagger-ui] distro.
424445
In order to do this, you should specify the following option:
425446

426447
.. code-block:: python
427448
428449
options = {'swagger_path': '/path/to/swagger_ui/'}
429450
app = connexion.App(__name__, specification_dir='swagger/', options=options)
430451
431-
Make sure that ``swagger_ui/index.html`` loads by default local swagger json.
432-
You can use the ``api_url`` jinja variable for this purpose:
452+
If you wish to provide your own swagger-ui distro, note that connextion
453+
expects a jinja2 file called ``swagger_ui/index.j2`` in order to load the
454+
correct ``swagger.json`` by default. Your ``index.j2`` file can use the
455+
``openapi_spec_url`` jinja variable for this purpose:
433456

434457
.. code-block::
435458
436-
const ui = SwaggerUIBundle({ url: "{{ api_url }}/swagger.json"})
459+
const ui = SwaggerUIBundle({ url: "{{ openapi_spec_url }}"})
460+
461+
Additionally, if you wish to use swagger-ui-3.x.x, it is also provided by
462+
installing connexion[swagger-ui], and can be enabled like this:
463+
464+
.. code-block:: python
465+
466+
from swagger_ui_bundle import swagger_ui_3_path
467+
options = {'swagger_path': swagger_ui_3_path}
468+
app = connexion.App(__name__, specification_dir='swagger/', options=options)
469+
437470
438471
Server Backend
439472
--------------
440473

441-
Connexion uses the default Flask server. For asynchronous
474+
By default Connexion uses the Flask_ server. For asynchronous
442475
applications, you can also use Tornado_ as the HTTP server. To do
443476
this, set your server to ``tornado``:
444477

@@ -534,7 +567,7 @@ Unless required by applicable law or agreed to in writing, software distributed
534567
.. _Swagger: http://swagger.io/open-source-integrations/
535568
.. _Jinja2: http://jinja.pocoo.org/
536569
.. _rfc6750: https://tools.ietf.org/html/rfc6750
537-
.. _OpenAPI 2.0 Specification: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md
570+
.. _OpenAPI Specification: https://www.openapis.org/
538571
.. _Operation Object: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#operation-object
539572
.. _swager.spec.security_definition: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#security-definitions-object
540573
.. _swager.spec.security_requirement: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#security-requirement-object

connexion/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def _required_lib(exec_info, *args, **kwargs):
2020

2121

2222
try:
23-
from .apis.flask_api import FlaskApi
23+
from .apis.flask_api import FlaskApi, context # NOQA
2424
from .apps.flask_app import FlaskApp
2525
from flask import request # NOQA
2626
except ImportError: # pragma: no cover

0 commit comments

Comments
 (0)