I’m using @model_validator along with model_validate to check if values match child class:
sample request payload:
<code>{
"name": "BC",
"connectorType": "SNOWFLAKE",
"productName": "bc",
"secretArn": "foobararn",
"warehouse": "foobarwarehouse",
"tableSchema": "foobarschema",
"database": "bardatabse"
}
</code>
<code>{
"name": "BC",
"connectorType": "SNOWFLAKE",
"productName": "bc",
"secretArn": "foobararn",
"warehouse": "foobarwarehouse",
"tableSchema": "foobarschema",
"database": "bardatabse"
}
</code>
{
"name": "BC",
"connectorType": "SNOWFLAKE",
"productName": "bc",
"secretArn": "foobararn",
"warehouse": "foobarwarehouse",
"tableSchema": "foobarschema",
"database": "bardatabse"
}
Snowflake connector class:
<code>class SnowflakeConnector(SpotApiBaseModel):
"""Snowflake Connector."""
model_config = ConfigDict(from_attributes=True)
secretArn: str = Field(description="AWS secret arn")
warehouse: str = Field(description="Snowflake warehouse. Required for connector type: SNOWFLAKE")
database: str = Field(description="Database name. Required for connector type: SNOWFLAKE")
tableSchema: str = Field(description="Database table schema. Required for connector type: SNOWFLAKE")
class ConnectorInterface(BaseConnector):
@model_validator(mode='before')
def check_allowed_products(cls, values):
connector = values.get('connectorType').lower()
if connector == "s3":
S3Connector.model_validate(values)
elif connector == "snowflake":
SnowflakeConnector.model_validate(values)
</code>
<code>class SnowflakeConnector(SpotApiBaseModel):
"""Snowflake Connector."""
model_config = ConfigDict(from_attributes=True)
secretArn: str = Field(description="AWS secret arn")
warehouse: str = Field(description="Snowflake warehouse. Required for connector type: SNOWFLAKE")
database: str = Field(description="Database name. Required for connector type: SNOWFLAKE")
tableSchema: str = Field(description="Database table schema. Required for connector type: SNOWFLAKE")
class ConnectorInterface(BaseConnector):
@model_validator(mode='before')
def check_allowed_products(cls, values):
connector = values.get('connectorType').lower()
if connector == "s3":
S3Connector.model_validate(values)
elif connector == "snowflake":
SnowflakeConnector.model_validate(values)
</code>
class SnowflakeConnector(SpotApiBaseModel):
"""Snowflake Connector."""
model_config = ConfigDict(from_attributes=True)
secretArn: str = Field(description="AWS secret arn")
warehouse: str = Field(description="Snowflake warehouse. Required for connector type: SNOWFLAKE")
database: str = Field(description="Database name. Required for connector type: SNOWFLAKE")
tableSchema: str = Field(description="Database table schema. Required for connector type: SNOWFLAKE")
class ConnectorInterface(BaseConnector):
@model_validator(mode='before')
def check_allowed_products(cls, values):
connector = values.get('connectorType').lower()
if connector == "s3":
S3Connector.model_validate(values)
elif connector == "snowflake":
SnowflakeConnector.model_validate(values)
When any of the required fields is missing I’m getting expected response:
<code>"Field required: ('body', 'database')"
</code>
<code>"Field required: ('body', 'database')"
</code>
"Field required: ('body', 'database')"
but when all fields are there, instead of getting correct response I’m getting this:
<code>"Input should be a valid dictionary or object to extract fields from: ('body',)"
</code>
<code>"Input should be a valid dictionary or object to extract fields from: ('body',)"
</code>
"Input should be a valid dictionary or object to extract fields from: ('body',)"
Exception:
<code>{"time": "2024-06-18T10:46:45.641Z", "l": "ERROR", "rid": "2558770a-66ff-4da0-b8a2-977afc5043e6", "org": "", "act": "", "message": "An error occurred: [{'type': 'model_attributes_type', 'loc': ('body',), 'msg': 'Input should be a valid dictionary or object to extract fields from', 'input': None, 'url': 'https://errors.pydantic.dev/2.6/v/model_attributes_type'}]", "component": {"name": "/app/common/exceptions/base_exception_handler.py", "version": "0.1.3"}, "exception": "Traceback (most recent call last):n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 68, in __call__n await self.app(scope, receive, sender)n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in __call__n raise en File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in __call__n await self.app(scope, receive, send)n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/routing.py", line 718, in __call__n await route.handle(scope, receive, send)n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/routing.py", line 276, in handlen await self.app(scope, receive, send)n File "Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/routing.py", line 66, in appn response = await func(request)n ^^^^^^^^^^^^^^^^^^^n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/fastapi/routing.py", line 273, in appn raise RequestValidationError(_normalize_errors(errors), body=body)nfastapi.exceptions.RequestValidationError: [{'type': 'model_attributes_type', 'loc': ('body',), 'msg': 'Input should be a valid dictionary or object to extract fields from', 'input': None, 'url': 'https://errors.pydantic.dev/2.6/v/model_attributes_type'}]"}
</code>
<code>{"time": "2024-06-18T10:46:45.641Z", "l": "ERROR", "rid": "2558770a-66ff-4da0-b8a2-977afc5043e6", "org": "", "act": "", "message": "An error occurred: [{'type': 'model_attributes_type', 'loc': ('body',), 'msg': 'Input should be a valid dictionary or object to extract fields from', 'input': None, 'url': 'https://errors.pydantic.dev/2.6/v/model_attributes_type'}]", "component": {"name": "/app/common/exceptions/base_exception_handler.py", "version": "0.1.3"}, "exception": "Traceback (most recent call last):n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 68, in __call__n await self.app(scope, receive, sender)n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in __call__n raise en File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in __call__n await self.app(scope, receive, send)n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/routing.py", line 718, in __call__n await route.handle(scope, receive, send)n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/routing.py", line 276, in handlen await self.app(scope, receive, send)n File "Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/routing.py", line 66, in appn response = await func(request)n ^^^^^^^^^^^^^^^^^^^n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/fastapi/routing.py", line 273, in appn raise RequestValidationError(_normalize_errors(errors), body=body)nfastapi.exceptions.RequestValidationError: [{'type': 'model_attributes_type', 'loc': ('body',), 'msg': 'Input should be a valid dictionary or object to extract fields from', 'input': None, 'url': 'https://errors.pydantic.dev/2.6/v/model_attributes_type'}]"}
</code>
{"time": "2024-06-18T10:46:45.641Z", "l": "ERROR", "rid": "2558770a-66ff-4da0-b8a2-977afc5043e6", "org": "", "act": "", "message": "An error occurred: [{'type': 'model_attributes_type', 'loc': ('body',), 'msg': 'Input should be a valid dictionary or object to extract fields from', 'input': None, 'url': 'https://errors.pydantic.dev/2.6/v/model_attributes_type'}]", "component": {"name": "/app/common/exceptions/base_exception_handler.py", "version": "0.1.3"}, "exception": "Traceback (most recent call last):n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 68, in __call__n await self.app(scope, receive, sender)n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in __call__n raise en File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in __call__n await self.app(scope, receive, send)n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/routing.py", line 718, in __call__n await route.handle(scope, receive, send)n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/routing.py", line 276, in handlen await self.app(scope, receive, send)n File "Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/starlette/routing.py", line 66, in appn response = await func(request)n ^^^^^^^^^^^^^^^^^^^n File "/Library/Caches/pypoetry/virtualenvs/service-Qx3_L5c2-py3.12/lib/python3.12/site-packages/fastapi/routing.py", line 273, in appn raise RequestValidationError(_normalize_errors(errors), body=body)nfastapi.exceptions.RequestValidationError: [{'type': 'model_attributes_type', 'loc': ('body',), 'msg': 'Input should be a valid dictionary or object to extract fields from', 'input': None, 'url': 'https://errors.pydantic.dev/2.6/v/model_attributes_type'}]"}
model validated and request proceed rest of the logic
New contributor
electromecca is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.