Coverage for tests / test_arbitrary_types.py: 100%

39 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-12 18:15 +0000

1from typing import Annotated 1abgc

2 

3import pytest 1abgc

4from fastapi import FastAPI 1abgc

5from fastapi.testclient import TestClient 1abgc

6from inline_snapshot import snapshot 1abgc

7 

8 

9@pytest.fixture(name="client") 1abgc

10def get_client(): 1abgc

11 from pydantic import ( 1abc

12 BaseModel, 

13 ConfigDict, 

14 PlainSerializer, 

15 TypeAdapter, 

16 WithJsonSchema, 

17 ) 

18 

19 class FakeNumpyArray: 1abc

20 def __init__(self): 1abc

21 self.data = [1.0, 2.0, 3.0] 1hij

22 

23 FakeNumpyArrayPydantic = Annotated[ 1abc

24 FakeNumpyArray, 

25 WithJsonSchema(TypeAdapter(list[float]).json_schema()), 

26 PlainSerializer(lambda v: v.data), 

27 ] 

28 

29 class MyModel(BaseModel): 1abc

30 model_config = ConfigDict(arbitrary_types_allowed=True) 1abc

31 custom_field: FakeNumpyArrayPydantic 1abc

32 

33 app = FastAPI() 1abc

34 

35 @app.get("/") 1abc

36 def test() -> MyModel: 1abc

37 return MyModel(custom_field=FakeNumpyArray()) 1hij

38 

39 client = TestClient(app) 1abc

40 return client 1abc

41 

42 

43def test_get(client: TestClient): 1abgc

44 response = client.get("/") 1hij

45 assert response.json() == {"custom_field": [1.0, 2.0, 3.0]} 1hij

46 

47 

48def test_typeadapter(): 1abgc

49 # This test is only to confirm that Pydantic alone is working as expected 

50 from pydantic import ( 1def

51 BaseModel, 

52 ConfigDict, 

53 PlainSerializer, 

54 TypeAdapter, 

55 WithJsonSchema, 

56 ) 

57 

58 class FakeNumpyArray: 1def

59 def __init__(self): 1def

60 self.data = [1.0, 2.0, 3.0] 1def

61 

62 FakeNumpyArrayPydantic = Annotated[ 1def

63 FakeNumpyArray, 

64 WithJsonSchema(TypeAdapter(list[float]).json_schema()), 

65 PlainSerializer(lambda v: v.data), 

66 ] 

67 

68 class MyModel(BaseModel): 1def

69 model_config = ConfigDict(arbitrary_types_allowed=True) 1def

70 custom_field: FakeNumpyArrayPydantic 1def

71 

72 ta = TypeAdapter(MyModel) 1def

73 assert ta.dump_python(MyModel(custom_field=FakeNumpyArray())) == { 1def

74 "custom_field": [1.0, 2.0, 3.0] 

75 } 

76 assert ta.json_schema() == snapshot( 1def

77 { 

78 "properties": { 

79 "custom_field": { 

80 "items": {"type": "number"}, 

81 "title": "Custom Field", 

82 "type": "array", 

83 } 

84 }, 

85 "required": ["custom_field"], 

86 "title": "MyModel", 

87 "type": "object", 

88 } 

89 ) 

90 

91 

92def test_openapi_schema(client: TestClient): 1abgc

93 response = client.get("openapi.json") 1klm

94 assert response.json() == snapshot( 1klm

95 { 

96 "openapi": "3.1.0", 

97 "info": {"title": "FastAPI", "version": "0.1.0"}, 

98 "paths": { 

99 "/": { 

100 "get": { 

101 "summary": "Test", 

102 "operationId": "test__get", 

103 "responses": { 

104 "200": { 

105 "description": "Successful Response", 

106 "content": { 

107 "application/json": { 

108 "schema": { 

109 "$ref": "#/components/schemas/MyModel" 

110 } 

111 } 

112 }, 

113 } 

114 }, 

115 } 

116 } 

117 }, 

118 "components": { 

119 "schemas": { 

120 "MyModel": { 

121 "properties": { 

122 "custom_field": { 

123 "items": {"type": "number"}, 

124 "type": "array", 

125 "title": "Custom Field", 

126 } 

127 }, 

128 "type": "object", 

129 "required": ["custom_field"], 

130 "title": "MyModel", 

131 } 

132 } 

133 }, 

134 } 

135 )