Coverage for tests / test_response_by_alias.py: 100%

78 statements  

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

1from fastapi import FastAPI 1abcd

2from fastapi.testclient import TestClient 1abcd

3from inline_snapshot import snapshot 1abcd

4from pydantic import BaseModel, ConfigDict, Field 1abcd

5 

6app = FastAPI() 1abcd

7 

8 

9class Model(BaseModel): 1abcd

10 name: str = Field(alias="alias") 1abcd

11 

12 

13class ModelNoAlias(BaseModel): 1abcd

14 name: str 1abcd

15 

16 model_config = ConfigDict( 1abcd

17 json_schema_extra={ 

18 "description": ( 

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

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

21 ) 

22 } 

23 ) 

24 

25 

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

27def read_dict(): 1abcd

28 return {"alias": "Foo"} 1efg

29 

30 

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

32def read_model(): 1abcd

33 return Model(alias="Foo") 1hij

34 

35 

36@app.get("/list", response_model=list[Model], response_model_by_alias=False) 1abcd

37def read_list(): 1abcd

38 return [{"alias": "Foo"}, {"alias": "Bar"}] 1klm

39 

40 

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

42def by_alias_dict(): 1abcd

43 return {"alias": "Foo"} 1nop

44 

45 

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

47def by_alias_model(): 1abcd

48 return Model(alias="Foo") 1qrs

49 

50 

51@app.get("/by-alias/list", response_model=list[Model]) 1abcd

52def by_alias_list(): 1abcd

53 return [{"alias": "Foo"}, {"alias": "Bar"}] 1tuv

54 

55 

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

57def no_alias_dict(): 1abcd

58 return {"name": "Foo"} 1wxy

59 

60 

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

62def no_alias_model(): 1abcd

63 return ModelNoAlias(name="Foo") 1zAB

64 

65 

66@app.get("/no-alias/list", response_model=list[ModelNoAlias]) 1abcd

67def no_alias_list(): 1abcd

68 return [{"name": "Foo"}, {"name": "Bar"}] 1CDE

69 

70 

71client = TestClient(app) 1abcd

72 

73 

74def test_read_dict(): 1abcd

75 response = client.get("/dict") 1efg

76 assert response.status_code == 200, response.text 1efg

77 assert response.json() == {"name": "Foo"} 1efg

78 

79 

80def test_read_model(): 1abcd

81 response = client.get("/model") 1hij

82 assert response.status_code == 200, response.text 1hij

83 assert response.json() == {"name": "Foo"} 1hij

84 

85 

86def test_read_list(): 1abcd

87 response = client.get("/list") 1klm

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

89 assert response.json() == [ 1klm

90 {"name": "Foo"}, 

91 {"name": "Bar"}, 

92 ] 

93 

94 

95def test_read_dict_by_alias(): 1abcd

96 response = client.get("/by-alias/dict") 1nop

97 assert response.status_code == 200, response.text 1nop

98 assert response.json() == {"alias": "Foo"} 1nop

99 

100 

101def test_read_model_by_alias(): 1abcd

102 response = client.get("/by-alias/model") 1qrs

103 assert response.status_code == 200, response.text 1qrs

104 assert response.json() == {"alias": "Foo"} 1qrs

105 

106 

107def test_read_list_by_alias(): 1abcd

108 response = client.get("/by-alias/list") 1tuv

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

110 assert response.json() == [ 1tuv

111 {"alias": "Foo"}, 

112 {"alias": "Bar"}, 

113 ] 

114 

115 

116def test_read_dict_no_alias(): 1abcd

117 response = client.get("/no-alias/dict") 1wxy

118 assert response.status_code == 200, response.text 1wxy

119 assert response.json() == {"name": "Foo"} 1wxy

120 

121 

122def test_read_model_no_alias(): 1abcd

123 response = client.get("/no-alias/model") 1zAB

124 assert response.status_code == 200, response.text 1zAB

125 assert response.json() == {"name": "Foo"} 1zAB

126 

127 

128def test_read_list_no_alias(): 1abcd

129 response = client.get("/no-alias/list") 1CDE

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

131 assert response.json() == [ 1CDE

132 {"name": "Foo"}, 

133 {"name": "Bar"}, 

134 ] 

135 

136 

137def test_openapi_schema(): 1abcd

138 response = client.get("/openapi.json") 1FGH

