Coverage for tests/pydantic_specific/test_schema.py: 100%

138 statements  

« prev     ^ index     » next       coverage.py v7.17.3, created at 2026-11-13 05:19 +0000

1from dirty_equals import IsDict, IsPartialDict 1abcdefghijklmno

2from pydantic import BaseModel, Field 1abcdefghijklmno

3 

4from fast_depends import Depends, Provider 1abcdefghijklmno

5from fast_depends.core import build_call_model 1abcdefghijklmno

6from fast_depends.pydantic._compat import PYDANTIC_V2 1abcdefghijklmno

7from fast_depends.pydantic.schema import get_schema 1abcdefghijklmno

8from fast_depends.pydantic.serializer import PydanticSerializer 1abcdefghijklmno

9 

10REF_KEY = "$defs" if PYDANTIC_V2 else "definitions" 1abcdefghijklmno

11 

12 

13def test_base() -> None: 1abcdefghijklmno

14 def handler(): 1abcdefghijklmno

15 pass 

16 

17 schema = get_schema( 1abcdefghijklmno

18 build_call_model( 

19 handler, 

20 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

21 dependency_provider=Provider(), 

22 ) 

23 ) 

24 assert schema == {"title": "handler", "type": "null"}, schema 1abcdefghijklmno

25 

26 

27class TestExclude: 1abcdefghijklmno

28 def test_exclude_one_field(self) -> None: 1abcdefghijklmno

29 def handler(a: int, b: str, c: bool) -> None: 1abcdefghijklmno

30 pass 

31 

32 schema = get_schema( 1abcdefghijklmno

33 build_call_model( 

34 handler, 

35 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

36 dependency_provider=Provider(), 

37 ), 

38 exclude=("b",), 

39 ) 

40 assert schema == { 1abcdefghijklmno

41 "properties": { 

42 "a": {"title": "A", "type": "integer"}, 

43 "c": {"title": "C", "type": "boolean"}, 

44 }, 

45 "required": ["a", "c"], 

46 "title": "handler", 

47 "type": "object", 

48 }, schema 

49 assert "b" not in schema["properties"] 1abcdefghijklmno

50 

51 def test_exclude_all_fields(self) -> None: 1abcdefghijklmno

52 def handler(a: int, b: str) -> None: 1abcdefghijklmno

53 pass 

54 

55 schema = get_schema( 1abcdefghijklmno

56 build_call_model( 

57 handler, 

58 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

59 dependency_provider=Provider(), 

60 ), 

61 exclude=("a", "b"), 

62 ) 

63 assert schema == {"title": "handler", "type": "null"}, schema 1abcdefghijklmno

64 

65 

66class TestNoType: 1abcdefghijklmno

67 def test_no_type(self) -> None: 1abcdefghijklmno

68 def handler(a): 1abcdefghijklmno

69 pass 

70 

71 schema = get_schema( 1abcdefghijklmno

72 build_call_model( 

73 handler, 

74 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

75 dependency_provider=Provider(), 

76 ) 

77 ) 

78 assert schema == { 1abcdefghijklmno

79 "properties": {"a": {"title": "A"}}, 

80 "required": ["a"], 

81 "title": "handler", 

82 "type": "object", 

83 }, schema 

84 

85 def test_no_type_embeded(self) -> None: 1abcdefghijklmno

86 def handler(a): 1abcdefghijklmno

87 pass 

88 

89 schema = get_schema( 1abcdefghijklmno

90 build_call_model( 

91 handler, 

92 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

93 dependency_provider=Provider(), 

94 ), 

95 embed=True, 

96 ) 

97 assert schema == {"title": "A"}, schema 1abcdefghijklmno

98 

99 def test_no_type_with_default(self) -> None: 1abcdefghijklmno

100 def handler(a=None): 1abcdefghijklmno

101 pass 

102 

103 schema = get_schema( 1abcdefghijklmno

104 build_call_model( 

105 handler, 

106 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

107 dependency_provider=Provider(), 

108 ) 

109 ) 

110 assert schema == { 1abcdefghijklmno

111 "properties": {"a": IsPartialDict({"title": "A"})}, 

112 "title": "handler", 

113 "type": "object", 

114 }, schema 

