OpenAPI v3 / Swagger - 调用函数并向其发送 json 字典

OpenAPI v3 / Swagger - calling a function and sending json dictionary to it

我正在尝试将 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)

编辑:根据海伦的评论

,在下面添加 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。这是一些工作代码。

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/

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

In the OpenAPI 3.x.x spec, the requestBody does not have a name. By default it will be passed in as ‘body’. You can optionally provide the x-body-name parameter in your requestBody schema to override the name of the parameter that will be passed to your handler function.

看起来您需要将 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'