139 assert response.status_code == 200, response.text 1FGH

140 assert response.json() == snapshot( 1FGH

141 { 

142 "openapi": "3.1.0", 

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

144 "paths": { 

145 "/dict": { 

146 "get": { 

147 "summary": "Read Dict", 

148 "operationId": "read_dict_dict_get", 

149 "responses": { 

150 "200": { 

151 "description": "Successful Response", 

152 "content": { 

153 "application/json": { 

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

155 } 

156 }, 

157 } 

158 }, 

159 } 

160 }, 

161 "/model": { 

162 "get": { 

163 "summary": "Read Model", 

164 "operationId": "read_model_model_get", 

165 "responses": { 

166 "200": { 

167 "description": "Successful Response", 

168 "content": { 

169 "application/json": { 

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

171 } 

172 }, 

173 } 

174 }, 

175 } 

176 }, 

177 "/list": { 

178 "get": { 

179 "summary": "Read List", 

180 "operationId": "read_list_list_get", 

181 "responses": { 

182 "200": { 

183 "description": "Successful Response", 

184 "content": { 

185 "application/json": { 

186 "schema": { 

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

188 "type": "array", 

189 "items": { 

190 "$ref": "#/components/schemas/Model" 

191 }, 

192 } 

193 } 

194 }, 

195 } 

196 }, 

197 } 

198 }, 

199 "/by-alias/dict": { 

200 "get": { 

201 "summary": "By Alias Dict", 

202 "operationId": "by_alias_dict_by_alias_dict_get", 

203 "responses": { 

204 "200": { 

205 "description": "Successful Response", 

206 "content": { 

207 "application/json": { 

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

209 } 

210 }, 

211 } 

212 }, 

213 } 

214 }, 

215 "/by-alias/model": { 

216 "get": { 

217 "summary": "By Alias Model", 

218 "operationId": "by_alias_model_by_alias_model_get", 

219 "responses": { 

220 "200": { 

221 "description": "Successful Response", 

222 "content": { 

223 "application/json": { 

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

225 } 

226 }, 

227 } 

228 }, 

229 } 

230 }, 

231 "/by-alias/list": { 

232 "get": { 

233 "summary": "By Alias List", 

234 "operationId": "by_alias_list_by_alias_list_get", 

235 "responses": { 

236 "200": { 

237 "description": "Successful Response", 

238 "content": { 

239 "application/json": { 

240 "schema": { 

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

242 "type": "array", 

243 "items": { 

244 "$ref": "#/components/schemas/Model" 

245 }, 

246 } 

247 } 

248 }, 

249 } 

250 }, 

251 } 

252 }, 

253 "/no-alias/dict": { 

254 "get": { 

255 "summary": "No Alias Dict", 

256 "operationId": "no_alias_dict_no_alias_dict_get", 

257 "responses": { 

258 "200": { 

259 "description": "Successful Response", 

260 "content": { 

261 "application/json": { 

262 "schema": { 

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

264 } 

265 } 

266 }, 

267 } 

268 }, 

269 } 

270 }, 

271 "/no-alias/model": { 

272 "get": { 

273 "summary": "No Alias Model", 

274 "operationId": "no_alias_model_no_alias_model_get", 

275 "responses": { 

276 "200": { 

277 "description": "Successful Response", 

278 "content": { 

279 "application/json": { 

280 "schema": { 

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

282 } 

283 } 

284 }, 

285 } 

286 }, 

287 } 

288 }, 

289 "/no-alias/list": { 

290 "get": { 

291 "summary": "No Alias List", 

292 "operationId": "no_alias_list_no_alias_list_get", 

293 "responses": { 

294 "200": { 

295 "description": "Successful Response", 

296 "content": { 

297 "application/json": { 

298 "schema": { 

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

300 "type": "array", 

301 "items": { 

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

303 }, 

304 } 

305 } 

306 }, 

307 } 

308 }, 

309 } 

310 }, 

311 }, 

312 "components": { 

313 "schemas": { 

314 "Model": { 

315 "title": "Model", 

316 "required": ["alias"], 

317 "type": "object", 

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

319 }, 

320 "ModelNoAlias": { 

321 "title": "ModelNoAlias", 

322 "required": ["name"], 

323 "type": "object", 

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

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

326 }, 

327 } 

328 }, 

329 } 

330 )