115 

116 def test_no_type_with_default_and_embed(self) -> None: 1abcdefghijklmno

117 def handler(a=None): 1abcdefghijklmno

118 pass 

119 

120 schema = get_schema( 1abcdefghijklmno

121 build_call_model( 

122 handler, 

123 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

124 dependency_provider=Provider(), 

125 ), 

126 embed=True, 

127 ) 

128 assert schema == IsPartialDict({"title": "A"}), schema 1abcdefghijklmno

129 

130 

131class TestOneArg: 1abcdefghijklmno

132 def test_one_arg(self) -> None: 1abcdefghijklmno

133 def handler(a: int): 1abcdefghijklmno

134 pass 

135 

136 schema = get_schema( 1abcdefghijklmno

137 build_call_model( 

138 handler, 

139 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

140 dependency_provider=Provider(), 

141 ) 

142 ) 

143 assert schema == { 1abcdefghijklmno

144 "properties": {"a": {"title": "A", "type": "integer"}}, 

145 "required": ["a"], 

146 "title": "handler", 

147 "type": "object", 

148 }, schema 

149 

150 def test_one_arg_with_embed(self) -> None: 1abcdefghijklmno

151 def handler(a: int) -> None: 1abcdefghijklmno

152 pass 

153 

154 schema = get_schema( 1abcdefghijklmno

155 build_call_model( 

156 handler, 

157 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

158 dependency_provider=Provider(), 

159 ), 

160 embed=True, 

161 ) 

162 assert schema == {"title": "A", "type": "integer"}, schema 1abcdefghijklmno

163 

164 def test_one_arg_with_optional(self) -> None: 1abcdefghijklmno

165 def handler(a: int | None) -> None: 1abcdefghijklmno

166 pass 

167 

168 schema = get_schema( 1abcdefghijklmno

169 build_call_model( 

170 handler, 

171 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

172 dependency_provider=Provider(), 

173 ) 

174 ) 

175 assert schema == { 1abcdefghijklmno

176 "properties": { 

177 "a": IsDict( 

178 {"anyOf": [{"type": "integer"}, {"type": "null"}], "title": "A"} 

179 ) 

180 | IsDict({"type": "integer", "title": "A"}) 

181 }, 

182 "required": ["a"], 

183 "title": "handler", 

184 "type": "object", 

185 }, schema 

186 

187 def test_one_arg_with_default(self) -> None: 1abcdefghijklmno

188 def handler(a: int = 0) -> None: 1abcdefghijklmno

189 pass 

190 

191 schema = get_schema( 1abcdefghijklmno

192 build_call_model( 

193 handler, 

194 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

195 dependency_provider=Provider(), 

196 ) 

197 ) 

198 assert schema == { 1abcdefghijklmno

199 "properties": {"a": {"default": 0, "title": "A", "type": "integer"}}, 

200 "title": "handler", 

201 "type": "object", 

202 }, schema 

203 

204 def test_one_arg_with_default_and_embed(self) -> None: 1abcdefghijklmno

205 def handler(a: int = 0) -> None: 1abcdefghijklmno

206 pass 

207 

208 schema = get_schema( 1abcdefghijklmno

209 build_call_model( 

210 handler, 

211 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

212 dependency_provider=Provider(), 

213 ), 

214 embed=True, 

215 ) 

216 assert schema == {"default": 0, "title": "A", "type": "integer"}, schema 1abcdefghijklmno

217 

218 

219class TestOneArgWithModel: 1abcdefghijklmno

220 def test_base(self) -> None: 1abcdefghijklmno

221 class Model(BaseModel): 1abcdefghijklmno

222 a: int 1abcdefghij

223 

224 def handler(a: Model) -> None: 1abcdefghijklmno

225 pass 

226 

227 schema = get_schema( 1abcdefghijklmno

228 build_call_model( 

229 handler, 

230 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

231 dependency_provider=Provider(), 

232 ) 

233 ) 

