Coverage for tests/test_compat_params_v1.py: 100%

201 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-12-04 08:29 +0000

1import sys 1abcdefm

2from typing import List, Optional 1abcdefm

3 

4import pytest 1abcdefm

5 

6from tests.utils import pydantic_snapshot, skip_module_if_py_gte_314 1abcdefm

7 

8if sys.version_info >= (3, 14): 1abcdefm

9 skip_module_if_py_gte_314() 1m

10 

11from fastapi import FastAPI 1abcdef

12from fastapi._compat.v1 import BaseModel 1abcdef

13from fastapi.temp_pydantic_v1_params import ( 1abcdef

14 Body, 

15 Cookie, 

16 File, 

17 Form, 

18 Header, 

19 Path, 

20 Query, 

21) 

22from fastapi.testclient import TestClient 1abcdef

23from inline_snapshot import snapshot 1abcdef

24from typing_extensions import Annotated 1abcdef

25 

26 

27class Item(BaseModel): 1abcdef

28 name: str 1abcdef

29 price: float 1abcdef

30 description: Optional[str] = None 1abcdef

31 

32 

33app = FastAPI() 1abcdef

34 

35 

36@app.get("/items/{item_id}") 1abcdef

37def get_item_with_path( 1abcdef

38 item_id: Annotated[int, Path(title="The ID of the item", ge=1, le=1000)], 

39): 

40 return {"item_id": item_id} 1zABCDE

41 

42 

43@app.get("/items/") 1abcdef

44def get_items_with_query( 1abcdef

45 q: Annotated[ 

46 Optional[str], Query(min_length=3, max_length=50, pattern="^[a-zA-Z0-9 ]+$") 

47 ] = None, 

48 skip: Annotated[int, Query(ge=0)] = 0, 

49 limit: Annotated[int, Query(ge=1, le=100, examples=[5])] = 10, 

50): 

51 return {"q": q, "skip": skip, "limit": limit} 1FGHIJKLMNOPQ

52 

53 

54@app.get("/users/") 1abcdef

55def get_user_with_header( 1abcdef

56 x_custom: Annotated[Optional[str], Header()] = None, 

57 x_token: Annotated[Optional[str], Header(convert_underscores=True)] = None, 

58): 

59 return {"x_custom": x_custom, "x_token": x_token} 1RSTUVWXYZ012345678

60 

61 

62@app.get("/cookies/") 1abcdef

63def get_cookies( 1abcdef

64 session_id: Annotated[Optional[str], Cookie()] = None, 

65 tracking_id: Annotated[Optional[str], Cookie(min_length=10)] = None, 

66): 

67 return {"session_id": session_id, "tracking_id": tracking_id} 1g9h!i#j$k%l'

68 

69 

70@app.post("/items/") 1abcdef

71def create_item( 1abcdef

72 item: Annotated[ 

73 Item, 

74 Body(examples=[{"name": "Foo", "price": 35.4, "description": "The Foo item"}]), 

75 ], 

76): 

77 return {"item": item} 1()*+,-./:;=?

78 

79 

80@app.post("/items-embed/") 1abcdef

81def create_item_embed( 1abcdef

82 item: Annotated[Item, Body(embed=True)], 

83): 

