跳转到主要内容

Connexion - 基于OpenAPI/Swagger和Flask的API优先应用

此版本被撤回的原因

请使用'connexion'包代替:https://pypi.ac.cn/project/connexion/

项目描述

Connexion

Join the chat at https://gitter.im/zalando/connexion Build status Coveralls status Latest Version Development Status Python Versions License

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 是在您编写代码之后生成规范的。根据代码生成规范的缺点是,它们通常缺乏细节,或者将您的文档与应用程序的代码逻辑混合在一起。

其他来源/提及

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 了!

OAuth 2 身份验证和授权

Connexion支持三种OAuth 2处理方法之一。(请参阅下方的“待办事项”。)使用Connexion时,API安全定义必须包括‘x-tokenInfoUrl’或‘x-tokenInfoFunc’(或分别设置TOKENINFO_URLTOKENINFO_FUNC环境变量)。‘x-tokenInfoUrl’必须包含一个URL,用于验证和获取令牌信息,而‘x-tokenInfoFunc’必须包含一个用于获取令牌信息的函数的引用。当同时使用‘x-tokenInfoUrl’和‘x-tokenInfoFunc’时,Connexion将优先使用函数方法。Connexion期望在RFC 6750第2.1节所述的格式中,在Authorization头部字段中接收OAuth令牌。这一方面与通常的OAuth流程存在显著差异。

动态渲染您的规范

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,fcollectionFormat: 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 (122.7 kB 查看散列)

上传时间

构建分发

connexion2-2.10.0-py2.py3-none-any.whl (92.4 kB 查看散列)

上传时间 Python 2 Python 3

由以下组织支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面