234 assert schema == { 1abcdefghijklmno

235 REF_KEY: { 

236 "Model": { 

237 "properties": {"a": {"title": "A", "type": "integer"}}, 

238 "required": ["a"], 

239 "title": "Model", 

240 "type": "object", 

241 } 

242 }, 

243 "properties": {"a": {"$ref": f"#/{REF_KEY}/Model"}}, 

244 "required": ["a"], 

245 "title": "handler", 

246 "type": "object", 

247 }, schema 

248 

249 def test_resolved_model(self) -> None: 1abcdefghijklmno

250 class Model(BaseModel): 1abcdefghijklmno

251 a: int 1abcdefghij

252 

253 def handler(a: Model) -> None: 1abcdefghijklmno

254 pass 

255 

256 schema = get_schema( 1abcdefghijklmno

257 build_call_model( 

258 handler, 

259 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

260 dependency_provider=Provider(), 

261 ), 

262 resolve_refs=True, 

263 ) 

264 assert schema == { 1abcdefghijklmno

265 "properties": { 

266 "a": { 

267 "properties": {"a": {"title": "A", "type": "integer"}}, 

268 "required": ["a"], 

269 "title": "Model", 

270 "type": "object", 

271 } 

272 }, 

273 "required": ["a"], 

274 "title": "handler", 

275 "type": "object", 

276 }, schema 

277 

278 def test_optional_model(self) -> None: 1abcdefghijklmno

279 class Model(BaseModel): 1abcdefghijklmno

280 a: int 1abcdefghij

281 

282 def handler(a: Model | None = None) -> None: 1abcdefghijklmno

283 pass 

284 

285 schema = get_schema( 1abcdefghijklmno

286 build_call_model( 

287 handler, 

288 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

289 dependency_provider=Provider(), 

290 ), 

291 resolve_refs=True, 

292 ) 

293 assert schema == { 1abcdefghijklmno

294 "properties": { 

295 "a": IsDict( 

296 { 

297 "anyOf": [ 

298 { 

299 "properties": {"a": {"title": "A", "type": "integer"}}, 

300 "required": ["a"], 

301 "title": "Model", 

302 "type": "object", 

303 }, 

304 {"type": "null"}, 

305 ], 

306 "default": None, 

307 } 

308 ) 

309 | IsDict( 

310 { 

311 "properties": {"a": {"title": "A", "type": "integer"}}, 

312 "required": ["a"], 

313 "title": "Model", 

314 "type": "object", 

315 } 

316 ) 

317 }, 

318 "title": "handler", 

319 "type": "object", 

320 }, schema 

321 

322 def test_optional_embeded_model(self) -> None: 1abcdefghijklmno

323 class Model(BaseModel): 1abcdefghijklmno

324 a: int 1abcdefghij

325 

326 def handler(a: Model | None) -> None: 1abcdefghijklmno

327 pass 

328 

329 schema = get_schema( 1abcdefghijklmno

330 build_call_model( 

331 handler, 

332 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

333 dependency_provider=Provider(), 

334 ), 

335 resolve_refs=True, 

336 embed=True, 

337 ) 

338 assert schema == IsDict( 1abcdefghijklmno

339 { 

340 "anyOf": [ 

341 { 

342 "properties": {"a": {"title": "A", "type": "integer"}}, 

343 "required": ["a"], 

344 "title": "Model", 

345 "type": "object", 

346 }, 

347 {"type": "null"}, 

348 ] 

349 } 

350 ) | IsDict( 

351 { 

352 "properties": {"a": {"title": "A", "type": "integer"}}, 

353 "required": ["a"], 

354 "title": "Model", 

355 "type": "object", 

356 } 

357 ), schema 

358 

359 def test_nested_resolved_model(self) -> None: 1abcdefghijklmno

360 class Model2(BaseModel): 1abcdefghijklmno

361 a: int 1abcdefghij

362 

363 class Model(BaseModel): 1abcdefghijklmno

364 a: Model2 1abcdefghij

365 

366 def handler(a: Model) -> None: 1abcdefghijklmno

367 pass 

368 

369 schema = get_schema( 1abcdefghijklmno

370 build_call_model( 

371 handler, 

372 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

373 dependency_provider=Provider(), 

374 ), 

375 resolve_refs=True, 

376 ) 