84 return {"item": item} 1@[]^_`

85 

86 

87@app.put("/items/{item_id}") 1abcdef

88def update_item( 1abcdef

89 item_id: Annotated[int, Path(ge=1)], 

90 item: Annotated[Item, Body()], 

91 importance: Annotated[int, Body(gt=0, le=10)], 

92): 

93 return {"item": item, "importance": importance} 2{ | } ~ abbb

94 

95 

96@app.post("/form-data/") 1abcdef

97def submit_form( 1abcdef

98 username: Annotated[str, Form(min_length=3, max_length=50)], 

99 password: Annotated[str, Form(min_length=8)], 

100 email: Annotated[Optional[str], Form()] = None, 

101): 

102 return {"username": username, "password": password, "email": email} 2cbdbebfbgbhbibjbkblbmbnb

103 

104 

105@app.post("/upload/") 1abcdef

106def upload_file( 1abcdef

107 file: Annotated[bytes, File()], 

108 description: Annotated[Optional[str], Form()] = None, 

109): 

110 return {"file_size": len(file), "description": description} 2obpbqbrbsbtbubvbwbxbybzb

111 

112 

113@app.post("/upload-multiple/") 1abcdef

114def upload_multiple_files( 1abcdef

115 files: Annotated[List[bytes], File()], 

116 note: Annotated[str, Form()] = "", 

117): 

118 return { 2Abn Bbo Cbp Dbq Ebr Fbs

119 "file_count": len(files), 

120 "total_size": sum(len(f) for f in files), 

121 "note": note, 

122 } 

123 

124 

125client = TestClient(app) 1abcdef

126 

127 

128# Path parameter tests 

129def test_path_param_valid(): 1abcdef

130 response = client.get("/items/50") 1zABCDE

131 assert response.status_code == 200 1zABCDE

132 assert response.json() == {"item_id": 50} 1zABCDE

133 

134 

135def test_path_param_too_large(): 1abcdef

136 response = client.get("/items/1001") 2GbHbIbJbKbLb

137 assert response.status_code == 422 2GbHbIbJbKbLb

138 error = response.json()["detail"][0] 2GbHbIbJbKbLb

139 assert error["loc"] == ["path", "item_id"] 2GbHbIbJbKbLb

140 

141 

142def test_path_param_too_small(): 1abcdef

143 response = client.get("/items/0") 2MbNbObPbQbRb

144 assert response.status_code == 422 2MbNbObPbQbRb

145 error = response.json()["detail"][0] 2MbNbObPbQbRb

146 assert error["loc"] == ["path", "item_id"] 2MbNbObPbQbRb

147 

148 

149# Query parameter tests 

150def test_query_params_valid(): 1abcdef

151 response = client.get("/items/?q=test search&skip=5&limit=20") 1GIKMOQ

152 assert response.status_code == 200 1GIKMOQ

153 assert response.json() == {"q": "test search", "skip": 5, "limit": 20} 1GIKMOQ

154 

155 

156def test_query_params_defaults(): 1abcdef

157 response = client.get("/items/") 1FHJLNP

158 assert response.status_code == 200 1FHJLNP

159 assert response.json() == {"q": None, "skip": 0, "limit": 10} 1FHJLNP

160 

161 

162def test_query_param_too_short(): 1abcdef

163 response = client.get("/items/?q=ab") 2SbTbUbVbWbXb

164 assert response.status_code == 422 2SbTbUbVbWbXb

165 error = response.json()["detail"][0] 2SbTbUbVbWbXb

166 assert error["loc"] == ["query", "q"] 2SbTbUbVbWbXb

167 

168 

169def test_query_param_invalid_pattern(): 1abcdef

170 response = client.get("/items/?q=test@#$") 2YbZb0b1b2b3b

171 assert response.status_code == 422 2YbZb0b1b2b3b

172 error = response.json()["detail"][0] 2YbZb0b1b2b3b

173 assert error["loc"] == ["query", "q"] 2YbZb0b1b2b3b

174 

175 

176def test_query_param_limit_too_large(): 1abcdef

177 response = client.get("/items/?limit=101") 24b5b6b7b8b9b

178 assert response.status_code == 422 24b5b6b7b8b9b

179 error = response.json()["detail"][0] 24b5b6b7b8b9b

180 assert error["loc"] == ["query", "limit"] 24b5b6b7b8b9b

181 

182 

183# Header parameter tests 

184def test_header_params(): 1abcdef

185 response = client.get( 1RUX036

186 "/users/", 

187 headers={"X-Custom": "Plumbus", "X-Token": "secret-token"}, 

188 ) 

189 assert response.status_code == 200 1RUX036

190 assert response.json() == { 1RUX036

191 "x_custom": "Plumbus", 

192 "x_token": "secret-token", 

193 } 

194 

195 

196def test_header_underscore_conversion(): 1abcdef

197 response = client.get( 1TWZ258

198 "/users/", 

199 headers={"x-token": "secret-token-with-dash"}, 

200 ) 

201 assert response.status_code == 200 1TWZ258

202 assert response.json()["x_token"] == "secret-token-with-dash" 1TWZ258

203 

204 

205def test_header_params_none(): 1abcdef

206 response = client.get("/users/") 1SVY147

207 assert response.status_code == 200 1SVY147

208 assert response.json() == {"x_custom": None, "x_token": None} 1SVY147

209 

210 

211# Cookie parameter tests 

212def test_cookie_params(): 1abcdef

213 with TestClient(app) as client: 1ghijkl

214 client.cookies.set("session_id", "abc123") 1ghijkl

215 client.cookies.set("tracking_id", "1234567890abcdef") 1ghijkl

216 response = client.get("/cookies/") 1ghijkl

217 assert response.status_code == 200 1ghijkl

218 assert response.json() == { 1ghijkl

219 "session_id": "abc123", 

220 "tracking_id": "1234567890abcdef", 

221 } 

222 

223 

224def test_cookie_tracking_id_too_short(): 1abcdef

225 with TestClient(app) as client: 1tuvwxy

226 client.cookies.set("tracking_id", "short") 1tuvwxy

227 response = client.get("/cookies/") 1tuvwxy

228 assert response.status_code == 422 1tuvwxy

229 assert response.json() == snapshot( 1tuvwxy

230 { 

231 "detail": [ 

232 { 

233 "loc": ["cookie", "tracking_id"], 

234 "msg": "ensure this value has at least 10 characters", 

235 "type": "value_error.any_str.min_length", 

236 "ctx": {"limit_value": 10}, 

237 } 

238 ] 

239 } 

240 ) 

241 

242 

243def test_cookie_params_none(): 1abcdef

244 response = client.get("/cookies/") 19!#$%'

245 assert response.status_code == 200 19!#$%'

246 assert response.json() == {"session_id": None, "tracking_id": None} 19!#$%'

247 

248 

249# Body parameter tests 

250def test_body_param(): 1abcdef

251 response = client.post( 1(*,.:=

252 "/items/", 

253 json={"name": "Test Item", "price": 29.99, "description": "A test item"}, 

254 ) 

255 assert response.status_code == 200 1(*,.:=

256 assert response.json() == { 1(*,.:=

257 "item": { 

258 "name": "Test Item", 

259 "price": 29.99, 

260 "description": "A test item", 

261 } 

262 } 

263 

264 

265def test_body_param_minimal(): 1abcdef

266 response = client.post( 1)+-/;?

267 "/items/", 

268 json={"name": "Minimal", "price": 9.99}, 

269 ) 

270 assert response.status_code == 200 1)+-/;?

271 assert response.json() == { 1)+-/;?

272 "item": {"name": "Minimal", "price": 9.99, "description": None} 

273 } 

274 

275 

276def test_body_param_missing_required(): 1abcdef

277 response = client.post( 2!b#b$b%b'b(b

278 "/items/", 

279 json={"name": "Incomplete"}, 

280 ) 

281 assert response.status_code == 422 2!b#b$b%b'b(b

282 error = response.json()["detail"][0] 2!b#b$b%b'b(b

283 assert error["loc"] == ["body", "price"] 2!b#b$b%b'b(b

284 

285 

286def test_body_embed(): 1abcdef

287 response = client.post( 1@[]^_`

