|
|
|
@ -24,6 +24,18 @@ class Item(BaseModel): |
|
|
|
model_config = {"json_schema_serialization_defaults_required": True} |
|
|
|
|
|
|
|
|
|
|
|
if PYDANTIC_V2: |
|
|
|
from pydantic import computed_field |
|
|
|
|
|
|
|
class WithComputedField(BaseModel): |
|
|
|
name: str |
|
|
|
|
|
|
|
@computed_field |
|
|
|
@property |
|
|
|
def computed_field(self) -> str: |
|
|
|
return f"computed {self.name}" |
|
|
|
|
|
|
|
|
|
|
|
def get_app_client(separate_input_output_schemas: bool = True) -> TestClient: |
|
|
|
app = FastAPI(separate_input_output_schemas=separate_input_output_schemas) |
|
|
|
|
|
|
|
@ -46,6 +58,14 @@ def get_app_client(separate_input_output_schemas: bool = True) -> TestClient: |
|
|
|
Item(name="Plumbus"), |
|
|
|
] |
|
|
|
|
|
|
|
if PYDANTIC_V2: |
|
|
|
|
|
|
|
@app.post("/with-computed-field/") |
|
|
|
def create_with_computed_field( |
|
|
|
with_computed_field: WithComputedField, |
|
|
|
) -> WithComputedField: |
|
|
|
return with_computed_field |
|
|
|
|
|
|
|
client = TestClient(app) |
|
|
|
return client |
|
|
|
|
|
|
|
@ -131,6 +151,23 @@ def test_read_items(): |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
@needs_pydanticv2 |
|
|
|
def test_with_computed_field(): |
|
|
|
client = get_app_client() |
|
|
|
client_no = get_app_client(separate_input_output_schemas=False) |
|
|
|
response = client.post("/with-computed-field/", json={"name": "example"}) |
|
|
|
response2 = client_no.post("/with-computed-field/", json={"name": "example"}) |
|
|
|
assert response.status_code == response2.status_code == 200, response.text |
|
|
|
assert ( |
|
|
|
response.json() |
|
|
|
== response2.json() |
|
|
|
== { |
|
|
|
"name": "example", |
|
|
|
"computed_field": "computed example", |
|
|
|
} |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
@needs_pydanticv2 |
|
|
|
def test_openapi_schema(): |
|
|
|
client = get_app_client() |
|
|
|
@ -245,6 +282,44 @@ def test_openapi_schema(): |
|
|
|
}, |
|
|
|
} |
|
|
|
}, |
|
|
|
"/with-computed-field/": { |
|
|
|
"post": { |
|
|
|
"summary": "Create With Computed Field", |
|
|
|
"operationId": "create_with_computed_field_with_computed_field__post", |
|
|
|
"requestBody": { |
|
|
|
"content": { |
|
|
|
"application/json": { |
|
|
|
"schema": { |
|
|
|
"$ref": "#/components/schemas/WithComputedField-Input" |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
"required": True, |
|
|
|
}, |
|
|
|
"responses": { |
|
|
|
"200": { |
|
|
|
"description": "Successful Response", |
|
|
|
"content": { |
|
|
|
"application/json": { |
|
|
|
"schema": { |
|
|
|
"$ref": "#/components/schemas/WithComputedField-Output" |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
"422": { |
|
|
|
"description": "Validation Error", |
|
|
|
"content": { |
|
|
|
"application/json": { |
|
|
|
"schema": { |
|
|
|
"$ref": "#/components/schemas/HTTPValidationError" |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
"components": { |
|
|
|
"schemas": { |
|
|
|
@ -333,6 +408,25 @@ def test_openapi_schema(): |
|
|
|
"required": ["subname", "sub_description", "tags"], |
|
|
|
"title": "SubItem", |
|
|
|
}, |
|
|
|
"WithComputedField-Input": { |
|
|
|
"properties": {"name": {"type": "string", "title": "Name"}}, |
|
|
|
"type": "object", |
|
|
|
"required": ["name"], |
|
|
|
"title": "WithComputedField", |
|
|
|
}, |
|
|
|
"WithComputedField-Output": { |
|
|
|
"properties": { |
|
|
|
"name": {"type": "string", "title": "Name"}, |
|
|
|
"computed_field": { |
|
|
|
"type": "string", |
|
|
|
"title": "Computed Field", |
|
|
|
"readOnly": True, |
|
|
|
}, |
|
|
|
}, |
|
|
|
"type": "object", |
|
|
|
"required": ["name", "computed_field"], |
|
|
|
"title": "WithComputedField", |
|
|
|
}, |
|
|
|
"ValidationError": { |
|
|
|
"properties": { |
|
|
|
"loc": { |
|
|
|
@ -458,6 +552,44 @@ def test_openapi_schema_no_separate(): |
|
|
|
}, |
|
|
|
} |
|
|
|
}, |
|
|
|
"/with-computed-field/": { |
|
|
|
"post": { |
|
|
|
"summary": "Create With Computed Field", |
|
|
|
"operationId": "create_with_computed_field_with_computed_field__post", |
|
|
|
"requestBody": { |
|
|
|
"content": { |
|
|
|
"application/json": { |
|
|
|
"schema": { |
|
|
|
"$ref": "#/components/schemas/WithComputedField-Input" |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
"required": True, |
|
|
|
}, |
|
|
|
"responses": { |
|
|
|
"200": { |
|
|
|
"description": "Successful Response", |
|
|
|
"content": { |
|
|
|
"application/json": { |
|
|
|
"schema": { |
|
|
|
"$ref": "#/components/schemas/WithComputedField-Output" |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
"422": { |
|
|
|
"description": "Validation Error", |
|
|
|
"content": { |
|
|
|
"application/json": { |
|
|
|
"schema": { |
|
|
|
"$ref": "#/components/schemas/HTTPValidationError" |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
"components": { |
|
|
|
"schemas": { |
|
|
|
@ -508,6 +640,25 @@ def test_openapi_schema_no_separate(): |
|
|
|
"required": ["subname"], |
|
|
|
"title": "SubItem", |
|
|
|
}, |
|
|
|
"WithComputedField-Input": { |
|
|
|
"properties": {"name": {"type": "string", "title": "Name"}}, |
|
|
|
"type": "object", |
|
|
|
"required": ["name"], |
|
|
|
"title": "WithComputedField", |
|
|
|
}, |
|
|
|
"WithComputedField-Output": { |
|
|
|
"properties": { |
|
|
|
"name": {"type": "string", "title": "Name"}, |
|
|
|
"computed_field": { |
|
|
|
"type": "string", |
|
|
|
"title": "Computed Field", |
|
|
|
"readOnly": True, |
|
|
|
}, |
|
|
|
}, |
|
|
|
"type": "object", |
|
|
|
"required": ["name", "computed_field"], |
|
|
|
"title": "WithComputedField", |
|
|
|
}, |
|
|
|
"ValidationError": { |
|
|
|
"properties": { |
|
|
|
"loc": { |
|
|
|
|