Coverage for tests/test_response_by_alias.py: 100%

82 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-05-05 00:03 +0000

1from typing import List 1abcdef

2 

3from fastapi import FastAPI 1abcdef

4from fastapi._compat import PYDANTIC_V2 1abcdef

5from fastapi.testclient import TestClient 1abcdef

6from pydantic import BaseModel, ConfigDict, Field 1abcdef

7 

8app = FastAPI() 1abcdef

9 

10 

11class Model(BaseModel): 1abcdef

12 name: str = Field(alias="alias") 1abcdef

13 

14 

15class ModelNoAlias(BaseModel): 1abcdef

16 name: str 1abcdef

17 

18 if PYDANTIC_V2: 1abcdef

19 model_config = ConfigDict( 1abcdef

20 json_schema_extra={ 

21 "description": ( 

22 "response_model_by_alias=False is basically a quick hack, to support " 

23 "proper OpenAPI use another model with the correct field names" 

24 ) 

25 } 

26 ) 

27 else: 

28 

29 class Config: 1abcdef

30 schema_extra = { 1abcdef

31 "description": ( 

32 "response_model_by_alias=False is basically a quick hack, to support " 

33 "proper OpenAPI use another model with the correct field names" 

34 ) 

35 } 

36 

37 

38@app.get("/dict", response_model=Model, response_model_by_alias=False) 1abcdef

39def read_dict(): 1abcdef

40 return {"alias": "Foo"} 1ghijkl

41 

42 

43@app.get("/model", response_model=Model, response_model_by_alias=False) 1abcdef

44def read_model(): 1abcdef

45 return Model(alias="Foo") 1mnopqr

46 

47 

48@app.get("/list", response_model=List[Model], response_model_by_alias=False) 1abcdef

49def read_list(): 1abcdef

50 return [{"alias": "Foo"}, {"alias": "Bar"}] 1stuvwx

51 

52 

53@app.get("/by-alias/dict", response_model=Model) 1abcdef

54def by_alias_dict(): 1abcdef

55 return {"alias": "Foo"} 1yzABCD

56 

57 

58@app.get("/by-alias/model", response_model=Model) 1abcdef

59def by_alias_model(): 1abcdef

60 return Model(alias="Foo") 1EFGHIJ

61 

62 

63@app.get("/by-alias/list", response_model=List[Model]) 1abcdef

64def by_alias_list(): 1abcdef

65 return [{"alias": "Foo"}, {"alias": "Bar"}] 1KLMNOP

66 

67 

68@app.get("/no-alias/dict", response_model=ModelNoAlias) 1abcdef

69def no_alias_dict(): 1abcdef

70 return {"name": "Foo"} 1QRSTUV

71 

72 

73@app.get("/no-alias/model", response_model=ModelNoAlias) 1abcdef

74def no_alias_model(): 1abcdef

75 return ModelNoAlias(name="Foo") 1WXYZ01

76 

77 

78@app.get("/no-alias/list", response_model=List[ModelNoAlias]) 1abcdef

79def no_alias_list(): 1abcdef

80 return [{"name": "Foo"}, {"name": "Bar"}] 1234567

81 

82 

83client = TestClient(app) 1abcdef

84 

85 

86def test_read_dict(): 1abcdef

87 response = client.get("/dict") 1ghijkl

88 assert response.status_code == 200, response.text 1ghijkl

89 assert response.json() == {"name": "Foo"} 1ghijkl

90 

91 

92def test_read_model(): 1abcdef

93 response = client.get("/model") 1mnopqr

94 assert response.status_code == 200, response.text 1mnopqr

95 assert response.json() == {"name": "Foo"} 1mnopqr

96 

97 

98def test_read_list(): 1abcdef

99 response = client.get("/list") 1stuvwx

100 assert response.status_code == 200, response.text 1stuvwx

101 assert response.json() == [ 1stuvwx

102 {"name": "Foo"}, 

103 {"name": "Bar"}, 

104 ] 

105 

106 

107def test_read_dict_by_alias(): 1abcdef

108 response = client.get("/by-alias/dict") 1yzABCD

109 assert response.status_code == 200, response.text 1yzABCD

110 assert response.json() == {"alias": "Foo"} 1yzABCD

111 

112 

113def test_read_model_by_alias(): 1abcdef

114 response = client.get("/by-alias/model") 1EFGHIJ

115 assert response.status_code == 200, response.text 1EFGHIJ

116 assert response.json() == {"alias": "Foo"} 1EFGHIJ

117 

118 

119def test_read_list_by_alias(): 1abcdef

120 response = client.get("/by-alias/list") 1KLMNOP

121 assert response.status_code == 200, response.text 1KLMNOP

122 assert response.json() == [ 1KLMNOP

123 {"alias": "Foo"}, 

124 {"alias": "Bar"}, 

125 ] 

126 

127 

128def test_read_dict_no_alias(): 1abcdef

129 response = client.get("/no-alias/dict") 1QRSTUV

130 assert response.status_code == 200, response.text 1QRSTUV

131 assert response.json() == {"name": "Foo"} 1QRSTUV

132 

133 

134def test_read_model_no_alias(): 1abcdef

135 response = client.get("/no-alias/model") 1WXYZ01

136 assert response.status_code == 200, response.text 1WXYZ01

137 assert response.json() == {"name": "Foo"} 1WXYZ01

138 

139 

140def test_read_list_no_alias(): 1abcdef