288 "/items-embed/", 

289 json={"item": {"name": "Embedded", "price": 15.0}}, 

290 ) 

291 assert response.status_code == 200 1@[]^_`

292 assert response.json() == { 1@[]^_`

293 "item": {"name": "Embedded", "price": 15.0, "description": None} 

294 } 

295 

296 

297def test_body_embed_wrong_structure(): 1abcdef

298 response = client.post( 2jckclcmcncoc

299 "/items-embed/", 

300 json={"name": "Not Embedded", "price": 15.0}, 

301 ) 

302 assert response.status_code == 422 2jckclcmcncoc

303 

304 

305# Multiple body parameters test 

306def test_multiple_body_params(): 1abcdef

307 response = client.put( 2{ | } ~ abbb

308 "/items/5", 

309 json={ 

310 "item": {"name": "Updated Item", "price": 49.99}, 

311 "importance": 8, 

312 }, 

313 ) 

314 assert response.status_code == 200 2{ | } ~ abbb

315 assert response.json() == snapshot( 2{ | } ~ abbb

316 { 

317 "item": {"name": "Updated Item", "price": 49.99, "description": None}, 

318 "importance": 8, 

319 } 

320 ) 

321 

322 

323def test_multiple_body_params_importance_too_large(): 1abcdef

324 response = client.put( 2)b*b+b,b-b.b

325 "/items/5", 

326 json={ 

327 "item": {"name": "Item", "price": 10.0}, 

328 "importance": 11, 

329 }, 

330 ) 

331 assert response.status_code == 422 2)b*b+b,b-b.b

332 assert response.json() == snapshot( 2)b*b+b,b-b.b

333 { 

334 "detail": [ 

335 { 

336 "loc": ["body", "importance"], 

337 "msg": "ensure this value is less than or equal to 10", 

338 "type": "value_error.number.not_le", 

339 "ctx": {"limit_value": 10}, 

340 } 

341 ] 

342 } 

343 ) 

344 

345 

346def test_multiple_body_params_importance_too_small(): 1abcdef

347 response = client.put( 2/b:b;b=b?b@b

348 "/items/5", 

349 json={ 

350 "item": {"name": "Item", "price": 10.0}, 

351 "importance": 0, 

352 }, 

353 ) 

