Coverage for tests / test_request_params / test_header / test_optional_str.py: 100%

123 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-04-06 01:24 +0000

1from typing import Annotated 1abcd

2 

3import pytest 1abcd

4from fastapi import FastAPI, Header 1abcd

5from fastapi.testclient import TestClient 1abcd

6from inline_snapshot import snapshot 1abcd

7from pydantic import BaseModel, Field 1abcd

8 

9app = FastAPI() 1abcd

10 

11# ===================================================================================== 

12# Without aliases 

13 

14 

15@app.get("/optional-str") 1abcd

16async def read_optional_str(p: Annotated[str | None, Header()] = None): 1abcd

17 return {"p": p} 1efghijk

18 

19 

20class HeaderModelOptionalStr(BaseModel): 1abcd

21 p: str | None = None 1abcd

22 

23 

24@app.get("/model-optional-str") 1abcd

25async def read_model_optional_str(p: Annotated[HeaderModelOptionalStr, Header()]): 1abcd

26 return {"p": p.p} 2l m ibn o p q r

27 

28 

29@pytest.mark.parametrize( 1abcd

30 "path", 

31 ["/optional-str", "/model-optional-str"], 

32) 

33def test_optional_str_schema(path: str): 1abcd

34 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 2jbkblbmbnbobpb

35 [ 

36 { 

37 "required": False, 

38 "schema": { 

39 "anyOf": [{"type": "string"}, {"type": "null"}], 

40 "title": "P", 

41 }, 

42 "name": "p", 

43 "in": "header", 

44 } 

45 ] 

46 ) 

47 

48 

49@pytest.mark.parametrize( 1abcd

50 "path", 

51 ["/optional-str", "/model-optional-str"], 

52) 

53def test_optional_str_missing(path: str): 1abcd

54 client = TestClient(app) 1mfngpirk

55 response = client.get(path) 1mfngpirk

56 assert response.status_code == 200 1mfngpirk

57 assert response.json() == {"p": None} 1mfngpirk

58 

59 

60@pytest.mark.parametrize( 1abcd

61 "path", 

62 ["/optional-str", "/model-optional-str"], 

63) 

64def test_optional_str(path: str): 1abcd

65 client = TestClient(app) 1le|ohqj

66 response = client.get(path, headers={"p": "hello"}) 1le|ohqj

67 assert response.status_code == 200 1le|ohqj

68 assert response.json() == {"p": "hello"} 1le|ohqj

69 

70 

71# ===================================================================================== 

72# Alias 

73 

74 

75@app.get("/optional-alias") 1abcd

76async def read_optional_alias( 1abcd

77 p: Annotated[str | None, Header(alias="p_alias")] = None, 

78): 

79 return {"p": p} 1stuvwxyzAB

80 

81 

82class HeaderModelOptionalAlias(BaseModel): 1abcd

83 p: str | None = Field(None, alias="p_alias") 1abcd

84 

85 

86@app.get("/model-optional-alias") 1abcd

87async def read_model_optional_alias(p: Annotated[HeaderModelOptionalAlias, Header()]): 1abcd

88 return {"p": p.p} 2C D E qbF G H I J K L

89 

90 

91@pytest.mark.parametrize( 1abcd

92 "path", 

93 ["/optional-alias", "/model-optional-alias"], 

94) 

95def test_optional_str_alias_schema(path: str): 1abcd

96 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 2rbsbtbubvbwbxbyb

97 [ 

98 { 

99 "required": False, 

100 "schema": { 

101 "anyOf": [{"type": "string"}, {"type": "null"}], 

102 "title": "P Alias", 

103 }, 

104 "name": "p_alias", 

105 "in": "header", 

106 } 

107 ] 

108 ) 

109 

110 

111@pytest.mark.parametrize( 1abcd

112 "path", 

113 ["/optional-alias", "/model-optional-alias"], 

114) 

115def test_optional_alias_missing(path: str): 1abcd

116 client = TestClient(app) 1EuFvIyLB

117 response = client.get(path) 1EuFvIyLB

118 assert response.status_code == 200 1EuFvIyLB