141 response = client.get("/no-alias/list") 1234567

142 assert response.status_code == 200, response.text 1234567

143 assert response.json() == [ 1234567

144 {"name": "Foo"}, 

145 {"name": "Bar"}, 

146 ] 

147 

148 

149def test_openapi_schema(): 1abcdef

150 response = client.get("/openapi.json") 189!#$%

151 assert response.status_code == 200, response.text 189!#$%

152 assert response.json() == { 189!#$%

153 "openapi": "3.1.0", 

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

155 "paths": { 

156 "/dict": { 

157 "get": { 

158 "summary": "Read Dict", 

159 "operationId": "read_dict_dict_get", 

160 "responses": { 

161 "200": { 

162 "description": "Successful Response", 

163 "content": { 

164 "application/json": { 

165 "schema": {"$ref": "#/components/schemas/Model"} 

166 } 

167 }, 

168 } 

169 }, 

170 } 

171 }, 

172 "/model": { 

173 "get": { 

174 "summary": "Read Model", 

175 "operationId": "read_model_model_get", 

176 "responses": { 

177 "200": { 

178 "description": "Successful Response", 

179 "content": { 

180 "application/json": { 

181 "schema": {"$ref": "#/components/schemas/Model"} 

182 } 

183 }, 

184 } 

185 }, 

186 } 

187 }, 

188 "/list": { 

189 "get": { 

190 "summary": "Read List", 

191 "operationId": "read_list_list_get", 

192 "responses": { 

193 "200": { 

194 "description": "Successful Response", 

195 "content": { 

196 "application/json": { 

197 "schema": { 

198 "title": "Response Read List List Get", 

199 "type": "array", 

200 "items": {"$ref": "#/components/schemas/Model"}, 

201 } 

202 } 

203 }, 

204 } 

205 }, 

206 } 

207 }, 

208 "/by-alias/dict": { 

209 "get": { 

210 "summary": "By Alias Dict", 

211 "operationId": "by_alias_dict_by_alias_dict_get", 

212 "responses": { 

213 "200": { 

214 "description": "Successful Response", 

215 "content": { 

216 "application/json": { 

217 "schema": {"$ref": "#/components/schemas/Model"} 

218 } 

219 }, 

220 } 

221 }, 

222 } 

223 }, 

224 "/by-alias/model": { 

225 "get": { 

226 "summary": "By Alias Model", 

227 "operationId": "by_alias_model_by_alias_model_get", 

228 "responses": { 

229 "200": { 

230 "description": "Successful Response", 

231 "content": { 

232 "application/json": { 

233 "schema": {"$ref": "#/components/schemas/Model"} 

234 } 

235 }, 

236 } 

237 }, 

238 } 

239 }, 

240 "/by-alias/list": { 

241 "get": { 

242 "summary": "By Alias List", 

243 "operationId": "by_alias_list_by_alias_list_get", 

244 "responses": { 

245 "200": { 

246 "description": "Successful Response", 

247 "content": { 

248 "application/json": { 

249 "schema": { 

250 "title": "Response By Alias List By Alias List Get", 

251 "type": "array", 

252 "items": {"$ref": "#/components/schemas/Model"}, 

253 } 

254 } 

255 }, 

256 } 

257 }, 

258 } 

259 }, 

260 "/no-alias/dict": { 

261 "get": { 

262 "summary": "No Alias Dict", 

263 "operationId": "no_alias_dict_no_alias_dict_get", 

264 "responses": { 

265 "200": { 

266 "description": "Successful Response", 

267 "content": { 

268 "application/json": { 

269 "schema": { 

270 "$ref": "#/components/schemas/ModelNoAlias" 

271 } 

272 } 

273 }, 

274 } 

275 }, 

276 } 

277 }, 

278 "/no-alias/model": { 

279 "get": { 

280 "summary": "No Alias Model", 

281 "operationId": "no_alias_model_no_alias_model_get", 

282 "responses": { 

283 "200": { 

284 "description": "Successful Response", 

285 "content": { 

286 "application/json": { 

287 "schema": { 

288 "$ref": "#/components/schemas/ModelNoAlias" 

289 } 

290 } 

291 }, 

292 } 

293 }, 

294 } 

295 }, 

296 "/no-alias/list": { 

297 "get": { 

298 "summary": "No Alias List", 

299 "operationId": "no_alias_list_no_alias_list_get", 

300 "responses": { 

301 "200": { 

302 "description": "Successful Response", 

303 "content": { 

304 "application/json": { 

305 "schema": { 

306 "title": "Response No Alias List No Alias List Get", 

307 "type": "array", 

308 "items": { 

309 "$ref": "#/components/schemas/ModelNoAlias" 

310 }, 

311 } 

312 } 

313 }, 

314 } 

315 }, 

316 } 

317 }, 

318 }, 

319 "components": { 

320 "schemas": { 

321 "Model": { 

322 "title": "Model", 

323 "required": ["alias"], 

324 "type": "object", 

325 "properties": {"alias": {"title": "Alias", "type": "string"}}, 

326 }, 

327 "ModelNoAlias": { 

328 "title": "ModelNoAlias", 

329 "required": ["name"], 

330 "type": "object", 

331 "properties": {"name": {"title": "Name", "type": "string"}}, 

332 "description": "response_model_by_alias=False is basically a quick hack, to support proper OpenAPI use another model with the correct field names", 

333 }, 

334 } 

335 }, 

336 }