Connexion - 基于OpenAPI/Swagger和Flask的API优先应用
此版本被撤回的原因
请使用'connexion'包代替:https://pypi.ac.cn/project/connexion/
项目描述
Connexion
Connexion是一个框架,可以自动处理基于API描述的YAML格式的HTTP请求(以前称为Swagger Spec)。Connexion允许您编写OpenAPI规范,然后将端点映射到Python函数;这使得它与众不同,因为许多工具基于您的Python代码生成规范。您可以详细描述您的REST API;然后Connexion保证它将按您指定的方式工作。
我们以这种方式构建Connexion是为了
简化开发过程
确认对API外观的期望
Connexion功能
自动根据规范验证请求和端点参数
提供Web Swagger控制台UI,以便您的API用户可以通过它获得实时文档,甚至调用API的端点
处理基于OAuth 2令牌的身份验证
支持API版本控制
支持自动序列化有效载荷。如果您的规范定义了一个端点返回 JSON,Connexion 将自动为您序列化返回值,并在 HTTP 头部设置正确的内容类型。
为何选择 Connexion
使用 Connexion,您首先编写规范。然后 Connexion 调用您的 Python 代码,处理规范到代码的映射。这激励您编写规范,以便您的所有开发人员都能在编写任何代码之前了解您的 API 是做什么的。
如果多个团队依赖于您的 API,您可以使用 Connexion 简单地向他们发送您的 API 文档。这确保了您的 API 将遵循您所编写的规范。这与像 Hug 这样的框架所提供的过程不同,Hug 是在您编写代码之后生成规范的。根据代码生成规范的缺点是,它们通常缺乏细节,或者将您的文档与应用程序的代码逻辑混合在一起。
其他来源/提及
带有 API First 的 Zalando RESTful API 指南
Connexion 列于 Swagger 网站上
博客文章: 在 Python 中构建有效的微服务
Connexion 2.0 中的新功能
必须通过“options”参数提供 App 和 Api 选项(已删除 old_style_options)。
为了消费表单数据,您必须在‘consumes’中指定表单内容类型。
已将 Operation 接口形式化为 AbstractOperation 类。
将 Operation 类重命名为 Swagger2Operation。
数组参数反序列化现在更接近 Swagger 2.0 规范。在查询参数被多次传递且 collectionFormat 为 csv 或 pipes 的情况下,将使用最右侧的值。例如,?q=1,2,3&q=4,5,6 将导致 q = [4, 5, 6]。可以通过将 collectionFormat 设置为 multi 或通过导入 decorators.uri_parsing.AlwaysMultiURIParser 并将 parser_class=AlwaysMultiURIParser 传递给您的 Api 来获得旧行为。
规范验证库已从 swagger-spec-validator 更改为 openapi-spec-validator。
以前引发 SwaggerValidationError 的错误现在引发 InvalidSpecification 异常。所有规范验证错误都应包装在 InvalidSpecification 中。
已将 nullable/x-nullable、readOnly 和 writeOnly/x-writeOnly 支持添加到标准 json schema 验证器。
现在可以在 API 级别(而不是应用级别)指定自定义验证器。
添加了对基本身份验证和 apikey 身份验证的支持
如果定义了不支持的密钥要求或 x-tokenInfoFunc/x-tokenInfoUrl 缺失,connexion 现在将拒绝请求,而不是允许不进行安全检查的访问。
不再支持访问 connexion.request.user / flask.request.user,请改用 connexion.context['user']。
如何使用
先决条件
Python 3.6+
安装它
在您的命令行中,键入
$ pip install connexion
运行它
将您的 API YAML 放在应用程序根路径中的一个文件夹内(例如 swagger/)。然后运行
import connexion
app = connexion.App(__name__, specification_dir='swagger/')
app.add_api('my_api.yaml')
app.run(port=8080)
查看 Connexion Pet Store 示例应用程序 中的样本规范。
现在您能够运行并使用 Connexion 了!
动态渲染您的规范
Connexion使用Jinja2允许通过arguments参数进行规范参数化。您可以为应用程序定义规范参数,可以是全局的(通过connexion.App构造函数)或者为每个特定的API(通过connexion.App#add_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)
当全局和API都提供了值时,API的值将具有优先级。
将端点路由到您的Python视图
Connexion使用每个操作对象中的operationId来识别应该处理哪个URL的Python函数。
显式路由:
paths:
/hello_world:
post:
operationId: myapp.api.hello_world
如果您在规范中提供此路径,则对http://MYHOST/hello_world的POST请求将由myapp.api模块中的hello_world函数处理。您可以选择在操作定义中包含x-swagger-router-controller(或x-openapi-router-controller),使operationId为相对路径
paths:
/hello_world:
post:
x-swagger-router-controller: myapp.api
operationId: hello_world
请注意,Connexion遵循Flask中HTTP方法的工作方式,因此HEAD请求将由规范中GET下的operationId处理。如果两种方法都受支持,则可以使用connexion.request.method来确定哪个请求被发起。
自动路由
要自定义此行为,Connexion可以使用替代的Resolvers(例如,RestyResolver)。RestyResolver将根据您的规范中端点的路径和HTTP方法组合一个operationId
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.put
copy:
# Implied operationId: api.foo.copy
delete:
# Implied operationId: api.foo.delete
RestyResolver将优先考虑规范中遇到的任何operationId。它还将尊重x-router-controller。您可以通过导入和扩展connexion.resolver.Resolver来实现自己的operationId(和函数)解析算法。
自动参数处理
Connexion自动将您在端点规范中定义的参数映射到Python视图的参数,并尽可能地进行值转换。只需使用与视图参数相同的名称定义端点参数即可。
例如,假设您有如下端点规范
paths:
/foo:
get:
operationId: api.foo_get
parameters:
- name: message
description: Some message.
in: query
type: string
required: true
和视图函数
# api.py file
def foo_get(message):
# do something
return 'You send the message: {}'.format(message), 200
在这个例子中,Connexion自动识别您的视图函数期望一个名为message的参数,并将端点参数message的值分配给您的视图函数。
类型转换
尽可能情况下,Connexion将尝试解析您的参数值并将其转换为相关的Python原生值。当前可用的类型转换有
OpenAPI类型 |
Python类型 |
---|---|
整数 |
int |
字符串 |
str |
数字 |
float |
布尔值 |
bool |
数组 |
list |
空值 |
None |
对象 |
dict |
如果您在Swagger定义中使用array类型,您可以定义collectionFormat,这样它就不会被识别。Connexion目前支持收集格式“管道”和“csv”。默认格式是“csv”。
Connexion对解析数组类型的URI的方式有自己的看法。对于定义多次的查询参数,默认行为是使用最右侧的值。例如,如果您提供了一个包含查询字符串?letters=a,b,c&letters=d,e,f的URI,则connexions将设置letters = ['d', 'e', 'f']。
您可以通过指定应用或API选项中的URI解析器来覆盖此行为。
from connexion.decorators.uri_parsing import AlwaysMultiURIParser
options = {'uri_parser_class': AlwaysMultiURIParser}
app = connexion.App(__name__, specification_dir='swagger/', options=options)
您可以通过从connexion.decorators.uri_parsing.AbstractURIParser继承来实现您自己的URI解析行为。
连接包含一些URI解析器。
OpenAPIURIParser默认:OpenAPI 3.0 |
此解析器遵循OpenAPI 3.x.x规范,并使用style参数。查询参数从左到右解析,因此如果查询参数被定义两次,则最右侧的定义将优先。例如,如果您提供了一个包含查询字符串?letters=a,b,c&letters=d,e,f的URI,并且style: simple,则connexions将设置letters = ['d', 'e', 'f']。有关更多信息,请参阅OpenAPI 3.0样式值。 |
Swagger2URIParser默认:OpenAPI 2.0 |
此解析器遵循Swagger 2.0规范,并且只有当collectionFormat设置为multi时,才会将多个相同查询参数的实例连接在一起。查询参数从左到右解析,因此如果查询参数被定义两次,则最右侧的定义获胜。例如,如果您提供了一个包含查询字符串?letters=a,b,c&letters=d,e,f的URI,并且collectionFormat: csv,则connexions将设置letters = ['d', 'e', 'f'] |
FirstValueURIParser |
此解析器的行为类似于Swagger2URIParser,但它优先选择第一个定义的值。例如,如果您提供了一个包含查询字符串?letters=a,b,c&letters=d,e,f和collectionFormat: csv的URI,则connexions将设置letters = ['a', 'b', 'c'] |
AlwaysMultiURIParser |
此解析器与Connexion 1.x向后兼容。它将相同查询参数的多个实例连接在一起。 |
参数验证
Connexion可以为查询和表单数据参数应用严格的参数验证。当此选项启用时,包含不在swagger规范中定义的参数的请求将返回400错误。您可以在将API添加到您的应用程序时启用它。
app.add_api('my_apy.yaml', strict_validation=True)
API版本控制和basePath
设置基本路径对于版本化API很有用。一个基本路径的例子是在 http://MYHOST/1.0/hello_world 中的 1.0。
如果您正在使用OpenAPI 3.x.x,您可以在规范的服务器块中设置基本URL路径。您可以指定一个完整的URL,也可以只指定一个相对路径。
servers:
- url: https://MYHOST/1.0
description: full url example
- url: /1.0
description: relative path example
paths:
...
如果您正在使用OpenAPI 2.0,您可以在OpenAPI 2.0规范的顶级定义 basePath。
basePath: /1.0
paths:
...
如果您不希望在规范中包含基本路径,您可以在将API添加到应用程序时提供它
app.add_api('my_api.yaml', base_path='/1.0')
Swagger JSON
Connexion通过 swagger.json(用于OpenAPI 2.0)或 openapi.json(用于OpenAPI 3.x.x)在API的基本路径处提供OpenAPI/Swagger规范(JSON格式)。例如,如果您的基本路径是 1.0,则规范将在 /1.0/openapi.json 处可用。
您可以在应用程序级别禁用提供规范JSON
options = {"serve_spec": False}
app = connexion.App(__name__, specification_dir='openapi/',
options=options)
app.add_api('my_api.yaml')
您也可以在API级别禁用它
options = {"serve_spec": False}
app = connexion.App(__name__, specification_dir='openapi/')
app.add_api('my_api.yaml', options=options)
HTTPS支持
当在API YAML文件中将方案指定为HTTPS时,所有在Swagger UI中提供的URI都是HTTPS端点。问题:默认运行的服务器是一个“普通”的HTTP服务器。这意味着您无法使用Swagger UI来与API交互。使用Connexion启动HTTPS服务器的正确方法是什么?
一种方法,由Flask描述,如下所示
from OpenSSL import SSL
context = 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)
然而,Connexion不提供ssl_context参数。这是因为Flask也没有,但它使用 **kwargs 将参数发送到底层的 werkzeug 服务器。
Swagger UI控制台
API的Swagger UI可以通过pip extras获取。您可以使用 pip install connexion[swagger-ui] 安装它。它将在 {base_path}/ui/ 处提供,其中 base_path 是API的基本路径。
您可以在应用程序级别禁用Swagger UI
app = connexion.App(__name__, specification_dir='openapi/',
options={"swagger_ui": False})
app.add_api('my_api.yaml')
您也可以在API级别禁用它
app = connexion.App(__name__, specification_dir='openapi/')
app.add_api('my_api.yaml', options={"swagger_ui": False})
如果需要,您可以明确指定swagger-ui目录的路径,以不使用connexion[swagger-ui]发行版。为了做到这一点,您应该指定以下选项
options = {'swagger_path': '/path/to/swagger_ui/'}
app = connexion.App(__name__, specification_dir='openapi/', options=options)
如果您希望提供自己的swagger-ui发行版,请注意,Connexion期望有一个名为 swagger_ui/index.j2 的jinja2文件,以便默认加载正确的 swagger.json。您的 index.j2 文件可以使用 openapi_spec_url jinja变量来完成此目的
const ui = SwaggerUIBundle({ url: "{{ openapi_spec_url }}"})
此外,如果您希望使用swagger-ui-3.x.x,它也通过安装connexion[swagger-ui]提供,可以像这样启用
from swagger_ui_bundle import swagger_ui_3_path
options = {'swagger_path': swagger_ui_3_path}
app = connexion.App(__name__, specification_dir='swagger/', options=options)
服务器后端
默认情况下,Connexion使用Flask服务器。对于异步应用程序,您也可以使用Tornado作为HTTP服务器。要这样做,将您的服务器设置为 tornado
import connexion
app = connexion.App(__name__, specification_dir='swagger/')
app.run(server='tornado', port=8080)
您可以使用Flask WSGI应用程序与任何WSGI容器一起使用,例如 使用Flask与uWSGI(这是常见的)
app = connexion.App(__name__, specification_dir='swagger/')
application = app.app # expose global WSGI application object
您也可以使用 aiohttp 框架作为服务器后端
import connexion
app = connexion.AioHttpApp(__name__, specification_dir='swagger/')
app.run(port=8080)
设置和运行安装代码
$ sudo pip3 install uwsgi
$ uwsgi --http :8080 -w app -p 16 # use 16 worker processes
有关更多信息,请参阅uWSGI文档。
文档
更多信息可在Connexion文档页面找到。
变更记录
完整的变更日志维护在GitHub发行页面。
为Connexion做出贡献/TODOs
我们欢迎您的想法、问题和拉取请求。只需遵循常规/标准的GitHub实践。
您可以通过查看我们的ARCHITECTURE.rst来了解Connexion是如何工作的以及如何应用您的更改。
除非您事先明确声明,否则您提交给此存储库管理者(Zalando SE,柏林)的任何非微不足道的贡献,均应受以下Apache License 2.0条款和条件的约束,不包含任何额外的版权信息、条款或条件。
待办事项
如果您想成为Connexion的更一致的贡献者,我们非常乐意您在这些问题中寻求贡献。
感谢
我们感谢所有为Connexion项目工作的贡献者,并感谢Swagger/OpenAPI的支持。
许可证
版权所有 2015 Zalando SE
根据Apache License,版本2.0(“许可证”);除非遵守许可证,否则不得使用此文件。您可以在https://apache.ac.cn/licenses/LICENSE-2.0获取许可证副本。
除非适用法律要求或书面同意,否则在许可证下分发的软件按“原样”分发,不提供任何形式的明示或暗示保证。有关许可证的权限和限制的具体语言,请参阅许可证。
项目详情
下载文件
下载您平台上的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分发
构建分发
connexion2-2.10.0.tar.gz的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | 8ebafc4be3a0a5512f6336c8c31f59c762762b0ad1c59c4e8fe1bbb4073ae856 |
|
MD5 | 0136780a6509273794061f34139e9d2a |
|
BLAKE2b-256 | 7d53dd3c6078a9be21bbb6b142c7f7b7ae91b5cee587682c796e8d59bea2a4e4 |
connexion2-2.10.0-py2.py3-none-any.whl的散列
算法 | 散列摘要 | |
---|---|---|
SHA256 | d5c21231cb08f1e0b204a1b77161ecef5391b18ecd30ba3731622f5412f28ed1 |
|
MD5 | fdbd215af3d946d638e5eb644a39f94a |
|
BLAKE2b-256 | a8a4d1a824e9abfd88782435c6a3c42b726a8b8abf39294623ac33c6e2d1dcde |