Package: connexion-aiohttp
Connexion=========.. image:: https://badges.gitter.im/zalando/connexion.svg:alt: Join the chat at https://gitter.im/zalando/connexion:target: https://gitter.im/zalando/connexion?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge.. image:: https://travis-ci.org/zalando/connexion.svg?branch=master:target: https://travis-ci.org/zalando/connexion:alt: Travis CI build status.. image:: https://coveralls.io/repos/zalando/connexion/badge.svg?branch=master:target: https://coveralls.io/r/zalando/connexion?branch=master:alt: Coveralls status.. image:: https://img.shields.io/pypi/v/connexion.svg:target: https://pypi.python.org/pypi/connexion:alt: Latest Version.. image:: https://img.shields.io/pypi/status/connexion.svg:target: https://pypi.python.org/pypi/connexion:alt: Development Status.. image:: https://img.shields.io/pypi/pyversions/connexion.svg:target: https://pypi.python.org/pypi/connexion:alt: Python Versions.. image:: https://img.shields.io/pypi/l/connexion.svg:target: https://github.com/zalando/connexion/blob/master/LICENSE:alt: LicenseConnexion is a framework on top of Flask_ that automagically handlesHTTP requests based on `OpenAPI 2.0 Specification`_ (formerly known asSwagger Spec) of your API described in `YAML format`_. Connexionallows you to write a Swagger specification, then maps theendpoints to your Python functions; this makes it unique, as manytools generate the specification based on your Pythoncode. You can describe your REST API in as much detail asyou want; then Connexion guarantees that it will work asyou specified.We built Connexion this way in order to:- simplify the development process- confirm expectations about what your API will look likeConnexion Features:-------------------- Validates requests and endpoint parameters automatically, based onyour specification- Provides a Web Swagger Console UI so that the users of your API canhave live documentation and even call your API's endpointsthrough it- Handles OAuth 2 token-based authentication- Supports API versioning- Supports automatic serialization of payloads. If yourspecification defines that an endpoint returns JSON, Connexion willautomatically serialize the return value for you and set the rightcontent type in the HTTP header.Why Connexion-------------With Connexion, you write the spec first. Connexion then calls your Pythoncode, handling the mapping from the specification to the code. Thisincentivizes you to write the specification so that all of yourdevelopers can understand what your API does, even before you write asingle line of code.If multiple teams depend on your APIs, you can use Connexion to easily send them the documentation of your API. This guarantees that your API will follow the specification that you wrote. This is a different process from that offered by frameworks such as Hug_, which generates a specification *after* you've written the code. Some disadvantages of generating specifications based on code is that they often end up lacking details or mix your documentation with the code logic of your application.Other Sources/Mentions----------------------- Zalando Tech blog post `API First`_- Connexion listed on Swagger_'s website- Blog post: `Crafting effective Microservices in Python`_How to Use==========Prerequisites-------------Python 2.7 or Python 3.4+Installing It-------------In your command line, type:.. code-block:: bash$ pip install connexionRunning It----------Place your API YAML inside a folder in the rootpath of your application (e.g ``swagger/``). Then run:.. code-block:: pythonimport connexionapp = connexion.App(__name__, specification_dir='swagger/')app.add_api('my_api.yaml')app.run(port=8080)See the `Connexion Pet Store Example Application`_ for a samplespecification.Now you're able to run and use Connexion!OAuth 2 Authentication and Authorization----------------------------------------Connexion supports one of the three OAuth 2 handling methods. (See"TODO" below.) With Connexion, the API security definition **must**include a 'x-tokenInfoUrl' or 'x-tokenInfoFunc (or set ``TOKENINFO_URL``or ``TOKENINFO_FUNC`` env var respectively). 'x-tokenInfoUrl' must contain anURL to validate and get the `token information`_ and 'x-tokenInfoFunc mustcontain a reference to a function used to obtain the token info. When both 'x-tokenInfoUrl'and 'x-tokenInfoFunc' are used, Connexion will prioritize the function method. Connexion expects toreceive the OAuth token in the ``Authorization`` header field in theformat described in `RFC 6750 <rfc6750_>`_ section 2.1. This aspectrepresents a significant difference from the usual OAuth flow.Dynamic Rendering of Your Specification---------------------------------------Connexion uses Jinja2_ to allow specification parameterization through the `arguments` parameter. You can define specification arguments for the application either globally (via the `connexion.App` constructor) or for each specific API (via the `connexion.App#add_api` method):.. code-block:: pythonapp = connexion.App(__name__, specification_dir='swagger/',arguments={'global': 'global_value'})app.add_api('my_api.yaml', arguments={'api_local': 'local_value'})app.run(port=8080)When a value is provided both globally and on the API, the API value will take precedence.Endpoint Routing to Your Python Views-------------------------------------Connexion uses the ``operationId`` from each `Operation Object`_ toidentify which Python function should handle each URL.**Explicit Routing**:.. code-block:: yamlpaths:/hello_world:post:operationId: myapp.api.hello_worldIf you provide this path in your specification POST requests to``http://MYHOST/hello_world``, it will be handled by the function``hello_world`` in the ``myapp.api`` module. Optionally, you can include``x-swagger-router-controller`` in your operation definition, making``operationId`` relative:.. code-block:: yamlpaths:/hello_world:post:x-swagger-router-controller: myapp.apioperationId: hello_worldAutomatic Routing-----------------To customize this behavior, Connexion can use alternative``Resolvers``--for example, ``RestyResolver``. The ``RestyResolver``will compose an ``operationId`` based on the path and HTTP method ofthe endpoints in your specification:.. code-block:: pythonfrom connexion.resolver import RestyResolverapp = connexion.App(__name__)app.add_api('swagger.yaml', resolver=RestyResolver('api')).. code-block:: yamlpaths:/:get:# Implied operationId: api.get/foo:get:# Implied operationId: api.foo.searchpost:# Implied operationId: api.foo.post'/foo/{id}':get:# Implied operationId: api.foo.getput:# Implied operationId: api.foo.putcopy:# Implied operationId: api.foo.copydelete:# Implied operationId: api.foo.delete``RestyResolver`` will give precedence to any ``operationId`` encountered in the specification. It will also respect``x-router-controller``. You can import and extend ``connexion.resolver.Resolver`` to implement your own ``operationId``(and function) resolution algorithm.Automatic Parameter Handling----------------------------Connexion automatically maps the parameters defined in your endpoint specification to arguments of your Python views as named parameters, and, whenever possible, with value casting. Simply define the endpoint's parameters with the same names as your views arguments.As an example, say you have an endpoint specified as:.. code-block:: yamlpaths:/foo:get:operationId: api.foo_getparameters:- name: messagedescription: Some message.in: querytype: stringrequired: trueAnd the view function:.. code-block:: python# api.py filedef foo_get(message):# do somethingreturn 'You send the message: {}'.format(message), 200In this example, Connexion automatically recognizes that your viewfunction expects an argument named `message` and assigns the valueof the endpoint parameter `message` to your view function... warning:: When you define a parameter at your endpoint as *not* required, and your Python view hasa non-named argument, you will get a "missing positional argument" exception whenever you call this endpoint WITHOUT the parameter.Type casting^^^^^^^^^^^^Whenever possible, Connexion will try to parse your argument values anddo type casting to related Python native values. The currentavailable type castings are:+--------------+-------------+| Swagger Type | Python Type |+==============+=============+| integer      | int         |+--------------+-------------+| string       | str         |+--------------+-------------+| number       | float       |+--------------+-------------+| boolean      | bool        |+--------------+-------------+| array        | list        |+--------------+-------------+| object       | dict        |+--------------+-------------+If you use the `array` type In the Swagger definition, you can define the`collectionFormat` so that it won't be recognized. Connexion currentlysupports collection formats "pipes" and "csv". The default format is "csv".Parameter validation^^^^^^^^^^^^^^^^^^^^Connexion can apply strict parameter validation for query and form dataparameters.  When this is enabled, requests that include parameters not definedin the swagger spec return a 400 error.  You can enable it when adding the APIto your application:.. code-block:: pythonapp.add_api('my_apy.yaml', strict_validation=True)API Versioning and basePath---------------------------You can also define a ``basePath`` on the top level of the APIspecification. This is useful for versioned APIs. To serve theprevious endpoint from ``http://MYHOST/1.0/hello_world``, type:.. code-block:: yamlbasePath: /1.0paths:/hello_world:post:operationId: myapp.api.hello_worldIf you don't want to include the base path in your specification, youcan provide it when adding the API to your application:.. code-block:: pythonapp.add_api('my_api.yaml', base_path='/1.0')Swagger JSON------------Connexion makes the OpenAPI/Swagger specification in JSON formatavailable from ``swagger.json`` in the base path of the API.You can disable the Swagger JSON at the application level:.. code-block:: pythonapp = connexion.App(__name__, specification_dir='swagger/',swagger_json=False)app.add_api('my_api.yaml')You can also disable it at the API level:.. code-block:: pythonapp = connexion.App(__name__, specification_dir='swagger/')app.add_api('my_api.yaml', swagger_json=False)HTTPS Support-------------When specifying HTTPS as the scheme in the API YAML file, all the URIsin the served Swagger UI are HTTPS endpoints. The problem: The defaultserver that runs is a "normal" HTTP server. This means that theSwagger UI cannot be used to play with the API. What is the correctway to start a HTTPS server when using Connexion?One way, `described by Flask`_, looks like this:.. code-block:: pythonfrom OpenSSL import SSLcontext = SSL.Context(SSL.SSLv23_METHOD)context.use_privatekey_file('yourserver.key')context.use_certificate_file('yourserver.crt')app.run(host='127.0.0.1', port='12344',debug=False/True, ssl_context=context)However, Connexion doesn't provide an ssl_context parameter. This isbecause Flask doesn't, either--but it uses `**kwargs` to send theparameters to the underlying [werkzeug](http://werkzeug.pocoo.org/) server.The Swagger UI Console----------------------The Swagger UI for an API is available, by default, in``{base_path}/ui/`` where ``base_path`` is the base path of the API.You can disable the Swagger UI at the application level:.. code-block:: pythonapp = connexion.App(__name__, specification_dir='swagger/',swagger_ui=False)app.add_api('my_api.yaml')You can also disable it at the API level:.. code-block:: pythonapp = connexion.App(__name__, specification_dir='swagger/')app.add_api('my_api.yaml', swagger_ui=False)If necessary, you can explicitly specify the path to the directory withswagger-ui to not use the connexion-embedded swagger-ui distro.In order to do this, you should specify the following option:.. code-block:: pythonoptions = {'swagger_path': '/path/to/swagger_ui/'}app = connexion.App(__name__, specification_dir='swagger/', options=options)Make sure that `swagger_ui/index.html` loads by default local swagger json.You can use the `api_url` jinja variable for this purpose:.. code-block::const ui = SwaggerUIBundle({ url: "{{ api_url }}/swagger.json"})Server Backend--------------Connexion uses the default Flask server. For asynchronousapplications, you can also use Tornado_ as the HTTP server. To dothis, set your server to ``tornado``:.. code-block:: pythonimport connexionapp = connexion.App(__name__, specification_dir='swagger/')app.run(server='tornado', port=8080)You can use the Flask WSGI app with any WSGI container, e.g. `usingFlask with uWSGI`_ (this is common):.. code-block:: pythonapp = connexion.App(__name__, specification_dir='swagger/')application = app.app # expose global WSGI application objectYou can use the ``aiohttp`` framework as server backend as well:.. code-block:: pythonimport connexionapp = connexion.AioHttpApp(__name__, specification_dir='swagger/')app.run(port=8080)**NOTE:** Also check aiohttp handler examples_.Set up and run the installation code:.. code-block:: bash$ sudo pip3 install uwsgi$ uwsgi --http :8080 -w app -p 16  # use 16 worker processesSee the `uWSGI documentation`_ for more information... _using Flask with uWSGI: http://flask.pocoo.org/docs/latest/deploying/uwsgi/.. _uWSGI documentation: https://uwsgi-docs.readthedocs.org/.. _examples: https://docs.aiohttp.org/en/stable/web.html#handlerDocumentation=============Additional information is available at `Connexion's Documentation Page`_.Changes=======A full changelog is maintained on the `GitHub releases page`_... _GitHub releases page: https://github.com/zalando/connexion/releasesContributing to Connexion/TODOs===============================We welcome your ideas, issues, and pull requests. Just follow theusual/standard GitHub practices.Unless you explicitly state otherwise in advance, any non trivialcontribution intentionally submitted for inclusion in this project by youto the steward of this repository (Zalando SE, Berlin) shall be under theterms and conditions of Apache License 2.0 written below, without anyadditional copyright information, terms or conditions.TODOs-----If you'd like to become a more consistent contributor to Connexion, we'd love your help working onthese we have a list of `issues where we are looking for contributions`_.Thanks===================We'd like to thank all of Connexion's contributors for working on thisproject, and to Swagger/OpenAPI for their support.License===================Copyright 2015 Zalando SELicensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License... _Flask: http://flask.pocoo.org/.. _issues waffle board: https://waffle.io/zalando/connexion.. _API First: https://tech.zalando.com/blog/on-apis-and-the-zalando-api-guild/.. _Hug: https://github.com/timothycrosley/hug.. _Swagger: http://swagger.io/open-source-integrations/.. _Jinja2: http://jinja.pocoo.org/.. _rfc6750: https://tools.ietf.org/html/rfc6750.. _OpenAPI 2.0 Specification: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md.. _Operation Object: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#operation-object.. _swager.spec.security_definition: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#security-definitions-object.. _swager.spec.security_requirement: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#security-requirement-object.. _YAML format: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#format.. _token information: https://tools.ietf.org/html/rfc6749.. _Tornado: http://www.tornadoweb.org/en/stable/.. _Connexion Pet Store Example Application: https://github.com/hjacobs/connexion-example.. _described by Flask: http://flask.pocoo.org/snippets/111/.. _Connexion's Documentation Page: http://connexion.readthedocs.org/en/latest/.. _Crafting effective Microservices in Python: http://caricio.com/2016/09/16/crafting-effective-microservices-in-python/.. _issues where we are looking for contributions: https://github.com/zalando/connexion/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22