119 assert response.json() == {"p": None} 1EuFvIyLB

120 

121 

122@pytest.mark.parametrize( 1abcd

123 "path", 

124 ["/optional-alias", "/model-optional-alias"], 

125) 

126def test_optional_alias_by_name(path: str): 1abcd

127 client = TestClient(app) 1Dt}HxKA

128 response = client.get(path, headers={"p": "hello"}) 1Dt}HxKA

129 assert response.status_code == 200 1Dt}HxKA

130 assert response.json() == {"p": None} 1Dt}HxKA

131 

132 

133@pytest.mark.parametrize( 1abcd

134 "path", 

135 [ 

136 "/optional-alias", 

137 "/model-optional-alias", 

138 ], 

139) 

140def test_optional_alias_by_alias(path: str): 1abcd

141 client = TestClient(app) 1Cs~GwJz

142 response = client.get(path, headers={"p_alias": "hello"}) 1Cs~GwJz

143 assert response.status_code == 200 1Cs~GwJz

144 assert response.json() == {"p": "hello"} 1Cs~GwJz

145 

146 

147# ===================================================================================== 

148# Validation alias 

149 

150 

151@app.get("/optional-validation-alias") 1abcd

152def read_optional_validation_alias( 1abcd

153 p: Annotated[str | None, Header(validation_alias="p_val_alias")] = None, 

154): 

155 return {"p": p} 1MNOPQRSTUV

156 

157 

158class HeaderModelOptionalValidationAlias(BaseModel): 1abcd

159 p: str | None = Field(None, validation_alias="p_val_alias") 1abcd

160 

161 

162@app.get("/model-optional-validation-alias") 1abcd

163def read_model_optional_validation_alias( 1abcd

164 p: Annotated[HeaderModelOptionalValidationAlias, Header()], 

165): 

166 return {"p": p.p} 1WXYZ012345

167 

168 

169@pytest.mark.parametrize( 1abcd

170 "path", 

171 ["/optional-validation-alias", "/model-optional-validation-alias"], 

172) 

173def test_optional_validation_alias_schema(path: str): 1abcd

174 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 2zbAbBbCbDbEbFbGb

175 [ 

176 { 

177 "required": False, 

178 "schema": { 

179 "anyOf": [{"type": "string"}, {"type": "null"}], 

180 "title": "P Val Alias", 

181 }, 

182 "name": "p_val_alias", 

183 "in": "header", 

184 } 

185 ] 

186 ) 

187 

188 

189@pytest.mark.parametrize( 1abcd

190 "path", 

191 ["/optional-validation-alias", "/model-optional-validation-alias"], 

192) 

193def test_optional_validation_alias_missing(path: str): 1abcd

194 client = TestClient(app) 1YOZP2S5V

195 response = client.get(path) 1YOZP2S5V

196 assert response.status_code == 200 1YOZP2S5V

197 assert response.json() == {"p": None} 1YOZP2S5V

198 

199 

200@pytest.mark.parametrize( 1abcd

201 "path", 

202 [ 

203 "/optional-validation-alias", 

204 "/model-optional-validation-alias", 

205 ], 

206) 

207def test_optional_validation_alias_by_name(path: str): 1abcd

208 client = TestClient(app) 2W M abbb0 Q 3 T

209 response = client.get(path, headers={"p": "hello"}) 2W M abbb0 Q 3 T

210 assert response.status_code == 200 2W M abbb0 Q 3 T

211 assert response.json() == {"p": None} 2W M abbb0 Q 3 T

212 

213 

214@pytest.mark.parametrize( 1abcd

215 "path", 

216 [ 

217 "/optional-validation-alias", 

218 "/model-optional-validation-alias", 

219 ], 

220) 

221def test_optional_validation_alias_by_validation_alias(path: str): 1abcd

222 client = TestClient(app) 2X N cbdb1 R 4 U

223 response = client.get(path, headers={"p_val_alias": "hello"}) 2X N cbdb1 R 4 U

224 assert response.status_code == 200 2X N cbdb1 R 4 U

225 assert response.json() == {"p": "hello"} 2X N cbdb1 R 4 U

226 