377 assert schema == { 1abcdefghijklmno

378 "properties": { 

379 "a": { 

380 "properties": { 

381 "a": { 

382 "properties": {"a": {"title": "A", "type": "integer"}}, 

383 "required": ["a"], 

384 "title": "Model2", 

385 "type": "object", 

386 } 

387 }, 

388 "required": ["a"], 

389 "title": "Model", 

390 "type": "object", 

391 } 

392 }, 

393 "required": ["a"], 

394 "title": "handler", 

395 "type": "object", 

396 }, schema 

397 

398 def test_embeded_model(self) -> None: 1abcdefghijklmno

399 class Model(BaseModel): 1abcdefghijklmno

400 a: int 1abcdefghij

401 

402 def handler(a: Model) -> None: 1abcdefghijklmno

403 pass 

404 

405 schema = get_schema( 1abcdefghijklmno

406 build_call_model( 

407 handler, 

408 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

409 dependency_provider=Provider(), 

410 ), 

411 resolve_refs=True, 

412 embed=True, 

413 ) 

414 assert schema == { 1abcdefghijklmno

415 "properties": {"a": {"title": "A", "type": "integer"}}, 

416 "required": ["a"], 

417 "title": "Model", 

418 "type": "object", 

419 }, schema 

420 

421 def test_embeded_resolved_model(self) -> None: 1abcdefghijklmno

422 class Model2(BaseModel): 1abcdefghijklmno

423 a: int 1abcdefghij

424 

425 class Model(BaseModel): 1abcdefghijklmno

426 a: Model2 1abcdefghij

427 

428 def handler(a: Model) -> None: 1abcdefghijklmno

429 pass 

430 

431 schema = get_schema( 1abcdefghijklmno

432 build_call_model( 

433 handler, 

434 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

435 dependency_provider=Provider(), 

436 ), 

437 resolve_refs=True, 

438 embed=True, 

439 ) 

440 assert schema == { 1abcdefghijklmno

441 "properties": { 

442 "a": { 

443 "properties": {"a": {"title": "A", "type": "integer"}}, 

444 "required": ["a"], 

445 "title": "Model2", 

446 "type": "object", 

447 } 

448 }, 

449 "required": ["a"], 

450 "title": "Model", 

451 "type": "object", 

452 }, schema 

453 

454 

455class TestMultiArgs: 1abcdefghijklmno

456 def test_base(self) -> None: 1abcdefghijklmno

457 def handler(a, b) -> None: 1abcdefghijklmno

458 pass 

459 

460 schema = get_schema( 1abcdefghijklmno

461 build_call_model( 

462 handler, 

463 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

464 dependency_provider=Provider(), 

465 ) 

466 ) 

467 assert schema == { 1abcdefghijklmno

468 "properties": {"a": {"title": "A"}, "b": {"title": "B"}}, 

469 "required": ["a", "b"], 

470 "title": "handler", 

471 "type": "object", 

472 }, schema 

473 

474 def test_types_and_default(self) -> None: 1abcdefghijklmno

475 def handler(a: str, b: int = 0) -> None: 1abcdefghijklmno

476 pass 

477 

478 schema = get_schema( 1abcdefghijklmno

479 build_call_model( 

480 handler, 

481 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

482 dependency_provider=Provider(), 

483 ) 

484 ) 

485 assert schema == { 1abcdefghijklmno

486 "properties": { 

487 "a": {"title": "A", "type": "string"}, 

488 "b": {"default": 0, "title": "B", "type": "integer"}, 

489 }, 

490 "required": ["a"], 

491 "title": "handler", 

492 "type": "object", 

493 }, schema 

494 

495 def test_ignores_embed(self) -> None: 1abcdefghijklmno

496 def handler(a: str, b: int = 0) -> None: 1abcdefghijklmno

497 pass 

498 

499 schema = get_schema( 1abcdefghijklmno

500 build_call_model( 

501 handler, 

502 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

503 dependency_provider=Provider(), 

504 ), 

505 embed=True, 

506 ) 

507 assert schema == { 1abcdefghijklmno

508 "properties": { 

509 "a": {"title": "A", "type": "string"}, 

510 "b": {"default": 0, "title": "B", "type": "integer"}, 

511 }, 

512 "required": ["a"], 

513 "title": "handler", 

514 "type": "object", 

515 }, schema 