354 assert response.status_code == 422 2/b:b;b=b?b@b

355 assert response.json() == snapshot( 2/b:b;b=b?b@b

356 { 

357 "detail": [ 

358 { 

359 "loc": ["body", "importance"], 

360 "msg": "ensure this value is greater than 0", 

361 "type": "value_error.number.not_gt", 

362 "ctx": {"limit_value": 0}, 

363 } 

364 ] 

365 } 

366 ) 

367 

368 

369# Form parameter tests 

370def test_form_data_valid(): 1abcdef

371 response = client.post( 2dbfbhbjblbnb

372 "/form-data/", 

373 data={ 

374 "username": "testuser", 

375 "password": "password123", 

376 "email": "test@example.com", 

377 }, 

378 ) 

379 assert response.status_code == 200, response.text 2dbfbhbjblbnb

380 assert response.json() == { 2dbfbhbjblbnb

381 "username": "testuser", 

382 "password": "password123", 

383 "email": "test@example.com", 

384 } 

385 

386 

387def test_form_data_optional_field(): 1abcdef

388 response = client.post( 2cbebgbibkbmb

389 "/form-data/", 

390 data={"username": "testuser", "password": "password123"}, 

391 ) 

392 assert response.status_code == 200 2cbebgbibkbmb

393 assert response.json() == { 2cbebgbibkbmb

394 "username": "testuser", 

395 "password": "password123", 

396 "email": None, 

397 } 

398 

399 

400def test_form_data_username_too_short(): 1abcdef

