Connexion is a framework on top of Flask to automagically handle your REST API requests based on Swagger 2.0 Specification files in YAML.
Put your API YAML inside a folder in the root path of your application (e.g swagger/
) and then do
import connexion
app = connexion.App(__name__, specification_dir='swagger/')
app.add_api('my_api.yaml')
app.run(port=8080)
See the Connexion Pet Store Example Application for details.
Connexion uses Jinja2 to allow the parameterization of specifications.
The specification arguments can be defined globally for the application or for each specific API:
app = 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)
If a value is provided both globally and on the API then the API value will take precedence.
Connexion uses the operationId
from each Operation Object to identify which function
should handle each URL.
For example:
paths:
/hello_world:
post:
operationId: myapp.api.hello_world
If you provided this path in your specification POST requests to http://MYHOST/hello_world
would be handled by the
function hello_world
in myapp.api
. Optionally you can include x-router-controller in your operation definition, making operationId
relative:
paths:
/hello_world:
post:
x-router-controller: myapp.api
operationId: hello_world
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 of the endpoints in your specification:
from connexion.resolver import RestyResolver
app = connexion.App(__name__)
app.add_api('swagger.yaml', resolver=RestyResolver('api'))
paths:
/:
get:
# Implied operationId: api.get
/foo:
get:
# Implied operationId: api.foo.search
post:
# Implied operationId: api.foo.post
'/foo/{id}':
get:
# Implied operationId: api.foo.get
put:
# Implied operationId: api.foo.post
copy:
# Implied operationId: api.foo.copy
delete:
# Implied operationId: api.foo.delete
RestyResolver
will give precedence to any operationId
encountered in the specification. It will also respect x-router-controller
. You may import and extend connexion.resolver.Resolver
to implement your own operationId
(and function) resolution algorithm.
Additionally you can also define a basePath
on the top level of the API specification, which is useful for versioned
APIs. If you wanted to serve the previous endpoint from http://MYHOST/1.0/hello_world
you could do:
basePath: /1.0
paths:
/hello_world:
post:
operationId: myapp.api.hello_world
Other alternative if you don't want to include the base path in your specification is provide the base path when adding the API to your application:
app.add_api('my_api.yaml', base_path='/1.0')
If the specification defines that a endpoint returns json connexion will automatically serialize the return value for you and set the right content type in the HTTP header.
If the specification includes a Oauth2 Security Definition compatible with the
Zalando Greendale Team's infrastructure connexion will automatically handle token validation and authorization for
operations that have Security Requirements. One main difference between the usual
Oauth flow and the one connexion uses is that the API Security Definition must include a 'x-tokenInfoUrl' with the
URL to use to validate and get the token information.
Connexion expects to receive the Oauth token in the Authorization
header field in the format described in
RFC 6750 section 2.1.
Connexion makes the Swagger specification in JSON format available from swagger.json
in the base path of the API.
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 either at application level:
app = connexion.App(__name__, port = 8080, specification_dir='swagger/', swagger_ui=False)
app.add_api('my_api.yaml')
You can also disable it at API level:
app = connexion.App(__name__, port = 8080, specification_dir='swagger/')
app.add_api('my_api.yaml', swagger_ui=False)
By default connexion uses the default flask server but you can also use Tornado as the http server, to do so set server
to tornado
:
import connexion
app = connexion.App(__name__, port = 8080, specification_dir='swagger/', server='tornado')
You can use the Flask WSGI app with any WSGI container, e.g. using Flask with uWSGI:
app = connexion.App(specification_dir='swagger/')
application = app.app # expose global WSGI application object
$ sudo pip3 install uwsgi
$ uwsgi --http :8080 -w app -p 16 # use 16 worker processes
You can run uwsgi with a large number of worker processes to get high concurrency.
See the uWSGI documentation for more information.
Build and upload new version to PyPI:
$ ./release.sh <NEW-VERSION>
Copyright 2015 Zalando SE
Licensed 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.