diff --git a/base_rest_demo/tests/data/partner_pydantic_api.json b/base_rest_demo/tests/data/partner_pydantic_api.json index f3e1aecc..53cfe03f 100644 --- a/base_rest_demo/tests/data/partner_pydantic_api.json +++ b/base_rest_demo/tests/data/partner_pydantic_api.json @@ -198,9 +198,7 @@ "openapi": "3.0.0", "components": { "schemas": { - "StateInfo": { - "title": "StateInfo", - "type": "object", + "CountryInfo": { "properties": { "id": { "title": "Id", @@ -211,11 +209,11 @@ "type": "string" } }, - "required": ["id", "name"] - }, - "CountryInfo": { + "required": ["id", "name"], "title": "CountryInfo", - "type": "object", + "type": "object" + }, + "StateInfo": { "properties": { "id": { "title": "Id", @@ -226,11 +224,11 @@ "type": "string" } }, - "required": ["id", "name"] + "required": ["id", "name"], + "title": "StateInfo", + "type": "object" }, "PartnerInfo": { - "title": "PartnerInfo", - "type": "object", "properties": { "id": { "title": "Id", @@ -245,12 +243,12 @@ "type": "string" }, "street2": { + "default": null, "title": "Street2", - "type": "string", - "default": null + "type": "string" }, - "zip": { - "title": "Zip", + "zip_code": { + "title": "Zip Code", "type": "string" }, "city": { @@ -258,9 +256,9 @@ "type": "string" }, "phone": { + "default": null, "title": "Phone", - "type": "string", - "default": null + "type": "string" }, "state": { "$ref": "#/components/schemas/StateInfo" @@ -269,48 +267,16 @@ "$ref": "#/components/schemas/CountryInfo" }, "is_company": { + "default": null, "title": "Is Company", - "type": "boolean", - "default": null + "type": "boolean" } }, - "required": ["id", "name", "street", "zip", "city", "state", "country"], - "$defs": { - "StateInfo": { - "title": "StateInfo", - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "integer" - }, - "name": { - "title": "Name", - "type": "string" - } - }, - "required": ["id", "name"] - }, - "CountryInfo": { - "title": "CountryInfo", - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "integer" - }, - "name": { - "title": "Name", - "type": "string" - } - }, - "required": ["id", "name"] - } - } + "required": ["id", "name", "street", "zip_code", "city", "state", "country"], + "title": "PartnerInfo", + "type": "object" }, "PartnerShortInfo": { - "title": "PartnerShortInfo", - "type": "object", "properties": { "id": { "title": "Id", @@ -321,7 +287,9 @@ "type": "string" } }, - "required": ["id", "name"] + "required": ["id", "name"], + "title": "PartnerShortInfo", + "type": "object" } }, "securitySchemes": { diff --git a/base_rest_pydantic/restapi.py b/base_rest_pydantic/restapi.py index 995ca451..f7301074 100644 --- a/base_rest_pydantic/restapi.py +++ b/base_rest_pydantic/restapi.py @@ -114,10 +114,10 @@ def to_openapi_responses(self, service, spec): } def to_json_schema(self, service, spec, direction): - schema = self._model_cls.model_json_schema() + schema = self._model_cls.model_json_schema(by_alias=False) schema_name = schema["title"] if schema_name not in spec.components.schemas: - definitions = schema.get("$defs", {}) + definitions = schema.pop("$defs", {}) for name, sch in definitions.items(): if name in spec.components.schemas: continue diff --git a/extendable_fastapi/schemas.py b/extendable_fastapi/schemas.py index 6ad7a9b3..dfa7a166 100644 --- a/extendable_fastapi/schemas.py +++ b/extendable_fastapi/schemas.py @@ -6,7 +6,6 @@ class StrictExtendableBaseModel( revalidate_instances="always", validate_assignment=True, extra="forbid", - strict=True, ): """ An ExtendableBaseModel with strict validation. @@ -24,6 +23,4 @@ class StrictExtendableBaseModel( (default is "never") * validate_assignment=True: revalidate the model when the data is changed (default is False) * extra="forbid": Forbid any extra attributes (default is "ignore") - * strict=True: raise an error if a value's type does not match the field's type - annotation (default is False; Pydantic attempts to coerce values to the correct type) """ diff --git a/extendable_fastapi/tests/test_strict_extendable_base_model.py b/extendable_fastapi/tests/test_strict_extendable_base_model.py index 650982f4..f05dfd79 100644 --- a/extendable_fastapi/tests/test_strict_extendable_base_model.py +++ b/extendable_fastapi/tests/test_strict_extendable_base_model.py @@ -55,14 +55,9 @@ def test_StrictModel_extra_forbidden(self): with self.assertRaises(ValidationError): self.StrictModel(x=1, z=3, d=None) - def test_Model_strict_false(self): - # Coerce str->date is allowed - m = self.Model(x=1, d=None) + def test_StrictModel_strict_false(self): + # Coerce str->date is allowed to enable coercion from JSON + # by FastAPI + m = self.StrictModel(x=1, d=None) m.d = "2023-01-01" self.assertTrue(m.model_validate(m)) - - def test_StrictModel_strict_true(self): - # Coerce str->date is forbidden - m = self.StrictModel(x=1, d=None) - with self.assertRaises(ValidationError): - m.d = "2023-01-01"