python 导出Pydantic模型,并展开所有ENUM值

fnatzsnv  于 2023-01-04  发布在  Python
关注(0)|答案(1)|浏览(189)

我有一个pydantic模型ModelX,定义了成员Enums。脚本应该按原样运行。

from enum import Enum
from pydantic import BaseModel,Field,schema_json_of
from typing import Optional

class FirstEnumList(str, Enum):
   VAL1="VAL1"
   VAL2="VAL2"
   VAL3="VAL3"

class SecondEnumList(str, Enum):
   VAL4="VAL4"
   VAL5="VAL5"

class ModelX(BaseModel):
   V: Optional[FirstEnumList]=Field(FirstEnumList.VAL1, alias='value1')
   A: Optional[str]
   B: Optional[int] 
   P: Optional[SecondEnumList]=Field(SecondEnumList.VAL4, alias='valueP')

print (schema_json_of(ModelX))

'''Output below for schema_json_of
{"title": "ParsingModel[ModelX]", "$ref": "#/definitions/ModelX", 
"definitions": 
    {
        "FirstEnumList": 
        {
            "title": "FirstEnumList", 
            "description": "An enumeration.", 
            "enum": ["VAL1", "VAL2", "VAL3"], 
            "type": "string"
        }, 
        "SecondEnumList": 
        {
            "title": "SecondEnumList", 
            "description": "An enumeration.", 
            "enum": ["VAL4", "VAL5"], 
            "type": "string"
        }, 
        "ModelX": 
        {
            "title": "ModelX", 
            "type": "object", 
            "properties": 
            {
                "value1": 
                {
                    "default": "VAL1", 
                    "allOf": [{"$ref": "#/definitions/FirstEnumList"}]
                }, 
                "A": {
                    "title": "A", 
                    "type": "string"
                    }, 
                "B": {
                    "title": "B", 
                    "type": "integer"
                    }, 
                "valueP": {
                    "default": "VAL4", 
                    "allOf": [{"$ref": "#/definitions/SecondEnumList"}]}
            }
        }
    }
}
'''

我想将这个模型导出为JSON,其中包含所有Enum值的列表。

{
  "value1": {
    "allOf": [
      "VAL1",
      "VAL2",
      "VAL3"
    ]
  },
  "A": {
    "type": "string"
  },
  "B": {
    "type": "integer"
  },
  "valueP": {
    "allOf": [
      "VAL4",
      "VAL5"
    ]
  }
}

我希望返回这个Json作为我的API调用的响应,所有枚举值,它可以在“allOf”键下或其他更好的方式。这样响应就有了所有可能的枚举值,这个响应的消费者可以使用它来预先验证请求,甚至在UI屏幕上显示它们。
如果需要更多细节或解释,请告知我。

4dbbbstv

4dbbbstv1#

Pydantic符合以下规范:一对一对一,一对二对一,一对三对一。
本规范遵循减少重复元素的设计原则,子模型引用ref,避免不必要的模型定义重复。
你可以通过修改Field类中的"子模型"来覆盖其中的一些元素,比如添加一个自定义的标题或者默认值,但是只有重载的值才会被包含进来。
在您的情况下,您将需要采用一种变通方法来处理最终状态:

my_schema = ModelX.schema()

for k, v in my_schema["properties"].items():
    if ('allOf' in v and
        len(v['allOf']) == 1 and
        isinstance(v['allOf'][0], dict) and
        v['allOf'][0].get('$ref') is not None
    ):
        # get the values
        enum_key = v['allOf'][0]['$ref'].replace('#/definitions/', '')
        enum_vals = my_schema['definitions'][enum_key]['enum']

        # Set the values
        my_schema["properties"][k]['allOf'] = enum_vals

# Get enum values
print(my_schema)

{
  "value1": {
    "title": "value1",
    "default": "VAL1",
    "allOf": [
      "VAL1",
      "VAL2",
      "VAL3"
    ]
  },
  "A": {
    "title": "A",
    "type": "string"
  },
  "B": {
    "title": "B",
    "type": "integer"
  },
  "valueP": {
    "default": "VAL4",
    "allOf": [
      "VAL4",
      "VAL5"
    ]
  }
}

相关问题