【问题标题】:OpenAPI v3 / Swagger - calling a function and sending json dictionary to itOpenAPI v3 / Swagger - 调用函数并向其发送 json 字典
【发布时间】:2021-09-15 16:10:06
【问题描述】:

我正在尝试使用 OpenAPI/Swagger 来运行能够使用 json 字典、发送到函数并获得响应的端点。

我正在使用operationId 来引用我要调用的函数,但不知道如何发送端点接收到的字典。

controllers.get_options 被调用,但我目前的方法没有向它发送参数。

我认为我遗漏了一些明显的东西,但并不明显!

我会这样调用端点:

curl -X 'POST' \
  'http://localhost:8080/getoptions' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "product_area": "Main",
  "product_type": "New"
}'

这是 openapi 配置文件 (./openapi.yaml)

编辑:根据 Helen 的评论在下面添加 x-body-name: DiscussionResult 解决了问题

openapi: 3.0.0
info:
  title: Test
  version: '1.0'
paths:
  /getoptions:
    post:
      description: Return product options from product type and area
      operationId: controllers.get_options
      requestBody:
        required: true
        content:
          application/json:
            x-body-name: DiscussionResult
            schema:
              $ref: '#/components/schemas/DiscussionResult'
      responses:
        200:
          description: "success"

components:
  schemas:
    DiscussionResult:
      type: object
      discriminator:
        propertyName: product_type
      properties:
        product_type:
          type: string
          example: "New"
        product_area:
          type: string
          example: "Main"


我正在使用connexion 运行它,如下所示:

main.py

import connexion
import logging

def create_app():
    logging.basicConfig(level=logging.DEBUG)
    connex_app = connexion.FlaskApp(__name__, specification_dir="./openapi/")
    connex_app.add_api("./openapi.yaml", resolver_error=501)
    return connex_app


if __name__ == "__main__":
    app = create_app()
    app.run(host="0.0.0.0", port=8080)

requirements.txt

connexion[swagger-ui]
connexion>=2.2.0
python-jose[cryptography]
six>=1.9
Flask>=0.10.1
sqlathanor

这是我要调用的函数

def get_options(DiscussionResult):
    msg = "{} {}".format(DiscussionResult['product_area'], DiscussionResult['product_type'])
    return jsonify(message=msg), 200

【问题讨论】:

  • 你是如何运行应用程序的?当你调用它时你会得到什么?也许如果您分享更多代码,那么我们也许可以复制并找到一些东西。
  • 在描述中添加了更多细节
  • 遗憾的是,我对连接没有经验,我知道我没有帮助解决这个问题,但是..连接是强制性的吗?我觉得 Fastapi 可能更合适,更容易理解。可以做一个符合需求的小demo。
  • 谢谢。我可能会切换到 Fastapi,但我会认为 controllers.get_options 仍然需要以类似的方式调用?
  • connexion.readthedocs.io/en/latest/request.html: "在 OpenAPI 3.x.x 规范中,requestBody 没有名称。默认情况下,它将作为 ‘body’ 传入。您可以选择提供x-body-name 模式中的 x-body-name 参数以覆盖将传递给处理程序函数的参数名称。” 另请参阅 github.com/zalando/connexion/issues/1241#issuecomment-876128903。这有帮助吗?

标签: swagger flask-sqlalchemy openapi connexion


【解决方案1】:

Request Handling 上的 Connexion 文档包括以下注释:

在 OpenAPI 3.x.x 规范中,requestBody 没有名称。默认情况下,它将作为“body”传入。您可以选择在您的 requestBody schema 中提供 x-body-name 参数,以覆盖将传递给您的处理函数的参数名称。

看来您需要将x-body-name: DiscussionResult 添加到requestBody 中使用的DiscussionResult 架构:

components:
  schemas:
    DiscussionResult:
      x-body-name: DiscussionResult   # <---------
      type: object
      ...

      requestBody:
        required: true
        content:
          application/json:
            schema:
              x-body-name: DiscussionResult   # <---------
              $ref: '#/components/schemas/DiscussionResult'

【讨论】:

    【解决方案2】:

    正如我之前在 cmets 中所说的,我非常推荐 FastApi。这是一个工作代码。

    main.py

    from fastapi import FastAPI
    from pydantic import BaseModel
    
    app = FastAPI()
    
    
    class DetailsModel(BaseModel):
        product_area: str
        product_type: str
    
    
    @app.post("/get_details")
    async def _(
            input_json: DetailsModel
    ):
        return {"returns": input_json.dict()}
    

    从根目录运行uvicorn main:app --reload

    然后查看http://127.0.0.1:8000/docs

    然后你可以调用:

    curl -X 'POST' \
      'http://127.0.0.1:8000/get_details' \
      -H 'accept: application/json' \
      -H 'Content-Type: application/json' \
      -d '{
      "product_area": "Main",
      "product_type": "New"
    }'
    

    Fastapi 使用 Pydantic 检查任何无法处理的实体,这对任何不适合模型的请求都有很大帮助。 检查官方和非常详细的文档https://fastapi.tiangolo.com/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-04
      • 2021-01-21
      • 2023-03-15
      • 2020-12-18
      • 1970-01-01
      • 2021-10-08
      • 2013-09-12
      相关资源
      最近更新 更多