516 

517 def test_model(self) -> None: 1abcdefghijklmno

518 class Model(BaseModel): 1abcdefghijklmno

519 a: int = Field(0, description="description") 1abcdefghijklmno

520 

521 def handler(a: str, b: Model) -> None: 1abcdefghijklmno

522 pass 

523 

524 schema = get_schema( 1abcdefghijklmno

525 build_call_model( 

526 handler, 

527 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

528 dependency_provider=Provider(), 

529 ) 

530 ) 

531 assert schema == { 1abcdefghijklmno

532 REF_KEY: { 

533 "Model": { 

534 "properties": { 

535 "a": { 

536 "default": 0, 

537 "description": "description", 

538 "title": "A", 

539 "type": "integer", 

540 } 

541 }, 

542 "title": "Model", 

543 "type": "object", 

544 } 

545 }, 

546 "properties": { 

547 "a": {"title": "A", "type": "string"}, 

548 "b": {"$ref": f"#/{REF_KEY}/Model"}, 

549 }, 

550 "required": ["a", "b"], 

551 "title": "handler", 

552 "type": "object", 

553 }, schema 

554 

555 def test_resolved_model(self) -> None: 1abcdefghijklmno

556 class Model(BaseModel): 1abcdefghijklmno

557 a: int = Field(0, description="description") 1abcdefghijklmno

558 

559 def handler(a: str, b: Model) -> None: 1abcdefghijklmno

560 pass 

561 

562 schema = get_schema( 1abcdefghijklmno

563 build_call_model( 

564 handler, 

565 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

566 dependency_provider=Provider(), 

567 ), 

568 resolve_refs=True, 

569 ) 

570 assert schema == { 1abcdefghijklmno

571 "properties": { 

572 "a": {"title": "A", "type": "string"}, 

573 "b": { 

574 "properties": { 

575 "a": { 

576 "default": 0, 

577 "description": "description", 

578 "title": "A", 

579 "type": "integer", 

580 } 

581 }, 

582 "title": "Model", 

583 "type": "object", 

584 }, 

585 }, 

586 "required": ["a", "b"], 

587 "title": "handler", 

588 "type": "object", 

589 }, schema 

590 

591 

592def test_depends() -> None: 1abcdefghijklmno

593 class Model(BaseModel): 1abcdefghijklmno

594 a: int = Field(0, description="description") 1abcdefghijklmno

595 

596 class CustomClass: 1abcdefghijklmno

597 pass 1abcdefghijklmno

598 

599 def dep4(d: Model) -> None: ... 1abcdefghijklmno

600 

601 def dep2(c: float = Field(..., title="best")) -> None: ... 1abcdefghijklmno

602 

603 def dep(a: float = 1, d: CustomClass = Depends(dep2)) -> None: ... 1abcdefghijklmno

604 

605 def handler( 1abcdefghijklmno

606 b: str = Field(""), 1abcdefghijklmno

607 a=Depends(dep), 1abcdefghijklmno

608 ) -> None: ... 1abcdefghij

609 

610 schema = get_schema( 1abcdefghijklmno

611 build_call_model( 

612 handler, 

613 extra_dependencies=(Depends(dep4),), 

614 serializer_cls=PydanticSerializer(use_fastdepends_errors=True), 

615 dependency_provider=Provider(), 

616 ), 

617 resolve_refs=True, 

618 embed=True, 

619 ) 

620 

621 assert schema == { 1abcdefghijklmno

622 "properties": { 

623 "a": {"default": 1, "title": "A", "type": "number"}, 

624 "b": {"default": "", "title": "B", "type": "string"}, 

625 "c": {"title": "best", "type": "number"}, 

626 "d": { 

627 "properties": { 

628 "a": { 

629 "default": 0, 

630 "description": "description", 

631 "title": "A", 

632 "type": "integer", 

633 } 

634 }, 

635 "title": "Model", 

636 "type": "object", 

637 }, 

638 }, 

639 "required": ["c", "d"], 

640 "title": "handler", 

641 "type": "object", 

642 }, schema