mirror of
https://github.com/LukeHagar/connexion.git
synced 2025-12-10 04:19:37 +00:00
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
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
==================
|
||||
SQLAlchemy Example
|
||||
==================
|
||||
|
||||
A simple example of how one might use SQLAlchemy as a backing store for a
|
||||
Connexion based application.
|
||||
|
||||
Running:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo pip3 install -r requirements.txt
|
||||
$ ./app.py
|
||||
|
||||
Now open your browser and go to http://localhost:8080/ui/ to see the Swagger UI.
|
||||
@@ -1,66 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
import connexion
|
||||
from connexion import NoContent
|
||||
|
||||
import orm
|
||||
|
||||
db_session = None
|
||||
|
||||
|
||||
def get_pets(limit, animal_type=None):
|
||||
q = db_session.query(orm.Pet)
|
||||
if animal_type:
|
||||
q = q.filter(orm.Pet.animal_type == animal_type)
|
||||
return [p.dump() for p in q][:limit]
|
||||
|
||||
|
||||
def get_pet(pet_id):
|
||||
pet = db_session.query(orm.Pet).filter(orm.Pet.id == pet_id).one_or_none()
|
||||
return pet.dump() if pet is not None else ('Not found', 404)
|
||||
|
||||
|
||||
def put_pet(pet_id, pet):
|
||||
p = db_session.query(orm.Pet).filter(orm.Pet.id == pet_id).one_or_none()
|
||||
pet['id'] = pet_id
|
||||
if p is not None:
|
||||
logging.info('Updating pet %s..', pet_id)
|
||||
p.update(**pet)
|
||||
else:
|
||||
logging.info('Creating pet %s..', pet_id)
|
||||
pet['created'] = datetime.datetime.utcnow()
|
||||
db_session.add(orm.Pet(**pet))
|
||||
db_session.commit()
|
||||
return NoContent, (200 if p is not None else 201)
|
||||
|
||||
|
||||
def delete_pet(pet_id):
|
||||
pet = db_session.query(orm.Pet).filter(orm.Pet.id == pet_id).one_or_none()
|
||||
if pet is not None:
|
||||
logging.info('Deleting pet %s..', pet_id)
|
||||
db_session.query(orm.Pet).filter(orm.Pet.id == pet_id).delete()
|
||||
db_session.commit()
|
||||
return NoContent, 204
|
||||
else:
|
||||
return NoContent, 404
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
db_session = orm.init_db('sqlite:///:memory:')
|
||||
app = connexion.FlaskApp(__name__)
|
||||
app.add_api('swagger.yaml')
|
||||
|
||||
application = app.app
|
||||
|
||||
|
||||
@application.teardown_appcontext
|
||||
def shutdown_session(exception=None):
|
||||
db_session.remove()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(
|
||||
port=8080,
|
||||
threaded=False # in-memory database isn't shared across threads
|
||||
)
|
||||
@@ -1,32 +0,0 @@
|
||||
from sqlalchemy import Column, DateTime, String, create_engine
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
class Pet(Base):
|
||||
__tablename__ = 'pets'
|
||||
id = Column(String(20), primary_key=True)
|
||||
name = Column(String(100))
|
||||
animal_type = Column(String(20))
|
||||
created = Column(DateTime())
|
||||
|
||||
def update(self, id=None, name=None, animal_type=None, tags=None, created=None):
|
||||
if name is not None:
|
||||
self.name = name
|
||||
if animal_type is not None:
|
||||
self.animal_type = animal_type
|
||||
if created is not None:
|
||||
self.created = created
|
||||
|
||||
def dump(self):
|
||||
return dict([(k, v) for k, v in vars(self).items() if not k.startswith('_')])
|
||||
|
||||
|
||||
def init_db(uri):
|
||||
engine = create_engine(uri, convert_unicode=True)
|
||||
db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
|
||||
Base.query = db_session.query_property()
|
||||
Base.metadata.create_all(bind=engine)
|
||||
return db_session
|
||||
@@ -1,3 +0,0 @@
|
||||
connexion>=1.0.97
|
||||
Flask>=0.10.1
|
||||
SQLAlchemy>=1.0.13
|
||||
@@ -1,111 +0,0 @@
|
||||
swagger: '2.0'
|
||||
info:
|
||||
title: Pet Shop Example API
|
||||
version: "0.1"
|
||||
consumes:
|
||||
- application/json
|
||||
produces:
|
||||
- application/json
|
||||
paths:
|
||||
/pets:
|
||||
get:
|
||||
tags: [Pets]
|
||||
operationId: app.get_pets
|
||||
summary: Get all pets
|
||||
parameters:
|
||||
- name: animal_type
|
||||
in: query
|
||||
type: string
|
||||
pattern: "^[a-zA-Z0-9]*$"
|
||||
- name: limit
|
||||
in: query
|
||||
type: integer
|
||||
minimum: 0
|
||||
default: 100
|
||||
responses:
|
||||
200:
|
||||
description: Return pets
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Pet'
|
||||
/pets/{pet_id}:
|
||||
get:
|
||||
tags: [Pets]
|
||||
operationId: app.get_pet
|
||||
summary: Get a single pet
|
||||
parameters:
|
||||
- $ref: '#/parameters/pet_id'
|
||||
responses:
|
||||
200:
|
||||
description: Return pet
|
||||
schema:
|
||||
$ref: '#/definitions/Pet'
|
||||
404:
|
||||
description: Pet does not exist
|
||||
put:
|
||||
tags: [Pets]
|
||||
operationId: app.put_pet
|
||||
summary: Create or update a pet
|
||||
parameters:
|
||||
- $ref: '#/parameters/pet_id'
|
||||
- name: pet
|
||||
in: body
|
||||
schema:
|
||||
$ref: '#/definitions/Pet'
|
||||
responses:
|
||||
200:
|
||||
description: Pet updated
|
||||
201:
|
||||
description: New pet created
|
||||
delete:
|
||||
tags: [Pets]
|
||||
operationId: app.delete_pet
|
||||
summary: Remove a pet
|
||||
parameters:
|
||||
- $ref: '#/parameters/pet_id'
|
||||
responses:
|
||||
204:
|
||||
description: Pet was deleted
|
||||
404:
|
||||
description: Pet does not exist
|
||||
|
||||
|
||||
parameters:
|
||||
pet_id:
|
||||
name: pet_id
|
||||
description: Pet's Unique identifier
|
||||
in: path
|
||||
type: string
|
||||
required: true
|
||||
pattern: "^[a-zA-Z0-9-]+$"
|
||||
|
||||
definitions:
|
||||
Pet:
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- animal_type
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique identifier
|
||||
example: "123"
|
||||
readOnly: true
|
||||
name:
|
||||
type: string
|
||||
description: Pet's name
|
||||
example: "Susie"
|
||||
minLength: 1
|
||||
maxLength: 100
|
||||
animal_type:
|
||||
type: string
|
||||
description: Kind of animal
|
||||
example: "cat"
|
||||
minLength: 1
|
||||
created:
|
||||
type: string
|
||||
format: date-time
|
||||
description: Creation time
|
||||
example: "2015-07-07T15:49:51.230+02:00"
|
||||
readOnly: true
|
||||
Reference in New Issue
Block a user