227 

228# ===================================================================================== 

229# Alias and validation alias 

230 

231 

232@app.get("/optional-alias-and-validation-alias") 1abcd

233def read_optional_alias_and_validation_alias( 1abcd

234 p: Annotated[ 

235 str | None, Header(alias="p_alias", validation_alias="p_val_alias") 

236 ] = None, 

237): 

238 return {"p": p} 16789!#$%'()*+,

239 

240 

241class HeaderModelOptionalAliasAndValidationAlias(BaseModel): 1abcd

242 p: str | None = Field(None, alias="p_alias", validation_alias="p_val_alias") 1abcd

243 

244 

245@app.get("/model-optional-alias-and-validation-alias") 1abcd

246def read_model_optional_alias_and_validation_alias( 1abcd

247 p: Annotated[HeaderModelOptionalAliasAndValidationAlias, Header()], 

248): 

249 return {"p": p.p} 1-./:;=?@[]^_`{

250 

251 

252@pytest.mark.parametrize( 1abcd

253 "path", 

254 [ 

255 "/optional-alias-and-validation-alias", 

256 "/model-optional-alias-and-validation-alias", 

257 ], 

258) 

259def test_optional_alias_and_validation_alias_schema(path: str): 1abcd

260 assert app.openapi()["paths"][path]["get"]["parameters"] == snapshot( 2HbIbJbKbLbMbNb

261 [ 

262 { 

263 "required": False, 

264 "schema": { 

265 "anyOf": [{"type": "string"}, {"type": "null"}], 

266 "title": "P Val Alias", 

267 }, 

268 "name": "p_val_alias", 

269 "in": "header", 

270 } 

271 ] 

272 ) 

273 

274 

275@pytest.mark.parametrize( 1abcd

276 "path", 

277 [ 

278 "/optional-alias-and-validation-alias", 

279 "/model-optional-alias-and-validation-alias", 

280 ], 

281) 

282def test_optional_alias_and_validation_alias_missing(path: str): 1abcd

283 client = TestClient(app) 1:9=#]({,

284 response = client.get(path) 1:9=#]({,

285 assert response.status_code == 200 1:9=#]({,

286 assert response.json() == {"p": None} 1:9=#]({,

287 

288 

289@pytest.mark.parametrize( 1abcd

290 "path", 

291 [ 

292 "/optional-alias-and-validation-alias", 

293 "/model-optional-alias-and-validation-alias", 

294 ], 

295) 

296def test_optional_alias_and_validation_alias_by_name(path: str): 1abcd

297 client = TestClient(app) 2. 7 ebfb@ % _ *

298 response = client.get(path, headers={"p": "hello"}) 2. 7 ebfb@ % _ *

299 assert response.status_code == 200 2. 7 ebfb@ % _ *

300 assert response.json() == {"p": None} 2. 7 ebfb@ % _ *

301 

302 

303@pytest.mark.parametrize( 1abcd

304 "path", 

305 [ 

306 "/optional-alias-and-validation-alias", 

307 "/model-optional-alias-and-validation-alias", 

308 ], 

309) 

310def test_optional_alias_and_validation_alias_by_alias(path: str): 1abcd

311 client = TestClient(app) 1-6;!?$^)

312 response = client.get(path, headers={"p_alias": "hello"}) 1-6;!?$^)

313 assert response.status_code == 200 1-6;!?$^)

314 assert response.json() == {"p": None} 1-6;!?$^)

315 

316 

317@pytest.mark.parametrize( 1abcd

318 "path", 

319 [ 

320 "/optional-alias-and-validation-alias", 

321 "/model-optional-alias-and-validation-alias", 

322 ], 

323) 

324def test_optional_alias_and_validation_alias_by_validation_alias(path: str): 1abcd

325 client = TestClient(app) 2/ 8 gbhb[ ' ` +

326 response = client.get(path, headers={"p_val_alias": "hello"}) 2/ 8 gbhb[ ' ` +

327 assert response.status_code == 200 2/ 8 gbhb[ ' ` +

328 assert response.json() == {"p": "hello"} 2/ 8 gbhb[ ' ` +