Browse Source

separate pydantic v1 v2 cases

pull/4573/head
jujumilk3 1 year ago
parent
commit
ce8de15a29
  1. 22
      fastapi/dependencies/utils.py
  2. 163
      tests/test_dependency_schema_query.py

22
fastapi/dependencies/utils.py

@ -208,16 +208,28 @@ def get_flat_params(dependant: Dependant) -> List[ModelField]:
def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature: def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
signature = inspect.signature(call) signature = inspect.signature(call)
globalns = getattr(call, "__globals__", {}) globalns = getattr(call, "__globals__", {})
fields = getattr(call, "model_fields", {}) if PYDANTIC_V2:
fields = getattr(call, "model_fields", {})
else:
fields = getattr(call, "__fields__", {})
if len(fields): if len(fields):
alias_dict = {} alias_dict = {}
query_extra_info = {} query_extra_info = {}
for param in fields: for param in fields:
query_extra_info[param] = dict(fields[param].__repr_args__()) if PYDANTIC_V2:
query_extra_info[param] = dict(fields[param].__repr_args__())
else:
query_extra_info[param] = dict(fields[param].field_info.__repr_args__())
if "alias" in query_extra_info[param]: if "alias" in query_extra_info[param]:
query_extra_info[query_extra_info[param]["alias"]] = dict( if PYDANTIC_V2:
fields[param].__repr_args__() query_extra_info[query_extra_info[param]["alias"]] = dict(
) fields[param].__repr_args__()
)
else:
query_extra_info[query_extra_info[param]["alias"]] = dict(
fields[param].field_info.__repr_args__()
)
alias_dict[query_extra_info[param]["alias"]] = param alias_dict[query_extra_info[param]["alias"]] = param
query_extra_info[param]["default"] = ( query_extra_info[param]["default"] = (
Required Required

163
tests/test_dependency_schema_query.py

@ -3,6 +3,10 @@ from typing import Optional
from fastapi import Depends, FastAPI, Query, status from fastapi import Depends, FastAPI, Query, status
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from pydantic import BaseModel from pydantic import BaseModel
from pydantic.version import VERSION as PYDANTIC_VERSION
PYDANTIC_V2 = PYDANTIC_VERSION.startswith("2.")
app = FastAPI() app = FastAPI()
@ -39,7 +43,158 @@ async def item_with_query_dependency(item: Item = Depends()):
client = TestClient(app) client = TestClient(app)
openapi_schema_with_not_omitted_description = { openapi_schema_with_not_omitted_description_pydantic_v1 = {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"/item": {
"get": {
"summary": "Item With Query Dependency",
"operationId": "item_with_query_dependency_item_get",
"parameters": [
{
"description": "This is a name_required_with_default field.",
"required": False,
"schema": {
"type": "string",
"title": "Name Required With Default",
"description": "This is a name_required_with_default field.",
"default": "name default",
"extra": {},
},
"name": "name_required_with_default",
"in": "query",
},
{
"description": "This is a name_required_without_default field.",
"required": True,
"schema": {
"type": "string",
"title": "Name Required Without Default",
"description": "This is a name_required_without_default field.",
"extra": {},
},
"name": "name_required_without_default",
"in": "query",
},
{
"description": "This is a optional_int field",
"required": False,
"schema": {
"type": "integer",
"title": "Optional Int",
"description": "This is a optional_int field",
"extra": {},
},
"name": "optional_int",
"in": "query",
},
{
"description": "This is a optional_str field",
"required": False,
"schema": {
"type": "string",
"title": "Optional Str",
"description": "This is a optional_str field",
"default": "default_exists",
"extra": {},
},
"name": "optional_str",
"in": "query",
},
{
"required": True,
"schema": {"type": "string", "title": "Model", "extra": {}},
"name": "model",
"in": "query",
},
{
"required": True,
"schema": {
"type": "string",
"title": "Manufacturer",
"extra": {},
},
"name": "manufacturer",
"in": "query",
},
{
"required": True,
"schema": {"type": "number", "title": "Price", "extra": {}},
"name": "price",
"in": "query",
},
{
"required": True,
"schema": {"type": "number", "title": "Tax", "extra": {}},
"name": "tax",
"in": "query",
},
{
"description": "This is a extra_optional_attributes field",
"required": False,
"schema": {
"type": "string",
"maxLength": 30,
"title": "Extra Optional Attributes Alias",
"description": "This is a extra_optional_attributes field",
"extra": {},
},
"name": "extra_optional_attributes_alias",
"in": "query",
},
],
"responses": {
"200": {
"description": "Successful Response",
"content": {"application/json": {"schema": {}}},
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
},
},
}
}
},
"components": {
"schemas": {
"HTTPValidationError": {
"properties": {
"detail": {
"items": {"$ref": "#/components/schemas/ValidationError"},
"type": "array",
"title": "Detail",
}
},
"type": "object",
"title": "HTTPValidationError",
},
"ValidationError": {
"properties": {
"loc": {
"items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
"type": "array",
"title": "Location",
},
"msg": {"type": "string", "title": "Message"},
"type": {"type": "string", "title": "Error Type"},
},
"type": "object",
"required": ["loc", "msg", "type"],
"title": "ValidationError",
},
}
},
}
openapi_schema_with_not_omitted_description_pydantic_v2 = {
"openapi": "3.1.0", "openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"}, "info": {"title": "FastAPI", "version": "0.1.0"},
"paths": { "paths": {
@ -202,8 +357,10 @@ openapi_schema_with_not_omitted_description = {
def test_openapi_schema_with_query_dependency(): def test_openapi_schema_with_query_dependency():
response = client.get("/openapi.json") response = client.get("/openapi.json")
assert response.status_code == 200, response.text assert response.status_code == 200, response.text
print(response.json()) if PYDANTIC_V2:
assert response.json() == openapi_schema_with_not_omitted_description assert response.json() == openapi_schema_with_not_omitted_description_pydantic_v2
else:
assert response.json() == openapi_schema_with_not_omitted_description_pydantic_v1
def test_response(): def test_response():

Loading…
Cancel
Save