401 response = client.post( 2[b]b^b_b`b{b

402 "/form-data/", 

403 data={"username": "ab", "password": "password123"}, 

404 ) 

405 assert response.status_code == 422 2[b]b^b_b`b{b

406 assert response.json() == snapshot( 2[b]b^b_b`b{b

407 { 

408 "detail": [ 

409 { 

410 "loc": ["body", "username"], 

411 "msg": "ensure this value has at least 3 characters", 

412 "type": "value_error.any_str.min_length", 

413 "ctx": {"limit_value": 3}, 

414 } 

415 ] 

416 } 

417 ) 

418 

419 

420def test_form_data_password_too_short(): 1abcdef

421 response = client.post( 2|b}b~bacbccc

422 "/form-data/", 

423 data={"username": "testuser", "password": "short"}, 

424 ) 

425 assert response.status_code == 422 2|b}b~bacbccc

426 assert response.json() == snapshot( 2|b}b~bacbccc

427 { 

428 "detail": [ 

429 { 

430 "loc": ["body", "password"], 

431 "msg": "ensure this value has at least 8 characters", 

432 "type": "value_error.any_str.min_length", 

433 "ctx": {"limit_value": 8}, 

434 } 

435 ] 

436 } 

437 ) 

438 

439 

440# File upload tests 

441def test_upload_file(): 1abcdef

442 response = client.post( 2obqbsbubwbyb

443 "/upload/", 

444 files={"file": ("test.txt", b"Hello, World!", "text/plain")}, 

445 data={"description": "A test file"}, 

446 ) 

447 assert response.status_code == 200 2obqbsbubwbyb

448 assert response.json() == { 2obqbsbubwbyb

449 "file_size": 13, 

450 "description": "A test file", 

451 } 

452 

453 

454def test_upload_file_without_description(): 1abcdef

455 response = client.post( 2pbrbtbvbxbzb

456 "/upload/", 

457 files={"file": ("test.txt", b"Hello!", "text/plain")}, 

458 ) 

459 assert response.status_code == 200 2pbrbtbvbxbzb

460 assert response.json() == { 2pbrbtbvbxbzb

461 "file_size": 6, 

462 "description": None, 

463 } 

464 

465 

466def test_upload_multiple_files(): 1abcdef

467 response = client.post( 2AbBbCbDbEbFb

468 "/upload-multiple/", 

469 files=[ 

470 ("files", ("file1.txt", b"Content 1", "text/plain")), 

471 ("files", ("file2.txt", b"Content 2", "text/plain")), 

472 ("files", ("file3.txt", b"Content 3", "text/plain")), 

473 ], 

474 data={"note": "Multiple files uploaded"}, 

475 ) 

476 assert response.status_code == 200 2AbBbCbDbEbFb

477 assert response.json() == { 2AbBbCbDbEbFb

478 "file_count": 3, 

479 "total_size": 27, 

480 "note": "Multiple files uploaded", 

481 } 

482 

483 

484def test_upload_multiple_files_empty_note(): 1abcdef

485 response = client.post( 1nopqrs

486 "/upload-multiple/", 

487 files=[ 

488 ("files", ("file1.txt", b"Test", "text/plain")), 

489 ], 

490 ) 

491 assert response.status_code == 200 1nopqrs

492 assert response.json()["file_count"] == 1 1nopqrs

493 assert response.json()["note"] == "" 1nopqrs

494 

495 

496# __repr__ tests 

497def test_query_repr(): 1abcdef

498 query_param = Query(default=None, min_length=3) 2pcqcrcsctcuc

499 assert repr(query_param) == "Query(None)" 2pcqcrcsctcuc

500 

501 

502def test_body_repr(): 1abcdef

503 body_param = Body(default=None) 2vcwcxcyczcAc

504 assert repr(body_param) == "Body(None)" 2vcwcxcyczcAc

505 

506 

507# Deprecation warning tests for regex parameter 

508def test_query_regex_deprecation_warning(): 1abcdef

509 with pytest.warns(DeprecationWarning, match="`regex` has been deprecated"): 2BcCcDcEcFcGc

510 Query(regex="^test$") 2BcCcDcEcFcGc

511 

512 

513def test_body_regex_deprecation_warning(): 1abcdef

514 with pytest.warns(DeprecationWarning, match="`regex` has been deprecated"): 2HcIcJcKcLcMc

515 Body(regex="^test$") 2HcIcJcKcLcMc

516 

517 

518# Deprecation warning tests for example parameter 

519def test_query_example_deprecation_warning(): 1abcdef

520 with pytest.warns(DeprecationWarning, match="`example` has been deprecated"): 2NcOcPcQcRcSc

521 Query(example="test example") 2NcOcPcQcRcSc

522 

523 

524def test_body_example_deprecation_warning(): 1abcdef

525 with pytest.warns(DeprecationWarning, match="`example` has been deprecated"): 2TcUcVcWcXcYc

526 Body(example={"test": "example"}) 2TcUcVcWcXcYc

527 

528 

529def test_openapi_schema(): 1abcdef

530 response = client.get("/openapi.json") 2dcecfcgchcic

531 assert response.status_code == 200, response.text 2dcecfcgchcic

532 assert response.json() == snapshot( 2dcecfcgchcic

533 { 

534 "openapi": "3.1.0", 

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

536 "paths": { 

537 "/items/{item_id}": { 

538 "get": { 

539 "summary": "Get Item With Path", 

540 "operationId": "get_item_with_path_items__item_id__get", 

541 "parameters": [ 

542 { 

543 "name": "item_id", 

544 "in": "path", 

545 "required": True, 

546 "schema": { 

547 "title": "The ID of the item", 

548 "minimum": 1, 

549 "maximum": 1000, 

550 "type": "integer", 

551 }, 

552 } 

553 ], 

554 "responses": { 

555 "200": { 

556 "description": "Successful Response", 

557 "content": {"application/json": {"schema": {}}}, 

558 }, 

559 "422": { 

560 "description": "Validation Error", 

561 "content": { 

562 "application/json": { 

563 "schema": { 

564 "$ref": "#/components/schemas/HTTPValidationError" 

565 } 

566 } 

567 }, 

568 }, 

569 }, 

570 }, 

571 "put": { 

572 "summary": "Update Item", 

573 "operationId": "update_item_items__item_id__put", 

574 "parameters": [ 

575 { 

576 "name": "item_id", 

577 "in": "path", 

578 "required": True, 

579 "schema": { 

580 "title": "Item Id", 

581 "minimum": 1, 

582 "type": "integer", 

583 }, 

584 } 

585 ], 

586 "requestBody": { 

587 "required": True, 

588 "content": { 

589 "application/json": { 

590 "schema": pydantic_snapshot( 

591 v1=snapshot( 

592 { 

593 "$ref": "#/components/schemas/Body_update_item_items__item_id__put" 

594 } 

595 ), 

596 v2=snapshot( 

597 { 

598 "title": "Body", 

599 "allOf": [ 

600 { 

601 "$ref": "#/components/schemas/Body_update_item_items__item_id__put" 

602 } 

603 ], 

604 } 

605 ), 

606 ), 

607 } 

608 }, 

609 }, 

610 "responses": { 

611 "200": { 

612 "description": "Successful Response", 

613 "content": {"application/json": {"schema": {}}}, 

614 }, 

615 "422": { 

616 "description": "Validation Error", 

617 "content": { 

618 "application/json": { 

619 "schema": { 

620 "$ref": "#/components/schemas/HTTPValidationError" 

621 } 

622 } 

623 }, 

624 }, 

625 }, 

626 }, 

627 }, 

628 "/items/": { 

629 "get": { 

630 "summary": "Get Items With Query", 

631 "operationId": "get_items_with_query_items__get", 

632 "parameters": [ 

633 { 

634 "name": "q", 

635 "in": "query", 

636 "required": False, 

637 "schema": { 

638 "title": "Q", 

639 "maxLength": 50, 

640 "minLength": 3, 

641 "pattern": "^[a-zA-Z0-9 ]+$", 

642 "type": "string", 

643 }, 

644 }, 

645 { 

646 "name": "skip", 

647 "in": "query", 

648 "required": False, 

649 "schema": { 

650 "title": "Skip", 

651 "default": 0, 

652 "minimum": 0, 

653 "type": "integer", 

654 }, 

655 }, 

656 { 

657 "name": "limit", 

658 "in": "query", 

659 "required": False, 

660 "schema": { 

661 "title": "Limit", 

662 "default": 10, 

663 "minimum": 1, 

664 "maximum": 100, 

665 "examples": [5], 

666 "type": "integer", 

667 }, 

668 }, 

669 ], 

670 "responses": { 

671 "200": { 

672 "description": "Successful Response", 

673 "content": {"application/json": {"schema": {}}}, 

674 }, 

675 "422": { 

676 "description": "Validation Error", 

677 "content": { 

678 "application/json": { 

679 "schema": { 

680 "$ref": "#/components/schemas/HTTPValidationError" 

681 } 

682 } 

683 }, 

684 }, 

685 }, 

686 }, 

687 "post": { 

688 "summary": "Create Item", 

689 "operationId": "create_item_items__post", 

690 "requestBody": { 

691 "required": True, 

692 "content": { 

693 "application/json": { 

694 "schema": { 

695 "title": "Item", 

696 "examples": [ 

697 { 

698 "name": "Foo", 

699 "price": 35.4, 

700 "description": "The Foo item", 

701 } 

702 ], 

703 "allOf": [ 

704 {"$ref": "#/components/schemas/Item"} 

705 ], 

706 } 

707 } 

708 }, 

709 }, 

710 "responses": { 

711 "200": { 

712 "description": "Successful Response", 

713 "content": {"application/json": {"schema": {}}}, 

714 }, 

715 "422": { 

716 "description": "Validation Error", 

717 "content": { 

718 "application/json": { 

719 "schema": { 

720 "$ref": "#/components/schemas/HTTPValidationError" 

721 } 

722 } 

723 }, 

724 }, 

725 }, 

726 }, 

727 }, 

728 "/users/": { 

729 "get": { 

730 "summary": "Get User With Header", 

731 "operationId": "get_user_with_header_users__get", 

732 "parameters": [ 

733 { 

734 "name": "x-custom", 

735 "in": "header", 

736 "required": False, 

737 "schema": {"title": "X-Custom", "type": "string"}, 

738 }, 

739 { 

740 "name": "x-token", 

741 "in": "header", 

742 "required": False, 

743 "schema": {"title": "X-Token", "type": "string"}, 

744 }, 

745 ], 

746 "responses": { 

747 "200": { 

748 "description": "Successful Response", 

749 "content": {"application/json": {"schema": {}}}, 

750 }, 

751 "422": { 

752 "description": "Validation Error", 

753 "content": { 

754 "application/json": { 

755 "schema": { 

756 "$ref": "#/components/schemas/HTTPValidationError" 

757 } 

758 } 

759 }, 

760 }, 

761 }, 

762 } 

763 }, 

764 "/cookies/": { 

765 "get": { 

766 "summary": "Get Cookies", 

767 "operationId": "get_cookies_cookies__get", 

768 "parameters": [ 

769 { 

770 "name": "session_id", 

771 "in": "cookie", 

772 "required": False, 

773 "schema": {"title": "Session Id", "type": "string"}, 

774 }, 

775 { 

776 "name": "tracking_id", 

777 "in": "cookie", 

778 "required": False, 

779 "schema": { 

780 "title": "Tracking Id", 

781 "minLength": 10, 

782 "type": "string", 

783 }, 

784 }, 

785 ], 

786 "responses": { 

787 "200": { 

788 "description": "Successful Response", 

789 "content": {"application/json": {"schema": {}}}, 

790 }, 

791 "422": { 

792 "description": "Validation Error", 

793 "content": { 

794 "application/json": { 

795 "schema": { 

796 "$ref": "#/components/schemas/HTTPValidationError" 

797 } 

798 } 

799 }, 

800 }, 

801 }, 

802 } 

803 }, 

804 "/items-embed/": { 

805 "post": { 

806 "summary": "Create Item Embed", 

807 "operationId": "create_item_embed_items_embed__post", 

808 "requestBody": { 

809 "content": { 

810 "application/json": { 

811 "schema": pydantic_snapshot( 

812 v1=snapshot( 

813 { 

814 "$ref": "#/components/schemas/Body_create_item_embed_items_embed__post" 

815 } 

816 ), 

817 v2=snapshot( 

818 { 

819 "allOf": [ 

820 { 

821 "$ref": "#/components/schemas/Body_create_item_embed_items_embed__post" 

822 } 

823 ], 

824 "title": "Body", 

825 } 

826 ), 

827 ), 

828 } 

829 }, 

830 "required": True, 

831 }, 

832 "responses": { 

833 "200": { 

834 "description": "Successful Response", 

835 "content": {"application/json": {"schema": {}}}, 

836 }, 

837 "422": { 

838 "description": "Validation Error", 

839 "content": { 

840 "application/json": { 

841 "schema": { 

842 "$ref": "#/components/schemas/HTTPValidationError" 

843 } 

844 } 

845 }, 

846 }, 

847 }, 

848 } 

849 }, 

850 "/form-data/": { 

851 "post": { 

852 "summary": "Submit Form", 

853 "operationId": "submit_form_form_data__post", 

854 "requestBody": { 

855 "content": { 

856 "application/x-www-form-urlencoded": { 

857 "schema": pydantic_snapshot( 

858 v1=snapshot( 

859 { 

860 "$ref": "#/components/schemas/Body_submit_form_form_data__post" 

861 } 

862 ), 

863 v2=snapshot( 

864 { 

865 "allOf": [ 

866 { 

867 "$ref": "#/components/schemas/Body_submit_form_form_data__post" 

868 } 

869 ], 

870 "title": "Body", 

871 } 

872 ), 

873 ), 

874 } 

875 }, 

876 "required": True, 

877 }, 

878 "responses": { 

879 "200": { 

880 "description": "Successful Response", 

881 "content": {"application/json": {"schema": {}}}, 

882 }, 

883 "422": { 

884 "description": "Validation Error", 

885 "content": { 

886 "application/json": { 

887 "schema": { 

888 "$ref": "#/components/schemas/HTTPValidationError" 

889 } 

890 } 

891 }, 

892 }, 

893 }, 

894 } 

895 }, 

896 "/upload/": { 

897 "post": { 

898 "summary": "Upload File", 

899 "operationId": "upload_file_upload__post", 

900 "requestBody": { 

901 "content": { 

902 "multipart/form-data": { 

903 "schema": pydantic_snapshot( 

904 v1=snapshot( 

905 { 

906 "$ref": "#/components/schemas/Body_upload_file_upload__post" 

907 } 

908 ), 

909 v2=snapshot( 

910 { 

911 "allOf": [ 

912 { 

913 "$ref": "#/components/schemas/Body_upload_file_upload__post" 

914 } 

915 ], 

916 "title": "Body", 

917 } 

918 ), 

919 ), 

920 } 

921 }, 

922 "required": True, 

923 }, 

924 "responses": { 

925 "200": { 

926 "description": "Successful Response", 

927 "content": {"application/json": {"schema": {}}}, 

928 }, 

929 "422": { 

930 "description": "Validation Error", 

931 "content": { 

932 "application/json": { 

933 "schema": { 

934 "$ref": "#/components/schemas/HTTPValidationError" 

935 } 

936 } 

937 }, 

938 }, 

939 }, 

940 } 

941 }, 

942 "/upload-multiple/": { 

943 "post": { 

944 "summary": "Upload Multiple Files", 

945 "operationId": "upload_multiple_files_upload_multiple__post", 

946 "requestBody": { 

947 "content": { 

948 "multipart/form-data": { 

949 "schema": pydantic_snapshot( 

950 v1=snapshot( 

951 { 

952 "$ref": "#/components/schemas/Body_upload_multiple_files_upload_multiple__post" 

953 } 

954 ), 

955 v2=snapshot( 

956 { 

957 "allOf": [ 

958 { 

959 "$ref": "#/components/schemas/Body_upload_multiple_files_upload_multiple__post" 

960 } 

961 ], 

962 "title": "Body", 

963 } 

964 ), 

965 ), 

966 } 

967 }, 

968 "required": True, 

969 }, 

970 "responses": { 

971 "200": { 

972 "description": "Successful Response", 

973 "content": {"application/json": {"schema": {}}}, 

974 }, 

975 "422": { 

976 "description": "Validation Error", 

977 "content": { 

978 "application/json": { 

979 "schema": { 

980 "$ref": "#/components/schemas/HTTPValidationError" 

981 } 

982 } 

983 }, 

984 }, 

985 }, 

986 } 

987 }, 

988 }, 

989 "components": { 

990 "schemas": { 

991 "Body_create_item_embed_items_embed__post": { 

992 "properties": pydantic_snapshot( 

993 v1=snapshot( 

994 {"item": {"$ref": "#/components/schemas/Item"}} 

995 ), 

996 v2=snapshot( 

997 { 

998 "item": { 

999 "allOf": [ 

1000 {"$ref": "#/components/schemas/Item"} 

1001 ], 

1002 "title": "Item", 

1003 } 

1004 } 

1005 ), 

1006 ), 

1007 "type": "object", 

1008 "required": ["item"], 

1009 "title": "Body_create_item_embed_items_embed__post", 

1010 }, 

1011 "Body_submit_form_form_data__post": { 

1012 "properties": { 

1013 "username": { 

1014 "type": "string", 

1015 "maxLength": 50, 

1016 "minLength": 3, 

1017 "title": "Username", 

1018 }, 

1019 "password": { 

1020 "type": "string", 

1021 "minLength": 8, 

1022 "title": "Password", 

1023 }, 

1024 "email": {"type": "string", "title": "Email"}, 

1025 }, 

1026 "type": "object", 

1027 "required": ["username", "password"], 

1028 "title": "Body_submit_form_form_data__post", 

1029 }, 

1030 "Body_update_item_items__item_id__put": { 

1031 "properties": { 

1032 "item": pydantic_snapshot( 

1033 v1=snapshot({"$ref": "#/components/schemas/Item"}), 

1034 v2=snapshot( 

1035 { 

1036 "allOf": [ 

1037 {"$ref": "#/components/schemas/Item"} 

1038 ], 

1039 "title": "Item", 

1040 } 

1041 ), 

1042 ), 

1043 "importance": { 

1044 "type": "integer", 

1045 "maximum": 10.0, 

1046 "exclusiveMinimum": 0.0, 

1047 "title": "Importance", 

1048 }, 

1049 }, 

1050 "type": "object", 

1051 "required": ["item", "importance"], 

1052 "title": "Body_update_item_items__item_id__put", 

1053 }, 

1054 "Body_upload_file_upload__post": { 

1055 "properties": { 

1056 "file": { 

1057 "type": "string", 

1058 "format": "binary", 

1059 "title": "File", 

1060 }, 

1061 "description": {"type": "string", "title": "Description"}, 

1062 }, 

1063 "type": "object", 

1064 "required": ["file"], 

1065 "title": "Body_upload_file_upload__post", 

1066 }, 

1067 "Body_upload_multiple_files_upload_multiple__post": { 

1068 "properties": { 

1069 "files": { 

1070 "items": {"type": "string", "format": "binary"}, 

1071 "type": "array", 

1072 "title": "Files", 

1073 }, 

1074 "note": {"type": "string", "title": "Note", "default": ""}, 

1075 }, 

1076 "type": "object", 

1077 "required": ["files"], 

1078 "title": "Body_upload_multiple_files_upload_multiple__post", 

1079 }, 

1080 "HTTPValidationError": { 

1081 "properties": { 

1082 "detail": { 

1083 "items": { 

1084 "$ref": "#/components/schemas/ValidationError" 

1085 }, 

1086 "type": "array", 

1087 "title": "Detail", 

1088 } 

1089 }, 

1090 "type": "object", 

1091 "title": "HTTPValidationError", 

1092 }, 

1093 "Item": { 

1094 "properties": { 

1095 "name": {"type": "string", "title": "Name"}, 

1096 "price": {"type": "number", "title": "Price"}, 

1097 "description": {"type": "string", "title": "Description"}, 

1098 }, 

1099 "type": "object", 

1100 "required": ["name", "price"], 

1101 "title": "Item", 

1102 }, 

1103 "ValidationError": { 

1104 "properties": { 

1105 "loc": { 

1106 "items": { 

1107 "anyOf": [{"type": "string"}, {"type": "integer"}] 

1108 }, 

1109 "type": "array", 

1110 "title": "Location", 

1111 }, 

1112 "msg": {"type": "string", "title": "Message"}, 

1113 "type": {"type": "string", "title": "Error Type"}, 

1114 }, 

1115 "type": "object", 

1116 "required": ["loc", "msg", "type"], 

1117 "title": "ValidationError", 

1118 }, 

1119 } 

1120 }, 

1121 } 

1122 )