self.response_field = create_response_field(
name=response_name,
type_=self.response_model,
- # TODO: This should actually set mode='serialization', just, that changes the schemas
- # mode="serialization",
- mode="validation",
+ mode="serialization",
)
# Create a clone of the field, so that a Pydantic submodel is not returned
# as is just because it's an instance of a subclass of a more limited class
--- /dev/null
+import pytest
+from fastapi import FastAPI
+from fastapi.testclient import TestClient
+
+from .utils import needs_pydanticv2
+
+
+@pytest.fixture(name="client")
+def get_client():
+ app = FastAPI()
+
+ from pydantic import BaseModel, computed_field
+
+ class Rectangle(BaseModel):
+ width: int
+ length: int
+
+ @computed_field
+ @property
+ def area(self) -> int:
+ return self.width * self.length
+
+ @app.get("/")
+ def read_root() -> Rectangle:
+ return Rectangle(width=3, length=4)
+
+ client = TestClient(app)
+ return client
+
+
+@needs_pydanticv2
+def test_get(client: TestClient):
+ response = client.get("/")
+ assert response.status_code == 200, response.text
+ assert response.json() == {"width": 3, "length": 4, "area": 12}
+
+
+@needs_pydanticv2
+def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/": {
+ "get": {
+ "summary": "Read Root",
+ "operationId": "read_root__get",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Rectangle"}
+ }
+ },
+ }
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "Rectangle": {
+ "properties": {
+ "width": {"type": "integer", "title": "Width"},
+ "length": {"type": "integer", "title": "Length"},
+ "area": {"type": "integer", "title": "Area", "readOnly": True},
+ },
+ "type": "object",
+ "required": ["width", "length", "area"],
+ "title": "Rectangle",
+ }
+ }
+ },
+ }
from typing import Optional
import pytest
-from dirty_equals import HasRepr, IsDict
+from dirty_equals import HasRepr, IsDict, IsOneOf
from fastapi import Depends, FastAPI
from fastapi.exceptions import ResponseValidationError
from fastapi.testclient import TestClient
},
"ModelA": {
"title": "ModelA",
- "required": ["name", "foo"],
+ "required": IsOneOf(
+ ["name", "description", "foo"],
+ # TODO remove when deprecating Pydantic v1
+ ["name", "foo"],
+ ),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
import pytest
-from dirty_equals import IsDict
from fastapi.testclient import TestClient
+from ...utils import needs_pydanticv1, needs_pydanticv2
+
@pytest.fixture(name="client")
def get_client():
}
+@needs_pydanticv2
def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/{item_id}": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ItemOutput"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Read Item",
+ "operationId": "read_item_items__item_id__get",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
+ },
+ "put": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ItemOutput"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Update Item",
+ "operationId": "update_item_items__item_id__put",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/ItemInput"}
+ }
+ },
+ "required": True,
+ },
+ },
+ }
+ },
+ "components": {
+ "schemas": {
+ "ItemInput": {
+ "title": "Item",
+ "type": "object",
+ "properties": {
+ "name": {
+ "title": "Name",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ "description": {
+ "title": "Description",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ "price": {
+ "title": "Price",
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ },
+ "tax": {"title": "Tax", "type": "number", "default": 10.5},
+ "tags": {
+ "title": "Tags",
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ItemOutput": {
+ "title": "Item",
+ "type": "object",
+ "required": ["name", "description", "price", "tax", "tags"],
+ "properties": {
+ "name": {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Name",
+ },
+ "description": {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Description",
+ },
+ "price": {
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ "title": "Price",
+ },
+ "tax": {"title": "Tax", "type": "number", "default": 10.5},
+ "tags": {
+ "title": "Tags",
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": ["loc", "msg", "type"],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ },
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
+ },
+ },
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/ValidationError"},
+ }
+ },
+ },
+ }
+ },
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+def test_openapi_schema_pv1(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"title": "Item",
"type": "object",
"properties": {
- "name": IsDict(
- {
- "title": "Name",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Name", "type": "string"}
- ),
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
- "price": IsDict(
- {
- "title": "Price",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Price", "type": "number"}
- ),
+ "name": {"title": "Name", "type": "string"},
+ "description": {"title": "Description", "type": "string"},
+ "price": {"title": "Price", "type": "number"},
"tax": {"title": "Tax", "type": "number", "default": 10.5},
"tags": {
"title": "Tags",
import pytest
-from dirty_equals import IsDict
from fastapi.testclient import TestClient
-from ...utils import needs_py310
+from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
@pytest.fixture(name="client")
@needs_py310
+@needs_pydanticv2
def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/{item_id}": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ItemOutput"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Read Item",
+ "operationId": "read_item_items__item_id__get",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
+ },
+ "put": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ItemOutput"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Update Item",
+ "operationId": "update_item_items__item_id__put",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/ItemInput"}
+ }
+ },
+ "required": True,
+ },
+ },
+ }
+ },
+ "components": {
+ "schemas": {
+ "ItemInput": {
+ "title": "Item",
+ "type": "object",
+ "properties": {
+ "name": {
+ "title": "Name",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ "description": {
+ "title": "Description",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ "price": {
+ "title": "Price",
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ },
+ "tax": {"title": "Tax", "type": "number", "default": 10.5},
+ "tags": {
+ "title": "Tags",
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ItemOutput": {
+ "title": "Item",
+ "type": "object",
+ "required": ["name", "description", "price", "tax", "tags"],
+ "properties": {
+ "name": {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Name",
+ },
+ "description": {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Description",
+ },
+ "price": {
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ "title": "Price",
+ },
+ "tax": {"title": "Tax", "type": "number", "default": 10.5},
+ "tags": {
+ "title": "Tags",
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": ["loc", "msg", "type"],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ },
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
+ },
+ },
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/ValidationError"},
+ }
+ },
+ },
+ }
+ },
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_py310
+@needs_pydanticv1
+def test_openapi_schema_pv1(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"title": "Item",
"type": "object",
"properties": {
- "name": IsDict(
- {
- "title": "Name",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Name", "type": "string"}
- ),
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
- "price": IsDict(
- {
- "title": "Price",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Price", "type": "number"}
- ),
+ "name": {"title": "Name", "type": "string"},
+ "description": {"title": "Description", "type": "string"},
+ "price": {"title": "Price", "type": "number"},
"tax": {"title": "Tax", "type": "number", "default": 10.5},
"tags": {
"title": "Tags",
import pytest
-from dirty_equals import IsDict
from fastapi.testclient import TestClient
-from ...utils import needs_py39
+from ...utils import needs_py39, needs_pydanticv1, needs_pydanticv2
@pytest.fixture(name="client")
@needs_py39
+@needs_pydanticv2
def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/{item_id}": {
+ "get": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ItemOutput"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Read Item",
+ "operationId": "read_item_items__item_id__get",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
+ },
+ "put": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ItemOutput"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Update Item",
+ "operationId": "update_item_items__item_id__put",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Item Id", "type": "string"},
+ "name": "item_id",
+ "in": "path",
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/ItemInput"}
+ }
+ },
+ "required": True,
+ },
+ },
+ }
+ },
+ "components": {
+ "schemas": {
+ "ItemInput": {
+ "title": "Item",
+ "type": "object",
+ "properties": {
+ "name": {
+ "title": "Name",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ "description": {
+ "title": "Description",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ "price": {
+ "title": "Price",
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ },
+ "tax": {"title": "Tax", "type": "number", "default": 10.5},
+ "tags": {
+ "title": "Tags",
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ItemOutput": {
+ "title": "Item",
+ "type": "object",
+ "required": ["name", "description", "price", "tax", "tags"],
+ "properties": {
+ "name": {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Name",
+ },
+ "description": {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Description",
+ },
+ "price": {
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ "title": "Price",
+ },
+ "tax": {"title": "Tax", "type": "number", "default": 10.5},
+ "tags": {
+ "title": "Tags",
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": ["loc", "msg", "type"],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ },
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
+ },
+ },
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/ValidationError"},
+ }
+ },
+ },
+ }
+ },
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_py39
+@needs_pydanticv1
+def test_openapi_schema_pv1(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"title": "Item",
"type": "object",
"properties": {
- "name": IsDict(
- {
- "title": "Name",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Name", "type": "string"}
- ),
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
- "price": IsDict(
- {
- "title": "Price",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Price", "type": "number"}
- ),
+ "name": {"title": "Name", "type": "string"},
+ "description": {"title": "Description", "type": "string"},
+ "price": {"title": "Price", "type": "number"},
"tax": {"title": "Tax", "type": "number", "default": 10.5},
"tags": {
"title": "Tags",
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from docs_src.dataclasses.tutorial002 import app
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200
- data = response.json()
- assert data == {
+ assert response.json() == {
"openapi": "3.1.0",
"info": {"title": "FastAPI", "version": "0.1.0"},
"paths": {
"schemas": {
"Item": {
"title": "Item",
- "required": ["name", "price"],
+ "required": IsOneOf(
+ ["name", "price", "tags", "description", "tax"],
+ # TODO: remove when deprecating Pydantic v1
+ ["name", "price"],
+ ),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
"title": "Tags",
"type": "array",
"items": {"type": "string"},
- "default": [],
}
)
| IsDict(
-from dirty_equals import IsDict
from fastapi.testclient import TestClient
from docs_src.dataclasses.tutorial003 import app
+from ...utils import needs_pydanticv1, needs_pydanticv2
+
client = TestClient(app)
]
+@needs_pydanticv2
def test_openapi_schema():
response = client.get("/openapi.json")
assert response.status_code == 200
"schema": {
"title": "Items",
"type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
+ "items": {"$ref": "#/components/schemas/ItemInput"},
}
}
},
"schemas": {
"Author": {
"title": "Author",
+ "required": ["name", "items"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "items": {
+ "title": "Items",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/ItemOutput"},
+ },
+ },
+ },
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/ValidationError"},
+ }
+ },
+ },
+ "ItemInput": {
+ "title": "Item",
"required": ["name"],
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
- "items": IsDict(
- {
- "title": "Items",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
- "default": [],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {
- "title": "Items",
- "type": "array",
- "items": {"$ref": "#/components/schemas/Item"},
+ "description": {
+ "title": "Description",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ },
+ },
+ "ItemOutput": {
+ "title": "Item",
+ "required": ["name", "description"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "description": {
+ "title": "Description",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ },
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": ["loc", "msg", "type"],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ },
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
+ },
+ },
+ }
+ },
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+def test_openapi_schema_pv1():
+ response = client.get("/openapi.json")
+ assert response.status_code == 200
+ assert response.json() == {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/authors/{author_id}/items/": {
+ "post": {
+ "summary": "Create Author Items",
+ "operationId": "create_author_items_authors__author_id__items__post",
+ "parameters": [
+ {
+ "required": True,
+ "schema": {"title": "Author Id", "type": "string"},
+ "name": "author_id",
+ "in": "path",
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "title": "Items",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/Item"},
+ }
}
- ),
+ },
+ "required": True,
+ },
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/Author"}
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ }
+ },
+ "/authors/": {
+ "get": {
+ "summary": "Get Authors",
+ "operationId": "get_authors_authors__get",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "title": "Response Get Authors Authors Get",
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Author"
+ },
+ }
+ }
+ },
+ }
+ },
+ }
+ },
+ },
+ "components": {
+ "schemas": {
+ "Author": {
+ "title": "Author",
+ "required": ["name"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "items": {
+ "title": "Items",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/Item"},
+ },
},
},
"HTTPValidationError": {
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
+ "description": {"title": "Description", "type": "string"},
},
},
"ValidationError": {
+from dirty_equals import IsOneOf
from fastapi.testclient import TestClient
from docs_src.extra_models.tutorial003 import app
"schemas": {
"PlaneItem": {
"title": "PlaneItem",
- "required": ["description", "size"],
+ "required": IsOneOf(
+ ["description", "type", "size"],
+ # TODO: remove when deprecating Pydantic v1
+ ["description", "size"],
+ ),
"type": "object",
"properties": {
"description": {"title": "Description", "type": "string"},
},
"CarItem": {
"title": "CarItem",
- "required": ["description"],
+ "required": IsOneOf(
+ ["description", "type"],
+ # TODO: remove when deprecating Pydantic v1
+ ["description"],
+ ),
"type": "object",
"properties": {
"description": {"title": "Description", "type": "string"},
import pytest
+from dirty_equals import IsOneOf
from fastapi.testclient import TestClient
from ...utils import needs_py310
"schemas": {
"PlaneItem": {
"title": "PlaneItem",
- "required": ["description", "size"],
+ "required": IsOneOf(
+ ["description", "type", "size"],
+ # TODO: remove when deprecating Pydantic v1
+ ["description", "size"],
+ ),
"type": "object",
"properties": {
"description": {"title": "Description", "type": "string"},
},
"CarItem": {
"title": "CarItem",
- "required": ["description"],
+ "required": IsOneOf(
+ ["description", "type"],
+ # TODO: remove when deprecating Pydantic v1
+ ["description"],
+ ),
"type": "object",
"properties": {
"description": {"title": "Description", "type": "string"},
-from dirty_equals import IsDict
from fastapi.testclient import TestClient
from docs_src.path_operation_advanced_configuration.tutorial004 import app
+from ...utils import needs_pydanticv1, needs_pydanticv2
+
client = TestClient(app)
}
+@needs_pydanticv2
def test_openapi_schema():
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ItemOutput"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Create an item",
+ "description": "Create an item with all the information:\n\n- **name**: each item must have a name\n- **description**: a long description\n- **price**: required\n- **tax**: if the item doesn't have tax, you can omit this\n- **tags**: a set of unique tag strings for this item",
+ "operationId": "create_item_items__post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/ItemInput"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "ItemInput": {
+ "title": "Item",
+ "required": ["name", "price"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "description": {
+ "title": "Description",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ "price": {"title": "Price", "type": "number"},
+ "tax": {
+ "title": "Tax",
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ },
+ "tags": {
+ "title": "Tags",
+ "uniqueItems": True,
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ItemOutput": {
+ "title": "Item",
+ "required": ["name", "description", "price", "tax", "tags"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "description": {
+ "title": "Description",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ "price": {"title": "Price", "type": "number"},
+ "tax": {
+ "title": "Tax",
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ },
+ "tags": {
+ "title": "Tags",
+ "uniqueItems": True,
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": ["loc", "msg", "type"],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ },
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
+ },
+ },
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/ValidationError"},
+ }
+ },
+ },
+ }
+ },
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+def test_openapi_schema_pv1():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
+ "description": {"title": "Description", "type": "string"},
"price": {"title": "Price", "type": "number"},
- "tax": IsDict(
- {
- "title": "Tax",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Tax", "type": "number"}
- ),
+ "tax": {"title": "Tax", "type": "number"},
"tags": {
"title": "Tags",
"uniqueItems": True,
-from dirty_equals import IsDict
from fastapi.testclient import TestClient
from docs_src.path_operation_configuration.tutorial005 import app
+from ...utils import needs_pydanticv1, needs_pydanticv2
+
client = TestClient(app)
}
+@needs_pydanticv2
def test_openapi_schema():
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "The created item",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ItemOutput"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Create an item",
+ "description": "Create an item with all the information:\n\n- **name**: each item must have a name\n- **description**: a long description\n- **price**: required\n- **tax**: if the item doesn't have tax, you can omit this\n- **tags**: a set of unique tag strings for this item",
+ "operationId": "create_item_items__post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/ItemInput"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "ItemInput": {
+ "title": "Item",
+ "required": ["name", "price"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "description": {
+ "title": "Description",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ "price": {"title": "Price", "type": "number"},
+ "tax": {
+ "title": "Tax",
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ },
+ "tags": {
+ "title": "Tags",
+ "uniqueItems": True,
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ItemOutput": {
+ "title": "Item",
+ "required": ["name", "description", "price", "tax", "tags"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "description": {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Description",
+ },
+ "price": {"title": "Price", "type": "number"},
+ "tax": {
+ "title": "Tax",
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ },
+ "tags": {
+ "title": "Tags",
+ "uniqueItems": True,
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": ["loc", "msg", "type"],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ },
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
+ },
+ },
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/ValidationError"},
+ }
+ },
+ },
+ }
+ },
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_pydanticv1
+def test_openapi_schema_pv1():
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
+ "description": {"title": "Description", "type": "string"},
"price": {"title": "Price", "type": "number"},
- "tax": IsDict(
- {
- "title": "Tax",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Tax", "type": "number"}
- ),
+ "tax": {"title": "Tax", "type": "number"},
"tags": {
"title": "Tags",
"uniqueItems": True,
import pytest
-from dirty_equals import IsDict
from fastapi.testclient import TestClient
-from ...utils import needs_py310
+from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
@pytest.fixture(name="client")
@needs_py310
+@needs_pydanticv2
def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "The created item",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ItemOutput"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Create an item",
+ "description": "Create an item with all the information:\n\n- **name**: each item must have a name\n- **description**: a long description\n- **price**: required\n- **tax**: if the item doesn't have tax, you can omit this\n- **tags**: a set of unique tag strings for this item",
+ "operationId": "create_item_items__post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/ItemInput"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "ItemInput": {
+ "title": "Item",
+ "required": ["name", "price"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "description": {
+ "title": "Description",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ "price": {"title": "Price", "type": "number"},
+ "tax": {
+ "title": "Tax",
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ },
+ "tags": {
+ "title": "Tags",
+ "uniqueItems": True,
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ItemOutput": {
+ "title": "Item",
+ "required": ["name", "description", "price", "tax", "tags"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "description": {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Description",
+ },
+ "price": {"title": "Price", "type": "number"},
+ "tax": {
+ "title": "Tax",
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ },
+ "tags": {
+ "title": "Tags",
+ "uniqueItems": True,
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": ["loc", "msg", "type"],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ },
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
+ },
+ },
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/ValidationError"},
+ }
+ },
+ },
+ }
+ },
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_py310
+@needs_pydanticv1
+def test_openapi_schema_pv1(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
+ "description": {"title": "Description", "type": "string"},
"price": {"title": "Price", "type": "number"},
- "tax": IsDict(
- {
- "title": "Tax",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Tax", "type": "number"}
- ),
+ "tax": {"title": "Tax", "type": "number"},
"tags": {
"title": "Tags",
"uniqueItems": True,
import pytest
-from dirty_equals import IsDict
from fastapi.testclient import TestClient
-from ...utils import needs_py39
+from ...utils import needs_py39, needs_pydanticv1, needs_pydanticv2
@pytest.fixture(name="client")
@needs_py39
+@needs_pydanticv2
def test_openapi_schema(client: TestClient):
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == {
+ "openapi": "3.1.0",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "The created item",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ItemOutput"
+ }
+ }
+ },
+ },
+ "422": {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/HTTPValidationError"
+ }
+ }
+ },
+ },
+ },
+ "summary": "Create an item",
+ "description": "Create an item with all the information:\n\n- **name**: each item must have a name\n- **description**: a long description\n- **price**: required\n- **tax**: if the item doesn't have tax, you can omit this\n- **tags**: a set of unique tag strings for this item",
+ "operationId": "create_item_items__post",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {"$ref": "#/components/schemas/ItemInput"}
+ }
+ },
+ "required": True,
+ },
+ }
+ }
+ },
+ "components": {
+ "schemas": {
+ "ItemInput": {
+ "title": "Item",
+ "required": ["name", "price"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "description": {
+ "title": "Description",
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ },
+ "price": {"title": "Price", "type": "number"},
+ "tax": {
+ "title": "Tax",
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ },
+ "tags": {
+ "title": "Tags",
+ "uniqueItems": True,
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ItemOutput": {
+ "title": "Item",
+ "required": ["name", "description", "price", "tax", "tags"],
+ "type": "object",
+ "properties": {
+ "name": {"title": "Name", "type": "string"},
+ "description": {
+ "anyOf": [{"type": "string"}, {"type": "null"}],
+ "title": "Description",
+ },
+ "price": {"title": "Price", "type": "number"},
+ "tax": {
+ "title": "Tax",
+ "anyOf": [{"type": "number"}, {"type": "null"}],
+ },
+ "tags": {
+ "title": "Tags",
+ "uniqueItems": True,
+ "type": "array",
+ "items": {"type": "string"},
+ "default": [],
+ },
+ },
+ },
+ "ValidationError": {
+ "title": "ValidationError",
+ "required": ["loc", "msg", "type"],
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "integer"}]
+ },
+ },
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
+ },
+ },
+ "HTTPValidationError": {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {"$ref": "#/components/schemas/ValidationError"},
+ }
+ },
+ },
+ }
+ },
+ }
+
+
+# TODO: remove when deprecating Pydantic v1
+@needs_py39
+@needs_pydanticv1
+def test_openapi_schema_pv1(client: TestClient):
response = client.get("/openapi.json")
assert response.status_code == 200, response.text
assert response.json() == {
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
- "description": IsDict(
- {
- "title": "Description",
- "anyOf": [{"type": "string"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Description", "type": "string"}
- ),
+ "description": {"title": "Description", "type": "string"},
"price": {"title": "Price", "type": "number"},
- "tax": IsDict(
- {
- "title": "Tax",
- "anyOf": [{"type": "number"}, {"type": "null"}],
- }
- )
- | IsDict(
- # TODO: remove when deprecating Pydantic v1
- {"title": "Tax", "type": "number"}
- ),
+ "tax": {"title": "Tax", "type": "number"},
"tags": {
"title": "Tags",
"uniqueItems": True,
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from docs_src.response_model.tutorial003 import app
"schemas": {
"UserOut": {
"title": "UserOut",
- "required": ["username", "email"],
+ "required": IsOneOf(
+ ["username", "email", "full_name"],
+ # TODO: remove when deprecating Pydantic v1
+ ["username", "email"],
+ ),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from docs_src.response_model.tutorial003_01 import app
"schemas": {
"BaseUser": {
"title": "BaseUser",
- "required": ["username", "email"],
+ "required": IsOneOf(
+ ["username", "email", "full_name"],
+ # TODO: remove when deprecating Pydantic v1
+ ["username", "email"],
+ ),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
import pytest
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from ...utils import needs_py310
"schemas": {
"BaseUser": {
"title": "BaseUser",
- "required": ["username", "email"],
+ "required": IsOneOf(
+ ["username", "email", "full_name"],
+ # TODO: remove when deprecating Pydantic v1
+ ["username", "email"],
+ ),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
import pytest
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from ...utils import needs_py310
"schemas": {
"UserOut": {
"title": "UserOut",
- "required": ["username", "email"],
+ "required": IsOneOf(
+ ["username", "email", "full_name"],
+ # TODO: remove when deprecating Pydantic v1
+ ["username", "email"],
+ ),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
import pytest
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from docs_src.response_model.tutorial004 import app
"schemas": {
"Item": {
"title": "Item",
- "required": ["name", "price"],
+ "required": IsOneOf(
+ ["name", "description", "price", "tax", "tags"],
+ # TODO: remove when deprecating Pydantic v1
+ ["name", "price"],
+ ),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
import pytest
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from ...utils import needs_py310
"schemas": {
"Item": {
"title": "Item",
- "required": ["name", "price"],
+ "required": IsOneOf(
+ ["name", "description", "price", "tax", "tags"],
+ # TODO: remove when deprecating Pydantic v1
+ ["name", "price"],
+ ),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
import pytest
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from ...utils import needs_py39
"schemas": {
"Item": {
"title": "Item",
- "required": ["name", "price"],
+ "required": IsOneOf(
+ ["name", "description", "price", "tax", "tags"],
+ # TODO: remove when deprecating Pydantic v1
+ ["name", "price"],
+ ),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from docs_src.response_model.tutorial005 import app
"schemas": {
"Item": {
"title": "Item",
- "required": ["name", "price"],
+ "required": IsOneOf(
+ ["name", "description", "price", "tax"],
+ # TODO: remove when deprecating Pydantic v1
+ ["name", "price"],
+ ),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
import pytest
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from ...utils import needs_py310
"schemas": {
"Item": {
"title": "Item",
- "required": ["name", "price"],
+ "required": IsOneOf(
+ ["name", "description", "price", "tax"],
+ # TODO: remove when deprecating Pydantic v1
+ ["name", "price"],
+ ),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from docs_src.response_model.tutorial006 import app
"schemas": {
"Item": {
"title": "Item",
- "required": ["name", "price"],
+ "required": IsOneOf(
+ ["name", "description", "price", "tax"],
+ # TODO: remove when deprecating Pydantic v1
+ ["name", "price"],
+ ),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
import pytest
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from ...utils import needs_py310
"schemas": {
"Item": {
"title": "Item",
- "required": ["name", "price"],
+ "required": IsOneOf(
+ ["name", "description", "price", "tax"],
+ # TODO: remove when deprecating Pydantic v1
+ ["name", "price"],
+ ),
"type": "object",
"properties": {
"name": {"title": "Name", "type": "string"},
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from docs_src.security.tutorial005 import (
"schemas": {
"User": {
"title": "User",
- "required": ["username"],
+ "required": IsOneOf(
+ ["username", "email", "full_name", "disabled"],
+ # TODO: remove when deprecating Pydantic v1
+ ["username"],
+ ),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from docs_src.security.tutorial005_an import (
"schemas": {
"User": {
"title": "User",
- "required": ["username"],
+ "required": IsOneOf(
+ ["username", "email", "full_name", "disabled"],
+ # TODO: remove when deprecating Pydantic v1
+ ["username"],
+ ),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
import pytest
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from ...utils import needs_py310
"schemas": {
"User": {
"title": "User",
- "required": ["username"],
+ "required": IsOneOf(
+ ["username", "email", "full_name", "disabled"],
+ # TODO: remove when deprecating Pydantic v1
+ ["username"],
+ ),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
import pytest
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from ...utils import needs_py39
"schemas": {
"User": {
"title": "User",
- "required": ["username"],
+ "required": IsOneOf(
+ ["username", "email", "full_name", "disabled"],
+ # TODO: remove when deprecating Pydantic v1
+ ["username"],
+ ),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
import pytest
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from ...utils import needs_py310
"schemas": {
"User": {
"title": "User",
- "required": ["username"],
+ "required": IsOneOf(
+ ["username", "email", "full_name", "disabled"],
+ # TODO: remove when deprecating Pydantic v1
+ ["username"],
+ ),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},
import pytest
-from dirty_equals import IsDict
+from dirty_equals import IsDict, IsOneOf
from fastapi.testclient import TestClient
from ...utils import needs_py39
"schemas": {
"User": {
"title": "User",
- "required": ["username"],
+ "required": IsOneOf(
+ ["username", "email", "full_name", "disabled"],
+ # TODO: remove when deprecating Pydantic v1
+ ["username"],
+ ),
"type": "object",
"properties": {
"username": {"title": "Username", "type": "string"},