mirror of
https://github.com/fastapi/fastapi.git
synced 2025-12-28 16:49:26 -05:00
Compare commits
826 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a372edf7e8 | ||
|
|
bc1aba7322 | ||
|
|
7563579dc8 | ||
|
|
938dd045fd | ||
|
|
2a446f7151 | ||
|
|
ed45b074b9 | ||
|
|
480cd8f4f9 | ||
|
|
16d75d90eb | ||
|
|
a4841de65e | ||
|
|
984d646705 | ||
|
|
ec087cfa24 | ||
|
|
1fe23335ce | ||
|
|
d48144a3e7 | ||
|
|
3d08a4f3a8 | ||
|
|
caa3ccf638 | ||
|
|
5226ff90d7 | ||
|
|
d597f92482 | ||
|
|
43f6115096 | ||
|
|
3112e05b77 | ||
|
|
4560158502 | ||
|
|
2ad28d436f | ||
|
|
d7604d16a3 | ||
|
|
79c51ad542 | ||
|
|
7cf567010d | ||
|
|
3d763c8d38 | ||
|
|
30a07155fb | ||
|
|
bb4772c5aa | ||
|
|
3e2dbf9169 | ||
|
|
f5b77ff0fc | ||
|
|
176cd8c9ef | ||
|
|
1884d76f61 | ||
|
|
8062aabdaa | ||
|
|
ee9ccac1e5 | ||
|
|
5cd4c3b6bd | ||
|
|
4584f706bd | ||
|
|
ba9c8fba0b | ||
|
|
d9249c1949 | ||
|
|
a973e787af | ||
|
|
1088d2abd9 | ||
|
|
98ec6a6079 | ||
|
|
6b4d292f3a | ||
|
|
d4ddcc5878 | ||
|
|
0e5832aa6d | ||
|
|
ee2acd8abc | ||
|
|
e902ed5fc6 | ||
|
|
cef1f166df | ||
|
|
8e63f75919 | ||
|
|
e1b9cc00ca | ||
|
|
408b8a9beb | ||
|
|
0817c955ec | ||
|
|
c55f7138a1 | ||
|
|
7653de2715 | ||
|
|
784f068aba | ||
|
|
6db05770f6 | ||
|
|
6be02e3d52 | ||
|
|
9cf7b70d7b | ||
|
|
f75c1532f6 | ||
|
|
5c3a70d5b6 | ||
|
|
6a45249303 | ||
|
|
c23051682b | ||
|
|
df779885fa | ||
|
|
9c7abbff43 | ||
|
|
d12c1ac82c | ||
|
|
dbc9d3a0ce | ||
|
|
f1b1449958 | ||
|
|
078324583c | ||
|
|
7df361eb41 | ||
|
|
753bb9fb9f | ||
|
|
ba0f6121b9 | ||
|
|
12b36a048c | ||
|
|
6ccad06081 | ||
|
|
6cee687a79 | ||
|
|
5c8d5214ff | ||
|
|
6df50d40fe | ||
|
|
f736e48ab3 | ||
|
|
c40bd0e426 | ||
|
|
11893d9cea | ||
|
|
37dd99ffe3 | ||
|
|
f8013621cc | ||
|
|
391887db91 | ||
|
|
b42e28753e | ||
|
|
92ea53baca | ||
|
|
2e16e105c9 | ||
|
|
d07159797b | ||
|
|
e7401d2e42 | ||
|
|
6e69d62bfe | ||
|
|
79d2576508 | ||
|
|
1c1c2e8ab9 | ||
|
|
3ad01a1247 | ||
|
|
a0ede1839a | ||
|
|
a9fbc4b8f5 | ||
|
|
1e4f123eb0 | ||
|
|
8abfa0f106 | ||
|
|
cf726c93d9 | ||
|
|
e326cec10e | ||
|
|
8af92a6139 | ||
|
|
b40acb83c9 | ||
|
|
7b2631a88d | ||
|
|
616106ca76 | ||
|
|
c656671609 | ||
|
|
9aab3d9e22 | ||
|
|
c74e7d1ce4 | ||
|
|
6516a6c4a6 | ||
|
|
d5d302c3da | ||
|
|
273b06adab | ||
|
|
4c40b484f1 | ||
|
|
adc328e258 | ||
|
|
4f0aae9d23 | ||
|
|
ae02be90b6 | ||
|
|
d67f092db8 | ||
|
|
3d60b5e23e | ||
|
|
89b4d1f076 | ||
|
|
2013336d65 | ||
|
|
8bfc783194 | ||
|
|
fcdd5031e1 | ||
|
|
bfbed30869 | ||
|
|
54c7c34b25 | ||
|
|
106a4338db | ||
|
|
e4453a850d | ||
|
|
4ca93aea04 | ||
|
|
da508e9dce | ||
|
|
ed48cc457f | ||
|
|
a5a4daa705 | ||
|
|
6bc29cc5ba | ||
|
|
c8f330314e | ||
|
|
d9e2aa8678 | ||
|
|
cf0c3cf2c4 | ||
|
|
4ec2c0bb5b | ||
|
|
5c74eeba5b | ||
|
|
27f4240750 | ||
|
|
679a97603a | ||
|
|
e6d09027e5 | ||
|
|
6726bf8559 | ||
|
|
3063c7c57d | ||
|
|
ce26b8e1ca | ||
|
|
313723494b | ||
|
|
095dab00c7 | ||
|
|
cad6880fd9 | ||
|
|
a6e79e68a4 | ||
|
|
2c13b1ba4b | ||
|
|
7179d48fd7 | ||
|
|
07bcb18a5a | ||
|
|
bd8f358fd9 | ||
|
|
18eb7a7080 | ||
|
|
dd906a998e | ||
|
|
b083ccd250 | ||
|
|
af64e9d196 | ||
|
|
0d5dc7ee7b | ||
|
|
8068a404c7 | ||
|
|
6682295c73 | ||
|
|
2915e31dab | ||
|
|
4f4d47baf4 | ||
|
|
8f336c5fd3 | ||
|
|
3e666dfdd7 | ||
|
|
be91d0c1bd | ||
|
|
f4bacfe1b5 | ||
|
|
943faf237c | ||
|
|
b0e09640e1 | ||
|
|
638b4355d8 | ||
|
|
21c8a32fa7 | ||
|
|
a86b9a5b03 | ||
|
|
c6037fc96f | ||
|
|
5e7c3ee1f3 | ||
|
|
6c1432801f | ||
|
|
ebdeda2de6 | ||
|
|
8fa19a6faa | ||
|
|
3ecb4c5389 | ||
|
|
9d0d8828cc | ||
|
|
df35896a0e | ||
|
|
8f64d09ee0 | ||
|
|
3b09dd8e01 | ||
|
|
c30821ff6e | ||
|
|
666890ac7f | ||
|
|
937af92ba7 | ||
|
|
1cf4b8c2de | ||
|
|
dcb223d850 | ||
|
|
baeeafa1e1 | ||
|
|
487f940e91 | ||
|
|
e9c33debaa | ||
|
|
041a37bb1f | ||
|
|
28038f19cf | ||
|
|
9026f3b1bd | ||
|
|
8d9ef5d343 | ||
|
|
b2923282ca | ||
|
|
ac160885e1 | ||
|
|
7d9195a248 | ||
|
|
4734df1db8 | ||
|
|
cdf6b31505 | ||
|
|
dfe9dde982 | ||
|
|
9957956ef8 | ||
|
|
aebff5006f | ||
|
|
64834d4a60 | ||
|
|
30b9dfb11c | ||
|
|
6b5b26fa61 | ||
|
|
3f908a47d9 | ||
|
|
01c3ad2eb2 | ||
|
|
85a2eed888 | ||
|
|
45fefe88cf | ||
|
|
da4605b039 | ||
|
|
4e4715b131 | ||
|
|
b4524145e6 | ||
|
|
1daf9fddfd | ||
|
|
6d78b228d8 | ||
|
|
10bf65f272 | ||
|
|
97fdbdd0d8 | ||
|
|
7dc9901f35 | ||
|
|
7c04182724 | ||
|
|
6e11a2d1c4 | ||
|
|
535d5b3f9f | ||
|
|
7565f580ce | ||
|
|
590abc4b96 | ||
|
|
3ac38eb195 | ||
|
|
6cbdcd3961 | ||
|
|
c7302ea99e | ||
|
|
49fe5bac2e | ||
|
|
1f79531a5b | ||
|
|
095dcc8a63 | ||
|
|
5ba94612c1 | ||
|
|
44d5abffc1 | ||
|
|
98fa4bd437 | ||
|
|
cdd5d6ce70 | ||
|
|
b8a3cccb75 | ||
|
|
14a55d864d | ||
|
|
37c8e7d76b | ||
|
|
4b12a2818a | ||
|
|
9ab43cc5ed | ||
|
|
7b3463de32 | ||
|
|
f7ab09884d | ||
|
|
9c4a1d2105 | ||
|
|
066c249bad | ||
|
|
2116d8aa56 | ||
|
|
2e21808094 | ||
|
|
736cce8329 | ||
|
|
f78aa8848b | ||
|
|
38c282039a | ||
|
|
b7a8850660 | ||
|
|
eae3025ed2 | ||
|
|
37e596599e | ||
|
|
37c6913ce5 | ||
|
|
7421a19b7f | ||
|
|
e71d87d8ef | ||
|
|
c3de47858c | ||
|
|
c430ef1ac1 | ||
|
|
54f255ecc8 | ||
|
|
751c7dc179 | ||
|
|
b2d742074c | ||
|
|
e48c526b62 | ||
|
|
be6cfd6cf5 | ||
|
|
02ca761365 | ||
|
|
cadb7f5c3a | ||
|
|
645d645737 | ||
|
|
bb05a68530 | ||
|
|
7ebcd8761c | ||
|
|
57ed433bef | ||
|
|
3855d808b0 | ||
|
|
d6b8b8f590 | ||
|
|
3337c3b9be | ||
|
|
950fb3f02d | ||
|
|
c83a5bf149 | ||
|
|
45a40f8b1c | ||
|
|
44c83dda0b | ||
|
|
57a7a706f3 | ||
|
|
aa2bb3e569 | ||
|
|
f0b3ebdf03 | ||
|
|
4f9b737548 | ||
|
|
2e9e5dfeec | ||
|
|
374626e036 | ||
|
|
6c1e7fb4de | ||
|
|
5f84703bea | ||
|
|
34856a2738 | ||
|
|
61cc7014cc | ||
|
|
e31f35ec65 | ||
|
|
29ed7d052b | ||
|
|
bcb7935ab7 | ||
|
|
a01a665b57 | ||
|
|
0e1ec48885 | ||
|
|
7382ceda57 | ||
|
|
4d1c69751e | ||
|
|
be0cf41d38 | ||
|
|
ea7b105476 | ||
|
|
214e0740c8 | ||
|
|
f3bfa3b8a5 | ||
|
|
a9a2782f95 | ||
|
|
acbf27c971 | ||
|
|
f61fe35178 | ||
|
|
9a33ba46ac | ||
|
|
1d63896c35 | ||
|
|
ea839df09e | ||
|
|
3620a2b213 | ||
|
|
6df106b877 | ||
|
|
fb1affca1b | ||
|
|
581e3a0051 | ||
|
|
b57b8e7ad2 | ||
|
|
4bef866495 | ||
|
|
bc56c74d6b | ||
|
|
7fdc4952bd | ||
|
|
16234a3f4f | ||
|
|
6eb31132e5 | ||
|
|
f512b17992 | ||
|
|
cae8f976d8 | ||
|
|
48c0d3405d | ||
|
|
3da3f3ab82 | ||
|
|
418c3c8d2b | ||
|
|
663aae13b2 | ||
|
|
ed88e25098 | ||
|
|
a748e7336b | ||
|
|
9b5b2dd7a2 | ||
|
|
699717cf7f | ||
|
|
26dc148cb9 | ||
|
|
4025751afb | ||
|
|
8fa56b46a1 | ||
|
|
4199172977 | ||
|
|
ea42ebda80 | ||
|
|
79bc96647b | ||
|
|
9fa8050e01 | ||
|
|
ba8d85fbe8 | ||
|
|
c2fb5cc109 | ||
|
|
fe0c643e90 | ||
|
|
9c03b8fd64 | ||
|
|
601d678e07 | ||
|
|
1d21c7f748 | ||
|
|
7c75b55580 | ||
|
|
9d937964ba | ||
|
|
4ec5e0a90a | ||
|
|
024d5d3318 | ||
|
|
a8c1333b4d | ||
|
|
d1962bb22f | ||
|
|
bd3e47ec59 | ||
|
|
5f9c7a3185 | ||
|
|
76b324d95b | ||
|
|
7b7ec90308 | ||
|
|
8032e21418 | ||
|
|
8bf01245b1 | ||
|
|
f4583c58b9 | ||
|
|
f0576e8ffd | ||
|
|
1abef20dbd | ||
|
|
286f5a0c42 | ||
|
|
77c8b5b3b9 | ||
|
|
6fefc17a84 | ||
|
|
1d434dec47 | ||
|
|
cfdcad1dd2 | ||
|
|
921e2e5881 | ||
|
|
4749ff586c | ||
|
|
94ae778082 | ||
|
|
d0a247fc5a | ||
|
|
c5e2837e46 | ||
|
|
396ca69603 | ||
|
|
4db37fdf95 | ||
|
|
a49f69f074 | ||
|
|
b5bdc153a1 | ||
|
|
031622a989 | ||
|
|
c8a7552e29 | ||
|
|
c12652b785 | ||
|
|
b58c2a31ed | ||
|
|
f0d59e57f1 | ||
|
|
cbd7d4895b | ||
|
|
d70f0ecec3 | ||
|
|
628c34e0ca | ||
|
|
8e76d4e5f4 | ||
|
|
2537d9d1c2 | ||
|
|
c08a3e8f22 | ||
|
|
241de23b68 | ||
|
|
4e40e1e85d | ||
|
|
ecf6e7eec2 | ||
|
|
3afd733753 | ||
|
|
8557a88d16 | ||
|
|
e4c1dd799d | ||
|
|
f977da6ae0 | ||
|
|
f077c17e1e | ||
|
|
f9f1d93c58 | ||
|
|
7e33df505a | ||
|
|
f806e03807 | ||
|
|
90d52cfa16 | ||
|
|
7ab1b9edcc | ||
|
|
6859691419 | ||
|
|
d3cfe72cd7 | ||
|
|
e988050f79 | ||
|
|
3565ea00b6 | ||
|
|
643d2845de | ||
|
|
c46e4a1b14 | ||
|
|
79bc28fab4 | ||
|
|
a88a6050a6 | ||
|
|
0c36a7ac05 | ||
|
|
a592e8ad4d | ||
|
|
daf6820307 | ||
|
|
8c94e97c89 | ||
|
|
ab22979dc5 | ||
|
|
316566e40e | ||
|
|
3824664620 | ||
|
|
a01ed2f6a7 | ||
|
|
a2c2e332a0 | ||
|
|
74fe89bf35 | ||
|
|
f5056f84b6 | ||
|
|
60f05868b7 | ||
|
|
b7d3f2a96e | ||
|
|
ea57612d69 | ||
|
|
186544760a | ||
|
|
89e0c10547 | ||
|
|
3fca8b2be8 | ||
|
|
bb98f7df6d | ||
|
|
a2644728f6 | ||
|
|
433837d9ca | ||
|
|
68074badcc | ||
|
|
15dd2b67d3 | ||
|
|
45e018517b | ||
|
|
74954352ed | ||
|
|
7c4d1fe13d | ||
|
|
23821e916b | ||
|
|
8bfec9fb6b | ||
|
|
5fbaf6d28c | ||
|
|
ee729d4522 | ||
|
|
344d765796 | ||
|
|
720dcc0990 | ||
|
|
f9c8726a1a | ||
|
|
c42c0d31b0 | ||
|
|
2cf2fee588 | ||
|
|
7047e59f29 | ||
|
|
99ea5bb641 | ||
|
|
34e03db068 | ||
|
|
67e7c15701 | ||
|
|
d5324fb5c3 | ||
|
|
2d60add4e2 | ||
|
|
eb7cd4f693 | ||
|
|
f4b4b0b0f5 | ||
|
|
e992a2ec8b | ||
|
|
29d3739bcf | ||
|
|
b78887f3d3 | ||
|
|
cc1f5de03c | ||
|
|
d90030c1e2 | ||
|
|
3639fb00be | ||
|
|
7eabff43de | ||
|
|
a27fb4764b | ||
|
|
7710a34800 | ||
|
|
6320832178 | ||
|
|
26f27982ac | ||
|
|
d974fbdda0 | ||
|
|
ccc7c8fef9 | ||
|
|
b021569913 | ||
|
|
48676b4f11 | ||
|
|
b1102e2388 | ||
|
|
31920eff62 | ||
|
|
4516a48c7c | ||
|
|
f8878f3a98 | ||
|
|
5c8fa58fd0 | ||
|
|
987d2f9a92 | ||
|
|
920110276a | ||
|
|
b397ad9e52 | ||
|
|
498ba94bfc | ||
|
|
6ebe753908 | ||
|
|
3aee64b94f | ||
|
|
001473ab66 | ||
|
|
8c9c536c0a | ||
|
|
70137c0f7d | ||
|
|
286fd694ea | ||
|
|
e157cf4b96 | ||
|
|
235300c1d2 | ||
|
|
c868581ce7 | ||
|
|
7e67a91b08 | ||
|
|
e24299b2ff | ||
|
|
e24a500292 | ||
|
|
5451d05bc8 | ||
|
|
2b3b416122 | ||
|
|
08b817a842 | ||
|
|
2e788bbbdc | ||
|
|
9ec452a154 | ||
|
|
2c937aabef | ||
|
|
f6872dd298 | ||
|
|
cbd7b986e7 | ||
|
|
1e6d95ce6d | ||
|
|
540d8ff398 | ||
|
|
261bc2d387 | ||
|
|
db554ca094 | ||
|
|
ac893a4446 | ||
|
|
b81d29fc00 | ||
|
|
10a13d05c4 | ||
|
|
d51936754d | ||
|
|
030012bf4c | ||
|
|
fc94d904c9 | ||
|
|
39b4692525 | ||
|
|
15afe2e301 | ||
|
|
03b24b5a52 | ||
|
|
3aeaa0a6a8 | ||
|
|
5cbb81cc26 | ||
|
|
eea196f4a5 | ||
|
|
126a9b33c9 | ||
|
|
57a9a64435 | ||
|
|
ad33193f2c | ||
|
|
c6c45ae488 | ||
|
|
828079cb6e | ||
|
|
4740ccdcce | ||
|
|
49b18c87a0 | ||
|
|
42a3b1526e | ||
|
|
83332ff9b2 | ||
|
|
8cde8dc2a9 | ||
|
|
e86ef5e57d | ||
|
|
8a6d81afad | ||
|
|
f9352c18de | ||
|
|
38d409dd67 | ||
|
|
e814707cd1 | ||
|
|
640a5b6fc3 | ||
|
|
6e8da9d00a | ||
|
|
25ee2357d7 | ||
|
|
27d0ccc11c | ||
|
|
b6b031b456 | ||
|
|
495ff5baa9 | ||
|
|
50b307c9f6 | ||
|
|
2bb94fb90b | ||
|
|
2d7d5dafb0 | ||
|
|
701f5791d3 | ||
|
|
eee8d4c58a | ||
|
|
0c24d0607b | ||
|
|
f97c8de41a | ||
|
|
52c1488a37 | ||
|
|
3958e5a113 | ||
|
|
fb19d9895d | ||
|
|
ae724b05ce | ||
|
|
c73e895b86 | ||
|
|
0310af3557 | ||
|
|
633ed1d8af | ||
|
|
133fe8170a | ||
|
|
df8f281674 | ||
|
|
7128971f1d | ||
|
|
55f8a446c7 | ||
|
|
83ab6ac957 | ||
|
|
3d02a920ab | ||
|
|
1b00f8ae78 | ||
|
|
d97647fd57 | ||
|
|
9667ce87a9 | ||
|
|
0541693bc7 | ||
|
|
041b2e1c46 | ||
|
|
30b270be9a | ||
|
|
d5ecbaceae | ||
|
|
43d9a4d2b1 | ||
|
|
c5b5af7c53 | ||
|
|
887270ff8a | ||
|
|
bd106fc750 | ||
|
|
eab0653a34 | ||
|
|
8c6f10b64a | ||
|
|
93e9fed2e8 | ||
|
|
e747f1938a | ||
|
|
92b745461c | ||
|
|
0a2b24653b | ||
|
|
a058d8ecbc | ||
|
|
326fec16b9 | ||
|
|
8525b879ed | ||
|
|
3da797aeb8 | ||
|
|
e925c0ec8e | ||
|
|
ff68d0894a | ||
|
|
d2f5097ded | ||
|
|
8f359273b5 | ||
|
|
18127b7907 | ||
|
|
24eb8eeeba | ||
|
|
1e44825ef2 | ||
|
|
998a9139d3 | ||
|
|
6bbd315f3e | ||
|
|
0e2d8d64a4 | ||
|
|
b6f6818d76 | ||
|
|
4d60022c88 | ||
|
|
fe513719ea | ||
|
|
7183f0d683 | ||
|
|
2b6f63df71 | ||
|
|
abd05a6d30 | ||
|
|
e39143d56d | ||
|
|
49e82ed2ac | ||
|
|
91c05b9245 | ||
|
|
82c74789e8 | ||
|
|
1a38cc506e | ||
|
|
548f67d465 | ||
|
|
a215687c98 | ||
|
|
8fa18e5e6f | ||
|
|
6ba09082a0 | ||
|
|
280fe73c03 | ||
|
|
9f3edbf537 | ||
|
|
182c28e57a | ||
|
|
b5e40a6233 | ||
|
|
39698df806 | ||
|
|
6d51389f75 | ||
|
|
2007993433 | ||
|
|
818eb1f365 | ||
|
|
3e12918325 | ||
|
|
2c83a11a7d | ||
|
|
081901cc99 | ||
|
|
0069963bba | ||
|
|
d309c9e140 | ||
|
|
9847cecf6f | ||
|
|
c7d888a15f | ||
|
|
96808fd44f | ||
|
|
09ccfce228 | ||
|
|
ec46247595 | ||
|
|
2e8db846b4 | ||
|
|
b123c5c489 | ||
|
|
aa60185781 | ||
|
|
d704f94cf0 | ||
|
|
3d017824ba | ||
|
|
ae93ec140a | ||
|
|
8015f832d4 | ||
|
|
cd521dff74 | ||
|
|
736712173a | ||
|
|
409a850c6c | ||
|
|
920df4d1ac | ||
|
|
c0fddaa9a9 | ||
|
|
0a882e926e | ||
|
|
f30dd4fe40 | ||
|
|
55ef9270b8 | ||
|
|
4191f4d33a | ||
|
|
1cedd8becf | ||
|
|
7e06c4c97f | ||
|
|
af599c92ac | ||
|
|
2acdc13608 | ||
|
|
2ee101fb81 | ||
|
|
ea0cdd120c | ||
|
|
35b24deef3 | ||
|
|
db48d9cf09 | ||
|
|
9e0d4fa0ef | ||
|
|
e773d7e919 | ||
|
|
d9a640e06c | ||
|
|
5f49397d19 | ||
|
|
16199c4a13 | ||
|
|
2612fa3e9d | ||
|
|
5d18ae0d90 | ||
|
|
09a0295bf3 | ||
|
|
cda85623fb | ||
|
|
62be4a1600 | ||
|
|
e69182940e | ||
|
|
f36927d0a6 | ||
|
|
e54cc8ffa3 | ||
|
|
837e94573d | ||
|
|
9d293b7086 | ||
|
|
3d2ef237ed | ||
|
|
9b88c7c18a | ||
|
|
fe4b25e2d7 | ||
|
|
0cc031f477 | ||
|
|
a8447c15e5 | ||
|
|
5d3f45c2d4 | ||
|
|
afd1502283 | ||
|
|
44adb29ce1 | ||
|
|
144f09ea14 | ||
|
|
4cd5a7ac1c | ||
|
|
d7bd68979f | ||
|
|
b0e70cb37e | ||
|
|
6e60d0a056 | ||
|
|
d784a90207 | ||
|
|
924c96bf90 | ||
|
|
dace29835c | ||
|
|
c99b945d87 | ||
|
|
f229dd97c0 | ||
|
|
023bc01967 | ||
|
|
083c6dd481 | ||
|
|
cf4dfcbd59 | ||
|
|
8416e3ee23 | ||
|
|
01a1fc8d15 | ||
|
|
87fb46bcac | ||
|
|
91738b5ae7 | ||
|
|
27c700a6d3 | ||
|
|
9eb712802e | ||
|
|
994340f839 | ||
|
|
4f04377270 | ||
|
|
ccae0c0cb9 | ||
|
|
aa27afdb24 | ||
|
|
1b8f823a05 | ||
|
|
548dd233c3 | ||
|
|
2d210f7313 | ||
|
|
af7db9b95d | ||
|
|
b59885c9d5 | ||
|
|
dd649ff814 | ||
|
|
274d3d9bd0 | ||
|
|
ad294d4d1e | ||
|
|
55ba3220f8 | ||
|
|
05b62724e0 | ||
|
|
324c3ba095 | ||
|
|
1d50bad455 | ||
|
|
db9da09f72 | ||
|
|
d4b6f1d1f6 | ||
|
|
acd9c4e1aa | ||
|
|
e2f6e5f6fc | ||
|
|
fe5b2e491e | ||
|
|
a6afa805cd | ||
|
|
495460d3ed | ||
|
|
d88473b739 | ||
|
|
13a5b3f9b9 | ||
|
|
741b95a454 | ||
|
|
abac475407 | ||
|
|
d5a11b6cdc | ||
|
|
b7367f2564 | ||
|
|
0370958171 | ||
|
|
d529449241 | ||
|
|
59401a7829 | ||
|
|
eece6344f5 | ||
|
|
b9a27be0d4 | ||
|
|
f2986a1d53 | ||
|
|
dd0b335052 | ||
|
|
e779069c92 | ||
|
|
d041f12331 | ||
|
|
c015245676 | ||
|
|
986d363a38 | ||
|
|
a9f63e5d22 | ||
|
|
3ca5fe1709 | ||
|
|
2b78866662 | ||
|
|
334c9bc7ad | ||
|
|
a559f8f397 | ||
|
|
0d8e9663d8 | ||
|
|
52d8ad8bfa | ||
|
|
dae2b957ba | ||
|
|
a0f6494803 | ||
|
|
b19af36826 | ||
|
|
d03ef24c92 | ||
|
|
5fc3e91020 | ||
|
|
929e844754 | ||
|
|
cfc17e5510 | ||
|
|
d3360406c4 | ||
|
|
940c0fb9fb | ||
|
|
c1220535cc | ||
|
|
488763e9f7 | ||
|
|
0e5f5d2e93 | ||
|
|
f5f0d20af0 | ||
|
|
97206ee28f | ||
|
|
d7f88623e1 | ||
|
|
0f5146fa5d | ||
|
|
6ae85b4742 | ||
|
|
627242b8ae | ||
|
|
fbd3ff4a6f | ||
|
|
a277942a52 | ||
|
|
a862acb877 | ||
|
|
974284be90 | ||
|
|
e90af0c0f9 | ||
|
|
9802b90b66 | ||
|
|
6c8deb5a4f | ||
|
|
0d49633776 | ||
|
|
727ce82e9b | ||
|
|
6455f4bb01 | ||
|
|
fed6fab8f9 | ||
|
|
5cc1b065ba | ||
|
|
bacf9e5af6 | ||
|
|
230f2077b9 | ||
|
|
c9470e7aec | ||
|
|
f7ba75e3f7 | ||
|
|
52cdbebbad | ||
|
|
d8e7edba80 | ||
|
|
c355ae1416 | ||
|
|
bc958ac3da | ||
|
|
a54e336b22 | ||
|
|
b667e6ff12 | ||
|
|
d05d970c4d | ||
|
|
365d9b93c3 | ||
|
|
f7bff17f98 | ||
|
|
889005d07d | ||
|
|
dfb6a6b74a | ||
|
|
b4155f7a76 | ||
|
|
329a81777b | ||
|
|
cb6edde2e5 | ||
|
|
fe604f360f | ||
|
|
ce843bb8e1 | ||
|
|
28f22e326c | ||
|
|
f6cf06c864 | ||
|
|
d2891b651d | ||
|
|
2fe5ee4151 | ||
|
|
502c928ab1 | ||
|
|
671eba1de6 | ||
|
|
2bbd7ce821 | ||
|
|
de1fe4d388 | ||
|
|
bb3cf8b902 | ||
|
|
d24a334923 | ||
|
|
87accca03e | ||
|
|
d0626aa565 | ||
|
|
eed1496b0e | ||
|
|
9e19613311 | ||
|
|
40f90b3a94 | ||
|
|
cbfb27ca91 | ||
|
|
b0f0abda0d | ||
|
|
c62fa0bd3b | ||
|
|
95267e58de | ||
|
|
f4a023451d | ||
|
|
28f820065f | ||
|
|
199803085f | ||
|
|
5e8fa0e842 | ||
|
|
5480386e39 | ||
|
|
92236cf6a4 | ||
|
|
30f00ace9a | ||
|
|
cb33e0aed2 | ||
|
|
49efaa5b7e | ||
|
|
d43fe2d2e1 | ||
|
|
8040927208 | ||
|
|
131b6dc21f | ||
|
|
01c6b41c52 | ||
|
|
f9514ac4b2 | ||
|
|
cc4db3294a | ||
|
|
d4e29ea3fe | ||
|
|
0b7b222e49 | ||
|
|
551c5613a9 | ||
|
|
4881d1e225 | ||
|
|
293d7c3bf8 | ||
|
|
bb8c2a6498 | ||
|
|
905ec1edde | ||
|
|
4f8157588e | ||
|
|
8255edfecf | ||
|
|
53c87842b0 | ||
|
|
297135244d | ||
|
|
8376228a49 | ||
|
|
6c7873c77e | ||
|
|
d75b81ce3f | ||
|
|
206037c292 | ||
|
|
478644086e | ||
|
|
a96dddb6fd | ||
|
|
66cadd9fdb | ||
|
|
572180348d | ||
|
|
4eefb2616a | ||
|
|
b9be1dde4b | ||
|
|
6d7b983cd4 | ||
|
|
e67120a116 | ||
|
|
b65ed450b3 | ||
|
|
13383e8333 | ||
|
|
c32cfc5c4d | ||
|
|
bffb4115a9 | ||
|
|
bf4fad1fda | ||
|
|
8c29eaec25 | ||
|
|
835b6465d9 | ||
|
|
1f7629d3e4 | ||
|
|
d3a4234e82 | ||
|
|
4a4c8c3bb2 | ||
|
|
1c711e7147 | ||
|
|
a0c3282af0 | ||
|
|
602e953158 | ||
|
|
1cfea408c0 | ||
|
|
1f27f41499 | ||
|
|
75aa13d007 | ||
|
|
b81c635a11 |
45
.github/DISCUSSION_TEMPLATE/translations.yml
vendored
Normal file
45
.github/DISCUSSION_TEMPLATE/translations.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
labels: [lang-all]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for your interest in helping translate the FastAPI docs! 🌍
|
||||
|
||||
Please follow these instructions carefully to propose a new language translation. 🙏
|
||||
|
||||
This structured process helps ensure translations can be properly maintained long-term.
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: Initial Checks
|
||||
description: Please confirm and check all the following options.
|
||||
options:
|
||||
- label: I checked that this language is not already being translated in FastAPI docs.
|
||||
required: true
|
||||
- label: I searched existing discussions to ensure no one else proposed this language.
|
||||
required: true
|
||||
- label: I am a native speaker of the language I want to help translate.
|
||||
required: true
|
||||
- type: input
|
||||
id: language
|
||||
attributes:
|
||||
label: Target Language
|
||||
description: What language do you want to translate the FastAPI docs into?
|
||||
placeholder: e.g. Latin
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: additional_info
|
||||
attributes:
|
||||
label: Additional Information
|
||||
description: Any other relevant information about your translation proposal
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Translations are automatized with AI and then reviewed by native speakers. 🤖 🙋
|
||||
|
||||
This allows us to keep them consistent and up-to-date.
|
||||
|
||||
If there are several native speakers commenting on this discussion and
|
||||
committing to help review new translations, the FastAPI team will review it
|
||||
and potentially make it an official translation. 😎
|
||||
@@ -1,7 +0,0 @@
|
||||
FROM python:3.9
|
||||
|
||||
RUN pip install httpx PyGithub "pydantic==1.5.1" "pyyaml>=5.3.1,<6.0.0"
|
||||
|
||||
COPY ./app /app
|
||||
|
||||
CMD ["python", "/app/main.py"]
|
||||
10
.github/actions/notify-translations/action.yml
vendored
10
.github/actions/notify-translations/action.yml
vendored
@@ -1,10 +0,0 @@
|
||||
name: "Notify Translations"
|
||||
description: "Notify in the issue for a translation when there's a new PR available"
|
||||
author: "Sebastián Ramírez <tiangolo@gmail.com>"
|
||||
inputs:
|
||||
token:
|
||||
description: 'Token, to read the GitHub API. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
|
||||
required: true
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'Dockerfile'
|
||||
7
.github/actions/people/Dockerfile
vendored
7
.github/actions/people/Dockerfile
vendored
@@ -1,7 +0,0 @@
|
||||
FROM python:3.9
|
||||
|
||||
RUN pip install httpx PyGithub "pydantic==2.0.2" pydantic-settings "pyyaml>=5.3.1,<6.0.0"
|
||||
|
||||
COPY ./app /app
|
||||
|
||||
CMD ["python", "/app/main.py"]
|
||||
10
.github/actions/people/action.yml
vendored
10
.github/actions/people/action.yml
vendored
@@ -1,10 +0,0 @@
|
||||
name: "Generate FastAPI People"
|
||||
description: "Generate the data for the FastAPI People page"
|
||||
author: "Sebastián Ramírez <tiangolo@gmail.com>"
|
||||
inputs:
|
||||
token:
|
||||
description: 'User token, to read the GitHub API. Can be passed in using {{ secrets.FASTAPI_PEOPLE }}'
|
||||
required: true
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'Dockerfile'
|
||||
682
.github/actions/people/app/main.py
vendored
682
.github/actions/people/app/main.py
vendored
@@ -1,682 +0,0 @@
|
||||
import logging
|
||||
import subprocess
|
||||
import sys
|
||||
from collections import Counter, defaultdict
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any, Container, DefaultDict, Dict, List, Set, Union
|
||||
|
||||
import httpx
|
||||
import yaml
|
||||
from github import Github
|
||||
from pydantic import BaseModel, SecretStr
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
github_graphql_url = "https://api.github.com/graphql"
|
||||
questions_category_id = "MDE4OkRpc2N1c3Npb25DYXRlZ29yeTMyMDAxNDM0"
|
||||
|
||||
discussions_query = """
|
||||
query Q($after: String, $category_id: ID) {
|
||||
repository(name: "fastapi", owner: "fastapi") {
|
||||
discussions(first: 100, after: $after, categoryId: $category_id) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
number
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
title
|
||||
createdAt
|
||||
comments(first: 100) {
|
||||
nodes {
|
||||
createdAt
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
isAnswer
|
||||
replies(first: 10) {
|
||||
nodes {
|
||||
createdAt
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
prs_query = """
|
||||
query Q($after: String) {
|
||||
repository(name: "fastapi", owner: "fastapi") {
|
||||
pullRequests(first: 100, after: $after) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
number
|
||||
labels(first: 100) {
|
||||
nodes {
|
||||
name
|
||||
}
|
||||
}
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
title
|
||||
createdAt
|
||||
state
|
||||
comments(first: 100) {
|
||||
nodes {
|
||||
createdAt
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
reviews(first:100) {
|
||||
nodes {
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
state
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
sponsors_query = """
|
||||
query Q($after: String) {
|
||||
user(login: "fastapi") {
|
||||
sponsorshipsAsMaintainer(first: 100, after: $after) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
sponsorEntity {
|
||||
... on Organization {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
... on User {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
}
|
||||
tier {
|
||||
name
|
||||
monthlyPriceInDollars
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class Author(BaseModel):
|
||||
login: str
|
||||
avatarUrl: str
|
||||
url: str
|
||||
|
||||
|
||||
# Discussions
|
||||
|
||||
|
||||
class CommentsNode(BaseModel):
|
||||
createdAt: datetime
|
||||
author: Union[Author, None] = None
|
||||
|
||||
|
||||
class Replies(BaseModel):
|
||||
nodes: List[CommentsNode]
|
||||
|
||||
|
||||
class DiscussionsCommentsNode(CommentsNode):
|
||||
replies: Replies
|
||||
|
||||
|
||||
class Comments(BaseModel):
|
||||
nodes: List[CommentsNode]
|
||||
|
||||
|
||||
class DiscussionsComments(BaseModel):
|
||||
nodes: List[DiscussionsCommentsNode]
|
||||
|
||||
|
||||
class DiscussionsNode(BaseModel):
|
||||
number: int
|
||||
author: Union[Author, None] = None
|
||||
title: str
|
||||
createdAt: datetime
|
||||
comments: DiscussionsComments
|
||||
|
||||
|
||||
class DiscussionsEdge(BaseModel):
|
||||
cursor: str
|
||||
node: DiscussionsNode
|
||||
|
||||
|
||||
class Discussions(BaseModel):
|
||||
edges: List[DiscussionsEdge]
|
||||
|
||||
|
||||
class DiscussionsRepository(BaseModel):
|
||||
discussions: Discussions
|
||||
|
||||
|
||||
class DiscussionsResponseData(BaseModel):
|
||||
repository: DiscussionsRepository
|
||||
|
||||
|
||||
class DiscussionsResponse(BaseModel):
|
||||
data: DiscussionsResponseData
|
||||
|
||||
|
||||
# PRs
|
||||
|
||||
|
||||
class LabelNode(BaseModel):
|
||||
name: str
|
||||
|
||||
|
||||
class Labels(BaseModel):
|
||||
nodes: List[LabelNode]
|
||||
|
||||
|
||||
class ReviewNode(BaseModel):
|
||||
author: Union[Author, None] = None
|
||||
state: str
|
||||
|
||||
|
||||
class Reviews(BaseModel):
|
||||
nodes: List[ReviewNode]
|
||||
|
||||
|
||||
class PullRequestNode(BaseModel):
|
||||
number: int
|
||||
labels: Labels
|
||||
author: Union[Author, None] = None
|
||||
title: str
|
||||
createdAt: datetime
|
||||
state: str
|
||||
comments: Comments
|
||||
reviews: Reviews
|
||||
|
||||
|
||||
class PullRequestEdge(BaseModel):
|
||||
cursor: str
|
||||
node: PullRequestNode
|
||||
|
||||
|
||||
class PullRequests(BaseModel):
|
||||
edges: List[PullRequestEdge]
|
||||
|
||||
|
||||
class PRsRepository(BaseModel):
|
||||
pullRequests: PullRequests
|
||||
|
||||
|
||||
class PRsResponseData(BaseModel):
|
||||
repository: PRsRepository
|
||||
|
||||
|
||||
class PRsResponse(BaseModel):
|
||||
data: PRsResponseData
|
||||
|
||||
|
||||
# Sponsors
|
||||
|
||||
|
||||
class SponsorEntity(BaseModel):
|
||||
login: str
|
||||
avatarUrl: str
|
||||
url: str
|
||||
|
||||
|
||||
class Tier(BaseModel):
|
||||
name: str
|
||||
monthlyPriceInDollars: float
|
||||
|
||||
|
||||
class SponsorshipAsMaintainerNode(BaseModel):
|
||||
sponsorEntity: SponsorEntity
|
||||
tier: Tier
|
||||
|
||||
|
||||
class SponsorshipAsMaintainerEdge(BaseModel):
|
||||
cursor: str
|
||||
node: SponsorshipAsMaintainerNode
|
||||
|
||||
|
||||
class SponsorshipAsMaintainer(BaseModel):
|
||||
edges: List[SponsorshipAsMaintainerEdge]
|
||||
|
||||
|
||||
class SponsorsUser(BaseModel):
|
||||
sponsorshipsAsMaintainer: SponsorshipAsMaintainer
|
||||
|
||||
|
||||
class SponsorsResponseData(BaseModel):
|
||||
user: SponsorsUser
|
||||
|
||||
|
||||
class SponsorsResponse(BaseModel):
|
||||
data: SponsorsResponseData
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
input_token: SecretStr
|
||||
github_repository: str
|
||||
httpx_timeout: int = 30
|
||||
|
||||
|
||||
def get_graphql_response(
|
||||
*,
|
||||
settings: Settings,
|
||||
query: str,
|
||||
after: Union[str, None] = None,
|
||||
category_id: Union[str, None] = None,
|
||||
) -> Dict[str, Any]:
|
||||
headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"}
|
||||
# category_id is only used by one query, but GraphQL allows unused variables, so
|
||||
# keep it here for simplicity
|
||||
variables = {"after": after, "category_id": category_id}
|
||||
response = httpx.post(
|
||||
github_graphql_url,
|
||||
headers=headers,
|
||||
timeout=settings.httpx_timeout,
|
||||
json={"query": query, "variables": variables, "operationName": "Q"},
|
||||
)
|
||||
if response.status_code != 200:
|
||||
logging.error(
|
||||
f"Response was not 200, after: {after}, category_id: {category_id}"
|
||||
)
|
||||
logging.error(response.text)
|
||||
raise RuntimeError(response.text)
|
||||
data = response.json()
|
||||
if "errors" in data:
|
||||
logging.error(f"Errors in response, after: {after}, category_id: {category_id}")
|
||||
logging.error(data["errors"])
|
||||
logging.error(response.text)
|
||||
raise RuntimeError(response.text)
|
||||
return data
|
||||
|
||||
|
||||
def get_graphql_question_discussion_edges(
|
||||
*,
|
||||
settings: Settings,
|
||||
after: Union[str, None] = None,
|
||||
):
|
||||
data = get_graphql_response(
|
||||
settings=settings,
|
||||
query=discussions_query,
|
||||
after=after,
|
||||
category_id=questions_category_id,
|
||||
)
|
||||
graphql_response = DiscussionsResponse.model_validate(data)
|
||||
return graphql_response.data.repository.discussions.edges
|
||||
|
||||
|
||||
def get_graphql_pr_edges(*, settings: Settings, after: Union[str, None] = None):
|
||||
data = get_graphql_response(settings=settings, query=prs_query, after=after)
|
||||
graphql_response = PRsResponse.model_validate(data)
|
||||
return graphql_response.data.repository.pullRequests.edges
|
||||
|
||||
|
||||
def get_graphql_sponsor_edges(*, settings: Settings, after: Union[str, None] = None):
|
||||
data = get_graphql_response(settings=settings, query=sponsors_query, after=after)
|
||||
graphql_response = SponsorsResponse.model_validate(data)
|
||||
return graphql_response.data.user.sponsorshipsAsMaintainer.edges
|
||||
|
||||
|
||||
class DiscussionExpertsResults(BaseModel):
|
||||
commenters: Counter
|
||||
last_month_commenters: Counter
|
||||
three_months_commenters: Counter
|
||||
six_months_commenters: Counter
|
||||
one_year_commenters: Counter
|
||||
authors: Dict[str, Author]
|
||||
|
||||
|
||||
def get_discussion_nodes(settings: Settings) -> List[DiscussionsNode]:
|
||||
discussion_nodes: List[DiscussionsNode] = []
|
||||
discussion_edges = get_graphql_question_discussion_edges(settings=settings)
|
||||
|
||||
while discussion_edges:
|
||||
for discussion_edge in discussion_edges:
|
||||
discussion_nodes.append(discussion_edge.node)
|
||||
last_edge = discussion_edges[-1]
|
||||
discussion_edges = get_graphql_question_discussion_edges(
|
||||
settings=settings, after=last_edge.cursor
|
||||
)
|
||||
return discussion_nodes
|
||||
|
||||
|
||||
def get_discussions_experts(
|
||||
discussion_nodes: List[DiscussionsNode],
|
||||
) -> DiscussionExpertsResults:
|
||||
commenters = Counter()
|
||||
last_month_commenters = Counter()
|
||||
three_months_commenters = Counter()
|
||||
six_months_commenters = Counter()
|
||||
one_year_commenters = Counter()
|
||||
authors: Dict[str, Author] = {}
|
||||
|
||||
now = datetime.now(tz=timezone.utc)
|
||||
one_month_ago = now - timedelta(days=30)
|
||||
three_months_ago = now - timedelta(days=90)
|
||||
six_months_ago = now - timedelta(days=180)
|
||||
one_year_ago = now - timedelta(days=365)
|
||||
|
||||
for discussion in discussion_nodes:
|
||||
discussion_author_name = None
|
||||
if discussion.author:
|
||||
authors[discussion.author.login] = discussion.author
|
||||
discussion_author_name = discussion.author.login
|
||||
discussion_commentors: dict[str, datetime] = {}
|
||||
for comment in discussion.comments.nodes:
|
||||
if comment.author:
|
||||
authors[comment.author.login] = comment.author
|
||||
if comment.author.login != discussion_author_name:
|
||||
author_time = discussion_commentors.get(
|
||||
comment.author.login, comment.createdAt
|
||||
)
|
||||
discussion_commentors[comment.author.login] = max(
|
||||
author_time, comment.createdAt
|
||||
)
|
||||
for reply in comment.replies.nodes:
|
||||
if reply.author:
|
||||
authors[reply.author.login] = reply.author
|
||||
if reply.author.login != discussion_author_name:
|
||||
author_time = discussion_commentors.get(
|
||||
reply.author.login, reply.createdAt
|
||||
)
|
||||
discussion_commentors[reply.author.login] = max(
|
||||
author_time, reply.createdAt
|
||||
)
|
||||
for author_name, author_time in discussion_commentors.items():
|
||||
commenters[author_name] += 1
|
||||
if author_time > one_month_ago:
|
||||
last_month_commenters[author_name] += 1
|
||||
if author_time > three_months_ago:
|
||||
three_months_commenters[author_name] += 1
|
||||
if author_time > six_months_ago:
|
||||
six_months_commenters[author_name] += 1
|
||||
if author_time > one_year_ago:
|
||||
one_year_commenters[author_name] += 1
|
||||
discussion_experts_results = DiscussionExpertsResults(
|
||||
authors=authors,
|
||||
commenters=commenters,
|
||||
last_month_commenters=last_month_commenters,
|
||||
three_months_commenters=three_months_commenters,
|
||||
six_months_commenters=six_months_commenters,
|
||||
one_year_commenters=one_year_commenters,
|
||||
)
|
||||
return discussion_experts_results
|
||||
|
||||
|
||||
def get_pr_nodes(settings: Settings) -> List[PullRequestNode]:
|
||||
pr_nodes: List[PullRequestNode] = []
|
||||
pr_edges = get_graphql_pr_edges(settings=settings)
|
||||
|
||||
while pr_edges:
|
||||
for edge in pr_edges:
|
||||
pr_nodes.append(edge.node)
|
||||
last_edge = pr_edges[-1]
|
||||
pr_edges = get_graphql_pr_edges(settings=settings, after=last_edge.cursor)
|
||||
return pr_nodes
|
||||
|
||||
|
||||
class ContributorsResults(BaseModel):
|
||||
contributors: Counter
|
||||
commenters: Counter
|
||||
reviewers: Counter
|
||||
translation_reviewers: Counter
|
||||
authors: Dict[str, Author]
|
||||
|
||||
|
||||
def get_contributors(pr_nodes: List[PullRequestNode]) -> ContributorsResults:
|
||||
contributors = Counter()
|
||||
commenters = Counter()
|
||||
reviewers = Counter()
|
||||
translation_reviewers = Counter()
|
||||
authors: Dict[str, Author] = {}
|
||||
|
||||
for pr in pr_nodes:
|
||||
author_name = None
|
||||
if pr.author:
|
||||
authors[pr.author.login] = pr.author
|
||||
author_name = pr.author.login
|
||||
pr_commentors: Set[str] = set()
|
||||
pr_reviewers: Set[str] = set()
|
||||
for comment in pr.comments.nodes:
|
||||
if comment.author:
|
||||
authors[comment.author.login] = comment.author
|
||||
if comment.author.login == author_name:
|
||||
continue
|
||||
pr_commentors.add(comment.author.login)
|
||||
for author_name in pr_commentors:
|
||||
commenters[author_name] += 1
|
||||
for review in pr.reviews.nodes:
|
||||
if review.author:
|
||||
authors[review.author.login] = review.author
|
||||
pr_reviewers.add(review.author.login)
|
||||
for label in pr.labels.nodes:
|
||||
if label.name == "lang-all":
|
||||
translation_reviewers[review.author.login] += 1
|
||||
break
|
||||
for reviewer in pr_reviewers:
|
||||
reviewers[reviewer] += 1
|
||||
if pr.state == "MERGED" and pr.author:
|
||||
contributors[pr.author.login] += 1
|
||||
return ContributorsResults(
|
||||
contributors=contributors,
|
||||
commenters=commenters,
|
||||
reviewers=reviewers,
|
||||
translation_reviewers=translation_reviewers,
|
||||
authors=authors,
|
||||
)
|
||||
|
||||
|
||||
def get_individual_sponsors(settings: Settings):
|
||||
nodes: List[SponsorshipAsMaintainerNode] = []
|
||||
edges = get_graphql_sponsor_edges(settings=settings)
|
||||
|
||||
while edges:
|
||||
for edge in edges:
|
||||
nodes.append(edge.node)
|
||||
last_edge = edges[-1]
|
||||
edges = get_graphql_sponsor_edges(settings=settings, after=last_edge.cursor)
|
||||
|
||||
tiers: DefaultDict[float, Dict[str, SponsorEntity]] = defaultdict(dict)
|
||||
for node in nodes:
|
||||
tiers[node.tier.monthlyPriceInDollars][node.sponsorEntity.login] = (
|
||||
node.sponsorEntity
|
||||
)
|
||||
return tiers
|
||||
|
||||
|
||||
def get_top_users(
|
||||
*,
|
||||
counter: Counter,
|
||||
authors: Dict[str, Author],
|
||||
skip_users: Container[str],
|
||||
min_count: int = 2,
|
||||
):
|
||||
users = []
|
||||
for commenter, count in counter.most_common(50):
|
||||
if commenter in skip_users:
|
||||
continue
|
||||
if count >= min_count:
|
||||
author = authors[commenter]
|
||||
users.append(
|
||||
{
|
||||
"login": commenter,
|
||||
"count": count,
|
||||
"avatarUrl": author.avatarUrl,
|
||||
"url": author.url,
|
||||
}
|
||||
)
|
||||
return users
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
settings = Settings()
|
||||
logging.info(f"Using config: {settings.model_dump_json()}")
|
||||
g = Github(settings.input_token.get_secret_value())
|
||||
repo = g.get_repo(settings.github_repository)
|
||||
discussion_nodes = get_discussion_nodes(settings=settings)
|
||||
experts_results = get_discussions_experts(discussion_nodes=discussion_nodes)
|
||||
pr_nodes = get_pr_nodes(settings=settings)
|
||||
contributors_results = get_contributors(pr_nodes=pr_nodes)
|
||||
authors = {**experts_results.authors, **contributors_results.authors}
|
||||
maintainers_logins = {"tiangolo"}
|
||||
bot_names = {"codecov", "github-actions", "pre-commit-ci", "dependabot"}
|
||||
maintainers = []
|
||||
for login in maintainers_logins:
|
||||
user = authors[login]
|
||||
maintainers.append(
|
||||
{
|
||||
"login": login,
|
||||
"answers": experts_results.commenters[login],
|
||||
"prs": contributors_results.contributors[login],
|
||||
"avatarUrl": user.avatarUrl,
|
||||
"url": user.url,
|
||||
}
|
||||
)
|
||||
|
||||
skip_users = maintainers_logins | bot_names
|
||||
experts = get_top_users(
|
||||
counter=experts_results.commenters,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
last_month_experts = get_top_users(
|
||||
counter=experts_results.last_month_commenters,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
three_months_experts = get_top_users(
|
||||
counter=experts_results.three_months_commenters,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
six_months_experts = get_top_users(
|
||||
counter=experts_results.six_months_commenters,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
one_year_experts = get_top_users(
|
||||
counter=experts_results.one_year_commenters,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
top_contributors = get_top_users(
|
||||
counter=contributors_results.contributors,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
top_reviewers = get_top_users(
|
||||
counter=contributors_results.reviewers,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
top_translations_reviewers = get_top_users(
|
||||
counter=contributors_results.translation_reviewers,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
|
||||
tiers = get_individual_sponsors(settings=settings)
|
||||
keys = list(tiers.keys())
|
||||
keys.sort(reverse=True)
|
||||
sponsors = []
|
||||
for key in keys:
|
||||
sponsor_group = []
|
||||
for login, sponsor in tiers[key].items():
|
||||
sponsor_group.append(
|
||||
{"login": login, "avatarUrl": sponsor.avatarUrl, "url": sponsor.url}
|
||||
)
|
||||
sponsors.append(sponsor_group)
|
||||
|
||||
people = {
|
||||
"maintainers": maintainers,
|
||||
"experts": experts,
|
||||
"last_month_experts": last_month_experts,
|
||||
"three_months_experts": three_months_experts,
|
||||
"six_months_experts": six_months_experts,
|
||||
"one_year_experts": one_year_experts,
|
||||
"top_contributors": top_contributors,
|
||||
"top_reviewers": top_reviewers,
|
||||
"top_translations_reviewers": top_translations_reviewers,
|
||||
}
|
||||
github_sponsors = {
|
||||
"sponsors": sponsors,
|
||||
}
|
||||
# For local development
|
||||
# people_path = Path("../../../../docs/en/data/people.yml")
|
||||
people_path = Path("./docs/en/data/people.yml")
|
||||
github_sponsors_path = Path("./docs/en/data/github_sponsors.yml")
|
||||
people_old_content = people_path.read_text(encoding="utf-8")
|
||||
github_sponsors_old_content = github_sponsors_path.read_text(encoding="utf-8")
|
||||
new_people_content = yaml.dump(
|
||||
people, sort_keys=False, width=200, allow_unicode=True
|
||||
)
|
||||
new_github_sponsors_content = yaml.dump(
|
||||
github_sponsors, sort_keys=False, width=200, allow_unicode=True
|
||||
)
|
||||
if (
|
||||
people_old_content == new_people_content
|
||||
and github_sponsors_old_content == new_github_sponsors_content
|
||||
):
|
||||
logging.info("The FastAPI People data hasn't changed, finishing.")
|
||||
sys.exit(0)
|
||||
people_path.write_text(new_people_content, encoding="utf-8")
|
||||
github_sponsors_path.write_text(new_github_sponsors_content, encoding="utf-8")
|
||||
logging.info("Setting up GitHub Actions git user")
|
||||
subprocess.run(["git", "config", "user.name", "github-actions"], check=True)
|
||||
subprocess.run(
|
||||
["git", "config", "user.email", "github-actions@github.com"], check=True
|
||||
)
|
||||
branch_name = "fastapi-people"
|
||||
logging.info(f"Creating a new branch {branch_name}")
|
||||
subprocess.run(["git", "checkout", "-b", branch_name], check=True)
|
||||
logging.info("Adding updated file")
|
||||
subprocess.run(
|
||||
["git", "add", str(people_path), str(github_sponsors_path)], check=True
|
||||
)
|
||||
logging.info("Committing updated file")
|
||||
message = "👥 Update FastAPI People"
|
||||
result = subprocess.run(["git", "commit", "-m", message], check=True)
|
||||
logging.info("Pushing branch")
|
||||
subprocess.run(["git", "push", "origin", branch_name], check=True)
|
||||
logging.info("Creating PR")
|
||||
pr = repo.create_pull(title=message, body=message, base="master", head=branch_name)
|
||||
logging.info(f"Created PR: {pr.number}")
|
||||
logging.info("Finished")
|
||||
14
.github/workflows/build-docs.yml
vendored
14
.github/workflows/build-docs.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
||||
outputs:
|
||||
docs: ${{ steps.filter.outputs.docs }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
# For pull requests it's not necessary to checkout the code but for the main branch it is
|
||||
- uses: dorny/paths-filter@v3
|
||||
id: filter
|
||||
@@ -47,13 +47,13 @@ jobs:
|
||||
outputs:
|
||||
langs: ${{ steps.show-langs.outputs.langs }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
@@ -89,13 +89,13 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
|
||||
53
.github/workflows/contributors.yml
vendored
Normal file
53
.github/workflows/contributors.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
name: FastAPI People Contributors
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 3 1 * *"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug_enabled:
|
||||
description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
job:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
||||
- name: FastAPI People Contributors
|
||||
run: python ./scripts/contributors.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
||||
13
.github/workflows/deploy-docs.yml
vendored
13
.github/workflows/deploy-docs.yml
vendored
@@ -23,13 +23,13 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
run: |
|
||||
rm -rf ./site
|
||||
mkdir ./site
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
path: ./site/
|
||||
pattern: docs-site-*
|
||||
@@ -62,10 +62,7 @@ jobs:
|
||||
env:
|
||||
PROJECT_NAME: fastapitiangolo
|
||||
BRANCH: ${{ ( github.event.workflow_run.head_repository.full_name == github.repository && github.event.workflow_run.head_branch == 'master' && 'main' ) || ( github.event.workflow_run.head_sha ) }}
|
||||
# TODO: Use v3 when it's fixed, probably in v3.11
|
||||
# https://github.com/cloudflare/wrangler-action/issues/307
|
||||
uses: cloudflare/wrangler-action@v3.12
|
||||
# uses: cloudflare/wrangler-action@v3
|
||||
uses: cloudflare/wrangler-action@v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
|
||||
19
.github/workflows/detect-conflicts.yml
vendored
Normal file
19
.github/workflows/detect-conflicts.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: "Conflict detector"
|
||||
on:
|
||||
push:
|
||||
pull_request_target:
|
||||
types: [synchronize]
|
||||
|
||||
jobs:
|
||||
main:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check if PRs have merge conflicts
|
||||
uses: eps1lon/actions-label-merge-conflict@v3
|
||||
with:
|
||||
dirtyLabel: "conflicts"
|
||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
||||
commentOnDirty: "This pull request has a merge conflict that needs to be resolved."
|
||||
6
.github/workflows/label-approved.yml
vendored
6
.github/workflows/label-approved.yml
vendored
@@ -20,13 +20,13 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
|
||||
2
.github/workflows/labeler.yml
vendored
2
.github/workflows/labeler.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v5
|
||||
- uses: actions/labeler@v6
|
||||
if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }}
|
||||
- run: echo "Done adding labels"
|
||||
# Run this after labeler applied labels
|
||||
|
||||
4
.github/workflows/latest-changes.yml
vendored
4
.github/workflows/latest-changes.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
# To allow latest-changes to commit to the main branch
|
||||
token: ${{ secrets.FASTAPI_LATEST_CHANGES }}
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
- uses: tiangolo/latest-changes@0.3.2
|
||||
- uses: tiangolo/latest-changes@0.4.0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
latest_changes_file: docs/en/docs/release-notes.md
|
||||
|
||||
27
.github/workflows/notify-translations.yml
vendored
27
.github/workflows/notify-translations.yml
vendored
@@ -15,40 +15,45 @@ on:
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
permissions:
|
||||
discussions: write
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
notify-translations:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
discussions: write
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
- uses: ./.github/actions/notify-translations
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Notify Translations
|
||||
run: python ./scripts/notify_translations.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NUMBER: ${{ github.event.inputs.number || null }}
|
||||
DEBUG: ${{ github.event.inputs.debug_enabled || 'false' }}
|
||||
|
||||
40
.github/workflows/people.yml
vendored
40
.github/workflows/people.yml
vendored
@@ -6,29 +6,49 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug_enabled:
|
||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
||||
description: Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)
|
||||
required: false
|
||||
default: 'false'
|
||||
default: "false"
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
fastapi-people:
|
||||
job:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
# Ref: https://github.com/actions/runner/issues/2033
|
||||
- name: Fix git safe.directory in container
|
||||
run: mkdir -p /home/runner/work/_temp/_github_home && printf "[safe]\n\tdirectory = /github/workspace" > /home/runner/work/_temp/_github_home/.gitconfig
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
- uses: ./.github/actions/people
|
||||
with:
|
||||
token: ${{ secrets.FASTAPI_PEOPLE }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
|
||||
- name: FastAPI People Experts
|
||||
run: python ./scripts/people.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
|
||||
SLEEP_INTERVAL: ${{ vars.PEOPLE_SLEEP_INTERVAL }}
|
||||
|
||||
6
.github/workflows/publish.yml
vendored
6
.github/workflows/publish.yml
vendored
@@ -20,9 +20,9 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.10"
|
||||
# Issue ref: https://github.com/actions/setup-python/issues/436
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
|
||||
run: python -m build
|
||||
- name: Publish
|
||||
uses: pypa/gh-action-pypi-publish@v1.12.2
|
||||
uses: pypa/gh-action-pypi-publish@v1.13.0
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
|
||||
20
.github/workflows/smokeshow.yml
vendored
20
.github/workflows/smokeshow.yml
vendored
@@ -21,12 +21,12 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.9'
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
@@ -34,13 +34,23 @@ jobs:
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- run: uv pip install -r requirements-github-actions.txt
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v5
|
||||
with:
|
||||
name: coverage-html
|
||||
path: htmlcov
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
- run: smokeshow upload htmlcov
|
||||
# Try 5 times to upload coverage to smokeshow
|
||||
- name: Upload coverage to Smokeshow
|
||||
run: |
|
||||
for i in 1 2 3 4 5; do
|
||||
if smokeshow upload htmlcov; then
|
||||
echo "Smokeshow upload success!"
|
||||
break
|
||||
fi
|
||||
echo "Smokeshow upload error, sleep 1 sec and try again."
|
||||
sleep 1
|
||||
done
|
||||
env:
|
||||
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}
|
||||
SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 100
|
||||
|
||||
52
.github/workflows/sponsors.yml
vendored
Normal file
52
.github/workflows/sponsors.yml
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
name: FastAPI People Sponsors
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 6 1 * *"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug_enabled:
|
||||
description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
job:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
- name: FastAPI People Sponsors
|
||||
run: python ./scripts/sponsors.py
|
||||
env:
|
||||
SPONSORS_TOKEN: ${{ secrets.SPONSORS_TOKEN }}
|
||||
PR_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
||||
4
.github/workflows/test-redistribute.yml
vendored
4
.github/workflows/test-redistribute.yml
vendored
@@ -22,9 +22,9 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- name: Install build dependencies
|
||||
|
||||
25
.github/workflows/test.yml
vendored
25
.github/workflows/test.yml
vendored
@@ -23,13 +23,13 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
@@ -48,6 +48,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version:
|
||||
- "3.13"
|
||||
- "3.12"
|
||||
- "3.11"
|
||||
- "3.10"
|
||||
@@ -60,13 +61,13 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
@@ -81,6 +82,10 @@ jobs:
|
||||
- name: Install Pydantic v2
|
||||
if: matrix.pydantic-version == 'pydantic-v2'
|
||||
run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
|
||||
# TODO: Remove this once Python 3.8 is no longer supported
|
||||
- name: Install older AnyIO in Python 3.8
|
||||
if: matrix.python-version == '3.8'
|
||||
run: uv pip install "anyio[trio]<4.0.0"
|
||||
- run: mkdir coverage
|
||||
- name: Test
|
||||
run: bash scripts/test.sh
|
||||
@@ -102,12 +107,12 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.8'
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
@@ -117,7 +122,7 @@ jobs:
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-tests.txt
|
||||
- name: Get coverage files
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v5
|
||||
with:
|
||||
pattern: coverage-*
|
||||
path: coverage
|
||||
|
||||
40
.github/workflows/topic-repos.yml
vendored
Normal file
40
.github/workflows/topic-repos.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
name: Update Topic Repos
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 12 1 * *"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
topic-repos:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install GitHub Actions dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
- name: Update Topic Repos
|
||||
run: python ./scripts/topic_repos.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
||||
77
.github/workflows/translate.yml
vendored
Normal file
77
.github/workflows/translate.yml
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
name: Translate
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug_enabled:
|
||||
description: Run with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)
|
||||
required: false
|
||||
default: "false"
|
||||
command:
|
||||
description: Command to run
|
||||
type: choice
|
||||
options:
|
||||
- translate-page
|
||||
- translate-lang
|
||||
- update-outdated
|
||||
- add-missing
|
||||
- update-and-add
|
||||
- remove-all-removable
|
||||
language:
|
||||
description: Language to translate to as a letter code (e.g. "es" for Spanish)
|
||||
type: string
|
||||
required: false
|
||||
default: ""
|
||||
en_path:
|
||||
description: File path in English to translate (e.g. docs/en/docs/index.md)
|
||||
type: string
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
job:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt -r requirements-translations.txt
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }}
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
- name: FastAPI Translate
|
||||
run: |
|
||||
python ./scripts/translate.py ${{ github.event.inputs.command }}
|
||||
python ./scripts/translate.py make-pr
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }}
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
LANGUAGE: ${{ github.event.inputs.language }}
|
||||
EN_PATH: ${{ github.event.inputs.en_path }}
|
||||
@@ -4,7 +4,7 @@ default_language_version:
|
||||
python: python3.10
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
rev: v6.0.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-toml
|
||||
@@ -14,7 +14,7 @@ repos:
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.7.3
|
||||
rev: v0.13.0
|
||||
hooks:
|
||||
- id: ruff
|
||||
args:
|
||||
|
||||
82
README.md
82
README.md
@@ -6,7 +6,7 @@
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
||||
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
|
||||
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
|
||||
</a>
|
||||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
|
||||
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
|
||||
@@ -42,33 +42,32 @@ The key features are:
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
|
||||
## Sponsors
|
||||
## Sponsors { #sponsors }
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
<a href="https://cryptapi.io/" target="_blank" title="CryptAPI: Your easy to use, secure and privacy oriented payment gateway."><img src="https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg"></a>
|
||||
<a href="https://platform.sh/try-it-now/?utm_source=fastapi-signup&utm_medium=banner&utm_campaign=FastAPI-signup-June-2023" target="_blank" title="Build, run and scale your apps on a modern, reliable, and secure PaaS."><img src="https://fastapi.tiangolo.com/img/sponsors/platform-sh.png"></a>
|
||||
<a href="https://www.porter.run" target="_blank" title="Deploy FastAPI on AWS with a few clicks"><img src="https://fastapi.tiangolo.com/img/sponsors/porter.png"></a>
|
||||
<a href="https://bump.sh/fastapi?utm_source=fastapi&utm_medium=referral&utm_campaign=sponsor" target="_blank" title="Automate FastAPI documentation generation with Bump.sh"><img src="https://fastapi.tiangolo.com/img/sponsors/bump-sh.svg"></a>
|
||||
<a href="https://blockbee.io?ref=fastapi" target="_blank" title="BlockBee Cryptocurrency Payment Gateway"><img src="https://fastapi.tiangolo.com/img/sponsors/blockbee.png"></a>
|
||||
<a href="https://github.com/scalar/scalar/?utm_source=fastapi&utm_medium=website&utm_campaign=main-badge" target="_blank" title="Scalar: Beautiful Open-Source API References from Swagger/OpenAPI files"><img src="https://fastapi.tiangolo.com/img/sponsors/scalar.svg"></a>
|
||||
<a href="https://www.propelauth.com/?utm_source=fastapi&utm_campaign=1223&utm_medium=mainbadge" target="_blank" title="Auth, user management and more for your B2B product"><img src="https://fastapi.tiangolo.com/img/sponsors/propelauth.png"></a>
|
||||
<a href="https://www.withcoherence.com/?utm_medium=advertising&utm_source=fastapi&utm_campaign=website" target="_blank" title="Coherence"><img src="https://fastapi.tiangolo.com/img/sponsors/coherence.png"></a>
|
||||
<a href="https://www.mongodb.com/developer/languages/python/python-quickstart-fastapi/?utm_campaign=fastapi_framework&utm_source=fastapi_sponsorship&utm_medium=web_referral" target="_blank" title="Simplify Full Stack Development with FastAPI & MongoDB"><img src="https://fastapi.tiangolo.com/img/sponsors/mongodb.png"></a>
|
||||
<a href="https://zuplo.link/fastapi-gh" target="_blank" title="Zuplo: Scale, Protect, Document, and Monetize your FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/zuplo.png"></a>
|
||||
<a href="https://zuplo.link/fastapi-gh" target="_blank" title="Zuplo: Deploy, Secure, Document, and Monetize your FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/zuplo.png"></a>
|
||||
<a href="https://liblab.com?utm_source=fastapi" target="_blank" title="liblab - Generate SDKs from FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/liblab.png"></a>
|
||||
<a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" target="_blank" title="Deploy & scale any full-stack web app on Render. Focus on building apps, not infra."><img src="https://fastapi.tiangolo.com/img/sponsors/render.svg"></a>
|
||||
<a href="https://github.com/deepset-ai/haystack/" target="_blank" title="Build powerful search from composable, open source building blocks"><img src="https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg"></a>
|
||||
<a href="https://databento.com/" target="_blank" title="Pay as you go for market data"><img src="https://fastapi.tiangolo.com/img/sponsors/databento.svg"></a>
|
||||
<a href="https://speakeasy.com?utm_source=fastapi+repo&utm_medium=github+sponsorship" target="_blank" title="SDKs for your API | Speakeasy"><img src="https://fastapi.tiangolo.com/img/sponsors/speakeasy.png"></a>
|
||||
<a href="https://www.coderabbit.ai/?utm_source=fastapi&utm_medium=badge&utm_campaign=fastapi" target="_blank" title="Cut Code Review Time & Bugs in Half with CodeRabbit"><img src="https://fastapi.tiangolo.com/img/sponsors/coderabbit.png"></a>
|
||||
<a href="https://subtotal.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=open-source" target="_blank" title="The Gold Standard in Retail Account Linking"><img src="https://fastapi.tiangolo.com/img/sponsors/subtotal.svg"></a>
|
||||
<a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" target="_blank" title="Deploy enterprise applications at startup speed"><img src="https://fastapi.tiangolo.com/img/sponsors/railway.png"></a>
|
||||
<a href="https://databento.com/?utm_source=fastapi&utm_medium=sponsor&utm_content=display" target="_blank" title="Pay as you go for market data"><img src="https://fastapi.tiangolo.com/img/sponsors/databento.svg"></a>
|
||||
<a href="https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship" target="_blank" title="SDKs for your API | Speakeasy"><img src="https://fastapi.tiangolo.com/img/sponsors/speakeasy.png"></a>
|
||||
<a href="https://www.svix.com/" target="_blank" title="Svix - Webhooks as a service"><img src="https://fastapi.tiangolo.com/img/sponsors/svix.svg"></a>
|
||||
<a href="https://www.codacy.com/?utm_source=github&utm_medium=sponsors&utm_id=pioneers" target="_blank" title="Take code reviews from hours to minutes"><img src="https://fastapi.tiangolo.com/img/sponsors/codacy.png"></a>
|
||||
<a href="https://www.stainlessapi.com/?utm_source=fastapi&utm_medium=referral" target="_blank" title="Stainless | Generate best-in-class SDKs"><img src="https://fastapi.tiangolo.com/img/sponsors/stainless.png"></a>
|
||||
<a href="https://www.permit.io/blog/implement-authorization-in-fastapi?utm_source=github&utm_medium=referral&utm_campaign=fastapi" target="_blank" title="Fine-Grained Authorization for FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/permit.png"></a>
|
||||
<a href="https://www.interviewpal.com/?utm_source=fastapi&utm_medium=open-source&utm_campaign=dev-hiring" target="_blank" title="InterviewPal - AI Interview Coach for Engineers and Devs"><img src="https://fastapi.tiangolo.com/img/sponsors/interviewpal.png"></a>
|
||||
<a href="https://dribia.com/en/" target="_blank" title="Dribia - Data Science within your reach"><img src="https://fastapi.tiangolo.com/img/sponsors/dribia.png"></a>
|
||||
|
||||
<!-- /sponsors -->
|
||||
|
||||
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
|
||||
|
||||
## Opinions
|
||||
## Opinions { #opinions }
|
||||
|
||||
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
|
||||
|
||||
@@ -90,7 +89,7 @@ The key features are:
|
||||
|
||||
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
@@ -104,7 +103,7 @@ The key features are:
|
||||
|
||||
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
@@ -114,7 +113,7 @@ The key features are:
|
||||
|
||||
---
|
||||
|
||||
## **Typer**, the FastAPI of CLIs
|
||||
## **Typer**, the FastAPI of CLIs { #typer-the-fastapi-of-clis }
|
||||
|
||||
<a href="https://typer.tiangolo.com" target="_blank"><img src="https://typer.tiangolo.com/img/logo-margin/logo-margin-vector.svg" style="width: 20%;"></a>
|
||||
|
||||
@@ -122,14 +121,14 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
|
||||
|
||||
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
|
||||
|
||||
## Requirements
|
||||
## Requirements { #requirements }
|
||||
|
||||
FastAPI stands on the shoulders of giants:
|
||||
|
||||
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> for the web parts.
|
||||
* <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> for the data parts.
|
||||
|
||||
## Installation
|
||||
## Installation { #installation }
|
||||
|
||||
Create and activate a <a href="https://fastapi.tiangolo.com/virtual-environments/" class="external-link" target="_blank">virtual environment</a> and then install FastAPI:
|
||||
|
||||
@@ -145,11 +144,11 @@ $ pip install "fastapi[standard]"
|
||||
|
||||
**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals.
|
||||
|
||||
## Example
|
||||
## Example { #example }
|
||||
|
||||
### Create it
|
||||
### Create it { #create-it }
|
||||
|
||||
* Create a file `main.py` with:
|
||||
Create a file `main.py` with:
|
||||
|
||||
```Python
|
||||
from typing import Union
|
||||
@@ -198,7 +197,7 @@ If you don't know, check the _"In a hurry?"_ section about <a href="https://fast
|
||||
|
||||
</details>
|
||||
|
||||
### Run it
|
||||
### Run it { #run-it }
|
||||
|
||||
Run the server with:
|
||||
|
||||
@@ -240,7 +239,7 @@ You can read more about it in the <a href="https://fastapi.tiangolo.com/fastapi-
|
||||
|
||||
</details>
|
||||
|
||||
### Check it
|
||||
### Check it { #check-it }
|
||||
|
||||
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
|
||||
|
||||
@@ -257,7 +256,7 @@ You already created an API that:
|
||||
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
|
||||
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
|
||||
|
||||
### Interactive API docs
|
||||
### Interactive API docs { #interactive-api-docs }
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
@@ -265,7 +264,7 @@ You will see the automatic interactive API documentation (provided by <a href="h
|
||||
|
||||

|
||||
|
||||
### Alternative API docs
|
||||
### Alternative API docs { #alternative-api-docs }
|
||||
|
||||
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
@@ -273,7 +272,7 @@ You will see the alternative automatic documentation (provided by <a href="https
|
||||
|
||||

|
||||
|
||||
## Example upgrade
|
||||
## Example upgrade { #example-upgrade }
|
||||
|
||||
Now modify the file `main.py` to receive a body from a `PUT` request.
|
||||
|
||||
@@ -311,7 +310,7 @@ def update_item(item_id: int, item: Item):
|
||||
|
||||
The `fastapi dev` server should reload automatically.
|
||||
|
||||
### Interactive API docs upgrade
|
||||
### Interactive API docs upgrade { #interactive-api-docs-upgrade }
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
@@ -327,7 +326,7 @@ Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_bl
|
||||
|
||||

|
||||
|
||||
### Alternative API docs upgrade
|
||||
### Alternative API docs upgrade { #alternative-api-docs-upgrade }
|
||||
|
||||
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
@@ -335,7 +334,7 @@ And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" targe
|
||||
|
||||

|
||||
|
||||
### Recap
|
||||
### Recap { #recap }
|
||||
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
|
||||
@@ -447,19 +446,19 @@ For a more complete example including more features, see the <a href="https://fa
|
||||
* **Cookie Sessions**
|
||||
* ...and more.
|
||||
|
||||
## Performance
|
||||
## Performance { #performance }
|
||||
|
||||
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
|
||||
|
||||
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
|
||||
|
||||
## Dependencies
|
||||
## Dependencies { #dependencies }
|
||||
|
||||
FastAPI depends on Pydantic and Starlette.
|
||||
|
||||
### `standard` Dependencies
|
||||
### `standard` Dependencies { #standard-dependencies }
|
||||
|
||||
When you install FastAPI with `pip install "fastapi[standard]"` it comes the `standard` group of optional dependencies:
|
||||
When you install FastAPI with `pip install "fastapi[standard]"` it comes with the `standard` group of optional dependencies:
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
@@ -471,16 +470,21 @@ Used by Starlette:
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
|
||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, with `request.form()`.
|
||||
|
||||
Used by FastAPI / Starlette:
|
||||
Used by FastAPI:
|
||||
|
||||
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application. This includes `uvicorn[standard]`, which includes some dependencies (e.g. `uvloop`) needed for high performance serving.
|
||||
* `fastapi-cli` - to provide the `fastapi` command.
|
||||
* `fastapi-cli[standard]` - to provide the `fastapi` command.
|
||||
* This includes `fastapi-cloud-cli`, which allows you to deploy your FastAPI application to <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>.
|
||||
|
||||
### Without `standard` Dependencies
|
||||
### Without `standard` Dependencies { #without-standard-dependencies }
|
||||
|
||||
If you don't want to include the `standard` optional dependencies, you can install with `pip install fastapi` instead of `pip install "fastapi[standard]"`.
|
||||
|
||||
### Additional Optional Dependencies
|
||||
### Without `fastapi-cloud-cli` { #without-fastapi-cloud-cli }
|
||||
|
||||
If you want to install FastAPI with the standard dependencies but without the `fastapi-cloud-cli`, you can install with `pip install "fastapi[standard-no-fastapi-cloud-cli]"`.
|
||||
|
||||
### Additional Optional Dependencies { #additional-optional-dependencies }
|
||||
|
||||
There are some additional dependencies you might want to install.
|
||||
|
||||
@@ -494,6 +498,6 @@ Additional optional FastAPI dependencies:
|
||||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
|
||||
|
||||
## License
|
||||
## License { #license }
|
||||
|
||||
This project is licensed under the terms of the MIT license.
|
||||
|
||||
@@ -16,7 +16,7 @@ You can learn more about [FastAPI versions and how to pin and upgrade them](http
|
||||
|
||||
If you think you found a vulnerability, and even if you are not sure about it, please report it right away by sending an email to: security@tiangolo.com. Please try to be as explicit as possible, describing all the steps and example code to reproduce the security issue.
|
||||
|
||||
I (the author, [@tiangolo](https://twitter.com/tiangolo)) will review it thoroughly and get back to you.
|
||||
I (the author, [@tiangolo](https://x.com/tiangolo)) will review it thoroughly and get back to you.
|
||||
|
||||
## Public Discussions
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
||||
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
|
||||
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
|
||||
</a>
|
||||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
|
||||
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Əhatə">
|
||||
@@ -81,7 +81,7 @@ FastAPI Python ilə API yaratmaq üçün standart Python <abbr title="Tip Məsl
|
||||
|
||||
"_**FastAPI** üçün həyəcanlıyam. Çox əyləncəlidir!_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
@@ -95,7 +95,7 @@ FastAPI Python ilə API yaratmaq üçün standart Python <abbr title="Tip Məsl
|
||||
|
||||
"_**API** xidmətlərimizi **FastAPI**-a köçürdük [...] Sizin də bəyənəcəyinizi düşünürük._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
3
docs/bn/docs/about/index.md
Normal file
3
docs/bn/docs/about/index.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# সম্পর্কে
|
||||
|
||||
**FastAPI** সম্পর্কে বিস্তারিত — এর ডিজাইন, অনুপ্রেরণা ও আরও অনেক কিছু। 🤓
|
||||
298
docs/bn/docs/environment-variables.md
Normal file
298
docs/bn/docs/environment-variables.md
Normal file
@@ -0,0 +1,298 @@
|
||||
# এনভায়রনমেন্ট ভেরিয়েবলস
|
||||
|
||||
/// tip
|
||||
|
||||
আপনি যদি "এনভায়রনমেন্ট ভেরিয়েবলস" কী এবং সেগুলো কীভাবে ব্যবহার করতে হয় সেটা জানেন, তাহলে এই অংশটি স্কিপ করে যেতে পারেন।
|
||||
|
||||
///
|
||||
|
||||
এনভায়রনমেন্ট ভেরিয়েবল (সংক্ষেপে "**env var**" নামেও পরিচিত) হলো এমন একটি ভেরিয়েবল যা পাইথন কোডের **বাইরে**, **অপারেটিং সিস্টেমে** থাকে এবং আপনার পাইথন কোড (বা অন্যান্য প্রোগ্রাম) দ্বারা যাকে রিড করা যায়।
|
||||
|
||||
এনভায়রনমেন্ট ভেরিয়েবলস অ্যাপ্লিকেশনের **সেটিংস** পরিচালনা করতে, পাইথনের **ইনস্টলেশন** প্রক্রিয়ার অংশ হিসেবে, ইত্যাদি কাজে উপযোগী হতে পারে।
|
||||
|
||||
## Env Vars তৈরী এবং ব্যবহার
|
||||
|
||||
আপনি **শেল (টার্মিনাল)**-এ, পাইথনের প্রয়োজন ছাড়াই, এনভায়রনমেন্ট ভেরিয়েবলস **তৈরি** এবং ব্যবহার করতে পারবেনঃ
|
||||
|
||||
//// tab | লিনাক্স, ম্যাকওএস, উইন্ডোজ Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// আপনি চাইলে MY_NAME নামে একটি env var তৈরি করতে পারেন
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// তারপরে এটিকে চাইলে অন্যান্য প্রোগ্রামে ব্যবহার করতে পারেন
|
||||
$ echo "Hello $MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | উইন্ডোজ পাওয়ারশেল
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// MY_NAME নামে env var তৈরি
|
||||
$ $Env:MY_NAME = "Wade Wilson"
|
||||
|
||||
// অন্যান্য প্রোগ্রামে এটিকে ব্যবহার
|
||||
$ echo "Hello $Env:MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
## পাইথনে env vars রিড করা
|
||||
|
||||
আপনি চাইলে পাইথনের **বাইরে**, টার্মিনালে (বা অন্য কোনো উপায়ে) এনভায়রনমেন্ট ভেরিয়েবলস তৈরি করতে পারেন, এবং পরে সেগুলো **পাইথনে রিড** (অ্যাক্সেস করতে) পারেন।
|
||||
|
||||
উদাহরণস্বরূপ, আপনার `main.py` নামে একটি ফাইল থাকতে পারেঃ
|
||||
|
||||
```Python hl_lines="3"
|
||||
import os
|
||||
|
||||
name = os.getenv("MY_NAME", "World")
|
||||
print(f"Hello {name} from Python")
|
||||
```
|
||||
|
||||
/// tip
|
||||
|
||||
<a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> এর দ্বিতীয় আর্গুমেন্টটি হলো এর ডিফল্ট ভ্যালু যা রিটার্ন করা হবে।
|
||||
|
||||
যদি এটি দেওয়া না হয়, ডিফল্টভাবে `None` ব্যবহৃত হবে, এখানে আমরা ডিফল্ট ভ্যালু হিসেবে `"World"` ব্যবহার করেছি।
|
||||
|
||||
///
|
||||
|
||||
তারপরে পাইথন প্রোগ্রামটিকে নিম্নোক্তভাবে কল করা যাবেঃ
|
||||
|
||||
//// tab | লিনাক্স, ম্যাকওএস, উইন্ডোজ Bash
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// এখনো আমরা এনভায়রনমেন্ট ভেরিয়েবল সেট করিনি
|
||||
$ python main.py
|
||||
|
||||
// যেহেতু env var সেট করা হয়নি, তাই আমরা ডিফল্ট ভ্যালু পাচ্ছি
|
||||
|
||||
Hello World from Python
|
||||
|
||||
// কিন্তু আমরা প্রথমে যদি একটা এনভায়রনমেন্ট ভারিয়েবল তৈরি করে নেই
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// এবং তারপর আবার প্রোগ্রাটিকে কল করি
|
||||
$ python main.py
|
||||
|
||||
// এখন এটি এনভায়রনমেন্ট ভেরিয়েবল রিড করতে পারবে
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | উইন্ডোজ পাওয়ারশেল
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// এখনো আমরা এনভায়রনমেন্ট ভেরিয়েবল সেট করিনি
|
||||
$ python main.py
|
||||
|
||||
// যেহেতু env var সেট করা হয়নি, তাই আমরা ডিফল্ট ভ্যালু পাচ্ছি
|
||||
|
||||
Hello World from Python
|
||||
|
||||
// কিন্তু আমরা প্রথমে যদি একটা এনভায়রনমেন্ট ভারিয়েবল তৈরি করে নেই
|
||||
$ $Env:MY_NAME = "Wade Wilson"
|
||||
|
||||
// এবং তারপর আবার প্রোগ্রাটিকে কল করি
|
||||
$ python main.py
|
||||
|
||||
// এখন এটি এনভায়রনমেন্ট ভেরিয়েবল রিড করতে পারবে
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
যেহেতু এনভায়রনমেন্ট ভেরিয়েবলস কোডের বাইরে সেট করা যায়, কিন্তু পরবর্তীতে কোড দ্বারা রিড করা যায়, এবং বাকি ফাইলগুলোর সাথে রাখতে (`git` এ কমিট) হয় না, তাই কনফিগারেশনস বা **সেটিংস** এর জন্য এগুলো সাধারণত ব্যবহৃত হয়ে থাকে।
|
||||
|
||||
আপনি একটি এনভায়রনমেন্ট ভেরিয়েবল শুধুমাত্র একটি **নির্দিষ্ট প্রোগ্রাম ইনভোকেশনের** জন্যও তৈরি করতে পারেন, যা শুধুমাত্র সেই প্রোগ্রামের জন্যই এভেইলেবল থাকবে এবং শুধুমাত্র তার চলাকালীন সময় পর্যন্তই সক্রিয় থাকবে।
|
||||
|
||||
এটি করতে, প্রোগ্রামটি রান করার ঠিক আগেই, একই লাইনে এনভায়রনমেন্ট ভেরিয়েবল তৈরি করুন:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// প্রোগ্রামটি কল করার সময় একই লাইনে MY_NAME এনভায়রনমেন্ট ভেরিয়েবল তৈরি করুন
|
||||
$ MY_NAME="Wade Wilson" python main.py
|
||||
|
||||
// এখন এটি এনভায়রনমেন্ট ভ্যরিয়েবলটিকে রিড করতে পারবে
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
|
||||
// পরবর্তীতে এনভায়রনমেন্ট ভেরিয়েবলটিকে আর ব্যবহার করা যাচ্ছে না
|
||||
$ python main.py
|
||||
|
||||
Hello World from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
/// tip
|
||||
|
||||
এটি নিয়ে আরো বিস্তারিত পড়তে পারেন এখানে <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a>।
|
||||
|
||||
///
|
||||
|
||||
## টাইপস এবং ভ্যালিডেশন
|
||||
|
||||
এই এনভায়রনমেন্ট ভেরিয়েবলগুলো শুধুমাত্র **টেক্সট স্ট্রিংস** হ্যান্ডেল করতে পারে, যেহেতু এগুলো পাইথনের বাইরে অবস্থিত এবং অন্যান্য প্রোগ্রাম এবং সিস্টেমের বাকি অংশের (এমনকি বিভিন্ন অপারেটিং সিস্টেম যেমন লিনাক্স, উইন্ডোজ, ম্যাকওএস) সাথে সামঞ্জস্যপূর্ণ হতে হয়।
|
||||
|
||||
এর অর্থ হচ্ছে পাইথনে এনভায়রনমেন্ট ভেরিয়েবল থেকে রিড করা **যেকোনো ভ্যালু** একটি `str` হবে, এবং অন্য কোনো টাইপে কনভার্সন বা যেকোনো ভেলিডেশন কোডে আলাদাভাবে করতে হবে।
|
||||
|
||||
এনভায়রনমেন্ট ভেরিয়েবল ব্যবহার করে **এপ্লিকেশন সেটিংস** হ্যান্ডেল করা নিয়ে আরো বিস্তারিত জানা যাবে [Advanced User Guide - Settings and Environment Variables](./advanced/settings.md){.internal-link target=_blank}.
|
||||
|
||||
## `PATH` এনভায়রনমেন্ট ভেরিয়েবল
|
||||
|
||||
**`PATH`** নামে একটি **বিশেষ** এনভায়রনমেন্ট ভেরিয়েবল রয়েছে, যেটি প্রোগ্রাম রান করার জন্য অপারেটিং সিস্টেমস (লিনাক্স, ম্যাকওএস, উইন্ডোজ) দ্বারা ব্যবহৃত হয়।
|
||||
|
||||
`PATH` ভেরিয়েবল এর ভ্যালু হচ্ছে একটি বিশাল স্ট্রিং যা ডিরেক্টরিকে কোলন `:` দিয়ে আলাদা করার মাধ্যমে লিনাক্সে ও ম্যাকওএস এ, এবং সেমিকোলন `;` এর মাধ্যমে উইন্ডোজ এ তৈরি করা থাকে।
|
||||
|
||||
উদাহরণস্বরূপ, `PATH` ভেরিয়েবল নিচের মতো দেখতে হতে পারেঃ
|
||||
|
||||
//// tab | লিনাক্স, ম্যাকওএস
|
||||
|
||||
```plaintext
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
তারমানে হলো সিস্টেম প্রোগ্রামগুলোকে নিচের ডিরেক্টরিগুলোতে খুঁজবেঃ
|
||||
|
||||
* `/usr/local/bin`
|
||||
* `/usr/bin`
|
||||
* `/bin`
|
||||
* `/usr/sbin`
|
||||
* `/sbin`
|
||||
|
||||
////
|
||||
|
||||
//// tab | উইন্ডোজ
|
||||
|
||||
```plaintext
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32
|
||||
```
|
||||
|
||||
তারমানে হলো সিস্টেম প্রোগ্রামগুলোকে নিচের ডিরেক্টরিগুলোতে খুঁজবেঃ
|
||||
|
||||
* `C:\Program Files\Python312\Scripts`
|
||||
* `C:\Program Files\Python312`
|
||||
* `C:\Windows\System32`
|
||||
|
||||
////
|
||||
|
||||
যখন আপনি টার্মিনালে কোনো **কমান্ড** লিখবেন, অপারেটিং সিস্টেম **প্রত্যেকটি ডিরেক্টরিতে** প্রোগ্রামটি **খুঁজবে** যেগুলো `PATH` এনভায়রনমেন্ট ভেরিয়েবল এ লিস্ট করা আছে।
|
||||
|
||||
উদাহরণস্বরূপ, যখন আপনি টার্মিনালে `python` টাইপ করবেন, অপারেটিং সিস্টেম এই লিস্ট এর **প্রথম ডিরেক্টরিতে** `python` নামের একটি প্রোগ্রাম খুঁজবে।
|
||||
|
||||
যদি এটি খুঁজে পায়, তাহলে এটি প্রোগ্রামটিকে ব্যবহার করবে। অন্যথায় এটি **অন্যান্য ডিরেক্টরিগুলোতে** এটিকে খুঁজতে থাকবে।
|
||||
|
||||
### পাইথন ইনস্টল এবং `PATH` আপডেট
|
||||
|
||||
যখন আপনি পাইথন ইনস্টল করেন, আপনি `PATH` এনভায়রনমেন্ট ভেরিয়েবল আপডেট করতে চান কিনা সেটা জিজ্ঞেস করা হতে পারে।
|
||||
|
||||
//// tab | লিনাক্স, ম্যাকওএস
|
||||
|
||||
ধরা যাক আপনি পাইথন ইনস্টল করলেন এবং এটি `/opt/custompython/bin` ডিরেক্টরিতে ইনস্টল হচ্ছে।
|
||||
|
||||
যদি আপনি "Yes" সিলেক্ট করে `PATH` এনভায়রনমেন্ট ভেরিয়েবল আপডেট করতে চান, তাহলে ইনস্টলার `/opt/custompython/bin` কে `PATH` এনভায়রনমেন্ট ভেরিয়েবল এ এড করে দিবে।
|
||||
|
||||
এটা দেখতে এমনটা হতে পারেঃ
|
||||
|
||||
```plaintext
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin
|
||||
```
|
||||
|
||||
এইভাবে, আপনি যখন টার্মিনালে `python` টাইপ করেন, সিস্টেম পাইথন প্রোগ্রামটিকে `/opt/custompython/bin` (সর্বশেষ ডিরেক্টরি) তে খুঁজে পাবে এবং এটাকে ব্যবহার করবে।
|
||||
|
||||
////
|
||||
|
||||
//// tab | উইন্ডোজ
|
||||
|
||||
ধরা যাক আপনি পাইথন ইনস্টল করলেন এবং এটি `C:\opt\custompython\bin` ডিরেক্টরিতে ইনস্টল হচ্ছে।
|
||||
|
||||
যদি আপনি "Yes" সিলেক্ট করে `PATH` এনভায়রনমেন্ট ভেরিয়েবল আপডেট করতে চান, তাহলে ইনস্টলার `C:\opt\custompython\bin` কে `PATH` এনভায়রনমেন্ট ভেরিয়েবল এ এড করে দিবে।
|
||||
|
||||
```plaintext
|
||||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin
|
||||
```
|
||||
|
||||
এইভাবে, আপনি যখন টার্মিনালে `python` টাইপ করেন, সিস্টেম পাইথন প্রোগ্রামটিকে `C:\opt\custompython\bin` (সর্বশেষ ডিরেক্টরি) তে খুঁজে পাবে এবং এটাকে ব্যবহার করবে।
|
||||
|
||||
////
|
||||
|
||||
তাই, আপনি যদি টাইপ করেনঃ
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
//// tab | লিনাক্স, ম্যাকওএস
|
||||
|
||||
সিস্টেম `python` প্রোগ্রামকে `/opt/custompython/bin` এ **খুঁজে পাবে** এবং এটাকে রান করবে।
|
||||
|
||||
এটা মোটামুটিভাবে নিচের মতো করে লেখার সমান হবেঃ
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ /opt/custompython/bin/python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
//// tab | উইন্ডোজ
|
||||
|
||||
সিস্টেম `python` প্রোগ্রামকে `C:\opt\custompython\bin\python` এ **খুঁজে পাবে** এবং এটাকে রান করবে।
|
||||
|
||||
এটা মোটামুটিভাবে নিচের মতো করে লেখার সমান হবেঃ
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ C:\opt\custompython\bin\python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
////
|
||||
|
||||
এই তথ্যগুলো [ভার্চুয়াল এনভায়রনমেন্টস](virtual-environments.md){.internal-link target=_blank} শেখার ক্ষেত্রে সহায়ক হবে।
|
||||
|
||||
## উপসংহার
|
||||
|
||||
এর মাধ্যমে আপনি **এনভায়রনমেন্ট ভেরিয়েবলস** কি এবং এটিকে পাইথনে কিভাবে ব্যবহার করতে হয় তার সম্পর্কে বেসিক ধারনা পেলেন।
|
||||
|
||||
চাইলে এই সম্পর্কে আরো বিস্তারিত পড়তে পারেন <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia for Environment Variable</a> এ।
|
||||
|
||||
অনেক ক্ষেত্রে, দেখা মাত্রই এনভায়রনমেন্ট ভেরিয়েবল কীভাবে প্রয়োজন হবে তা স্পষ্ট হয় না। কিন্তু ডেভেলপমেন্টের সময় আপনি নানা রকম পরিস্থিতিতে এগুলোর সম্মুখীন হবেন, তাই এগুলো সম্পর্কে জেনে রাখা ভালো।
|
||||
|
||||
উদাহরণস্বরূপ, আপনার এই ইনফরমেশনটি পরবর্তী, [ভার্চুয়াল এনভায়রনমেন্টস](virtual-environments.md) অংশে দরকার হবে।
|
||||
@@ -5,15 +5,18 @@
|
||||
<em>FastAPI উচ্চক্ষমতা সম্পন্ন, সহজে শেখার এবং দ্রুত কোড করে প্রোডাকশনের জন্য ফ্রামওয়ার্ক।</em>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest" target="_blank">
|
||||
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg" alt="Test">
|
||||
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
||||
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/fastapi/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/codecov/c/github/fastapi/fastapi?color=%2334D058" alt="Coverage">
|
||||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
|
||||
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Supported Python versions">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
@@ -79,7 +82,7 @@ FastAPI একটি আধুনিক, দ্রুত ( বেশি ক্
|
||||
|
||||
"_আমি **FastAPI** নিয়ে চাঁদের সমান উৎসাহিত। এটি খুবই মজার!_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">ব্রায়ান ওকেন - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">পাইথন বাইটস</a> পডকাস্ট হোস্ট</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">ব্রায়ান ওকেন - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">পাইথন বাইটস</a> পডকাস্ট হোস্ট</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
@@ -93,7 +96,7 @@ FastAPI একটি আধুনিক, দ্রুত ( বেশি ক্
|
||||
|
||||
"_আমরা আমাদের **APIs** [...] এর জন্য **FastAPI**- তে এসেছি [...] আমি মনে করি আপনিও এটি পছন্দ করবেন [...]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">ইনেস মন্টানি - ম্যাথিউ হোনিবাল - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> প্রতিষ্ঠাতা - <a href="https://spacy.io" target="_blank">spaCy</a> স্রষ্টা</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">ইনেস মন্টানি - ম্যাথিউ হোনিবাল - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> প্রতিষ্ঠাতা - <a href="https://spacy.io" target="_blank">spaCy</a> স্রষ্টা</strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -22,9 +22,8 @@ Python-এ ঐচ্ছিক "টাইপ হিন্ট" (যা "টাই
|
||||
|
||||
চলুন একটি সাধারণ উদাহরণ দিয়ে শুরু করি:
|
||||
|
||||
```Python
|
||||
{!../../docs_src/python_types/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/python_types/tutorial001.py *}
|
||||
|
||||
|
||||
এই প্রোগ্রামটি কল করলে আউটপুট হয়:
|
||||
|
||||
@@ -38,9 +37,8 @@ John Doe
|
||||
* প্রতিটির প্রথম অক্ষরকে `title()` ব্যবহার করে বড় হাতের অক্ষরে রূপান্তর করে।
|
||||
* তাদেরকে মাঝখানে একটি স্পেস দিয়ে <abbr title="একটার পরে একটা একত্রিত করা">concatenate</abbr> করে।
|
||||
|
||||
```Python hl_lines="2"
|
||||
{!../../docs_src/python_types/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/python_types/tutorial001.py hl[2] *}
|
||||
|
||||
|
||||
### এটি সম্পাদনা করুন
|
||||
|
||||
@@ -82,9 +80,8 @@ John Doe
|
||||
|
||||
এগুলিই "টাইপ হিন্ট":
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../docs_src/python_types/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/python_types/tutorial002.py hl[1] *}
|
||||
|
||||
|
||||
এটি ডিফল্ট ভ্যালু ঘোষণা করার মত নয় যেমন:
|
||||
|
||||
@@ -112,9 +109,8 @@ John Doe
|
||||
|
||||
এই ফাংশনটি দেখুন, এটিতে ইতিমধ্যে টাইপ হিন্ট রয়েছে:
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../docs_src/python_types/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/python_types/tutorial003.py hl[1] *}
|
||||
|
||||
|
||||
এডিটর ভেরিয়েবলগুলির টাইপ জানার কারণে, আপনি শুধুমাত্র অটোকমপ্লিশনই পান না, আপনি এরর চেকও পান:
|
||||
|
||||
@@ -122,9 +118,8 @@ John Doe
|
||||
|
||||
এখন আপনি জানেন যে আপনাকে এটি ঠিক করতে হবে, `age`-কে একটি স্ট্রিং হিসেবে রূপান্তর করতে `str(age)` ব্যবহার করতে হবে:
|
||||
|
||||
```Python hl_lines="2"
|
||||
{!../../docs_src/python_types/tutorial004.py!}
|
||||
```
|
||||
{* ../../docs_src/python_types/tutorial004.py hl[2] *}
|
||||
|
||||
|
||||
## টাইপ ঘোষণা
|
||||
|
||||
@@ -143,9 +138,8 @@ John Doe
|
||||
* `bool`
|
||||
* `bytes`
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../docs_src/python_types/tutorial005.py!}
|
||||
```
|
||||
{* ../../docs_src/python_types/tutorial005.py hl[1] *}
|
||||
|
||||
|
||||
### টাইপ প্যারামিটার সহ জেনেরিক টাইপ
|
||||
|
||||
@@ -369,9 +363,8 @@ Python 3.6 এবং তার উপরের সংস্করণগুলি
|
||||
|
||||
একটি উদাহরণ হিসেবে, এই ফাংশনটি নিন:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../docs_src/python_types/tutorial009c.py!}
|
||||
```
|
||||
{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
|
||||
|
||||
|
||||
`name` প্যারামিটারটি `Optional[str]` হিসেবে সংজ্ঞায়িত হয়েছে, কিন্তু এটি **অপশনাল নয়**, আপনি প্যারামিটার ছাড়া ফাংশনটি কল করতে পারবেন না:
|
||||
|
||||
@@ -387,9 +380,8 @@ say_hi(name=None) # এটি কাজ করে, None বৈধ 🎉
|
||||
|
||||
সুখবর হল, একবার আপনি Python 3.10 ব্যবহার করা শুরু করলে, আপনাকে এগুলোর ব্যাপারে আর চিন্তা করতে হবে না, যেহুতু আপনি | ব্যবহার করেই ইউনিয়ন ঘোষণা করতে পারবেন:
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../docs_src/python_types/tutorial009c_py310.py!}
|
||||
```
|
||||
{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
|
||||
|
||||
|
||||
এবং তারপর আপনাকে নামগুলি যেমন `Optional` এবং `Union` নিয়ে আর চিন্তা করতে হবে না। 😎
|
||||
|
||||
@@ -451,15 +443,13 @@ Python 3.10-এ, `Union` এবং `Optional` জেনেরিকস ব্য
|
||||
|
||||
ধরুন আপনার কাছে `Person` নামে একটি ক্লাস আছে, যার একটি নাম আছে:
|
||||
|
||||
```Python hl_lines="1-3"
|
||||
{!../../docs_src/python_types/tutorial010.py!}
|
||||
```
|
||||
{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
|
||||
|
||||
|
||||
তারপর আপনি একটি ভেরিয়েবলকে `Person` টাইপের হিসেবে ঘোষণা করতে পারেন:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../docs_src/python_types/tutorial010.py!}
|
||||
```
|
||||
{* ../../docs_src/python_types/tutorial010.py hl[6] *}
|
||||
|
||||
|
||||
এবং তারপর, আবার, আপনি এডিটর সাপোর্ট পেয়ে যাবেন:
|
||||
|
||||
|
||||
@@ -14,57 +14,7 @@ Sie möchten aber auch, dass sie neue Artikel akzeptiert. Und wenn die Elemente
|
||||
|
||||
Um dies zu erreichen, importieren Sie `JSONResponse`, und geben Sie Ihren Inhalt direkt zurück, indem Sie den gewünschten `status_code` setzen:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="4 25"
|
||||
{!> ../../docs_src/additional_status_codes/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="4 25"
|
||||
{!> ../../docs_src/additional_status_codes/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="4 26"
|
||||
{!> ../../docs_src/additional_status_codes/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="2 23"
|
||||
{!> ../../docs_src/additional_status_codes/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="4 25"
|
||||
{!> ../../docs_src/additional_status_codes/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/additional_status_codes/tutorial001_an_py310.py hl[4,25] *}
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
|
||||
@@ -18,35 +18,7 @@ Nicht die Klasse selbst (die bereits aufrufbar ist), sondern eine Instanz dieser
|
||||
|
||||
Dazu deklarieren wir eine Methode `__call__`:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
|
||||
|
||||
In diesem Fall ist dieses `__call__` das, was **FastAPI** verwendet, um nach zusätzlichen Parametern und Unterabhängigkeiten zu suchen, und das ist es auch, was später aufgerufen wird, um einen Wert an den Parameter in Ihrer *Pfadoperation-Funktion* zu übergeben.
|
||||
|
||||
@@ -54,35 +26,7 @@ In diesem Fall ist dieses `__call__` das, was **FastAPI** verwendet, um nach zus
|
||||
|
||||
Und jetzt können wir `__init__` verwenden, um die Parameter der Instanz zu deklarieren, die wir zum `Parametrisieren` der Abhängigkeit verwenden können:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
|
||||
|
||||
In diesem Fall wird **FastAPI** `__init__` nie berühren oder sich darum kümmern, wir werden es direkt in unserem Code verwenden.
|
||||
|
||||
@@ -90,35 +34,7 @@ In diesem Fall wird **FastAPI** `__init__` nie berühren oder sich darum kümmer
|
||||
|
||||
Wir könnten eine Instanz dieser Klasse erstellen mit:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
|
||||
|
||||
Und auf diese Weise können wir unsere Abhängigkeit „parametrisieren“, die jetzt `"bar"` enthält, als das Attribut `checker.fixed_content`.
|
||||
|
||||
@@ -134,35 +50,7 @@ checker(q="somequery")
|
||||
|
||||
... und übergibt, was immer das als Wert dieser Abhängigkeit in unserer *Pfadoperation-Funktion* zurückgibt, als den Parameter `fixed_content_included`:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../docs_src/dependencies/tutorial011_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -32,15 +32,11 @@ Betrachten wir als einfaches Beispiel eine Dateistruktur ähnlich der in [Größ
|
||||
|
||||
Die Datei `main.py` hätte als Inhalt:
|
||||
|
||||
```Python
|
||||
{!../../docs_src/async_tests/main.py!}
|
||||
```
|
||||
{* ../../docs_src/async_tests/main.py *}
|
||||
|
||||
Die Datei `test_main.py` hätte die Tests für `main.py`, das könnte jetzt so aussehen:
|
||||
|
||||
```Python
|
||||
{!../../docs_src/async_tests/test_main.py!}
|
||||
```
|
||||
{* ../../docs_src/async_tests/test_main.py *}
|
||||
|
||||
## Es ausführen
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@ In diesem Fall würde der ursprüngliche Pfad `/app` tatsächlich unter `/api/v1
|
||||
|
||||
Auch wenn Ihr gesamter Code unter der Annahme geschrieben ist, dass es nur `/app` gibt.
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../docs_src/behind_a_proxy/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *}
|
||||
|
||||
Und der Proxy würde das **Pfadpräfix** on-the-fly **"entfernen**", bevor er die Anfrage an Uvicorn übermittelt, dafür sorgend, dass Ihre Anwendung davon überzeugt ist, dass sie unter `/app` bereitgestellt wird, sodass Sie nicht Ihren gesamten Code dahingehend aktualisieren müssen, das Präfix `/api/v1` zu verwenden.
|
||||
|
||||
@@ -98,9 +96,7 @@ Sie können den aktuellen `root_path` abrufen, der von Ihrer Anwendung für jede
|
||||
|
||||
Hier fügen wir ihn, nur zu Demonstrationszwecken, in die Nachricht ein.
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!../../docs_src/behind_a_proxy/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *}
|
||||
|
||||
Wenn Sie Uvicorn dann starten mit:
|
||||
|
||||
@@ -127,9 +123,7 @@ wäre die Response etwa:
|
||||
|
||||
Falls Sie keine Möglichkeit haben, eine Kommandozeilenoption wie `--root-path` oder ähnlich zu übergeben, können Sie als Alternative beim Erstellen Ihrer FastAPI-Anwendung den Parameter `root_path` setzen:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../docs_src/behind_a_proxy/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *}
|
||||
|
||||
Die Übergabe des `root_path` an `FastAPI` wäre das Äquivalent zur Übergabe der `--root-path`-Kommandozeilenoption an Uvicorn oder Hypercorn.
|
||||
|
||||
@@ -309,9 +303,7 @@ Wenn Sie eine benutzerdefinierte Liste von Servern (`servers`) übergeben und es
|
||||
|
||||
Zum Beispiel:
|
||||
|
||||
```Python hl_lines="4-7"
|
||||
{!../../docs_src/behind_a_proxy/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *}
|
||||
|
||||
Erzeugt ein OpenAPI-Schema, wie:
|
||||
|
||||
@@ -358,9 +350,7 @@ Die Dokumentationsoberfläche interagiert mit dem von Ihnen ausgewählten Server
|
||||
|
||||
Wenn Sie nicht möchten, dass **FastAPI** einen automatischen Server inkludiert, welcher `root_path` verwendet, können Sie den Parameter `root_path_in_servers=False` verwenden:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../docs_src/behind_a_proxy/tutorial004.py!}
|
||||
```
|
||||
{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *}
|
||||
|
||||
Dann wird er nicht in das OpenAPI-Schema aufgenommen.
|
||||
|
||||
|
||||
@@ -30,9 +30,7 @@ Das liegt daran, dass FastAPI standardmäßig jedes enthaltene Element überprü
|
||||
|
||||
Wenn Sie jedoch sicher sind, dass der von Ihnen zurückgegebene Inhalt **mit JSON serialisierbar** ist, können Sie ihn direkt an die Response-Klasse übergeben und die zusätzliche Arbeit vermeiden, die FastAPI hätte, indem es Ihren zurückgegebenen Inhalt durch den `jsonable_encoder` leitet, bevor es ihn an die Response-Klasse übergibt.
|
||||
|
||||
```Python hl_lines="2 7"
|
||||
{!../../docs_src/custom_response/tutorial001b.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
|
||||
|
||||
/// info
|
||||
|
||||
@@ -57,9 +55,7 @@ Um eine Response mit HTML direkt von **FastAPI** zurückzugeben, verwenden Sie `
|
||||
* Importieren Sie `HTMLResponse`.
|
||||
* Übergeben Sie `HTMLResponse` als den Parameter `response_class` Ihres *Pfadoperation-Dekorators*.
|
||||
|
||||
```Python hl_lines="2 7"
|
||||
{!../../docs_src/custom_response/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
|
||||
|
||||
/// info
|
||||
|
||||
@@ -77,9 +73,7 @@ Wie in [Eine Response direkt zurückgeben](response-directly.md){.internal-link
|
||||
|
||||
Das gleiche Beispiel von oben, das eine `HTMLResponse` zurückgibt, könnte so aussehen:
|
||||
|
||||
```Python hl_lines="2 7 19"
|
||||
{!../../docs_src/custom_response/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
@@ -103,9 +97,7 @@ Die `response_class` wird dann nur zur Dokumentation der OpenAPI-Pfadoperation*
|
||||
|
||||
Es könnte zum Beispiel so etwas sein:
|
||||
|
||||
```Python hl_lines="7 21 23"
|
||||
{!../../docs_src/custom_response/tutorial004.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
|
||||
|
||||
In diesem Beispiel generiert die Funktion `generate_html_response()` bereits eine `Response` und gibt sie zurück, anstatt das HTML in einem `str` zurückzugeben.
|
||||
|
||||
@@ -144,9 +136,7 @@ Sie akzeptiert die folgenden Parameter:
|
||||
|
||||
FastAPI (eigentlich Starlette) fügt automatisch einen Content-Length-Header ein. Außerdem wird es einen Content-Type-Header einfügen, der auf dem media_type basiert, und für Texttypen einen Zeichensatz (charset) anfügen.
|
||||
|
||||
```Python hl_lines="1 18"
|
||||
{!../../docs_src/response_directly/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
|
||||
|
||||
### `HTMLResponse`
|
||||
|
||||
@@ -156,9 +146,7 @@ Nimmt Text oder Bytes entgegen und gibt eine HTML-Response zurück, wie Sie oben
|
||||
|
||||
Nimmt Text oder Bytes entgegen und gibt eine Plain-Text-Response zurück.
|
||||
|
||||
```Python hl_lines="2 7 9"
|
||||
{!../../docs_src/custom_response/tutorial005.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
|
||||
|
||||
### `JSONResponse`
|
||||
|
||||
@@ -180,9 +168,7 @@ Eine alternative JSON-Response mit <a href="https://github.com/ultrajson/ultrajs
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="2 7"
|
||||
{!../../docs_src/custom_response/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -196,18 +182,14 @@ Gibt eine HTTP-Weiterleitung (HTTP-Redirect) zurück. Verwendet standardmäßig
|
||||
|
||||
Sie können eine `RedirectResponse` direkt zurückgeben:
|
||||
|
||||
```Python hl_lines="2 9"
|
||||
{!../../docs_src/custom_response/tutorial006.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
|
||||
|
||||
---
|
||||
|
||||
Oder Sie können sie im Parameter `response_class` verwenden:
|
||||
|
||||
|
||||
```Python hl_lines="2 7 9"
|
||||
{!../../docs_src/custom_response/tutorial006b.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
|
||||
|
||||
Wenn Sie das tun, können Sie die URL direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
|
||||
|
||||
@@ -217,17 +199,13 @@ In diesem Fall ist der verwendete `status_code` der Standardcode für die `Redir
|
||||
|
||||
Sie können den Parameter `status_code` auch in Kombination mit dem Parameter `response_class` verwenden:
|
||||
|
||||
```Python hl_lines="2 7 9"
|
||||
{!../../docs_src/custom_response/tutorial006c.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
|
||||
|
||||
### `StreamingResponse`
|
||||
|
||||
Nimmt einen asynchronen Generator oder einen normalen Generator/Iterator und streamt den Responsebody.
|
||||
|
||||
```Python hl_lines="2 14"
|
||||
{!../../docs_src/custom_response/tutorial007.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
|
||||
|
||||
#### Verwendung von `StreamingResponse` mit dateiähnlichen Objekten
|
||||
|
||||
@@ -268,15 +246,11 @@ Nimmt zur Instanziierung einen anderen Satz von Argumenten entgegen als die ande
|
||||
|
||||
Datei-Responses enthalten die entsprechenden `Content-Length`-, `Last-Modified`- und `ETag`-Header.
|
||||
|
||||
```Python hl_lines="2 10"
|
||||
{!../../docs_src/custom_response/tutorial009.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
|
||||
|
||||
Sie können auch den Parameter `response_class` verwenden:
|
||||
|
||||
```Python hl_lines="2 8 10"
|
||||
{!../../docs_src/custom_response/tutorial009b.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
|
||||
|
||||
In diesem Fall können Sie den Dateipfad direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
|
||||
|
||||
@@ -290,9 +264,7 @@ Sie möchten etwa, dass Ihre Response eingerücktes und formatiertes JSON zurüc
|
||||
|
||||
Sie könnten eine `CustomORJSONResponse` erstellen. Das Wichtigste, was Sie tun müssen, ist, eine `Response.render(content)`-Methode zu erstellen, die den Inhalt als `bytes` zurückgibt:
|
||||
|
||||
```Python hl_lines="9-14 17"
|
||||
{!../../docs_src/custom_response/tutorial009c.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *}
|
||||
|
||||
Statt:
|
||||
|
||||
@@ -318,9 +290,7 @@ Der Parameter, der das definiert, ist `default_response_class`.
|
||||
|
||||
Im folgenden Beispiel verwendet **FastAPI** standardmäßig `ORJSONResponse` in allen *Pfadoperationen*, anstelle von `JSONResponse`.
|
||||
|
||||
```Python hl_lines="2 4"
|
||||
{!../../docs_src/custom_response/tutorial010.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -30,9 +30,7 @@ Beginnen wir mit einem Beispiel und sehen es uns dann im Detail an.
|
||||
|
||||
Wir erstellen eine asynchrone Funktion `lifespan()` mit `yield` wie folgt:
|
||||
|
||||
```Python hl_lines="16 19"
|
||||
{!../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/events/tutorial003.py hl[16,19] *}
|
||||
|
||||
Hier simulieren wir das langsame *Hochfahren*, das Laden des Modells, indem wir die (Fake-)Modellfunktion vor dem `yield` in das Dictionary mit Modellen für maschinelles Lernen einfügen. Dieser Code wird ausgeführt, **bevor** die Anwendung **beginnt, Requests entgegenzunehmen**, während des *Hochfahrens*.
|
||||
|
||||
@@ -50,9 +48,7 @@ Möglicherweise müssen Sie eine neue Version starten, oder Sie haben es einfach
|
||||
|
||||
Das Erste, was auffällt, ist, dass wir eine asynchrone Funktion mit `yield` definieren. Das ist sehr ähnlich zu Abhängigkeiten mit `yield`.
|
||||
|
||||
```Python hl_lines="14-19"
|
||||
{!../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/events/tutorial003.py hl[14:19] *}
|
||||
|
||||
Der erste Teil der Funktion, vor dem `yield`, wird ausgeführt **bevor** die Anwendung startet.
|
||||
|
||||
@@ -64,9 +60,7 @@ Wie Sie sehen, ist die Funktion mit einem `@asynccontextmanager` versehen.
|
||||
|
||||
Dadurch wird die Funktion in einen sogenannten „**asynchronen Kontextmanager**“ umgewandelt.
|
||||
|
||||
```Python hl_lines="1 13"
|
||||
{!../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/events/tutorial003.py hl[1,13] *}
|
||||
|
||||
Ein **Kontextmanager** in Python ist etwas, das Sie in einer `with`-Anweisung verwenden können, zum Beispiel kann `open()` als Kontextmanager verwendet werden:
|
||||
|
||||
@@ -88,9 +82,7 @@ In unserem obigen Codebeispiel verwenden wir ihn nicht direkt, sondern übergebe
|
||||
|
||||
Der Parameter `lifespan` der `FastAPI`-App benötigt einen **asynchronen Kontextmanager**, wir können ihm also unseren neuen asynchronen Kontextmanager `lifespan` übergeben.
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/events/tutorial003.py hl[22] *}
|
||||
|
||||
## Alternative Events (deprecated)
|
||||
|
||||
@@ -112,9 +104,7 @@ Diese Funktionen können mit `async def` oder normalem `def` deklariert werden.
|
||||
|
||||
Um eine Funktion hinzuzufügen, die vor dem Start der Anwendung ausgeführt werden soll, deklarieren Sie diese mit dem Event `startup`:
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!../../docs_src/events/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/events/tutorial001.py hl[8] *}
|
||||
|
||||
In diesem Fall initialisiert die Eventhandler-Funktion `startup` die „Datenbank“ der Items (nur ein `dict`) mit einigen Werten.
|
||||
|
||||
@@ -126,9 +116,7 @@ Und Ihre Anwendung empfängt erst dann Anfragen, wenn alle `startup`-Eventhandle
|
||||
|
||||
Um eine Funktion hinzuzufügen, die beim Herunterfahren der Anwendung ausgeführt werden soll, deklarieren Sie sie mit dem Event `shutdown`:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../docs_src/events/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/events/tutorial002.py hl[6] *}
|
||||
|
||||
Hier schreibt die `shutdown`-Eventhandler-Funktion eine Textzeile `"Application shutdown"` in eine Datei `log.txt`.
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Einige von diesen ✨ [**sponsern FastAPI**](../help-fastapi.md#den-autor-sponse
|
||||
|
||||
Und es zeigt deren wahres Engagement für FastAPI und seine **Community** (Sie), da diese Ihnen nicht nur einen **guten Service** bieten möchten, sondern auch sicherstellen möchten, dass Sie über ein **gutes und gesundes Framework** verfügen, FastAPI. 🙇
|
||||
|
||||
Beispielsweise könnten Sie <a href="https://speakeasy.com/?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a> ausprobieren.
|
||||
Beispielsweise könnten Sie <a href="https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a> ausprobieren.
|
||||
|
||||
Es gibt auch mehrere andere Unternehmen, welche ähnliche Dienste anbieten und die Sie online suchen und finden können. 🤓
|
||||
|
||||
@@ -28,21 +28,7 @@ Es gibt auch mehrere andere Unternehmen, welche ähnliche Dienste anbieten und d
|
||||
|
||||
Beginnen wir mit einer einfachen FastAPI-Anwendung:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="7-9 12-13 16-17 21"
|
||||
{!> ../../docs_src/generate_clients/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9-11 14-15 18 19 23"
|
||||
{!> ../../docs_src/generate_clients/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
|
||||
|
||||
Beachten Sie, dass die *Pfadoperationen* die Modelle definieren, welche diese für die Request- und Response-<abbr title="Die eigentlichen Nutzdaten, abzüglich der Metadaten">Payload</abbr> verwenden, indem sie die Modelle `Item` und `ResponseMessage` verwenden.
|
||||
|
||||
@@ -147,21 +133,7 @@ In vielen Fällen wird Ihre FastAPI-Anwendung größer sein und Sie werden wahrs
|
||||
|
||||
Beispielsweise könnten Sie einen Abschnitt für **Items (Artikel)** und einen weiteren Abschnitt für **Users (Benutzer)** haben, und diese könnten durch Tags getrennt sein:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="21 26 34"
|
||||
{!> ../../docs_src/generate_clients/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="23 28 36"
|
||||
{!> ../../docs_src/generate_clients/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
|
||||
|
||||
### Einen TypeScript-Client mit Tags generieren
|
||||
|
||||
@@ -208,21 +180,7 @@ Hier verwendet sie beispielsweise den ersten Tag (Sie werden wahrscheinlich nur
|
||||
|
||||
Anschließend können Sie diese benutzerdefinierte Funktion als Parameter `generate_unique_id_function` an **FastAPI** übergeben:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="6-7 10"
|
||||
{!> ../../docs_src/generate_clients/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8-9 12"
|
||||
{!> ../../docs_src/generate_clients/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
|
||||
|
||||
### Einen TypeScript-Client mit benutzerdefinierten Operation-IDs generieren
|
||||
|
||||
@@ -244,13 +202,7 @@ Aber für den generierten Client könnten wir die OpenAPI-Operation-IDs direkt v
|
||||
|
||||
Wir könnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dann mit einem Skript wie dem folgenden **den vorangestellten Tag entfernen**:
|
||||
|
||||
//// tab | Python
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/generate_clients/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/generate_clients/tutorial004.py *}
|
||||
|
||||
//// tab | Node.js
|
||||
|
||||
|
||||
@@ -57,17 +57,13 @@ Erzwingt, dass alle eingehenden Requests entweder `https` oder `wss` sein müsse
|
||||
|
||||
Alle eingehenden Requests an `http` oder `ws` werden stattdessen an das sichere Schema umgeleitet.
|
||||
|
||||
```Python hl_lines="2 6"
|
||||
{!../../docs_src/advanced_middleware/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
|
||||
|
||||
## `TrustedHostMiddleware`
|
||||
|
||||
Erzwingt, dass alle eingehenden Requests einen korrekt gesetzten `Host`-Header haben, um sich vor HTTP-Host-Header-Angriffen zu schützen.
|
||||
|
||||
```Python hl_lines="2 6-8"
|
||||
{!../../docs_src/advanced_middleware/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *}
|
||||
|
||||
Die folgenden Argumente werden unterstützt:
|
||||
|
||||
@@ -81,9 +77,7 @@ Verarbeitet GZip-Responses für alle Requests, die `"gzip"` im `Accept-Encoding`
|
||||
|
||||
Diese Middleware verarbeitet sowohl Standard- als auch Streaming-Responses.
|
||||
|
||||
```Python hl_lines="2 6"
|
||||
{!../../docs_src/advanced_middleware/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *}
|
||||
|
||||
Die folgenden Argumente werden unterstützt:
|
||||
|
||||
|
||||
@@ -31,9 +31,7 @@ Sie verfügt über eine *Pfadoperation*, die einen `Invoice`-Body empfängt, und
|
||||
|
||||
Dieser Teil ist ziemlich normal, der größte Teil des Codes ist Ihnen wahrscheinlich bereits bekannt:
|
||||
|
||||
```Python hl_lines="9-13 36-53"
|
||||
{!../../docs_src/openapi_callbacks/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -92,9 +90,7 @@ Wenn Sie diese Sichtweise (des *externen Entwicklers*) vorübergehend übernehme
|
||||
|
||||
Erstellen Sie zunächst einen neuen `APIRouter`, der einen oder mehrere Callbacks enthält.
|
||||
|
||||
```Python hl_lines="3 25"
|
||||
{!../../docs_src/openapi_callbacks/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[3,25] *}
|
||||
|
||||
### Die Callback-*Pfadoperation* erstellen
|
||||
|
||||
@@ -105,9 +101,7 @@ Sie sollte wie eine normale FastAPI-*Pfadoperation* aussehen:
|
||||
* Sie sollte wahrscheinlich eine Deklaration des Bodys enthalten, die sie erhalten soll, z. B. `body: InvoiceEvent`.
|
||||
* Und sie könnte auch eine Deklaration der Response enthalten, die zurückgegeben werden soll, z. B. `response_model=InvoiceEventReceived`.
|
||||
|
||||
```Python hl_lines="16-18 21-22 28-32"
|
||||
{!../../docs_src/openapi_callbacks/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *}
|
||||
|
||||
Es gibt zwei Hauptunterschiede zu einer normalen *Pfadoperation*:
|
||||
|
||||
@@ -175,9 +169,7 @@ An diesem Punkt haben Sie die benötigte(n) *Callback-Pfadoperation(en)* (diejen
|
||||
|
||||
Verwenden Sie nun den Parameter `callbacks` im *Pfadoperation-Dekorator Ihrer API*, um das Attribut `.routes` (das ist eigentlich nur eine `list`e von Routen/*Pfadoperationen*) dieses Callback-Routers zu übergeben:
|
||||
|
||||
```Python hl_lines="35"
|
||||
{!../../docs_src/openapi_callbacks/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[35] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -32,9 +32,7 @@ Webhooks sind in OpenAPI 3.1.0 und höher verfügbar und werden von FastAPI `0.9
|
||||
|
||||
Wenn Sie eine **FastAPI**-Anwendung erstellen, gibt es ein `webhooks`-Attribut, mit dem Sie *Webhooks* definieren können, genauso wie Sie *Pfadoperationen* definieren würden, zum Beispiel mit `@app.webhooks.post()`.
|
||||
|
||||
```Python hl_lines="9-13 36-53"
|
||||
{!../../docs_src/openapi_webhooks/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *}
|
||||
|
||||
Die von Ihnen definierten Webhooks landen im **OpenAPI**-Schema und der automatischen **Dokumentations-Oberfläche**.
|
||||
|
||||
|
||||
@@ -12,9 +12,7 @@ Mit dem Parameter `operation_id` können Sie die OpenAPI `operationId` festlegen
|
||||
|
||||
Sie müssten sicherstellen, dass sie für jede Operation eindeutig ist.
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
|
||||
|
||||
### Verwendung des Namens der *Pfadoperation-Funktion* als operationId
|
||||
|
||||
@@ -22,9 +20,7 @@ Wenn Sie die Funktionsnamen Ihrer API als `operationId`s verwenden möchten, kö
|
||||
|
||||
Sie sollten dies tun, nachdem Sie alle Ihre *Pfadoperationen* hinzugefügt haben.
|
||||
|
||||
```Python hl_lines="2 12-21 24"
|
||||
{!../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2,12:21,24] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -44,9 +40,7 @@ Auch wenn diese sich in unterschiedlichen Modulen (Python-Dateien) befinden.
|
||||
|
||||
Um eine *Pfadoperation* aus dem generierten OpenAPI-Schema (und damit aus den automatischen Dokumentationssystemen) auszuschließen, verwenden Sie den Parameter `include_in_schema` und setzen Sie ihn auf `False`:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
|
||||
|
||||
## Fortgeschrittene Beschreibung mittels Docstring
|
||||
|
||||
@@ -56,9 +50,7 @@ Das Hinzufügen eines `\f` (ein maskiertes „Form Feed“-Zeichen) führt dazu,
|
||||
|
||||
Sie wird nicht in der Dokumentation angezeigt, aber andere Tools (z. B. Sphinx) können den Rest verwenden.
|
||||
|
||||
```Python hl_lines="19-29"
|
||||
{!../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
|
||||
|
||||
## Zusätzliche Responses
|
||||
|
||||
@@ -100,9 +92,7 @@ Sie können das OpenAPI-Schema für eine *Pfadoperation* erweitern, indem Sie de
|
||||
|
||||
Dieses `openapi_extra` kann beispielsweise hilfreich sein, um <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions" class="external-link" target="_blank">OpenAPI-Erweiterungen</a> zu deklarieren:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../docs_src/path_operation_advanced_configuration/tutorial005.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
|
||||
|
||||
Wenn Sie die automatische API-Dokumentation öffnen, wird Ihre Erweiterung am Ende der spezifischen *Pfadoperation* angezeigt.
|
||||
|
||||
@@ -149,9 +139,7 @@ Sie könnten sich beispielsweise dafür entscheiden, den Request mit Ihrem eigen
|
||||
|
||||
Das könnte man mit `openapi_extra` machen:
|
||||
|
||||
```Python hl_lines="20-37 39-40"
|
||||
{!../../docs_src/path_operation_advanced_configuration/tutorial006.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[20:37,39:40] *}
|
||||
|
||||
In diesem Beispiel haben wir kein Pydantic-Modell deklariert. Tatsächlich wird der Requestbody nicht einmal als JSON <abbr title="von einem einfachen Format, wie Bytes, in Python-Objekte konvertieren">geparst</abbr>, sondern direkt als `bytes` gelesen und die Funktion `magic_data_reader ()` wäre dafür verantwortlich, ihn in irgendeiner Weise zu parsen.
|
||||
|
||||
@@ -167,17 +155,13 @@ In der folgenden Anwendung verwenden wir beispielsweise weder die integrierte Fu
|
||||
|
||||
//// tab | Pydantic v2
|
||||
|
||||
```Python hl_lines="17-22 24"
|
||||
{!> ../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22,24] *}
|
||||
|
||||
////
|
||||
|
||||
//// tab | Pydantic v1
|
||||
|
||||
```Python hl_lines="17-22 24"
|
||||
{!> ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22,24] *}
|
||||
|
||||
////
|
||||
|
||||
@@ -195,17 +179,13 @@ Und dann parsen wir in unserem Code diesen YAML-Inhalt direkt und verwenden dann
|
||||
|
||||
//// tab | Pydantic v2
|
||||
|
||||
```Python hl_lines="26-33"
|
||||
{!> ../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
|
||||
|
||||
////
|
||||
|
||||
//// tab | Pydantic v1
|
||||
|
||||
```Python hl_lines="26-33"
|
||||
{!> ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *}
|
||||
|
||||
////
|
||||
|
||||
|
||||
@@ -20,9 +20,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
|
||||
|
||||
Anschließend können Sie den `status_code` in diesem *vorübergehenden* Response-Objekt festlegen.
|
||||
|
||||
```Python hl_lines="1 9 12"
|
||||
{!../../docs_src/response_change_status_code/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *}
|
||||
|
||||
Und dann können Sie wie gewohnt jedes benötigte Objekt zurückgeben (ein `dict`, ein Datenbankmodell usw.).
|
||||
|
||||
|
||||
@@ -6,9 +6,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
|
||||
|
||||
Und dann können Sie Cookies in diesem *vorübergehenden* Response-Objekt setzen.
|
||||
|
||||
```Python hl_lines="1 8-9"
|
||||
{!../../docs_src/response_cookies/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/response_cookies/tutorial002.py hl[1,8:9] *}
|
||||
|
||||
Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
|
||||
|
||||
@@ -26,9 +24,7 @@ Dazu können Sie eine Response erstellen, wie unter [Eine Response direkt zurüc
|
||||
|
||||
Setzen Sie dann Cookies darin und geben Sie sie dann zurück:
|
||||
|
||||
```Python hl_lines="10-12"
|
||||
{!../../docs_src/response_cookies/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -34,9 +34,7 @@ Sie können beispielsweise kein Pydantic-Modell in eine `JSONResponse` einfügen
|
||||
|
||||
In diesen Fällen können Sie den `jsonable_encoder` verwenden, um Ihre Daten zu konvertieren, bevor Sie sie an eine Response übergeben:
|
||||
|
||||
```Python hl_lines="6-7 21-22"
|
||||
{!../../docs_src/response_directly/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
@@ -56,9 +54,7 @@ Nehmen wir an, Sie möchten eine <a href="https://en.wikipedia.org/wiki/XML" cla
|
||||
|
||||
Sie könnten Ihren XML-Inhalt als String in eine `Response` einfügen und sie zurückgeben:
|
||||
|
||||
```Python hl_lines="1 18"
|
||||
{!../../docs_src/response_directly/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
|
||||
|
||||
## Anmerkungen
|
||||
|
||||
|
||||
@@ -6,9 +6,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
|
||||
|
||||
Und dann können Sie Header in diesem *vorübergehenden* Response-Objekt festlegen.
|
||||
|
||||
```Python hl_lines="1 7-8"
|
||||
{!../../docs_src/response_headers/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/response_headers/tutorial002.py hl[1,7:8] *}
|
||||
|
||||
Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
|
||||
|
||||
@@ -24,9 +22,7 @@ Sie können auch Header hinzufügen, wenn Sie eine `Response` direkt zurückgebe
|
||||
|
||||
Erstellen Sie eine Response wie in [Eine Response direkt zurückgeben](response-directly.md){.internal-link target=_blank} beschrieben und übergeben Sie die Header als zusätzlichen Parameter:
|
||||
|
||||
```Python hl_lines="10-12"
|
||||
{!../../docs_src/response_headers/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *}
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ Sie können OAuth2-<abbr title="Geltungsbereiche">Scopes</abbr> direkt in **Fast
|
||||
|
||||
Das ermöglicht es Ihnen, ein feingranuliertes Berechtigungssystem nach dem OAuth2-Standard in Ihre OpenAPI-Anwendung (und deren API-Dokumentation) zu integrieren.
|
||||
|
||||
OAuth2 mit Scopes ist der Mechanismus, der von vielen großen Authentifizierungsanbietern wie Facebook, Google, GitHub, Microsoft, Twitter usw. verwendet wird. Sie verwenden ihn, um Benutzern und Anwendungen spezifische Berechtigungen zu erteilen.
|
||||
OAuth2 mit Scopes ist der Mechanismus, der von vielen großen Authentifizierungsanbietern wie Facebook, Google, GitHub, Microsoft, X (Twitter) usw. verwendet wird. Sie verwenden ihn, um Benutzern und Anwendungen spezifische Berechtigungen zu erteilen.
|
||||
|
||||
Jedes Mal, wenn Sie sich mit Facebook, Google, GitHub, Microsoft oder Twitter anmelden („log in with“), verwendet die entsprechende Anwendung OAuth2 mit Scopes.
|
||||
Jedes Mal, wenn Sie sich mit Facebook, Google, GitHub, Microsoft oder X (Twitter) anmelden („log in with“), verwendet die entsprechende Anwendung OAuth2 mit Scopes.
|
||||
|
||||
In diesem Abschnitt erfahren Sie, wie Sie Authentifizierung und Autorisierung mit demselben OAuth2, mit Scopes in Ihrer **FastAPI**-Anwendung verwalten.
|
||||
|
||||
@@ -62,71 +62,7 @@ Für OAuth2 sind es einfach nur Strings.
|
||||
|
||||
Sehen wir uns zunächst kurz die Teile an, die sich gegenüber den Beispielen im Haupt-**Tutorial – Benutzerhandbuch** für [OAuth2 mit Password (und Hashing), Bearer mit JWT-Tokens](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank} ändern. Diesmal verwenden wir OAuth2-Scopes:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="4 8 12 46 64 105 107-115 121-124 128-134 139 155"
|
||||
{!> ../../docs_src/security/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 155"
|
||||
{!> ../../docs_src/security/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="2 4 8 12 47 65 106 108-116 122-125 129-135 140 156"
|
||||
{!> ../../docs_src/security/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="3 7 11 45 63 104 106-114 120-123 127-133 138 154"
|
||||
{!> ../../docs_src/security/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 155"
|
||||
{!> ../../docs_src/security/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 155"
|
||||
{!> ../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[4,8,12,46,64,105,107:115,121:124,128:134,139,155] *}
|
||||
|
||||
Sehen wir uns diese Änderungen nun Schritt für Schritt an.
|
||||
|
||||
@@ -136,71 +72,7 @@ Die erste Änderung ist, dass wir jetzt das OAuth2-Sicherheitsschema mit zwei ve
|
||||
|
||||
Der `scopes`-Parameter erhält ein `dict` mit jedem Scope als Schlüssel und dessen Beschreibung als Wert:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="62-65"
|
||||
{!> ../../docs_src/security/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="62-65"
|
||||
{!> ../../docs_src/security/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="63-66"
|
||||
{!> ../../docs_src/security/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="61-64"
|
||||
{!> ../../docs_src/security/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="62-65"
|
||||
{!> ../../docs_src/security/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="62-65"
|
||||
{!> ../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[62:65] *}
|
||||
|
||||
Da wir diese Scopes jetzt deklarieren, werden sie in der API-Dokumentation angezeigt, wenn Sie sich einloggen/autorisieren.
|
||||
|
||||
@@ -226,71 +98,7 @@ Aus Sicherheitsgründen sollten Sie jedoch sicherstellen, dass Sie in Ihrer Anwe
|
||||
|
||||
///
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="155"
|
||||
{!> ../../docs_src/security/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="155"
|
||||
{!> ../../docs_src/security/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="156"
|
||||
{!> ../../docs_src/security/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="154"
|
||||
{!> ../../docs_src/security/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="155"
|
||||
{!> ../../docs_src/security/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="155"
|
||||
{!> ../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[155] *}
|
||||
|
||||
## Scopes in *Pfadoperationen* und Abhängigkeiten deklarieren
|
||||
|
||||
@@ -316,71 +124,7 @@ Wir tun dies hier, um zu demonstrieren, wie **FastAPI** auf verschiedenen Ebenen
|
||||
|
||||
///
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="4 139 170"
|
||||
{!> ../../docs_src/security/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="4 139 170"
|
||||
{!> ../../docs_src/security/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="4 140 171"
|
||||
{!> ../../docs_src/security/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="3 138 167"
|
||||
{!> ../../docs_src/security/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="4 139 168"
|
||||
{!> ../../docs_src/security/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="4 139 168"
|
||||
{!> ../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[4,139,170] *}
|
||||
|
||||
/// info | Technische Details
|
||||
|
||||
@@ -406,71 +150,7 @@ Wir deklarieren auch einen speziellen Parameter vom Typ `SecurityScopes`, der au
|
||||
|
||||
Diese `SecurityScopes`-Klasse ähnelt `Request` (`Request` wurde verwendet, um das Request-Objekt direkt zu erhalten).
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8 105"
|
||||
{!> ../../docs_src/security/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="8 105"
|
||||
{!> ../../docs_src/security/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8 106"
|
||||
{!> ../../docs_src/security/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7 104"
|
||||
{!> ../../docs_src/security/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8 105"
|
||||
{!> ../../docs_src/security/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8 105"
|
||||
{!> ../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[8,105] *}
|
||||
|
||||
## Die `scopes` verwenden
|
||||
|
||||
@@ -484,71 +164,7 @@ Wir erstellen eine `HTTPException`, die wir später an mehreren Stellen wiederve
|
||||
|
||||
In diese Exception fügen wir (falls vorhanden) die erforderlichen Scopes als durch Leerzeichen getrennten String ein (unter Verwendung von `scope_str`). Wir fügen diesen String mit den Scopes in den Header `WWW-Authenticate` ein (das ist Teil der Spezifikation).
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="105 107-115"
|
||||
{!> ../../docs_src/security/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="105 107-115"
|
||||
{!> ../../docs_src/security/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="106 108-116"
|
||||
{!> ../../docs_src/security/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="104 106-114"
|
||||
{!> ../../docs_src/security/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="105 107-115"
|
||||
{!> ../../docs_src/security/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="105 107-115"
|
||||
{!> ../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[105,107:115] *}
|
||||
|
||||
## Den `username` und das Format der Daten überprüfen
|
||||
|
||||
@@ -564,71 +180,7 @@ Anstelle beispielsweise eines `dict`s oder etwas anderem, was später in der Anw
|
||||
|
||||
Wir verifizieren auch, dass wir einen Benutzer mit diesem Benutzernamen haben, und wenn nicht, lösen wir dieselbe Exception aus, die wir zuvor erstellt haben.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="46 116-127"
|
||||
{!> ../../docs_src/security/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="46 116-127"
|
||||
{!> ../../docs_src/security/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="47 117-128"
|
||||
{!> ../../docs_src/security/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="45 115-126"
|
||||
{!> ../../docs_src/security/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="46 116-127"
|
||||
{!> ../../docs_src/security/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="46 116-127"
|
||||
{!> ../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[46,116:127] *}
|
||||
|
||||
## Die `scopes` verifizieren
|
||||
|
||||
@@ -636,71 +188,7 @@ Wir überprüfen nun, ob das empfangenen Token alle Scopes enthält, die von die
|
||||
|
||||
Hierzu verwenden wir `security_scopes.scopes`, das eine `list`e mit allen diesen Scopes als `str` enthält.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="128-134"
|
||||
{!> ../../docs_src/security/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="128-134"
|
||||
{!> ../../docs_src/security/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="129-135"
|
||||
{!> ../../docs_src/security/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="127-133"
|
||||
{!> ../../docs_src/security/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="128-134"
|
||||
{!> ../../docs_src/security/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="128-134"
|
||||
{!> ../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial005_an_py310.py hl[128:134] *}
|
||||
|
||||
## Abhängigkeitsbaum und Scopes
|
||||
|
||||
|
||||
@@ -180,9 +180,7 @@ Sie können dieselben Validierungs-Funktionen und -Tools verwenden, die Sie für
|
||||
|
||||
//// tab | Pydantic v2
|
||||
|
||||
```Python hl_lines="2 5-8 11"
|
||||
{!> ../../docs_src/settings/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *}
|
||||
|
||||
////
|
||||
|
||||
@@ -194,9 +192,7 @@ In Pydantic v1 würden Sie `BaseSettings` direkt von `pydantic` statt von `pydan
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="2 5-8 11"
|
||||
{!> ../../docs_src/settings/tutorial001_pv1.py!}
|
||||
```
|
||||
{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *}
|
||||
|
||||
////
|
||||
|
||||
@@ -214,9 +210,7 @@ Als Nächstes werden die Daten konvertiert und validiert. Wenn Sie also dieses `
|
||||
|
||||
Dann können Sie das neue `settings`-Objekt in Ihrer Anwendung verwenden:
|
||||
|
||||
```Python hl_lines="18-20"
|
||||
{!../../docs_src/settings/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/settings/tutorial001.py hl[18:20] *}
|
||||
|
||||
### Den Server ausführen
|
||||
|
||||
@@ -250,15 +244,11 @@ Sie könnten diese Einstellungen in eine andere Moduldatei einfügen, wie Sie in
|
||||
|
||||
Sie könnten beispielsweise eine Datei `config.py` haben mit:
|
||||
|
||||
```Python
|
||||
{!../../docs_src/settings/app01/config.py!}
|
||||
```
|
||||
{* ../../docs_src/settings/app01/config.py *}
|
||||
|
||||
Und dann verwenden Sie diese in einer Datei `main.py`:
|
||||
|
||||
```Python hl_lines="3 11-13"
|
||||
{!../../docs_src/settings/app01/main.py!}
|
||||
```
|
||||
{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -276,9 +266,7 @@ Dies könnte besonders beim Testen nützlich sein, da es sehr einfach ist, eine
|
||||
|
||||
Ausgehend vom vorherigen Beispiel könnte Ihre Datei `config.py` so aussehen:
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!../../docs_src/settings/app02/config.py!}
|
||||
```
|
||||
{* ../../docs_src/settings/app02/config.py hl[10] *}
|
||||
|
||||
Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen.
|
||||
|
||||
@@ -286,35 +274,7 @@ Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erste
|
||||
|
||||
Jetzt erstellen wir eine Abhängigkeit, die ein neues `config.Settings()` zurückgibt.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="6 12-13"
|
||||
{!> ../../docs_src/settings/app02_an_py39/main.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="6 12-13"
|
||||
{!> ../../docs_src/settings/app02_an/main.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="5 11-12"
|
||||
{!> ../../docs_src/settings/app02/main.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -326,43 +286,13 @@ Im Moment nehmen Sie an, dass `get_settings()` eine normale Funktion ist.
|
||||
|
||||
Und dann können wir das von der *Pfadoperation-Funktion* als Abhängigkeit einfordern und es überall dort verwenden, wo wir es brauchen.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="17 19-21"
|
||||
{!> ../../docs_src/settings/app02_an_py39/main.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="17 19-21"
|
||||
{!> ../../docs_src/settings/app02_an/main.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="16 18-20"
|
||||
{!> ../../docs_src/settings/app02/main.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
|
||||
|
||||
### Einstellungen und Tests
|
||||
|
||||
Dann wäre es sehr einfach, beim Testen ein anderes Einstellungsobjekt bereitzustellen, indem man eine Abhängigkeitsüberschreibung für `get_settings` erstellt:
|
||||
|
||||
```Python hl_lines="9-10 13 21"
|
||||
{!../../docs_src/settings/app02/test_main.py!}
|
||||
```
|
||||
{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
|
||||
|
||||
Bei der Abhängigkeitsüberschreibung legen wir einen neuen Wert für `admin_email` fest, wenn wir das neue `Settings`-Objekt erstellen, und geben dann dieses neue Objekt zurück.
|
||||
|
||||
@@ -405,9 +335,7 @@ Und dann aktualisieren Sie Ihre `config.py` mit:
|
||||
|
||||
//// tab | Pydantic v2
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/settings/app03_an/config.py!}
|
||||
```
|
||||
{* ../../docs_src/settings/app03_an/config.py hl[9] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -419,9 +347,7 @@ Das Attribut `model_config` wird nur für die Pydantic-Konfiguration verwendet.
|
||||
|
||||
//// tab | Pydantic v1
|
||||
|
||||
```Python hl_lines="9-10"
|
||||
{!> ../../docs_src/settings/app03_an/config_pv1.py!}
|
||||
```
|
||||
{* ../../docs_src/settings/app03_an/config_pv1.py hl[9:10] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -462,35 +388,7 @@ würden wir dieses Objekt für jeden Request erstellen und die `.env`-Datei für
|
||||
|
||||
Da wir jedoch den `@lru_cache`-Dekorator oben verwenden, wird das `Settings`-Objekt nur einmal erstellt, nämlich beim ersten Aufruf. ✔️
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="1 11"
|
||||
{!> ../../docs_src/settings/app03_an_py39/main.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 11"
|
||||
{!> ../../docs_src/settings/app03_an/main.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1 10"
|
||||
{!> ../../docs_src/settings/app03/main.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
|
||||
|
||||
Dann wird bei allen nachfolgenden Aufrufen von `get_settings()`, in den Abhängigkeiten für darauffolgende Requests, dasselbe Objekt zurückgegeben, das beim ersten Aufruf zurückgegeben wurde, anstatt den Code von `get_settings()` erneut auszuführen und ein neues `Settings`-Objekt zu erstellen.
|
||||
|
||||
|
||||
@@ -10,9 +10,7 @@ Wenn Sie zwei unabhängige FastAPI-Anwendungen mit deren eigenen unabhängigen O
|
||||
|
||||
Erstellen Sie zunächst die Hauptanwendung **FastAPI** und deren *Pfadoperationen*:
|
||||
|
||||
```Python hl_lines="3 6-8"
|
||||
{!../../docs_src/sub_applications/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/sub_applications/tutorial001.py hl[3,6:8] *}
|
||||
|
||||
### Unteranwendung
|
||||
|
||||
@@ -20,9 +18,7 @@ Erstellen Sie dann Ihre Unteranwendung und deren *Pfadoperationen*.
|
||||
|
||||
Diese Unteranwendung ist nur eine weitere Standard-FastAPI-Anwendung, aber diese wird „gemountet“:
|
||||
|
||||
```Python hl_lines="11 14-16"
|
||||
{!../../docs_src/sub_applications/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/sub_applications/tutorial001.py hl[11,14:16] *}
|
||||
|
||||
### Die Unteranwendung mounten
|
||||
|
||||
@@ -30,9 +26,7 @@ Mounten Sie in Ihrer Top-Level-Anwendung `app` die Unteranwendung `subapi`.
|
||||
|
||||
In diesem Fall wird sie im Pfad `/subapi` gemountet:
|
||||
|
||||
```Python hl_lines="11 19"
|
||||
{!../../docs_src/sub_applications/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/sub_applications/tutorial001.py hl[11,19] *}
|
||||
|
||||
### Es in der automatischen API-Dokumentation betrachten
|
||||
|
||||
|
||||
@@ -27,9 +27,7 @@ $ pip install jinja2
|
||||
* Deklarieren Sie einen `Request`-Parameter in der *Pfadoperation*, welcher ein Template zurückgibt.
|
||||
* Verwenden Sie die von Ihnen erstellten `templates`, um eine `TemplateResponse` zu rendern und zurückzugeben, übergeben Sie den Namen des Templates, das Requestobjekt und ein „Kontext“-Dictionary mit Schlüssel-Wert-Paaren, die innerhalb des Jinja2-Templates verwendet werden sollen.
|
||||
|
||||
```Python hl_lines="4 11 15-18"
|
||||
{!../../docs_src/templates/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
|
||||
@@ -28,57 +28,7 @@ Um eine Abhängigkeit für das Testen zu überschreiben, geben Sie als Schlüsse
|
||||
|
||||
Und dann ruft **FastAPI** diese Überschreibung anstelle der ursprünglichen Abhängigkeit auf.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="26-27 30"
|
||||
{!> ../../docs_src/dependency_testing/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="28-29 32"
|
||||
{!> ../../docs_src/dependency_testing/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="29-30 33"
|
||||
{!> ../../docs_src/dependency_testing/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="24-25 28"
|
||||
{!> ../../docs_src/dependency_testing/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="28-29 32"
|
||||
{!> ../../docs_src/dependency_testing/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependency_testing/tutorial001_an_py310.py hl[26:27,30] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -2,6 +2,4 @@
|
||||
|
||||
Wenn Sie in Ihren Tests Ihre Event-Handler (`startup` und `shutdown`) ausführen wollen, können Sie den `TestClient` mit einer `with`-Anweisung verwenden:
|
||||
|
||||
```Python hl_lines="9-12 20-24"
|
||||
{!../../docs_src/app_testing/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *}
|
||||
|
||||
@@ -4,9 +4,7 @@ Sie können den schon bekannten `TestClient` zum Testen von WebSockets verwenden
|
||||
|
||||
Dazu verwenden Sie den `TestClient` in einer `with`-Anweisung, eine Verbindung zum WebSocket herstellend:
|
||||
|
||||
```Python hl_lines="27-31"
|
||||
{!../../docs_src/app_testing/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
|
||||
@@ -29,9 +29,7 @@ Angenommen, Sie möchten auf die IP-Adresse/den Host des Clients in Ihrer *Pfado
|
||||
|
||||
Dazu müssen Sie direkt auf den Request zugreifen.
|
||||
|
||||
```Python hl_lines="1 7-8"
|
||||
{!../../docs_src/using_request_directly/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *}
|
||||
|
||||
Durch die Deklaration eines *Pfadoperation-Funktionsparameters*, dessen Typ der `Request` ist, weiß **FastAPI**, dass es den `Request` diesem Parameter übergeben soll.
|
||||
|
||||
|
||||
@@ -38,17 +38,13 @@ In der Produktion hätten Sie eine der oben genannten Optionen.
|
||||
|
||||
Aber es ist die einfachste Möglichkeit, sich auf die Serverseite von WebSockets zu konzentrieren und ein funktionierendes Beispiel zu haben:
|
||||
|
||||
```Python hl_lines="2 6-38 41-43"
|
||||
{!../../docs_src/websockets/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
|
||||
|
||||
## Einen `websocket` erstellen
|
||||
|
||||
Erstellen Sie in Ihrer **FastAPI**-Anwendung einen `websocket`:
|
||||
|
||||
```Python hl_lines="1 46-47"
|
||||
{!../../docs_src/websockets/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
@@ -62,9 +58,7 @@ Sie können auch `from starlette.websockets import WebSocket` verwenden.
|
||||
|
||||
In Ihrer WebSocket-Route können Sie Nachrichten `await`en und Nachrichten senden.
|
||||
|
||||
```Python hl_lines="48-52"
|
||||
{!../../docs_src/websockets/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}
|
||||
|
||||
Sie können Binär-, Text- und JSON-Daten empfangen und senden.
|
||||
|
||||
@@ -115,57 +109,7 @@ In WebSocket-Endpunkten können Sie Folgendes aus `fastapi` importieren und verw
|
||||
|
||||
Diese funktionieren auf die gleiche Weise wie für andere FastAPI-Endpunkte/*Pfadoperationen*:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="68-69 82"
|
||||
{!> ../../docs_src/websockets/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="68-69 82"
|
||||
{!> ../../docs_src/websockets/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="69-70 83"
|
||||
{!> ../../docs_src/websockets/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="66-67 79"
|
||||
{!> ../../docs_src/websockets/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="68-69 81"
|
||||
{!> ../../docs_src/websockets/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/websockets/tutorial002_an_py310.py hl[68:69,82] *}
|
||||
|
||||
/// info
|
||||
|
||||
@@ -210,21 +154,7 @@ Damit können Sie den WebSocket verbinden und dann Nachrichten senden und empfan
|
||||
|
||||
Wenn eine WebSocket-Verbindung geschlossen wird, löst `await websocket.receive_text()` eine `WebSocketDisconnect`-Exception aus, die Sie dann wie in folgendem Beispiel abfangen und behandeln können.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="79-81"
|
||||
{!> ../../docs_src/websockets/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="81-83"
|
||||
{!> ../../docs_src/websockets/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
|
||||
|
||||
Zum Ausprobieren:
|
||||
|
||||
|
||||
@@ -12,9 +12,7 @@ Wrappen Sie dann die WSGI-Anwendung (z. B. Flask) mit der Middleware.
|
||||
|
||||
Und dann mounten Sie das auf einem Pfad.
|
||||
|
||||
```Python hl_lines="2-3 23"
|
||||
{!../../docs_src/wsgi/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/wsgi/tutorial001.py hl[2:3,23] *}
|
||||
|
||||
## Es ansehen
|
||||
|
||||
|
||||
@@ -381,7 +381,7 @@ Davor war der Umgang mit asynchronem Code jedoch deutlich komplexer und schwieri
|
||||
|
||||
In früheren Versionen von Python hätten Sie Threads oder <a href="https://www.gevent.org/" class="external-link" target="_blank">Gevent</a> verwenden können. Der Code ist jedoch viel komplexer zu verstehen, zu debuggen und nachzuvollziehen.
|
||||
|
||||
In früheren Versionen von NodeJS / Browser JavaScript hätten Sie „Callbacks“ verwendet. Was zur <a href="http://callbackhell.com/" class="external-link" target="_blank">Callback-Hölle</a> führt.
|
||||
In früheren Versionen von NodeJS / Browser JavaScript hätten Sie „Callbacks“ verwendet. Was zur "Callback-Hölle" führt.
|
||||
|
||||
## Coroutinen
|
||||
|
||||
|
||||
@@ -10,8 +10,4 @@ Einige Cloud-Anbieter ✨ [**sponsern FastAPI**](../help-fastapi.md#den-autor-sp
|
||||
|
||||
Und es zeigt deren wahres Engagement für FastAPI und seine **Community** (Sie), da diese Ihnen nicht nur einen **guten Service** bieten möchten, sondern auch sicherstellen möchten, dass Sie über ein **gutes und gesundes Framework** verfügen, FastAPI. 🙇
|
||||
|
||||
Vielleicht möchten Sie deren Dienste ausprobieren und deren Anleitungen folgen:
|
||||
|
||||
* <a href="https://docs.platform.sh/languages/python.html?utm_source=fastapi-signup&utm_medium=banner&utm_campaign=FastAPI-signup-June-2023" class="external-link" target="_blank">Platform.sh</a>
|
||||
* <a href="https://docs.porter.run/language-specific-guides/fastapi" class="external-link" target="_blank">Porter</a>
|
||||
* <a href="https://docs.withcoherence.com/docs/configuration/frameworks?utm_medium=advertising&utm_source=fastapi&utm_campaign=banner%20january%2024#fast-api-example" class="external-link" target="_blank">Coherence</a>
|
||||
Vielleicht möchten Sie deren Dienste ausprobieren und deren Anleitungen folgen.
|
||||
|
||||
@@ -216,7 +216,7 @@ Dieser Manager-Prozess wäre wahrscheinlich derjenige, welcher der IP am **Port*
|
||||
|
||||
Diese Workerprozesse würden Ihre Anwendung ausführen, sie würden die Hauptberechnungen durchführen, um einen **Request** entgegenzunehmen und eine **Response** zurückzugeben, und sie würden alles, was Sie in Variablen einfügen, in den RAM laden.
|
||||
|
||||
<img src="/img/deployment/concepts/process-ram.svg">
|
||||
<img src="/img/deployment/concepts/process-ram.drawio.svg">
|
||||
|
||||
Und natürlich würden auf derselben Maschine neben Ihrer Anwendung wahrscheinlich auch **andere Prozesse** laufen.
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ Zuerst würde der Browser mithilfe der **DNS-Server** herausfinden, welches die
|
||||
|
||||
Die DNS-Server geben dem Browser eine bestimmte **IP-Adresse** zurück. Das wäre die von Ihrem Server verwendete öffentliche IP-Adresse, die Sie in den DNS-Servern konfiguriert haben.
|
||||
|
||||
<img src="/img/deployment/https/https01.svg">
|
||||
<img src="/img/deployment/https/https01.drawio.svg">
|
||||
|
||||
### TLS-Handshake-Start
|
||||
|
||||
@@ -93,7 +93,7 @@ Der Browser kommuniziert dann mit dieser IP-Adresse über **Port 443** (den HTTP
|
||||
|
||||
Der erste Teil der Kommunikation besteht lediglich darin, die Verbindung zwischen dem Client und dem Server herzustellen und die zu verwendenden kryptografischen Schlüssel usw. zu vereinbaren.
|
||||
|
||||
<img src="/img/deployment/https/https02.svg">
|
||||
<img src="/img/deployment/https/https02.drawio.svg">
|
||||
|
||||
Diese Interaktion zwischen dem Client und dem Server zum Aufbau der TLS-Verbindung wird als **<abbr title="TLS-Handschlag">TLS-Handshake</abbr>** bezeichnet.
|
||||
|
||||
@@ -111,7 +111,7 @@ Mithilfe der oben beschriebenen **SNI-Erweiterung** würde der TLS-Terminierungs
|
||||
|
||||
In diesem Fall würde er das Zertifikat für `someapp.example.com` verwenden.
|
||||
|
||||
<img src="/img/deployment/https/https03.svg">
|
||||
<img src="/img/deployment/https/https03.drawio.svg">
|
||||
|
||||
Der Client **vertraut** bereits der Entität, die das TLS-Zertifikat generiert hat (in diesem Fall Let's Encrypt, aber wir werden später mehr darüber erfahren), sodass er **verifizieren** kann, dass das Zertifikat gültig ist.
|
||||
|
||||
@@ -133,19 +133,19 @@ Da Client und Server (sprich, der Browser und der TLS-Terminierungsproxy) nun ü
|
||||
|
||||
Der Client sendet also einen **HTTPS-Request**. Das ist einfach ein HTTP-Request über eine verschlüsselte TLS-Verbindung.
|
||||
|
||||
<img src="/img/deployment/https/https04.svg">
|
||||
<img src="/img/deployment/https/https04.drawio.svg">
|
||||
|
||||
### Den Request entschlüsseln
|
||||
|
||||
Der TLS-Terminierungsproxy würde die vereinbarte Verschlüsselung zum **Entschlüsseln des Requests** verwenden und den **einfachen (entschlüsselten) HTTP-Request** an den Prozess weiterleiten, der die Anwendung ausführt (z. B. einen Prozess, bei dem Uvicorn die FastAPI-Anwendung ausführt).
|
||||
|
||||
<img src="/img/deployment/https/https05.svg">
|
||||
<img src="/img/deployment/https/https05.drawio.svg">
|
||||
|
||||
### HTTP-Response
|
||||
|
||||
Die Anwendung würde den Request verarbeiten und eine **einfache (unverschlüsselte) HTTP-Response** an den TLS-Terminierungsproxy senden.
|
||||
|
||||
<img src="/img/deployment/https/https06.svg">
|
||||
<img src="/img/deployment/https/https06.drawio.svg">
|
||||
|
||||
### HTTPS-Response
|
||||
|
||||
@@ -153,7 +153,7 @@ Der TLS-Terminierungsproxy würde dann die Response mithilfe der zuvor vereinbar
|
||||
|
||||
Als Nächstes überprüft der Browser, ob die Response gültig und mit dem richtigen kryptografischen Schlüssel usw. verschlüsselt ist. Anschließend **entschlüsselt er die Response** und verarbeitet sie.
|
||||
|
||||
<img src="/img/deployment/https/https07.svg">
|
||||
<img src="/img/deployment/https/https07.drawio.svg">
|
||||
|
||||
Der Client (Browser) weiß, dass die Response vom richtigen Server kommt, da dieser die Kryptografie verwendet, die zuvor mit dem **HTTPS-Zertifikat** vereinbart wurde.
|
||||
|
||||
@@ -163,7 +163,7 @@ Auf demselben Server (oder denselben Servern) könnten sich **mehrere Anwendunge
|
||||
|
||||
Nur ein Prozess kann diese spezifische IP und den Port verarbeiten (in unserem Beispiel der TLS-Terminierungsproxy), aber die anderen Anwendungen/Prozesse können auch auf dem/den Server(n) ausgeführt werden, solange sie nicht versuchen, dieselbe **Kombination aus öffentlicher IP und Port** zu verwenden.
|
||||
|
||||
<img src="/img/deployment/https/https08.svg">
|
||||
<img src="/img/deployment/https/https08.drawio.svg">
|
||||
|
||||
Auf diese Weise könnte der TLS-Terminierungsproxy HTTPS und Zertifikate für **mehrere Domains**, für mehrere Anwendungen, verarbeiten und die Requests dann jeweils an die richtige Anwendung weiterleiten.
|
||||
|
||||
@@ -173,7 +173,7 @@ Irgendwann in der Zukunft würde jedes Zertifikat **ablaufen** (etwa 3 Monate na
|
||||
|
||||
Und dann gäbe es ein anderes Programm (in manchen Fällen ist es ein anderes Programm, in manchen Fällen ist es derselbe TLS-Terminierungsproxy), das mit Let's Encrypt kommuniziert und das/die Zertifikat(e) erneuert.
|
||||
|
||||
<img src="/img/deployment/https/https.svg">
|
||||
<img src="/img/deployment/https/https.drawio.svg">
|
||||
|
||||
Die **TLS-Zertifikate** sind **einem Domainnamen zugeordnet**, nicht einer IP-Adresse.
|
||||
|
||||
|
||||
@@ -19,9 +19,9 @@ Sie können den (unregelmäßig erscheinenden) [**FastAPI and Friends**-Newslett
|
||||
* Funktionen ✨
|
||||
* Breaking Changes 🚨
|
||||
* Tipps und Tricks ✅
|
||||
## FastAPI auf Twitter folgen
|
||||
## FastAPI auf X (Twitter) folgen
|
||||
|
||||
<a href="https://twitter.com/fastapi" class="external-link" target="_blank">Folgen Sie @fastapi auf **Twitter**</a>, um die neuesten Nachrichten über **FastAPI** zu erhalten. 🐦
|
||||
<a href="https://x.com/fastapi" class="external-link" target="_blank">Folgen Sie @fastapi auf **X (Twitter)**</a>, um die neuesten Nachrichten über **FastAPI** zu erhalten. 🐦
|
||||
|
||||
## **FastAPI** auf GitHub einen Stern geben
|
||||
|
||||
@@ -46,19 +46,19 @@ Insbesondere:
|
||||
* <a href="https://github.com/tiangolo" class="external-link" target="_blank"> Folgen Sie mir auf **GitHub**</a>.
|
||||
* Finden Sie andere Open-Source-Projekte, die ich erstellt habe und die Ihnen helfen könnten.
|
||||
* Folgen Sie mir, um mitzubekommen, wenn ich ein neues Open-Source-Projekt erstelle.
|
||||
* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">Folgen Sie mir auf **Twitter**</a> oder <a href="https://fosstodon.org/@tiangolo" class="external-link" target="_blank">Mastodon</a>.
|
||||
* <a href="https://x.com/tiangolo" class="external-link" target="_blank">Folgen Sie mir auf **X (Twitter)**</a> oder <a href="https://fosstodon.org/@tiangolo" class="external-link" target="_blank">Mastodon</a>.
|
||||
* Berichten Sie mir, wie Sie FastAPI verwenden (das höre ich gerne).
|
||||
* Bekommen Sie mit, wenn ich Ankündigungen mache oder neue Tools veröffentliche.
|
||||
* Sie können auch <a href="https://twitter.com/fastapi" class="external-link" target="_blank">@fastapi auf Twitter folgen</a> (ein separates Konto).
|
||||
* Sie können auch <a href="https://x.com/fastapi" class="external-link" target="_blank">@fastapi auf X (Twitter) folgen</a> (ein separates Konto).
|
||||
* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">Folgen Sie mir auf **LinkedIn**</a>.
|
||||
* Bekommen Sie mit, wenn ich Ankündigungen mache oder neue Tools veröffentliche (obwohl ich Twitter häufiger verwende 🤷♂).
|
||||
* Bekommen Sie mit, wenn ich Ankündigungen mache oder neue Tools veröffentliche (obwohl ich X (Twitter) häufiger verwende 🤷♂).
|
||||
* Lesen Sie, was ich schreibe (oder folgen Sie mir) auf <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> oder <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>.
|
||||
* Lesen Sie andere Ideen, Artikel, und erfahren Sie mehr über die von mir erstellten Tools.
|
||||
* Folgen Sie mir, um zu lesen, wenn ich etwas Neues veröffentliche.
|
||||
|
||||
## Über **FastAPI** tweeten
|
||||
|
||||
<a href="https://twitter.com/compose/tweet?text=Ich liebe @fastapi, weil ... https://github.com/fastapi/fastapi" class="external-link" target= "_blank">Tweeten Sie über **FastAPI**</a> und teilen Sie mir und anderen mit, warum es Ihnen gefällt. 🎉
|
||||
<a href="https://x.com/compose/tweet?text=Ich liebe @fastapi, weil ... https://github.com/fastapi/fastapi" class="external-link" target= "_blank">Tweeten Sie über **FastAPI**</a> und teilen Sie mir und anderen mit, warum es Ihnen gefällt. 🎉
|
||||
|
||||
Ich höre gerne, wie **FastAPI** verwendet wird, was Ihnen daran gefallen hat, in welchem Projekt/Unternehmen Sie es verwenden, usw.
|
||||
|
||||
|
||||
@@ -29,9 +29,7 @@ Sie können problemlos dieselben Pydantic-Einstellungen verwenden, um Ihre gener
|
||||
|
||||
Zum Beispiel:
|
||||
|
||||
```Python hl_lines="6 11"
|
||||
{!../../docs_src/conditional_openapi/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *}
|
||||
|
||||
Hier deklarieren wir die Einstellung `openapi_url` mit dem gleichen Defaultwert `"/openapi.json"`.
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@ Der erste Schritt besteht darin, die automatischen Dokumentationen zu deaktivier
|
||||
|
||||
Um diese zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!../../docs_src/custom_docs_ui/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *}
|
||||
|
||||
### Die benutzerdefinierten Dokumentationen hinzufügen
|
||||
|
||||
@@ -36,9 +34,7 @@ Sie können die internen Funktionen von FastAPI wiederverwenden, um die HTML-Sei
|
||||
|
||||
Und genau so für ReDoc ...
|
||||
|
||||
```Python hl_lines="2-6 11-19 22-24 27-33"
|
||||
{!../../docs_src/custom_docs_ui/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -54,9 +50,7 @@ Swagger UI erledigt das hinter den Kulissen für Sie, benötigt aber diesen „U
|
||||
|
||||
Um nun testen zu können, ob alles funktioniert, erstellen Sie eine *Pfadoperation*:
|
||||
|
||||
```Python hl_lines="36-38"
|
||||
{!../../docs_src/custom_docs_ui/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *}
|
||||
|
||||
### Es ausprobieren
|
||||
|
||||
@@ -104,7 +98,7 @@ Sie können wahrscheinlich mit der rechten Maustaste auf jeden Link klicken und
|
||||
|
||||
Und **ReDoc** verwendet diese Datei:
|
||||
|
||||
* <a href="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js" class="external-link" target="_blank">`redoc.standalone.js`</a>
|
||||
* <a href="https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js" class="external-link" target="_blank">`redoc.standalone.js`</a>
|
||||
|
||||
Danach könnte Ihre Dateistruktur wie folgt aussehen:
|
||||
|
||||
@@ -124,9 +118,7 @@ Danach könnte Ihre Dateistruktur wie folgt aussehen:
|
||||
* Importieren Sie `StaticFiles`.
|
||||
* „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
|
||||
|
||||
```Python hl_lines="7 11"
|
||||
{!../../docs_src/custom_docs_ui/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *}
|
||||
|
||||
### Die statischen Dateien testen
|
||||
|
||||
@@ -137,14 +129,8 @@ Sie sollten eine sehr lange JavaScript-Datei für **ReDoc** sehen.
|
||||
Sie könnte beginnen mit etwas wie:
|
||||
|
||||
```JavaScript
|
||||
/*!
|
||||
* ReDoc - OpenAPI/Swagger-generated API Reference Documentation
|
||||
* -------------------------------------------------------------
|
||||
* Version: "2.0.0-rc.18"
|
||||
* Repo: https://github.com/Redocly/redoc
|
||||
*/
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof m
|
||||
|
||||
/*! For license information please see redoc.standalone.js.LICENSE.txt */
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("null")):
|
||||
...
|
||||
```
|
||||
|
||||
@@ -158,9 +144,7 @@ Wie bei der Verwendung eines benutzerdefinierten CDN besteht der erste Schritt d
|
||||
|
||||
Um diese zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../docs_src/custom_docs_ui/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *}
|
||||
|
||||
### Die benutzerdefinierten Dokumentationen, mit statischen Dateien, hinzufügen
|
||||
|
||||
@@ -176,9 +160,7 @@ Auch hier können Sie die internen Funktionen von FastAPI wiederverwenden, um di
|
||||
|
||||
Und genau so für ReDoc ...
|
||||
|
||||
```Python hl_lines="2-6 14-22 25-27 30-36"
|
||||
{!../../docs_src/custom_docs_ui/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -194,9 +176,7 @@ Swagger UI erledigt das hinter den Kulissen für Sie, benötigt aber diesen „U
|
||||
|
||||
Um nun testen zu können, ob alles funktioniert, erstellen Sie eine *Pfadoperation*:
|
||||
|
||||
```Python hl_lines="39-41"
|
||||
{!../../docs_src/custom_docs_ui/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *}
|
||||
|
||||
### Benutzeroberfläche, mit statischen Dateien, testen
|
||||
|
||||
|
||||
@@ -42,9 +42,7 @@ Wenn der Header kein `gzip` enthält, wird nicht versucht, den Body zu dekomprim
|
||||
|
||||
Auf diese Weise kann dieselbe Routenklasse gzip-komprimierte oder unkomprimierte Requests verarbeiten.
|
||||
|
||||
```Python hl_lines="8-15"
|
||||
{!../../docs_src/custom_request_and_route/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *}
|
||||
|
||||
### Eine benutzerdefinierte `GzipRoute`-Klasse erstellen
|
||||
|
||||
@@ -56,9 +54,7 @@ Diese Methode gibt eine Funktion zurück. Und diese Funktion empfängt einen Req
|
||||
|
||||
Hier verwenden wir sie, um aus dem ursprünglichen Request einen `GzipRequest` zu erstellen.
|
||||
|
||||
```Python hl_lines="18-26"
|
||||
{!../../docs_src/custom_request_and_route/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[18:26] *}
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
@@ -96,26 +92,18 @@ Wir können denselben Ansatz auch verwenden, um in einem Exceptionhandler auf de
|
||||
|
||||
Alles, was wir tun müssen, ist, den Request innerhalb eines `try`/`except`-Blocks zu handhaben:
|
||||
|
||||
```Python hl_lines="13 15"
|
||||
{!../../docs_src/custom_request_and_route/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[13,15] *}
|
||||
|
||||
Wenn eine Exception auftritt, befindet sich die `Request`-Instanz weiterhin im Gültigkeitsbereich, sodass wir den Requestbody lesen und bei der Fehlerbehandlung verwenden können:
|
||||
|
||||
```Python hl_lines="16-18"
|
||||
{!../../docs_src/custom_request_and_route/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *}
|
||||
|
||||
## Benutzerdefinierte `APIRoute`-Klasse in einem Router
|
||||
|
||||
Sie können auch den Parameter `route_class` eines `APIRouter` festlegen:
|
||||
|
||||
```Python hl_lines="26"
|
||||
{!../../docs_src/custom_request_and_route/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[26] *}
|
||||
|
||||
In diesem Beispiel verwenden die *Pfadoperationen* unter dem `router` die benutzerdefinierte `TimedRoute`-Klasse und haben in der Response einen zusätzlichen `X-Response-Time`-Header mit der Zeit, die zum Generieren der Response benötigt wurde:
|
||||
|
||||
```Python hl_lines="13-20"
|
||||
{!../../docs_src/custom_request_and_route/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
|
||||
|
||||
@@ -43,25 +43,19 @@ Fügen wir beispielsweise <a href="https://github.com/Rebilly/ReDoc/blob/master/
|
||||
|
||||
Schreiben Sie zunächst wie gewohnt Ihre ganze **FastAPI**-Anwendung:
|
||||
|
||||
```Python hl_lines="1 4 7-9"
|
||||
{!../../docs_src/extending_openapi/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *}
|
||||
|
||||
### Das OpenAPI-Schema generieren
|
||||
|
||||
Verwenden Sie dann dieselbe Hilfsfunktion, um das OpenAPI-Schema innerhalb einer `custom_openapi()`-Funktion zu generieren:
|
||||
|
||||
```Python hl_lines="2 15-21"
|
||||
{!../../docs_src/extending_openapi/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *}
|
||||
|
||||
### Das OpenAPI-Schema ändern
|
||||
|
||||
Jetzt können Sie die ReDoc-Erweiterung hinzufügen und dem `info`-„Objekt“ im OpenAPI-Schema ein benutzerdefiniertes `x-logo` hinzufügen:
|
||||
|
||||
```Python hl_lines="22-24"
|
||||
{!../../docs_src/extending_openapi/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *}
|
||||
|
||||
### Zwischenspeichern des OpenAPI-Schemas
|
||||
|
||||
@@ -71,17 +65,13 @@ Auf diese Weise muss Ihre Anwendung das Schema nicht jedes Mal generieren, wenn
|
||||
|
||||
Es wird nur einmal generiert und dann wird dasselbe zwischengespeicherte Schema für die nächsten Requests verwendet.
|
||||
|
||||
```Python hl_lines="13-14 25-26"
|
||||
{!../../docs_src/extending_openapi/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *}
|
||||
|
||||
### Die Methode überschreiben
|
||||
|
||||
Jetzt können Sie die Methode `.openapi()` durch Ihre neue Funktion ersetzen.
|
||||
|
||||
```Python hl_lines="29"
|
||||
{!../../docs_src/extending_openapi/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[29] *}
|
||||
|
||||
### Testen
|
||||
|
||||
|
||||
@@ -35,9 +35,7 @@ Abhängig von Ihrem Anwendungsfall bevorzugen Sie vielleicht eine andere Bibliot
|
||||
|
||||
Hier ist eine kleine Vorschau, wie Sie Strawberry mit FastAPI integrieren können:
|
||||
|
||||
```Python hl_lines="3 22 25-26"
|
||||
{!../../docs_src/graphql/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/graphql/tutorial001.py hl[3,22,25:26] *}
|
||||
|
||||
Weitere Informationen zu Strawberry finden Sie in der <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry-Dokumentation</a>.
|
||||
|
||||
|
||||
@@ -10,123 +10,13 @@ Sehen wir uns an, wie das funktioniert und wie Sie es bei Bedarf ändern können
|
||||
|
||||
Nehmen wir an, Sie haben ein Pydantic-Modell mit Defaultwerten wie dieses:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-7]!}
|
||||
|
||||
# Code unterhalb weggelassen 👇
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>👀 Vollständige Dateivorschau</summary>
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py[ln:1-9]!}
|
||||
|
||||
# Code unterhalb weggelassen 👇
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>👀 Vollständige Dateivorschau</summary>
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py[ln:1-9]!}
|
||||
|
||||
# Code unterhalb weggelassen 👇
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>👀 Vollständige Dateivorschau</summary>
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
////
|
||||
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:7] hl[7] *}
|
||||
|
||||
### Modell für Eingabe
|
||||
|
||||
Wenn Sie dieses Modell wie hier als Eingabe verwenden:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py[ln:1-15]!}
|
||||
|
||||
# Code unterhalb weggelassen 👇
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>👀 Vollständige Dateivorschau</summary>
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py[ln:1-17]!}
|
||||
|
||||
# Code unterhalb weggelassen 👇
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>👀 Vollständige Dateivorschau</summary>
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py[ln:1-17]!}
|
||||
|
||||
# Code unterhalb weggelassen 👇
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>👀 Vollständige Dateivorschau</summary>
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
////
|
||||
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py ln[1:15] hl[14] *}
|
||||
|
||||
... dann ist das Feld `description` **nicht erforderlich**. Weil es den Defaultwert `None` hat.
|
||||
|
||||
@@ -142,29 +32,7 @@ Sie können überprüfen, dass das Feld `description` in der Dokumentation kein
|
||||
|
||||
Wenn Sie jedoch dasselbe Modell als Ausgabe verwenden, wie hier:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/separate_openapi_schemas/tutorial001_py310.py hl[19] *}
|
||||
|
||||
... dann, weil `description` einen Defaultwert hat, wird es, wenn Sie für dieses Feld **nichts zurückgeben**, immer noch diesen **Defaultwert** haben.
|
||||
|
||||
@@ -223,29 +91,7 @@ Unterstützung für `separate_input_output_schemas` wurde in FastAPI `0.102.0` h
|
||||
|
||||
///
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/separate_openapi_schemas/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/separate_openapi_schemas/tutorial002_py310.py hl[10] *}
|
||||
|
||||
### Gleiches Schema für Eingabe- und Ausgabemodelle in der Dokumentation
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/fastapi/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
||||
<img src="https://github.com/fastapi/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
|
||||
<img src="https://github.com/fastapi/fastapi/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Test">
|
||||
</a>
|
||||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi" target="_blank">
|
||||
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi.svg" alt="Coverage">
|
||||
@@ -88,7 +88,7 @@ Seine Schlüssel-Merkmale sind:
|
||||
|
||||
„_Ich bin überglücklich mit **FastAPI**. Es macht so viel Spaß!_“
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong>Host des <a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> Podcast</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(Ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong>Host des <a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> Podcast</strong> <a href="https://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(Ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
@@ -102,7 +102,7 @@ Seine Schlüssel-Merkmale sind:
|
||||
|
||||
„_Wir haben zu **FastAPI** für unsere **APIs** gewechselt [...] Ich denke, es wird Ihnen gefallen [...]_“
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong>Gründer von <a href="https://explosion.ai" target="_blank">Explosion AI</a> - Autoren von <a href="https://spacy.io" target="_blank">spaCy</a></strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(Ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(Ref)</small></a></div>
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong>Gründer von <a href="https://explosion.ai" target="_blank">Explosion AI</a> - Autoren von <a href="https://spacy.io" target="_blank">spaCy</a></strong> <a href="https://x.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(Ref)</small></a> - <a href="https://x.com/honnibal/status/1144031421859655680" target="_blank"><small>(Ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -15,9 +15,7 @@ Hierzu zählen beispielsweise:
|
||||
|
||||
Importieren Sie zunächst `BackgroundTasks` und definieren Sie einen Parameter in Ihrer *Pfadoperation-Funktion* mit der Typdeklaration `BackgroundTasks`:
|
||||
|
||||
```Python hl_lines="1 13"
|
||||
{!../../docs_src/background_tasks/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
|
||||
|
||||
**FastAPI** erstellt für Sie das Objekt vom Typ `BackgroundTasks` und übergibt es als diesen Parameter.
|
||||
|
||||
@@ -33,17 +31,13 @@ In diesem Fall schreibt die Taskfunktion in eine Datei (den Versand einer E-Mail
|
||||
|
||||
Und da der Schreibvorgang nicht `async` und `await` verwendet, definieren wir die Funktion mit normalem `def`:
|
||||
|
||||
```Python hl_lines="6-9"
|
||||
{!../../docs_src/background_tasks/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
|
||||
|
||||
## Den Hintergrundtask hinzufügen
|
||||
|
||||
Übergeben Sie innerhalb Ihrer *Pfadoperation-Funktion* Ihre Taskfunktion mit der Methode `.add_task()` an das *Hintergrundtasks*-Objekt:
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!../../docs_src/background_tasks/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
|
||||
|
||||
`.add_task()` erhält als Argumente:
|
||||
|
||||
@@ -57,57 +51,7 @@ Die Verwendung von `BackgroundTasks` funktioniert auch mit dem <abbr title="Einb
|
||||
|
||||
**FastAPI** weiß, was jeweils zu tun ist und wie dasselbe Objekt wiederverwendet werden kann, sodass alle Hintergrundtasks zusammengeführt und anschließend im Hintergrund ausgeführt werden:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="13 15 22 25"
|
||||
{!> ../../docs_src/background_tasks/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="13 15 22 25"
|
||||
{!> ../../docs_src/background_tasks/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="14 16 23 26"
|
||||
{!> ../../docs_src/background_tasks/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11 13 20 23"
|
||||
{!> ../../docs_src/background_tasks/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="13 15 22 25"
|
||||
{!> ../../docs_src/background_tasks/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/background_tasks/tutorial002_an_py310.py hl[13,15,22,25] *}
|
||||
|
||||
In obigem Beispiel werden die Nachrichten, *nachdem* die Response gesendet wurde, in die Datei `log.txt` geschrieben.
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ from app.routers import items
|
||||
* Es gibt auch ein Unterverzeichnis `app/internal/` mit einer weiteren Datei `__init__.py`, es handelt sich also um ein weiteres „Python-Subpackage“: `app.internal`.
|
||||
* Und die Datei `app/internal/admin.py` ist ein weiteres Submodul: `app.internal.admin`.
|
||||
|
||||
<img src="/img/tutorial/bigger-applications/package.svg">
|
||||
<img src="/img/tutorial/bigger-applications/package.drawio.svg">
|
||||
|
||||
Die gleiche Dateistruktur mit Kommentaren:
|
||||
|
||||
@@ -270,7 +270,7 @@ Aber diese Datei existiert nicht, unsere Abhängigkeiten befinden sich in einer
|
||||
|
||||
Erinnern Sie sich, wie unsere Anwendungs-/Dateistruktur aussieht:
|
||||
|
||||
<img src="/img/tutorial/bigger-applications/package.svg">
|
||||
<img src="/img/tutorial/bigger-applications/package.drawio.svg">
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -6,57 +6,7 @@ So wie Sie zusätzliche Validation und Metadaten in Parametern der **Pfadoperati
|
||||
|
||||
Importieren Sie es zuerst:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!> ../../docs_src/body_fields/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!> ../../docs_src/body_fields/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!> ../../docs_src/body_fields/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="2"
|
||||
{!> ../../docs_src/body_fields/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!> ../../docs_src/body_fields/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[4] *}
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
@@ -68,57 +18,7 @@ Beachten Sie, dass `Field` direkt von `pydantic` importiert wird, nicht von `fas
|
||||
|
||||
Dann können Sie `Field` mit Modellattributen deklarieren:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="11-14"
|
||||
{!> ../../docs_src/body_fields/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="11-14"
|
||||
{!> ../../docs_src/body_fields/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="12-15"
|
||||
{!> ../../docs_src/body_fields/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9-12"
|
||||
{!> ../../docs_src/body_fields/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11-14"
|
||||
{!> ../../docs_src/body_fields/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_fields/tutorial001_an_py310.py hl[11:14] *}
|
||||
|
||||
`Field` funktioniert genauso wie `Query`, `Path` und `Body`, es hat die gleichen Parameter, usw.
|
||||
|
||||
|
||||
@@ -6,21 +6,7 @@ Mit **FastAPI** können Sie (dank Pydantic) beliebig tief verschachtelte Modelle
|
||||
|
||||
Sie können ein Attribut als Kindtyp definieren, zum Beispiel eine Python-`list`e.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/body_nested_models/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../docs_src/body_nested_models/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_nested_models/tutorial001_py310.py hl[12] *}
|
||||
|
||||
Das bewirkt, dass `tags` eine Liste ist, wenngleich es nichts über den Typ der Elemente der Liste aussagt.
|
||||
|
||||
@@ -34,9 +20,7 @@ In Python 3.9 oder darüber können Sie einfach `list` verwenden, um diese Typan
|
||||
|
||||
In Python-Versionen vor 3.9 (3.6 und darüber), müssen Sie zuerst `List` von Pythons Standardmodul `typing` importieren.
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/body_nested_models/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
|
||||
|
||||
### Eine `list`e mit einem Typ-Parameter deklarieren
|
||||
|
||||
@@ -65,29 +49,7 @@ Verwenden Sie dieselbe Standardsyntax für Modellattribute mit inneren Typen.
|
||||
|
||||
In unserem Beispiel können wir also bewirken, dass `tags` spezifisch eine „Liste von Strings“ ist:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/body_nested_models/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../docs_src/body_nested_models/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../docs_src/body_nested_models/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_nested_models/tutorial002_py310.py hl[12] *}
|
||||
|
||||
## Set-Typen
|
||||
|
||||
@@ -97,29 +59,7 @@ Python hat einen Datentyp speziell für Mengen eindeutiger Dinge: das <abbr titl
|
||||
|
||||
Deklarieren wir also `tags` als Set von Strings.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/body_nested_models/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../docs_src/body_nested_models/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 14"
|
||||
{!> ../../docs_src/body_nested_models/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_nested_models/tutorial003_py310.py hl[12] *}
|
||||
|
||||
Jetzt, selbst wenn Sie einen Request mit duplizierten Daten erhalten, werden diese zu einem Set eindeutiger Dinge konvertiert.
|
||||
|
||||
@@ -141,57 +81,13 @@ Alles das beliebig tief verschachtelt.
|
||||
|
||||
Wir können zum Beispiel ein `Image`-Modell definieren.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7-9"
|
||||
{!> ../../docs_src/body_nested_models/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9-11"
|
||||
{!> ../../docs_src/body_nested_models/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9-11"
|
||||
{!> ../../docs_src/body_nested_models/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[7:9] *}
|
||||
|
||||
### Das Kindmodell als Typ verwenden
|
||||
|
||||
Und dann können wir es als Typ eines Attributes verwenden.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../docs_src/body_nested_models/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../docs_src/body_nested_models/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../docs_src/body_nested_models/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_nested_models/tutorial004_py310.py hl[18] *}
|
||||
|
||||
Das würde bedeuten, dass **FastAPI** einen Body erwartet wie:
|
||||
|
||||
@@ -224,29 +120,7 @@ Um alle Optionen kennenzulernen, die Sie haben, schauen Sie sich <a href="https:
|
||||
|
||||
Da wir zum Beispiel im `Image`-Modell ein Feld `url` haben, können wir deklarieren, dass das eine Instanz von Pydantics `HttpUrl` sein soll, anstelle eines `str`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="2 8"
|
||||
{!> ../../docs_src/body_nested_models/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="4 10"
|
||||
{!> ../../docs_src/body_nested_models/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="4 10"
|
||||
{!> ../../docs_src/body_nested_models/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_nested_models/tutorial005_py310.py hl[2,8] *}
|
||||
|
||||
Es wird getestet, ob der String eine gültige URL ist, und als solche wird er in JSON Schema / OpenAPI dokumentiert.
|
||||
|
||||
@@ -254,29 +128,7 @@ Es wird getestet, ob der String eine gültige URL ist, und als solche wird er in
|
||||
|
||||
Sie können Pydantic-Modelle auch als Typen innerhalb von `list`, `set`, usw. verwenden:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../docs_src/body_nested_models/tutorial006_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../docs_src/body_nested_models/tutorial006_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../docs_src/body_nested_models/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_nested_models/tutorial006_py310.py hl[18] *}
|
||||
|
||||
Das wird einen JSON-Body erwarten (konvertieren, validieren, dokumentieren), wie:
|
||||
|
||||
@@ -314,29 +166,7 @@ Beachten Sie, dass der `images`-Schlüssel jetzt eine Liste von Bild-Objekten ha
|
||||
|
||||
Sie können beliebig tief verschachtelte Modelle definieren:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7 12 18 21 25"
|
||||
{!> ../../docs_src/body_nested_models/tutorial007_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9 14 20 23 27"
|
||||
{!> ../../docs_src/body_nested_models/tutorial007_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9 14 20 23 27"
|
||||
{!> ../../docs_src/body_nested_models/tutorial007.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_nested_models/tutorial007_py310.py hl[7,12,18,21,25] *}
|
||||
|
||||
/// info
|
||||
|
||||
@@ -360,21 +190,7 @@ images: list[Image]
|
||||
|
||||
so wie in:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../docs_src/body_nested_models/tutorial008_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../docs_src/body_nested_models/tutorial008.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
|
||||
|
||||
## Editor-Unterstützung überall
|
||||
|
||||
@@ -404,21 +220,7 @@ Das schauen wir uns mal an.
|
||||
|
||||
Im folgenden Beispiel akzeptieren Sie irgendein `dict`, solange es `int`-Schlüssel und `float`-Werte hat.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/body_nested_models/tutorial009_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/body_nested_models/tutorial009.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -6,29 +6,7 @@ Um einen Artikel zu aktualisieren, können Sie die <a href="https://developer.mo
|
||||
|
||||
Sie können den `jsonable_encoder` verwenden, um die empfangenen Daten in etwas zu konvertieren, das als JSON gespeichert werden kann (in z. B. einer NoSQL-Datenbank). Zum Beispiel, um ein `datetime` in einen `str` zu konvertieren.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="28-33"
|
||||
{!> ../../docs_src/body_updates/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="30-35"
|
||||
{!> ../../docs_src/body_updates/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="30-35"
|
||||
{!> ../../docs_src/body_updates/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_updates/tutorial001_py310.py hl[28:33] *}
|
||||
|
||||
`PUT` wird verwendet, um Daten zu empfangen, die die existierenden Daten ersetzen sollen.
|
||||
|
||||
@@ -84,29 +62,7 @@ Das wird ein `dict` erstellen, mit nur den Daten, die gesetzt wurden als das `it
|
||||
|
||||
Sie können das verwenden, um ein `dict` zu erstellen, das nur die (im Request) gesendeten Daten enthält, ohne Defaultwerte:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="32"
|
||||
{!> ../../docs_src/body_updates/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="34"
|
||||
{!> ../../docs_src/body_updates/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="34"
|
||||
{!> ../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_updates/tutorial002_py310.py hl[32] *}
|
||||
|
||||
### Pydantics `update`-Parameter verwenden
|
||||
|
||||
@@ -122,29 +78,7 @@ Die Beispiele hier verwenden `.copy()` für die Kompatibilität mit Pydantic v1,
|
||||
|
||||
Wie in `stored_item_model.model_copy(update=update_data)`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="33"
|
||||
{!> ../../docs_src/body_updates/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="35"
|
||||
{!> ../../docs_src/body_updates/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="35"
|
||||
{!> ../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
|
||||
|
||||
### Rekapitulation zum teilweisen Ersetzen
|
||||
|
||||
@@ -161,29 +95,7 @@ Zusammengefasst, um Teil-Ersetzungen vorzunehmen:
|
||||
* Speichern Sie die Daten in Ihrer Datenbank.
|
||||
* Geben Sie das aktualisierte Modell zurück.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="28-35"
|
||||
{!> ../../docs_src/body_updates/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="30-37"
|
||||
{!> ../../docs_src/body_updates/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="30-37"
|
||||
{!> ../../docs_src/body_updates/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body_updates/tutorial002_py310.py hl[28:35] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -22,21 +22,7 @@ Da aber davon abgeraten wird, zeigt die interaktive Dokumentation mit Swagger-Be
|
||||
|
||||
Zuerst müssen Sie `BaseModel` von `pydantic` importieren:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="2"
|
||||
{!> ../../docs_src/body/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!> ../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body/tutorial001_py310.py hl[2] *}
|
||||
|
||||
## Erstellen Sie Ihr Datenmodell
|
||||
|
||||
@@ -44,21 +30,7 @@ Dann deklarieren Sie Ihr Datenmodell als eine Klasse, die von `BaseModel` erbt.
|
||||
|
||||
Verwenden Sie Standard-Python-Typen für die Klassenattribute:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="5-9"
|
||||
{!> ../../docs_src/body/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="7-11"
|
||||
{!> ../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body/tutorial001_py310.py hl[5:9] *}
|
||||
|
||||
Wie auch bei Query-Parametern gilt, wenn ein Modellattribut einen Defaultwert hat, ist das Attribut nicht erforderlich. Ansonsten ist es erforderlich. Verwenden Sie `None`, um es als optional zu kennzeichnen.
|
||||
|
||||
@@ -86,21 +58,7 @@ Da `description` und `tax` optional sind (mit `None` als Defaultwert), wäre fol
|
||||
|
||||
Um es zu Ihrer *Pfadoperation* hinzuzufügen, deklarieren Sie es auf die gleiche Weise, wie Sie Pfad- und Query-Parameter deklariert haben:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../docs_src/body/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../docs_src/body/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body/tutorial001_py310.py hl[16] *}
|
||||
|
||||
... und deklarieren Sie seinen Typ als das Modell, welches Sie erstellt haben, `Item`.
|
||||
|
||||
@@ -167,21 +125,7 @@ Es verbessert die Editor-Unterstützung für Pydantic-Modelle, mit:
|
||||
|
||||
Innerhalb der Funktion können Sie alle Attribute des Modells direkt verwenden:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/body/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../docs_src/body/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body/tutorial002_py310.py hl[19] *}
|
||||
|
||||
## Requestbody- + Pfad-Parameter
|
||||
|
||||
@@ -189,21 +133,7 @@ Sie können Pfad- und Requestbody-Parameter gleichzeitig deklarieren.
|
||||
|
||||
**FastAPI** erkennt, dass Funktionsparameter, die mit Pfad-Parametern übereinstimmen, **vom Pfad genommen** werden sollen, und dass Funktionsparameter, welche Pydantic-Modelle sind, **vom Requestbody genommen** werden sollen.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="15-16"
|
||||
{!> ../../docs_src/body/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="17-18"
|
||||
{!> ../../docs_src/body/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body/tutorial003_py310.py hl[15:16] *}
|
||||
|
||||
## Requestbody- + Pfad- + Query-Parameter
|
||||
|
||||
@@ -211,21 +141,7 @@ Sie können auch zur gleichen Zeit **Body-**, **Pfad-** und **Query-Parameter**
|
||||
|
||||
**FastAPI** wird jeden Parameter korrekt erkennen und die Daten vom richtigen Ort holen.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../docs_src/body/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../docs_src/body/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/body/tutorial004_py310.py hl[16] *}
|
||||
|
||||
Die Funktionsparameter werden wie folgt erkannt:
|
||||
|
||||
|
||||
@@ -6,57 +6,7 @@ So wie `Query`- und `Path`-Parameter können Sie auch <abbr title='Cookie –
|
||||
|
||||
Importieren Sie zuerst `Cookie`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/cookie_params/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/cookie_params/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/cookie_params/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/cookie_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[3] *}
|
||||
|
||||
## `Cookie`-Parameter deklarieren
|
||||
|
||||
@@ -64,57 +14,7 @@ Dann deklarieren Sie Ihre Cookie-Parameter, auf die gleiche Weise, wie Sie auch
|
||||
|
||||
Der erste Wert ist der Typ. Sie können `Cookie` die gehabten Extra Validierungs- und Beschreibungsparameter hinzufügen. Danach können Sie einen Defaultwert vergeben:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/cookie_params/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/cookie_params/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/cookie_params/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/cookie_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/cookie_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/cookie_params/tutorial001_an_py310.py hl[9] *}
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
|
||||
@@ -6,57 +6,7 @@ Bevor wir tiefer in das **Dependency Injection** System eintauchen, lassen Sie u
|
||||
|
||||
Im vorherigen Beispiel haben wir ein `dict` von unserer Abhängigkeit („Dependable“) zurückgegeben:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[9] *}
|
||||
|
||||
Aber dann haben wir ein `dict` im Parameter `commons` der *Pfadoperation-Funktion*.
|
||||
|
||||
@@ -119,165 +69,15 @@ Das gilt auch für Callables ohne Parameter. So wie es auch für *Pfadoperation-
|
||||
|
||||
Dann können wir das „Dependable“ `common_parameters` der Abhängigkeit von oben in die Klasse `CommonQueryParams` ändern:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="12-16"
|
||||
{!> ../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9-13"
|
||||
{!> ../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11-15"
|
||||
{!> ../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[11:15] *}
|
||||
|
||||
Achten Sie auf die Methode `__init__`, die zum Erstellen der Instanz der Klasse verwendet wird:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[12] *}
|
||||
|
||||
... sie hat die gleichen Parameter wie unsere vorherige `common_parameters`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8] *}
|
||||
|
||||
Diese Parameter werden von **FastAPI** verwendet, um die Abhängigkeit „aufzulösen“.
|
||||
|
||||
@@ -293,57 +93,7 @@ In beiden Fällen werden die Daten konvertiert, validiert, im OpenAPI-Schema dok
|
||||
|
||||
Jetzt können Sie Ihre Abhängigkeit mithilfe dieser Klasse deklarieren.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/dependencies/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/dependencies/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../docs_src/dependencies/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../docs_src/dependencies/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/dependencies/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial002_an_py310.py hl[19] *}
|
||||
|
||||
**FastAPI** ruft die Klasse `CommonQueryParams` auf. Dadurch wird eine „Instanz“ dieser Klasse erstellt und die Instanz wird als Parameter `commons` an Ihre Funktion überreicht.
|
||||
|
||||
@@ -437,57 +187,7 @@ commons = Depends(CommonQueryParams)
|
||||
|
||||
... wie in:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/dependencies/tutorial003_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/dependencies/tutorial003_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../docs_src/dependencies/tutorial003_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../docs_src/dependencies/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/dependencies/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial003_an_py310.py hl[19] *}
|
||||
|
||||
Es wird jedoch empfohlen, den Typ zu deklarieren, da Ihr Editor so weiß, was als Parameter `commons` übergeben wird, und Ihnen dann bei der Codevervollständigung, Typprüfungen, usw. helfen kann:
|
||||
|
||||
@@ -575,57 +275,7 @@ Sie deklarieren die Abhängigkeit als Typ des Parameters und verwenden `Depends(
|
||||
|
||||
Dasselbe Beispiel würde dann so aussehen:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/dependencies/tutorial004_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/dependencies/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../docs_src/dependencies/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../docs_src/dependencies/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/dependencies/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial004_an_py310.py hl[19] *}
|
||||
|
||||
... und **FastAPI** wird wissen, was zu tun ist.
|
||||
|
||||
|
||||
@@ -14,35 +14,7 @@ Der *Pfadoperation-Dekorator* erhält ein optionales Argument `dependencies`.
|
||||
|
||||
Es sollte eine `list`e von `Depends()` sein:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!> ../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
|
||||
|
||||
Diese Abhängigkeiten werden auf die gleiche Weise wie normale Abhängigkeiten ausgeführt/aufgelöst. Aber ihr Wert (falls sie einen zurückgeben) wird nicht an Ihre *Pfadoperation-Funktion* übergeben.
|
||||
|
||||
@@ -72,69 +44,13 @@ Sie können dieselben Abhängigkeits-*Funktionen* verwenden, die Sie normalerwei
|
||||
|
||||
Sie können Anforderungen für einen Request (wie Header) oder andere Unterabhängigkeiten deklarieren:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="8 13"
|
||||
{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="7 12"
|
||||
{!> ../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="6 11"
|
||||
{!> ../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
|
||||
|
||||
### Exceptions auslösen
|
||||
|
||||
Die Abhängigkeiten können Exceptions `raise`n, genau wie normale Abhängigkeiten:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10 15"
|
||||
{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
{!> ../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8 13"
|
||||
{!> ../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
|
||||
|
||||
### Rückgabewerte
|
||||
|
||||
@@ -142,35 +58,7 @@ Und sie können Werte zurückgeben oder nicht, die Werte werden nicht verwendet.
|
||||
|
||||
Sie können also eine normale Abhängigkeit (die einen Wert zurückgibt), die Sie bereits an anderer Stelle verwenden, wiederverwenden, und auch wenn der Wert nicht verwendet wird, wird die Abhängigkeit ausgeführt:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="11 16"
|
||||
{!> ../../docs_src/dependencies/tutorial006_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10 15"
|
||||
{!> ../../docs_src/dependencies/tutorial006_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
{!> ../../docs_src/dependencies/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
|
||||
|
||||
## Abhängigkeiten für eine Gruppe von *Pfadoperationen*
|
||||
|
||||
|
||||
@@ -29,21 +29,15 @@ Sie könnten damit beispielsweise eine Datenbanksession erstellen und diese nach
|
||||
|
||||
Nur der Code vor und einschließlich der `yield`-Anweisung wird ausgeführt, bevor eine Response erzeugt wird:
|
||||
|
||||
```Python hl_lines="2-4"
|
||||
{!../../docs_src/dependencies/tutorial007.py!}
|
||||
```
|
||||
{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *}
|
||||
|
||||
Der ge`yield`ete Wert ist das, was in *Pfadoperationen* und andere Abhängigkeiten eingefügt wird:
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!../../docs_src/dependencies/tutorial007.py!}
|
||||
```
|
||||
{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
|
||||
|
||||
Der auf die `yield`-Anweisung folgende Code wird ausgeführt, nachdem die Response gesendet wurde:
|
||||
|
||||
```Python hl_lines="5-6"
|
||||
{!../../docs_src/dependencies/tutorial007.py!}
|
||||
```
|
||||
{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -63,9 +57,7 @@ Sie können also mit `except SomeException` diese bestimmte Exception innerhalb
|
||||
|
||||
Auf die gleiche Weise können Sie `finally` verwenden, um sicherzustellen, dass die Exit-Schritte ausgeführt werden, unabhängig davon, ob eine Exception geworfen wurde oder nicht.
|
||||
|
||||
```Python hl_lines="3 5"
|
||||
{!../../docs_src/dependencies/tutorial007.py!}
|
||||
```
|
||||
{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
|
||||
|
||||
## Unterabhängigkeiten mit `yield`.
|
||||
|
||||
@@ -75,35 +67,7 @@ Sie können Unterabhängigkeiten und „Bäume“ von Unterabhängigkeiten belie
|
||||
|
||||
Beispielsweise kann `dependency_c` von `dependency_b` und `dependency_b` von `dependency_a` abhängen:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="6 14 22"
|
||||
{!> ../../docs_src/dependencies/tutorial008_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="5 13 21"
|
||||
{!> ../../docs_src/dependencies/tutorial008_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="4 12 20"
|
||||
{!> ../../docs_src/dependencies/tutorial008.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
|
||||
|
||||
Und alle können `yield` verwenden.
|
||||
|
||||
@@ -111,35 +75,7 @@ In diesem Fall benötigt `dependency_c` zum Ausführen seines Exit-Codes, dass d
|
||||
|
||||
Und wiederum benötigt `dependency_b` den Wert von `dependency_a` (hier `dep_a` genannt) für seinen Exit-Code.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="18-19 26-27"
|
||||
{!> ../../docs_src/dependencies/tutorial008_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="17-18 25-26"
|
||||
{!> ../../docs_src/dependencies/tutorial008_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="16-17 24-25"
|
||||
{!> ../../docs_src/dependencies/tutorial008.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
|
||||
|
||||
Auf die gleiche Weise könnten Sie einige Abhängigkeiten mit `yield` und einige andere Abhängigkeiten mit `return` haben, und alle können beliebig voneinander abhängen.
|
||||
|
||||
@@ -171,35 +107,7 @@ Aber es ist für Sie da, wenn Sie es brauchen. 🤓
|
||||
|
||||
///
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="18-22 31"
|
||||
{!> ../../docs_src/dependencies/tutorial008b_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="17-21 30"
|
||||
{!> ../../docs_src/dependencies/tutorial008b_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="16-20 29"
|
||||
{!> ../../docs_src/dependencies/tutorial008b.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
|
||||
|
||||
Eine Alternative zum Abfangen von Exceptions (und möglicherweise auch zum Auslösen einer weiteren `HTTPException`) besteht darin, einen [benutzerdefinierten Exceptionhandler](../handling-errors.md#benutzerdefinierte-exceptionhandler-definieren){.internal-link target=_blank} zu erstellen.
|
||||
|
||||
@@ -320,9 +228,7 @@ In Python können Sie Kontextmanager erstellen, indem Sie <a href="https://docs.
|
||||
|
||||
Sie können solche auch innerhalb von **FastAPI**-Abhängigkeiten mit `yield` verwenden, indem Sie `with`- oder `async with`-Anweisungen innerhalb der Abhängigkeits-Funktion verwenden:
|
||||
|
||||
```Python hl_lines="1-9 13"
|
||||
{!../../docs_src/dependencies/tutorial010.py!}
|
||||
```
|
||||
{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -6,35 +6,7 @@ Bei einigen Anwendungstypen möchten Sie möglicherweise Abhängigkeiten zur ges
|
||||
|
||||
In diesem Fall werden sie auf alle *Pfadoperationen* in der Anwendung angewendet:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../docs_src/dependencies/tutorial012_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../docs_src/dependencies/tutorial012_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../docs_src/dependencies/tutorial012.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[16] *}
|
||||
|
||||
Und alle Ideen aus dem Abschnitt über das [Hinzufügen von `dependencies` zu den *Pfadoperation-Dekoratoren*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} gelten weiterhin, aber in diesem Fall für alle *Pfadoperationen* in der Anwendung.
|
||||
|
||||
|
||||
@@ -30,57 +30,7 @@ Aber so können wir uns besser auf die Funktionsweise des **Dependency Injection
|
||||
Konzentrieren wir uns zunächst auf die Abhängigkeit - die Dependency.
|
||||
|
||||
Es handelt sich einfach um eine Funktion, die die gleichen Parameter entgegennimmt wie eine *Pfadoperation-Funktion*:
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="8-11"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9-12"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!> ../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8-11"
|
||||
{!> ../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[8:9] *}
|
||||
|
||||
Das war's schon.
|
||||
|
||||
@@ -112,113 +62,13 @@ Bitte [aktualisieren Sie FastAPI](../../deployment/versions.md#upgrade-der-fasta
|
||||
|
||||
### `Depends` importieren
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[3] *}
|
||||
|
||||
### Deklarieren der Abhängigkeit im <abbr title="Das Abhängige, der Verwender der Abhängigkeit">„Dependant“</abbr>
|
||||
|
||||
So wie auch `Body`, `Query`, usw., verwenden Sie `Depends` mit den Parametern Ihrer *Pfadoperation-Funktion*:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="13 18"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="15 20"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="16 21"
|
||||
{!> ../../docs_src/dependencies/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11 16"
|
||||
{!> ../../docs_src/dependencies/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="15 20"
|
||||
{!> ../../docs_src/dependencies/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial001_an_py310.py hl[13,18] *}
|
||||
|
||||
Obwohl Sie `Depends` in den Parametern Ihrer Funktion genauso verwenden wie `Body`, `Query`, usw., funktioniert `Depends` etwas anders.
|
||||
|
||||
@@ -275,29 +125,7 @@ commons: Annotated[dict, Depends(common_parameters)]
|
||||
|
||||
Da wir jedoch `Annotated` verwenden, können wir diesen `Annotated`-Wert in einer Variablen speichern und an mehreren Stellen verwenden:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="12 16 21"
|
||||
{!> ../../docs_src/dependencies/tutorial001_02_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="14 18 23"
|
||||
{!> ../../docs_src/dependencies/tutorial001_02_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="15 19 24"
|
||||
{!> ../../docs_src/dependencies/tutorial001_02_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial001_02_an_py310.py hl[12,16,21] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -10,57 +10,7 @@ Diese können so **tief** verschachtelt sein, wie nötig.
|
||||
|
||||
Sie könnten eine erste Abhängigkeit („Dependable“) wie folgt erstellen:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../docs_src/dependencies/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../docs_src/dependencies/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9-10"
|
||||
{!> ../../docs_src/dependencies/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10 nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!> ../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[8:9] *}
|
||||
|
||||
Diese deklariert einen optionalen Abfrageparameter `q` vom Typ `str` und gibt ihn dann einfach zurück.
|
||||
|
||||
@@ -70,57 +20,7 @@ Das ist recht einfach (nicht sehr nützlich), hilft uns aber dabei, uns auf die
|
||||
|
||||
Dann können Sie eine weitere Abhängigkeitsfunktion (ein „Dependable“) erstellen, die gleichzeitig eine eigene Abhängigkeit deklariert (also auch ein „Dependant“ ist):
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../docs_src/dependencies/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../docs_src/dependencies/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../docs_src/dependencies/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10 nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[13] *}
|
||||
|
||||
Betrachten wir die deklarierten Parameter:
|
||||
|
||||
@@ -133,57 +33,7 @@ Betrachten wir die deklarierten Parameter:
|
||||
|
||||
Diese Abhängigkeit verwenden wir nun wie folgt:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="23"
|
||||
{!> ../../docs_src/dependencies/tutorial005_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="23"
|
||||
{!> ../../docs_src/dependencies/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!> ../../docs_src/dependencies/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10 nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/dependencies/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../docs_src/dependencies/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/dependencies/tutorial005_an_py310.py hl[23] *}
|
||||
|
||||
/// info
|
||||
|
||||
|
||||
@@ -20,21 +20,7 @@ Sie können für diese Fälle `jsonable_encoder` verwenden.
|
||||
|
||||
Es nimmt ein Objekt entgegen, wie etwa ein Pydantic-Modell, und gibt eine JSON-kompatible Version zurück:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="4 21"
|
||||
{!> ../../docs_src/encoder/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="5 22"
|
||||
{!> ../../docs_src/encoder/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/encoder/tutorial001_py310.py hl[4,21] *}
|
||||
|
||||
In diesem Beispiel wird das Pydantic-Modell in ein `dict`, und das `datetime`-Objekt in ein `str` konvertiert.
|
||||
|
||||
|
||||
@@ -55,108 +55,8 @@ Hier sind einige der zusätzlichen Datentypen, die Sie verwenden können:
|
||||
|
||||
Hier ist ein Beispiel für eine *Pfadoperation* mit Parametern, die einige der oben genannten Typen verwenden.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1 3 12-16"
|
||||
{!> ../../docs_src/extra_data_types/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="1 3 12-16"
|
||||
{!> ../../docs_src/extra_data_types/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 3 13-17"
|
||||
{!> ../../docs_src/extra_data_types/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1 2 11-15"
|
||||
{!> ../../docs_src/extra_data_types/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1 2 12-16"
|
||||
{!> ../../docs_src/extra_data_types/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/extra_data_types/tutorial001_an_py310.py hl[1,3,12:16] *}
|
||||
|
||||
Beachten Sie, dass die Parameter innerhalb der Funktion ihren natürlichen Datentyp haben und Sie beispielsweise normale Datumsmanipulationen durchführen können, wie zum Beispiel:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="18-19"
|
||||
{!> ../../docs_src/extra_data_types/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="18-19"
|
||||
{!> ../../docs_src/extra_data_types/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="19-20"
|
||||
{!> ../../docs_src/extra_data_types/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="17-18"
|
||||
{!> ../../docs_src/extra_data_types/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="18-19"
|
||||
{!> ../../docs_src/extra_data_types/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/extra_data_types/tutorial001_an_py310.py hl[18:19] *}
|
||||
|
||||
@@ -20,21 +20,7 @@ Falls Ihnen das nichts sagt, in den [Sicherheits-Kapiteln](security/simple-oauth
|
||||
|
||||
Hier der generelle Weg, wie die Modelle mit ihren Passwort-Feldern aussehen könnten, und an welchen Orten sie verwendet werden würden.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7 9 14 20 22 27-28 31-33 38-39"
|
||||
{!> ../../docs_src/extra_models/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9 11 16 22 24 29-30 33-35 40-41"
|
||||
{!> ../../docs_src/extra_models/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
|
||||
|
||||
/// info
|
||||
|
||||
@@ -176,21 +162,7 @@ Die ganze Datenkonvertierung, -validierung, -dokumentation, usw. wird immer noch
|
||||
|
||||
Auf diese Weise beschreiben wir nur noch die Unterschiede zwischen den Modellen (mit Klartext-`password`, mit `hashed_password`, und ohne Passwort):
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7 13-14 17-18 21-22"
|
||||
{!> ../../docs_src/extra_models/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9 15-16 19-20 23-24"
|
||||
{!> ../../docs_src/extra_models/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/extra_models/tutorial002_py310.py hl[7,13:14,17:18,21:22] *}
|
||||
|
||||
## `Union`, oder `anyOf`
|
||||
|
||||
@@ -206,21 +178,7 @@ Listen Sie, wenn Sie eine <a href="https://pydantic-docs.helpmanual.io/usage/typ
|
||||
|
||||
///
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1 14-15 18-20 33"
|
||||
{!> ../../docs_src/extra_models/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 14-15 18-20 33"
|
||||
{!> ../../docs_src/extra_models/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *}
|
||||
|
||||
### `Union` in Python 3.10
|
||||
|
||||
@@ -242,21 +200,7 @@ Genauso können Sie eine Response deklarieren, die eine Liste von Objekten ist.
|
||||
|
||||
Verwenden Sie dafür Pythons Standard `typing.List` (oder nur `list` in Python 3.9 und darüber):
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../docs_src/extra_models/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 20"
|
||||
{!> ../../docs_src/extra_models/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
|
||||
|
||||
## Response mit beliebigem `dict`
|
||||
|
||||
@@ -266,21 +210,7 @@ Das ist nützlich, wenn Sie die gültigen Feld-/Attribut-Namen von vorneherein n
|
||||
|
||||
In diesem Fall können Sie `typing.Dict` verwenden (oder nur `dict` in Python 3.9 und darüber):
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../docs_src/extra_models/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 8"
|
||||
{!> ../../docs_src/extra_models/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
Die einfachste FastAPI-Datei könnte wie folgt aussehen:
|
||||
|
||||
```Python
|
||||
{!../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/first_steps/tutorial001.py *}
|
||||
|
||||
Kopieren Sie dies in eine Datei `main.py`.
|
||||
|
||||
@@ -133,9 +131,7 @@ Ebenfalls können Sie es verwenden, um automatisch Code für Clients zu generier
|
||||
|
||||
### Schritt 1: Importieren von `FastAPI`
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
|
||||
|
||||
`FastAPI` ist eine Python-Klasse, die die gesamte Funktionalität für Ihre API bereitstellt.
|
||||
|
||||
@@ -149,9 +145,7 @@ Sie können alle <a href="https://www.starlette.io/" class="external-link" targe
|
||||
|
||||
### Schritt 2: Erzeugen einer `FastAPI`-„Instanz“
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
|
||||
|
||||
In diesem Beispiel ist die Variable `app` eine „Instanz“ der Klasse `FastAPI`.
|
||||
|
||||
@@ -171,9 +165,7 @@ $ uvicorn main:app --reload
|
||||
|
||||
Wenn Sie Ihre Anwendung wie folgt erstellen:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../docs_src/first_steps/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/first_steps/tutorial002.py hl[3] *}
|
||||
|
||||
Und in eine Datei `main.py` einfügen, dann würden Sie `uvicorn` wie folgt aufrufen:
|
||||
|
||||
@@ -250,9 +242,7 @@ Wir werden sie auch „**Operationen**“ nennen.
|
||||
|
||||
#### Definieren eines *Pfadoperation-Dekorators*
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
|
||||
|
||||
Das `@app.get("/")` sagt **FastAPI**, dass die Funktion direkt darunter für die Bearbeitung von Anfragen zuständig ist, die an:
|
||||
|
||||
@@ -306,9 +296,7 @@ Das ist unsere „**Pfadoperation-Funktion**“:
|
||||
* **Operation**: ist `get`.
|
||||
* **Funktion**: ist die Funktion direkt unter dem „Dekorator“ (unter `@app.get("/")`).
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
|
||||
|
||||
Dies ist eine Python-Funktion.
|
||||
|
||||
@@ -320,9 +308,7 @@ In diesem Fall handelt es sich um eine `async`-Funktion.
|
||||
|
||||
Sie könnten sie auch als normale Funktion anstelle von `async def` definieren:
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!../../docs_src/first_steps/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
@@ -332,9 +318,7 @@ Wenn Sie den Unterschied nicht kennen, lesen Sie [Async: *„In Eile?“*](../as
|
||||
|
||||
### Schritt 5: den Inhalt zurückgeben
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!../../docs_src/first_steps/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
|
||||
|
||||
Sie können ein `dict`, eine `list`, einzelne Werte wie `str`, `int`, usw. zurückgeben.
|
||||
|
||||
|
||||
@@ -25,9 +25,7 @@ Um HTTP-Responses mit Fehlern zum Client zurückzugeben, verwenden Sie `HTTPExce
|
||||
|
||||
### `HTTPException` importieren
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!../../docs_src/handling_errors/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
|
||||
|
||||
### Eine `HTTPException` in Ihrem Code auslösen
|
||||
|
||||
@@ -41,9 +39,7 @@ Der Vorteil, eine Exception auszulösen (`raise`), statt sie zurückzugeben (`re
|
||||
|
||||
Im folgenden Beispiel lösen wir, wenn der Client eine ID anfragt, die nicht existiert, eine Exception mit dem Statuscode `404` aus.
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!../../docs_src/handling_errors/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/handling_errors/tutorial001.py hl[11] *}
|
||||
|
||||
### Die resultierende Response
|
||||
|
||||
@@ -81,9 +77,7 @@ Sie müssen das wahrscheinlich nicht direkt in ihrem Code verwenden.
|
||||
|
||||
Aber falls es in einem fortgeschrittenen Szenario notwendig ist, können Sie benutzerdefinierte Header wie folgt hinzufügen:
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!../../docs_src/handling_errors/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/handling_errors/tutorial002.py hl[14] *}
|
||||
|
||||
## Benutzerdefinierte Exceptionhandler definieren
|
||||
|
||||
@@ -95,9 +89,7 @@ Und Sie möchten diese Exception global mit FastAPI handhaben.
|
||||
|
||||
Sie könnten einen benutzerdefinierten Exceptionhandler mittels `@app.exception_handler()` hinzufügen:
|
||||
|
||||
```Python hl_lines="5-7 13-18 24"
|
||||
{!../../docs_src/handling_errors/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *}
|
||||
|
||||
Wenn Sie nun `/unicorns/yolo` anfragen, `raise`d die *Pfadoperation* eine `UnicornException`.
|
||||
|
||||
@@ -135,9 +127,7 @@ Um diesen zu überschreiben, importieren Sie den `RequestValidationError` und ve
|
||||
|
||||
Der Exceptionhandler wird einen `Request` und die Exception entgegennehmen.
|
||||
|
||||
```Python hl_lines="2 14-16"
|
||||
{!../../docs_src/handling_errors/tutorial004.py!}
|
||||
```
|
||||
{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:16] *}
|
||||
|
||||
Wenn Sie nun `/items/foo` besuchen, erhalten Sie statt des Default-JSON-Errors:
|
||||
|
||||
@@ -188,9 +178,7 @@ Genauso können Sie den `HTTPException`-Handler überschreiben.
|
||||
|
||||
Zum Beispiel könnten Sie eine Klartext-Response statt JSON für diese Fehler zurückgeben wollen:
|
||||
|
||||
```Python hl_lines="3-4 9-11 22"
|
||||
{!../../docs_src/handling_errors/tutorial004.py!}
|
||||
```
|
||||
{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,22] *}
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
@@ -206,9 +194,7 @@ Der `RequestValidationError` enthält den empfangenen `body` mit den ungültigen
|
||||
|
||||
Sie könnten diesen verwenden, während Sie Ihre Anwendung entwickeln, um den Body zu loggen und zu debuggen, ihn zum Benutzer zurückzugeben, usw.
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!../../docs_src/handling_errors/tutorial005.py!}
|
||||
```
|
||||
{* ../../docs_src/handling_errors/tutorial005.py hl[14] *}
|
||||
|
||||
Jetzt versuchen Sie, einen ungültigen Artikel zu senden:
|
||||
|
||||
@@ -264,8 +250,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
|
||||
|
||||
Wenn Sie die Exception zusammen mit denselben Default-Exceptionhandlern von **FastAPI** verwenden möchten, können Sie die Default-Exceptionhandler von `fastapi.Exception_handlers` importieren und wiederverwenden:
|
||||
|
||||
```Python hl_lines="2-5 15 21"
|
||||
{!../../docs_src/handling_errors/tutorial006.py!}
|
||||
```
|
||||
{* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *}
|
||||
|
||||
In diesem Beispiel `print`en Sie nur den Fehler mit einer sehr ausdrucksstarken Nachricht, aber Sie sehen, worauf wir hinauswollen. Sie können mit der Exception etwas machen und dann einfach die Default-Exceptionhandler wiederverwenden.
|
||||
|
||||
@@ -6,57 +6,7 @@ So wie `Query`-, `Path`-, und `Cookie`-Parameter können Sie auch <abbr title='H
|
||||
|
||||
Importieren Sie zuerst `Header`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/header_params/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/header_params/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/header_params/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/header_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/header_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/header_params/tutorial001_an_py310.py hl[3] *}
|
||||
|
||||
## `Header`-Parameter deklarieren
|
||||
|
||||
@@ -64,57 +14,7 @@ Dann deklarieren Sie Ihre Header-Parameter, auf die gleiche Weise, wie Sie auch
|
||||
|
||||
Der erste Wert ist der Typ. Sie können `Header` die gehabten Extra Validierungs- und Beschreibungsparameter hinzufügen. Danach können Sie einen Defaultwert vergeben:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/header_params/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/header_params/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/header_params/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/header_params/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/header_params/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/header_params/tutorial001_an_py310.py hl[9] *}
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
@@ -146,57 +46,7 @@ Sie können also `user_agent` schreiben, wie Sie es normalerweise in Python-Code
|
||||
|
||||
Wenn Sie aus irgendeinem Grund das automatische Konvertieren von Unterstrichen zu Bindestrichen abschalten möchten, setzen Sie den Parameter `convert_underscores` auf `False`.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/header_params/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/header_params/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/header_params/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/header_params/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/header_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/header_params/tutorial002_an_py310.py hl[10] *}
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
@@ -214,71 +64,7 @@ Sie erhalten dann alle Werte von diesem doppelten Header als Python-`list`e.
|
||||
|
||||
Um zum Beispiel einen Header `X-Token` zu deklarieren, der mehrmals vorkommen kann, schreiben Sie:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/header_params/tutorial003_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/header_params/tutorial003_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/header_params/tutorial003_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/header_params/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/header_params/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/header_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/header_params/tutorial003_an_py310.py hl[9] *}
|
||||
|
||||
Wenn Sie mit einer *Pfadoperation* kommunizieren, die zwei HTTP-Header sendet, wie:
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@ Sie können die folgenden Felder festlegen, welche in der OpenAPI-Spezifikation
|
||||
|
||||
Sie können diese wie folgt setzen:
|
||||
|
||||
```Python hl_lines="3-16 19-32"
|
||||
{!../../docs_src/metadata/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/metadata/tutorial001.py hl[3:16,19:32] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -38,9 +36,7 @@ Seit OpenAPI 3.1.0 und FastAPI 0.99.0 können Sie die `license_info` auch mit ei
|
||||
|
||||
Zum Beispiel:
|
||||
|
||||
```Python hl_lines="31"
|
||||
{!../../docs_src/metadata/tutorial001_1.py!}
|
||||
```
|
||||
{* ../../docs_src/metadata/tutorial001_1.py hl[31] *}
|
||||
|
||||
## Metadaten für Tags
|
||||
|
||||
@@ -62,9 +58,7 @@ Versuchen wir das an einem Beispiel mit Tags für `users` und `items`.
|
||||
|
||||
Erstellen Sie Metadaten für Ihre Tags und übergeben Sie sie an den Parameter `openapi_tags`:
|
||||
|
||||
```Python hl_lines="3-16 18"
|
||||
{!../../docs_src/metadata/tutorial004.py!}
|
||||
```
|
||||
{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
|
||||
|
||||
Beachten Sie, dass Sie Markdown in den Beschreibungen verwenden können. Beispielsweise wird „login“ in Fettschrift (**login**) und „fancy“ in Kursivschrift (_fancy_) angezeigt.
|
||||
|
||||
@@ -78,9 +72,7 @@ Sie müssen nicht für alle von Ihnen verwendeten Tags Metadaten hinzufügen.
|
||||
|
||||
Verwenden Sie den Parameter `tags` mit Ihren *Pfadoperationen* (und `APIRouter`n), um diese verschiedenen Tags zuzuweisen:
|
||||
|
||||
```Python hl_lines="21 26"
|
||||
{!../../docs_src/metadata/tutorial004.py!}
|
||||
```
|
||||
{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
|
||||
|
||||
/// info
|
||||
|
||||
@@ -108,9 +100,7 @@ Sie können das aber mit dem Parameter `openapi_url` konfigurieren.
|
||||
|
||||
Um beispielsweise festzulegen, dass es unter `/api/v1/openapi.json` bereitgestellt wird:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../docs_src/metadata/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/metadata/tutorial002.py hl[3] *}
|
||||
|
||||
Wenn Sie das OpenAPI-Schema vollständig deaktivieren möchten, können Sie `openapi_url=None` festlegen, wodurch auch die Dokumentationsbenutzeroberflächen deaktiviert werden, die es verwenden.
|
||||
|
||||
@@ -127,6 +117,4 @@ Sie können die beiden enthaltenen Dokumentationsbenutzeroberflächen konfigurie
|
||||
|
||||
Um beispielsweise Swagger UI so einzustellen, dass sie unter `/documentation` bereitgestellt wird, und ReDoc zu deaktivieren:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../docs_src/metadata/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/metadata/tutorial003.py hl[3] *}
|
||||
|
||||
@@ -16,29 +16,7 @@ Sie können direkt den `int`-Code übergeben, etwa `404`.
|
||||
|
||||
Aber falls Sie sich nicht mehr erinnern, wofür jede Nummer steht, können Sie die Abkürzungs-Konstanten in `status` verwenden:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1 15"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="3 17"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="3 17"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_operation_configuration/tutorial001_py310.py hl[1,15] *}
|
||||
|
||||
Dieser Statuscode wird in der Response verwendet und zum OpenAPI-Schema hinzugefügt.
|
||||
|
||||
@@ -54,29 +32,7 @@ Sie können auch `from starlette import status` verwenden.
|
||||
|
||||
Sie können Ihrer *Pfadoperation* Tags hinzufügen, mittels des Parameters `tags`, dem eine `list`e von `str`s übergeben wird (in der Regel nur ein `str`):
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="15 20 25"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="17 22 27"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="17 22 27"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_operation_configuration/tutorial002_py310.py hl[15,20,25] *}
|
||||
|
||||
Diese werden zum OpenAPI-Schema hinzugefügt und von den automatischen Dokumentations-Benutzeroberflächen verwendet:
|
||||
|
||||
@@ -90,37 +46,13 @@ In diesem Fall macht es Sinn, die Tags in einem `Enum` zu speichern.
|
||||
|
||||
**FastAPI** unterstützt diese genauso wie einfache Strings:
|
||||
|
||||
```Python hl_lines="1 8-10 13 18"
|
||||
{!../../docs_src/path_operation_configuration/tutorial002b.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_configuration/tutorial002b.py hl[1,8:10,13,18] *}
|
||||
|
||||
## Zusammenfassung und Beschreibung
|
||||
|
||||
Sie können eine Zusammenfassung (`summary`) und eine Beschreibung (`description`) hinzufügen:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="18-19"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="20-21"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="20-21"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_operation_configuration/tutorial003_py310.py hl[18:19] *}
|
||||
|
||||
## Beschreibung mittels Docstring
|
||||
|
||||
@@ -128,29 +60,7 @@ Da Beschreibungen oft mehrere Zeilen lang sind, können Sie die Beschreibung der
|
||||
|
||||
Sie können im Docstring <a href="https://en.wikipedia.org/wiki/Markdown" class="external-link" target="_blank">Markdown</a> schreiben, es wird korrekt interpretiert und angezeigt (die Einrückung des Docstring beachtend).
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="17-25"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="19-27"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="19-27"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_operation_configuration/tutorial004_py310.py hl[17:25] *}
|
||||
|
||||
In der interaktiven Dokumentation sieht das dann so aus:
|
||||
|
||||
@@ -160,29 +70,7 @@ In der interaktiven Dokumentation sieht das dann so aus:
|
||||
|
||||
Die Response können Sie mit dem Parameter `response_description` beschreiben:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial005_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="21"
|
||||
{!> ../../docs_src/path_operation_configuration/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_operation_configuration/tutorial005_py310.py hl[19] *}
|
||||
|
||||
/// info
|
||||
|
||||
@@ -204,9 +92,7 @@ Daher, wenn Sie keine vergeben, wird **FastAPI** automatisch eine für „Erfolg
|
||||
|
||||
Wenn Sie eine *Pfadoperation* als <abbr title="deprecated – obsolet, veraltet: Es soll nicht mehr verwendet werden">deprecated</abbr> kennzeichnen möchten, ohne sie zu entfernen, fügen Sie den Parameter `deprecated` hinzu:
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!../../docs_src/path_operation_configuration/tutorial006.py!}
|
||||
```
|
||||
{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *}
|
||||
|
||||
Sie wird in der interaktiven Dokumentation gut sichtbar als deprecated markiert werden:
|
||||
|
||||
|
||||
@@ -6,57 +6,7 @@ So wie Sie mit `Query` für Query-Parameter zusätzliche Validierungen und Metad
|
||||
|
||||
Importieren Sie zuerst `Path` von `fastapi`, und importieren Sie `Annotated`.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1 3"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="1 3"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="3-4"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[1,3] *}
|
||||
|
||||
/// info
|
||||
|
||||
@@ -74,57 +24,7 @@ Sie können die gleichen Parameter deklarieren wie für `Query`.
|
||||
|
||||
Um zum Beispiel einen `title`-Metadaten-Wert für den Pfad-Parameter `item_id` zu deklarieren, schreiben Sie:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial001_an_py310.py hl[10] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
@@ -174,21 +74,7 @@ Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
Aber bedenken Sie, dass Sie dieses Problem nicht haben, wenn Sie `Annotated` verwenden, da Sie nicht die Funktions-Parameter-Defaultwerte für `Query()` oder `Path()` verwenden.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py hl[10] *}
|
||||
|
||||
## Sortieren Sie die Parameter wie Sie möchten: Tricks
|
||||
|
||||
@@ -213,64 +99,20 @@ Wenn Sie eines der folgenden Dinge tun möchten:
|
||||
|
||||
Python macht nichts mit diesem `*`, aber es wird wissen, dass alle folgenden Parameter als <abbr title="Keyword-Argument – Schlüsselwort-Argument: Das Argument wird anhand seines Namens erkannt, nicht anhand seiner Reihenfolge in der Argumentliste">Keyword-Argumente</abbr> (Schlüssel-Wert-Paare), auch bekannt als <abbr title="Von: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>, verwendet werden. Selbst wenn diese keinen Defaultwert haben.
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!../../docs_src/path_params_numeric_validations/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
|
||||
|
||||
### Besser mit `Annotated`
|
||||
|
||||
Bedenken Sie, dass Sie, wenn Sie `Annotated` verwenden, dieses Problem nicht haben, weil Sie keine Defaultwerte für Ihre Funktionsparameter haben. Sie müssen daher wahrscheinlich auch nicht `*` verwenden.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial003_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
|
||||
|
||||
## Validierung von Zahlen: Größer oder gleich
|
||||
|
||||
Mit `Query` und `Path` (und anderen, die Sie später kennenlernen), können Sie Zahlenbeschränkungen deklarieren.
|
||||
|
||||
Hier, mit `ge=1`, wird festgelegt, dass `item_id` eine Ganzzahl benötigt, die größer oder gleich `1` ist (`g`reater than or `e`qual).
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
|
||||
|
||||
## Validierung von Zahlen: Größer und kleiner oder gleich
|
||||
|
||||
@@ -279,35 +121,7 @@ Das Gleiche trifft zu auf:
|
||||
* `gt`: `g`reater `t`han – größer als
|
||||
* `le`: `l`ess than or `e`qual – kleiner oder gleich
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
|
||||
|
||||
## Validierung von Zahlen: Floats, größer und kleiner
|
||||
|
||||
@@ -319,35 +133,7 @@ Hier wird es wichtig, in der Lage zu sein, <abbr title="greater than – größe
|
||||
|
||||
Das gleiche gilt für <abbr title="less than – kleiner als"><code>lt</code></abbr>.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial006_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/path_params_numeric_validations/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
Sie können Pfad-„Parameter“ oder -„Variablen“ mit der gleichen Syntax deklarieren, welche in Python-<abbr title="Format-String – Formatierter String: Der String enthält Variablen, die mit geschweiften Klammern umschlossen sind. Solche Stellen werden durch den Wert der Variable ersetzt">Format-Strings</abbr> verwendet wird:
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!../../docs_src/path_params/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
|
||||
|
||||
Der Wert des Pfad-Parameters `item_id` wird Ihrer Funktion als das Argument `item_id` übergeben.
|
||||
|
||||
@@ -18,9 +16,7 @@ Wenn Sie dieses Beispiel ausführen und auf <a href="http://127.0.0.1:8000/items
|
||||
|
||||
Sie können den Typ eines Pfad-Parameters in der Argumentliste der Funktion deklarieren, mit Standard-Python-Typannotationen:
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!../../docs_src/path_params/tutorial002.py!}
|
||||
```
|
||||
{* ../../docs_src/path_params/tutorial002.py hl[7] *}
|
||||
|
||||
In diesem Fall wird `item_id` als `int` deklariert, also als Ganzzahl.
|
||||
|
||||
@@ -60,8 +56,7 @@ Wenn Sie aber im Browser <a href="http://127.0.0.1:8000/items/foo" class="extern
|
||||
"item_id"
|
||||
],
|
||||
"msg": "Input should be a valid integer, unable to parse string as an integer",
|
||||
"input": "foo",
|
||||
"url": "https://errors.pydantic.dev/2.1/v/int_parsing"
|
||||
"input": "foo"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -123,17 +118,13 @@ Und Sie haben auch einen Pfad `/users/{user_id}`, um Daten über einen spezifisc
|
||||
|
||||
Weil *Pfadoperationen* in ihrer Reihenfolge ausgewertet werden, müssen Sie sicherstellen, dass der Pfad `/users/me` vor `/users/{user_id}` deklariert wurde:
|
||||
|
||||
```Python hl_lines="6 11"
|
||||
{!../../docs_src/path_params/tutorial003.py!}
|
||||
```
|
||||
{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
|
||||
|
||||
Ansonsten würde der Pfad für `/users/{user_id}` auch `/users/me` auswerten, und annehmen, dass ein Parameter `user_id` mit dem Wert `"me"` übergeben wurde.
|
||||
|
||||
Sie können eine Pfadoperation auch nicht erneut definieren:
|
||||
|
||||
```Python hl_lines="6 11"
|
||||
{!../../docs_src/path_params/tutorial003b.py!}
|
||||
```
|
||||
{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
|
||||
|
||||
Die erste Definition wird immer verwendet werden, da ihr Pfad zuerst übereinstimmt.
|
||||
|
||||
@@ -149,9 +140,7 @@ Indem Sie von `str` erben, weiß die API Dokumentation, dass die Werte des Enums
|
||||
|
||||
Erstellen Sie dann Klassen-Attribute mit festgelegten Werten, welches die erlaubten Werte sein werden:
|
||||
|
||||
```Python hl_lines="1 6-9"
|
||||
{!../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
|
||||
|
||||
/// info
|
||||
|
||||
@@ -169,9 +158,7 @@ Falls Sie sich fragen, was „AlexNet“, „ResNet“ und „LeNet“ ist, das
|
||||
|
||||
Dann erstellen Sie einen *Pfad-Parameter*, der als Typ die gerade erstellte Enum-Klasse hat (`ModelName`):
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
{* ../../docs_src/path_params/tutorial005.py hl[16] *}
|
||||
|
||||
### Testen Sie es in der API-Dokumentation
|
||||
|
||||
@@ -187,17 +174,13 @@ Der *Pfad-Parameter* wird ein *<abbr title="Member – Mitglied: Einer der mögl
|
||||
|
||||
Sie können ihn mit einem Member Ihres Enums `ModelName` vergleichen:
|
||||
|
||||
```Python hl_lines="17"
|
||||
{!../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
{* ../../docs_src/path_params/tutorial005.py hl[17] *}
|
||||
|
||||
#### *Enum-Wert* erhalten
|
||||
|
||||
Den tatsächlichen Wert (in diesem Fall ein `str`) erhalten Sie via `model_name.value`, oder generell, `ihr_enum_member.value`:
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
{* ../../docs_src/path_params/tutorial005.py hl[20] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -211,9 +194,7 @@ Sie können *Enum-Member* in ihrer *Pfadoperation* zurückgeben, sogar verschach
|
||||
|
||||
Diese werden zu ihren entsprechenden Werten konvertiert (in diesem Fall Strings), bevor sie zum Client übertragen werden:
|
||||
|
||||
```Python hl_lines="18 21 23"
|
||||
{!../../docs_src/path_params/tutorial005.py!}
|
||||
```
|
||||
{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
|
||||
|
||||
In Ihrem Client erhalten Sie eine JSON-Response, wie etwa:
|
||||
|
||||
@@ -252,9 +233,7 @@ In diesem Fall ist der Name des Parameters `file_path`. Der letzte Teil, `:path`
|
||||
|
||||
Sie verwenden das also wie folgt:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../docs_src/path_params/tutorial004.py!}
|
||||
```
|
||||
{* ../../docs_src/path_params/tutorial004.py hl[6] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -4,21 +4,7 @@
|
||||
|
||||
Nehmen wir als Beispiel die folgende Anwendung:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial001_py310.py hl[7] *}
|
||||
|
||||
Der Query-Parameter `q` hat den Typ `Union[str, None]` (oder `str | None` in Python 3.10), was bedeutet, er ist entweder ein `str` oder `None`. Der Defaultwert ist `None`, also weiß FastAPI, der Parameter ist nicht erforderlich.
|
||||
|
||||
@@ -123,21 +109,7 @@ Wenden wir uns jetzt den spannenden Dingen zu. 🎉
|
||||
|
||||
Jetzt, da wir `Annotated` für unsere Metadaten deklariert haben, fügen Sie `Query` hinzu, und setzen Sie den Parameter `max_length` auf `50`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial002_an_py310.py hl[9] *}
|
||||
|
||||
Beachten Sie, dass der Defaultwert immer noch `None` ist, sodass der Parameter immer noch optional ist.
|
||||
|
||||
@@ -161,21 +133,7 @@ Verwenden Sie für neuen Code, und wann immer möglich, `Annotated`, wie oben er
|
||||
|
||||
So würden Sie `Query()` als Defaultwert Ihres Funktionsparameters verwenden, den Parameter `max_length` auf 50 gesetzt:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial002_py310.py hl[7] *}
|
||||
|
||||
Da wir in diesem Fall (ohne die Verwendung von `Annotated`) den Parameter-Defaultwert `None` mit `Query()` ersetzen, müssen wir nun dessen Defaultwert mit dem Parameter `Query(default=None)` deklarieren. Das dient demselben Zweck, `None` als Defaultwert für den Funktionsparameter zu setzen (zumindest für FastAPI).
|
||||
|
||||
@@ -275,113 +233,13 @@ Da `Annotated` mehrere Metadaten haben kann, können Sie dieselbe Funktion auch
|
||||
|
||||
Sie können auch einen Parameter `min_length` hinzufügen:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial003_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial003_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial003_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial003_an_py310.py hl[10] *}
|
||||
|
||||
## Reguläre Ausdrücke hinzufügen
|
||||
|
||||
Sie können einen <abbr title="Ein regulärer Ausdruck, auch regex oder regexp genannt, ist eine Zeichensequenz, die ein Suchmuster für Strings definiert.">Regulären Ausdruck</abbr> `pattern` definieren, mit dem der Parameter übereinstimmen muss:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial004_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial004_an_py310.py hl[11] *}
|
||||
|
||||
Dieses bestimmte reguläre Suchmuster prüft, ob der erhaltene Parameter-Wert:
|
||||
|
||||
@@ -399,11 +257,9 @@ Vor Pydantic Version 2 und vor FastAPI Version 0.100.0, war der Name des Paramet
|
||||
|
||||
Sie könnten immer noch Code sehen, der den alten Namen verwendet:
|
||||
|
||||
//// tab | Python 3.10+ Pydantic v1
|
||||
//// tab | Pydantic v1
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial004_an_py310_regex.py!}
|
||||
```
|
||||
{* ../../docs_src/query_params_str_validations/tutorial004_regex_an_py310.py hl[11] *}
|
||||
|
||||
////
|
||||
|
||||
@@ -415,35 +271,7 @@ Sie können natürlich andere Defaultwerte als `None` verwenden.
|
||||
|
||||
Beispielsweise könnten Sie den `q` Query-Parameter so deklarieren, dass er eine `min_length` von `3` hat, und den Defaultwert `"fixedquery"`:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial005_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial005_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
@@ -485,87 +313,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
|
||||
|
||||
Wenn Sie einen Parameter erforderlich machen wollen, während Sie `Query` verwenden, deklarieren Sie ebenfalls einfach keinen Defaultwert:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial006_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial006_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial006.py!}
|
||||
```
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Beachten Sie, dass, obwohl in diesem Fall `Query()` der Funktionsparameter-Defaultwert ist, wir nicht `default=None` zu `Query()` hinzufügen.
|
||||
|
||||
Verwenden Sie bitte trotzdem die `Annotated`-Version. 😉
|
||||
|
||||
///
|
||||
|
||||
////
|
||||
|
||||
### Erforderlich mit Ellipse (`...`)
|
||||
|
||||
Es gibt eine Alternative, die explizit deklariert, dass ein Wert erforderlich ist. Sie können als Default das <abbr title='Zeichenfolge, die einen Wert direkt darstellt, etwa 1, "hallowelt", True, None'>Literal</abbr> `...` setzen:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial006b_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial006b_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial006b.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// info
|
||||
|
||||
Falls Sie das `...` bisher noch nicht gesehen haben: Es ist ein spezieller einzelner Wert, <a href="https://docs.python.org/3/library/constants.html#Ellipsis" class="external-link" target="_blank">Teil von Python und wird „Ellipsis“ genannt</a> (Deutsch: Ellipse).
|
||||
|
||||
Es wird von Pydantic und FastAPI verwendet, um explizit zu deklarieren, dass ein Wert erforderlich ist.
|
||||
|
||||
///
|
||||
|
||||
Dies wird **FastAPI** wissen lassen, dass dieser Parameter erforderlich ist.
|
||||
{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
|
||||
|
||||
### Erforderlich, kann `None` sein
|
||||
|
||||
@@ -573,57 +321,7 @@ Sie können deklarieren, dass ein Parameter `None` akzeptiert, aber dennoch erfo
|
||||
|
||||
Um das zu machen, deklarieren Sie, dass `None` ein gültiger Typ ist, aber verwenden Sie dennoch `...` als Default:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial006c_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial006c_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial006c_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial006c.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial006c_an_py310.py hl[9] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -643,71 +341,7 @@ Wenn Sie einen Query-Parameter explizit mit `Query` auszeichnen, können Sie ihn
|
||||
|
||||
Um zum Beispiel einen Query-Parameter `q` zu deklarieren, der mehrere Male in der URL vorkommen kann, schreiben Sie:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial011_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial011_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial011_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial011_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial011_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial011_an_py310.py hl[9] *}
|
||||
|
||||
Dann, mit einer URL wie:
|
||||
|
||||
@@ -742,49 +376,7 @@ Die interaktive API-Dokumentation wird entsprechend aktualisiert und erlaubt jet
|
||||
|
||||
Und Sie können auch eine Default-`list`e von Werten definieren, wenn keine übergeben werden:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial012_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial012_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial012_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial012.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
|
||||
|
||||
Wenn Sie auf:
|
||||
|
||||
@@ -807,35 +399,7 @@ gehen, wird der Default für `q` verwendet: `["foo", "bar"]`, und als Response e
|
||||
|
||||
Sie können auch `list` direkt verwenden, anstelle von `List[str]` (oder `list[str]` in Python 3.9+):
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial013_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial013_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial013.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
@@ -861,111 +425,11 @@ Einige könnten noch nicht alle zusätzlichen Informationen anzeigen, die Sie de
|
||||
|
||||
Sie können einen Titel hinzufügen – `title`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial007_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial007_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial007_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial007_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial007.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial007_an_py310.py hl[10] *}
|
||||
|
||||
Und eine Beschreibung – `description`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial008_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial008_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="15"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial008_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial008_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial008.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial008_an_py310.py hl[14] *}
|
||||
|
||||
## Alias-Parameter
|
||||
|
||||
@@ -985,57 +449,7 @@ Aber Sie möchten dennoch exakt `item-query` verwenden.
|
||||
|
||||
Dann können Sie einen `alias` deklarieren, und dieser Alias wird verwendet, um den Parameter-Wert zu finden:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial009_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial009_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial009_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial009_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial009.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial009_an_py310.py hl[9] *}
|
||||
|
||||
## Parameter als deprecated ausweisen
|
||||
|
||||
@@ -1045,57 +459,7 @@ Sie müssen ihn eine Weile dort belassen, weil Clients ihn benutzen, aber Sie m
|
||||
|
||||
In diesem Fall fügen Sie den Parameter `deprecated=True` zu `Query` hinzu.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial010_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="19"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial010_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial010_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial010_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial010.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial010_an_py310.py hl[19] *}
|
||||
|
||||
Die Dokumentation wird das so anzeigen:
|
||||
|
||||
@@ -1105,57 +469,7 @@ Die Dokumentation wird das so anzeigen:
|
||||
|
||||
Um einen Query-Parameter vom generierten OpenAPI-Schema auszuschließen (und daher von automatischen Dokumentations-Systemen), setzen Sie den Parameter `include_in_schema` in `Query` auf `False`.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial014_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial014_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial014_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial014_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params_str_validations/tutorial014.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params_str_validations/tutorial014_an_py310.py hl[10] *}
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
Wenn Sie in ihrer Funktion Parameter deklarieren, die nicht Teil der Pfad-Parameter sind, dann werden diese automatisch als „Query“-Parameter interpretiert.
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../docs_src/query_params/tutorial001.py!}
|
||||
```
|
||||
{* ../../docs_src/query_params/tutorial001.py hl[9] *}
|
||||
|
||||
Query-Parameter (Deutsch: Abfrage-Parameter) sind die Schlüssel-Wert-Paare, die nach dem `?` in einer URL aufgelistet sind, getrennt durch `&`-Zeichen.
|
||||
|
||||
@@ -63,21 +61,7 @@ gehen, werden die Parameter-Werte Ihrer Funktion sein:
|
||||
|
||||
Auf die gleiche Weise können Sie optionale Query-Parameter deklarieren, indem Sie deren Defaultwert auf `None` setzen:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params/tutorial002_py310.py hl[7] *}
|
||||
|
||||
In diesem Fall wird der Funktionsparameter `q` optional, und standardmäßig `None` sein.
|
||||
|
||||
@@ -91,21 +75,7 @@ Beachten Sie auch, dass **FastAPI** intelligent genug ist, um zu erkennen, dass
|
||||
|
||||
Sie können auch `bool`-Typen deklarieren und sie werden konvertiert:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/query_params/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/query_params/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params/tutorial003_py310.py hl[7] *}
|
||||
|
||||
Wenn Sie nun zu:
|
||||
|
||||
@@ -147,21 +117,7 @@ Und Sie müssen sie auch nicht in einer spezifischen Reihenfolge deklarieren.
|
||||
|
||||
Parameter werden anhand ihres Namens erkannt:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="6 8"
|
||||
{!> ../../docs_src/query_params/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8 10"
|
||||
{!> ../../docs_src/query_params/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params/tutorial004_py310.py hl[6,8] *}
|
||||
|
||||
## Erforderliche Query-Parameter
|
||||
|
||||
@@ -171,9 +127,7 @@ Wenn Sie keinen spezifischen Wert haben wollen, sondern der Parameter einfach op
|
||||
|
||||
Aber wenn Sie wollen, dass ein Query-Parameter erforderlich ist, vergeben Sie einfach keinen Defaultwert:
|
||||
|
||||
```Python hl_lines="6-7"
|
||||
{!../../docs_src/query_params/tutorial005.py!}
|
||||
```
|
||||
{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
|
||||
|
||||
Hier ist `needy` ein erforderlicher Query-Parameter vom Typ `str`.
|
||||
|
||||
@@ -195,8 +149,7 @@ http://127.0.0.1:8000/items/foo-item
|
||||
"needy"
|
||||
],
|
||||
"msg": "Field required",
|
||||
"input": null,
|
||||
"url": "https://errors.pydantic.dev/2.1/v/missing"
|
||||
"input": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -219,21 +172,7 @@ http://127.0.0.1:8000/items/foo-item?needy=sooooneedy
|
||||
|
||||
Und natürlich können Sie einige Parameter als erforderlich, einige mit Defaultwert, und einige als vollständig optional definieren:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/query_params/tutorial006_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/query_params/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/query_params/tutorial006_py310.py hl[8] *}
|
||||
|
||||
In diesem Fall gibt es drei Query-Parameter:
|
||||
|
||||
|
||||
@@ -16,69 +16,13 @@ Das, weil hochgeladene Dateien als „Formulardaten“ gesendet werden.
|
||||
|
||||
Importieren Sie `File` und `UploadFile` von `fastapi`:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/request_files/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/request_files/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/request_files/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
|
||||
|
||||
## `File`-Parameter definieren
|
||||
|
||||
Erstellen Sie Datei-Parameter, so wie Sie es auch mit `Body` und `Form` machen würden:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/request_files/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/request_files/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/request_files/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
|
||||
|
||||
/// info
|
||||
|
||||
@@ -106,35 +50,7 @@ Aber es gibt viele Fälle, in denen Sie davon profitieren, `UploadFile` zu verwe
|
||||
|
||||
Definieren Sie einen Datei-Parameter mit dem Typ `UploadFile`:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="14"
|
||||
{!> ../../docs_src/request_files/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="13"
|
||||
{!> ../../docs_src/request_files/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/request_files/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
|
||||
|
||||
`UploadFile` zu verwenden, hat mehrere Vorzüge gegenüber `bytes`:
|
||||
|
||||
@@ -217,91 +133,13 @@ Das ist keine Limitation von **FastAPI**, sondern Teil des HTTP-Protokolls.
|
||||
|
||||
Sie können eine Datei optional machen, indem Sie Standard-Typannotationen verwenden und den Defaultwert auf `None` setzen:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9 17"
|
||||
{!> ../../docs_src/request_files/tutorial001_02_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9 17"
|
||||
{!> ../../docs_src/request_files/tutorial001_02_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10 18"
|
||||
{!> ../../docs_src/request_files/tutorial001_02_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7 15"
|
||||
{!> ../../docs_src/request_files/tutorial001_02_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9 17"
|
||||
{!> ../../docs_src/request_files/tutorial001_02.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *}
|
||||
|
||||
## `UploadFile` mit zusätzlichen Metadaten
|
||||
|
||||
Sie können auch `File()` zusammen mit `UploadFile` verwenden, um zum Beispiel zusätzliche Metadaten zu setzen:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9 15"
|
||||
{!> ../../docs_src/request_files/tutorial001_03_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8 14"
|
||||
{!> ../../docs_src/request_files/tutorial001_03_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7 13"
|
||||
{!> ../../docs_src/request_files/tutorial001_03.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
|
||||
|
||||
## Mehrere Datei-Uploads
|
||||
|
||||
@@ -311,49 +149,7 @@ Diese werden demselben Formularfeld zugeordnet, welches mit den Formulardaten ge
|
||||
|
||||
Um das zu machen, deklarieren Sie eine Liste von `bytes` oder `UploadFile`s:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10 15"
|
||||
{!> ../../docs_src/request_files/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="11 16"
|
||||
{!> ../../docs_src/request_files/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8 13"
|
||||
{!> ../../docs_src/request_files/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10 15"
|
||||
{!> ../../docs_src/request_files/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
|
||||
|
||||
Sie erhalten, wie deklariert, eine `list`e von `bytes` oder `UploadFile`s.
|
||||
|
||||
@@ -369,49 +165,7 @@ Sie können auch `from starlette.responses import HTMLResponse` verwenden.
|
||||
|
||||
Und so wie zuvor können Sie `File()` verwenden, um zusätzliche Parameter zu setzen, sogar für `UploadFile`:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="11 18-20"
|
||||
{!> ../../docs_src/request_files/tutorial003_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="12 19-21"
|
||||
{!> ../../docs_src/request_files/tutorial003_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="9 16"
|
||||
{!> ../../docs_src/request_files/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="11 18"
|
||||
{!> ../../docs_src/request_files/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
|
||||
@@ -12,69 +12,13 @@ Z. B. `pip install python-multipart`.
|
||||
|
||||
## `File` und `Form` importieren
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/request_forms_and_files/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/request_forms_and_files/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/request_forms_and_files/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
|
||||
|
||||
## `File` und `Form`-Parameter definieren
|
||||
|
||||
Erstellen Sie Datei- und Formularparameter, so wie Sie es auch mit `Body` und `Query` machen würden:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="10-12"
|
||||
{!> ../../docs_src/request_forms_and_files/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9-11"
|
||||
{!> ../../docs_src/request_forms_and_files/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/request_forms_and_files/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
|
||||
|
||||
Die Datei- und Formularfelder werden als Formulardaten hochgeladen, und Sie erhalten diese Dateien und Formularfelder.
|
||||
|
||||
|
||||
@@ -14,69 +14,13 @@ Z. B. `pip install python-multipart`.
|
||||
|
||||
Importieren Sie `Form` von `fastapi`:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!> ../../docs_src/request_forms/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/request_forms/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/request_forms/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
|
||||
|
||||
## `Form`-Parameter definieren
|
||||
|
||||
Erstellen Sie Formular-Parameter, so wie Sie es auch mit `Body` und `Query` machen würden:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/request_forms/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/request_forms/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/request_forms/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
|
||||
|
||||
Zum Beispiel stellt eine der Möglichkeiten, die OAuth2 Spezifikation zu verwenden (genannt <abbr title='„Passwort-Fluss“'>„password flow“</abbr>), die Bedingung, einen `username` und ein `password` als Formularfelder zu senden.
|
||||
|
||||
|
||||
@@ -4,29 +4,7 @@ Sie können den Typ der <abbr title="Response – Antwort: Daten, die zum anfrag
|
||||
|
||||
Hierbei können Sie **Typannotationen** genauso verwenden, wie Sie es bei Werten von Funktions-**Parametern** machen; verwenden Sie Pydantic-Modelle, Listen, Dicts und skalare Werte wie Nummern, Booleans, usw.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="16 21"
|
||||
{!> ../../docs_src/response_model/tutorial001_01_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="18 23"
|
||||
{!> ../../docs_src/response_model/tutorial001_01_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="18 23"
|
||||
{!> ../../docs_src/response_model/tutorial001_01.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
|
||||
|
||||
FastAPI wird diesen Rückgabetyp verwenden, um:
|
||||
|
||||
@@ -59,29 +37,7 @@ Sie können `response_model` in jeder möglichen *Pfadoperation* verwenden:
|
||||
* `@app.delete()`
|
||||
* usw.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="17 22 24-27"
|
||||
{!> ../../docs_src/response_model/tutorial001_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="17 22 24-27"
|
||||
{!> ../../docs_src/response_model/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="17 22 24-27"
|
||||
{!> ../../docs_src/response_model/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial001_py310.py hl[17,22,24:27] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
@@ -113,21 +69,7 @@ Sie können auch `response_model=None` verwenden, um das Erstellen eines Respons
|
||||
|
||||
Im Folgenden deklarieren wir ein `UserIn`-Modell; es enthält ein Klartext-Passwort:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7 9"
|
||||
{!> ../../docs_src/response_model/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9 11"
|
||||
{!> ../../docs_src/response_model/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial002_py310.py hl[7,9] *}
|
||||
|
||||
/// info
|
||||
|
||||
@@ -140,21 +82,7 @@ oder `pip install pydantic[email]`.
|
||||
|
||||
Wir verwenden dieses Modell, um sowohl unsere Eingabe- als auch Ausgabedaten zu deklarieren:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!> ../../docs_src/response_model/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="18"
|
||||
{!> ../../docs_src/response_model/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial002_py310.py hl[16] *}
|
||||
|
||||
Immer wenn jetzt ein Browser einen Benutzer mit Passwort erzeugt, gibt die API dasselbe Passwort in der Response zurück.
|
||||
|
||||
@@ -172,57 +100,15 @@ Speichern Sie niemals das Klartext-Passwort eines Benutzers, oder versenden Sie
|
||||
|
||||
Wir können stattdessen ein Eingabemodell mit dem Klartext-Passwort, und ein Ausgabemodell ohne das Passwort erstellen:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9 11 16"
|
||||
{!> ../../docs_src/response_model/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9 11 16"
|
||||
{!> ../../docs_src/response_model/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial003_py310.py hl[9,11,16] *}
|
||||
|
||||
Obwohl unsere *Pfadoperation-Funktion* hier denselben `user` von der Eingabe zurückgibt, der das Passwort enthält:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!> ../../docs_src/response_model/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!> ../../docs_src/response_model/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial003_py310.py hl[24] *}
|
||||
|
||||
... haben wir deklariert, dass `response_model` das Modell `UserOut` ist, welches das Passwort nicht enthält:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../docs_src/response_model/tutorial003_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../docs_src/response_model/tutorial003.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial003_py310.py hl[22] *}
|
||||
|
||||
Darum wird **FastAPI** sich darum kümmern, dass alle Daten, die nicht im Ausgabemodell deklariert sind, herausgefiltert werden (mittels Pydantic).
|
||||
|
||||
@@ -246,21 +132,7 @@ Aber in den meisten Fällen, wenn wir so etwas machen, wollen wir nur, dass das
|
||||
|
||||
Und in solchen Fällen können wir Klassen und Vererbung verwenden, um Vorteil aus den Typannotationen in der Funktion zu ziehen, was vom Editor und von Tools besser unterstützt wird, während wir gleichzeitig FastAPIs **Datenfilterung** behalten.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7-10 13-14 18"
|
||||
{!> ../../docs_src/response_model/tutorial003_01_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9-13 15-16 20"
|
||||
{!> ../../docs_src/response_model/tutorial003_01.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial003_01_py310.py hl[7:10,13:14,18] *}
|
||||
|
||||
Damit erhalten wir Tool-Unterstützung, vom Editor und mypy, da dieser Code hinsichtlich der Typen korrekt ist, aber wir erhalten auch die Datenfilterung von FastAPI.
|
||||
|
||||
@@ -302,9 +174,7 @@ Es kann Fälle geben, bei denen Sie etwas zurückgeben, das kein gültiges Pydan
|
||||
|
||||
Der häufigste Anwendungsfall ist, wenn Sie [eine Response direkt zurückgeben, wie es später im Handbuch für fortgeschrittene Benutzer erläutert wird](../advanced/response-directly.md){.internal-link target=_blank}.
|
||||
|
||||
```Python hl_lines="8 10-11"
|
||||
{!> ../../docs_src/response_model/tutorial003_02.py!}
|
||||
```
|
||||
{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *}
|
||||
|
||||
Dieser einfache Anwendungsfall wird automatisch von FastAPI gehandhabt, weil die Annotation des Rückgabetyps die Klasse (oder eine Unterklasse von) `Response` ist.
|
||||
|
||||
@@ -314,9 +184,7 @@ Und Tools werden auch glücklich sein, weil sowohl `RedirectResponse` als auch `
|
||||
|
||||
Sie können auch eine Unterklasse von `Response` in der Typannotation verwenden.
|
||||
|
||||
```Python hl_lines="8-9"
|
||||
{!> ../../docs_src/response_model/tutorial003_03.py!}
|
||||
```
|
||||
{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *}
|
||||
|
||||
Das wird ebenfalls funktionieren, weil `RedirectResponse` eine Unterklasse von `Response` ist, und FastAPI sich um diesen einfachen Anwendungsfall automatisch kümmert.
|
||||
|
||||
@@ -326,21 +194,7 @@ Aber wenn Sie ein beliebiges anderes Objekt zurückgeben, das kein gültiger Pyd
|
||||
|
||||
Das gleiche wird passieren, wenn Sie eine <abbr title='Eine Union mehrerer Typen bedeutet: „Irgendeiner dieser Typen“'>Union</abbr> mehrerer Typen haben, und einer oder mehrere sind nicht gültige Pydantic-Typen. Zum Beispiel funktioniert folgendes nicht 💥:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/response_model/tutorial003_04_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/response_model/tutorial003_04.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial003_04_py310.py hl[8] *}
|
||||
|
||||
... das scheitert, da die Typannotation kein Pydantic-Typ ist, und auch keine einzelne `Response`-Klasse, oder -Unterklasse, es ist eine Union (eines von beiden) von `Response` und `dict`.
|
||||
|
||||
@@ -352,21 +206,7 @@ Aber Sie möchten dennoch den Rückgabetyp in der Funktion annotieren, um Unters
|
||||
|
||||
In diesem Fall können Sie die Generierung des Responsemodells abschalten, indem Sie `response_model=None` setzen:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/response_model/tutorial003_05_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!> ../../docs_src/response_model/tutorial003_05.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial003_05_py310.py hl[7] *}
|
||||
|
||||
Das bewirkt, dass FastAPI die Generierung des Responsemodells unterlässt, und damit können Sie jede gewünschte Rückgabetyp-Annotation haben, ohne dass es Ihre FastAPI-Anwendung beeinflusst. 🤓
|
||||
|
||||
@@ -374,29 +214,7 @@ Das bewirkt, dass FastAPI die Generierung des Responsemodells unterlässt, und d
|
||||
|
||||
Ihr Responsemodell könnte Defaultwerte haben, wie:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="9 11-12"
|
||||
{!> ../../docs_src/response_model/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="11 13-14"
|
||||
{!> ../../docs_src/response_model/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="11 13-14"
|
||||
{!> ../../docs_src/response_model/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial004_py310.py hl[9,11:12] *}
|
||||
|
||||
* `description: Union[str, None] = None` (oder `str | None = None` in Python 3.10) hat einen Defaultwert `None`.
|
||||
* `tax: float = 10.5` hat einen Defaultwert `10.5`.
|
||||
@@ -410,29 +228,7 @@ Wenn Sie zum Beispiel Modelle mit vielen optionalen Attributen in einer NoSQL-Da
|
||||
|
||||
Sie können den *Pfadoperation-Dekorator*-Parameter `response_model_exclude_unset=True` setzen:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!> ../../docs_src/response_model/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!> ../../docs_src/response_model/tutorial004_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!> ../../docs_src/response_model/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial004_py310.py hl[22] *}
|
||||
|
||||
Die Defaultwerte werden dann nicht in der Response enthalten sein, sondern nur die tatsächlich gesetzten Werte.
|
||||
|
||||
@@ -529,21 +325,7 @@ Das trifft auch auf `response_model_by_alias` zu, welches ähnlich funktioniert.
|
||||
|
||||
///
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="29 35"
|
||||
{!> ../../docs_src/response_model/tutorial005_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="31 37"
|
||||
{!> ../../docs_src/response_model/tutorial005.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial005_py310.py hl[29,35] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -557,21 +339,7 @@ Die Syntax `{"name", "description"}` erzeugt ein `set` mit diesen zwei Werten.
|
||||
|
||||
Wenn Sie vergessen, ein `set` zu verwenden, und stattdessen eine `list`e oder ein `tuple` übergeben, wird FastAPI die dennoch in ein `set` konvertieren, und es wird korrekt funktionieren:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="29 35"
|
||||
{!> ../../docs_src/response_model/tutorial006_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="31 37"
|
||||
{!> ../../docs_src/response_model/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/response_model/tutorial006_py310.py hl[29,35] *}
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
|
||||
@@ -20,35 +20,7 @@ Lassen Sie uns zunächst einfach den Code verwenden und sehen, wie er funktionie
|
||||
|
||||
Kopieren Sie das Beispiel in eine Datei `main.py`:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/security/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/security/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/security/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial001_an_py39.py *}
|
||||
|
||||
## Ausführen
|
||||
|
||||
@@ -154,35 +126,7 @@ In dem Fall gibt Ihnen **FastAPI** ebenfalls die Tools, die Sie zum Erstellen br
|
||||
|
||||
Wenn wir eine Instanz der Klasse `OAuth2PasswordBearer` erstellen, übergeben wir den Parameter `tokenUrl`. Dieser Parameter enthält die URL, die der Client (das Frontend, das im Browser des Benutzers ausgeführt wird) verwendet, wenn er den `username` und das `password` sendet, um einen Token zu erhalten.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!> ../../docs_src/security/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!> ../../docs_src/security/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!> ../../docs_src/security/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -220,35 +164,7 @@ Es kann also mit `Depends` verwendet werden.
|
||||
|
||||
Jetzt können Sie dieses `oauth2_scheme` als Abhängigkeit `Depends` übergeben.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/security/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/security/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/security/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
|
||||
|
||||
Diese Abhängigkeit stellt einen `str` bereit, der dem Parameter `token` der *Pfadoperation-Funktion* zugewiesen wird.
|
||||
|
||||
|
||||
@@ -2,35 +2,7 @@
|
||||
|
||||
Im vorherigen Kapitel hat das Sicherheitssystem (das auf dem Dependency Injection System basiert) der *Pfadoperation-Funktion* einen `token` vom Typ `str` überreicht:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="12"
|
||||
{!> ../../docs_src/security/tutorial001_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="11"
|
||||
{!> ../../docs_src/security/tutorial001_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!> ../../docs_src/security/tutorial001.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
|
||||
|
||||
Aber das ist immer noch nicht so nützlich.
|
||||
|
||||
@@ -42,57 +14,7 @@ Erstellen wir zunächst ein Pydantic-Benutzermodell.
|
||||
|
||||
So wie wir Pydantic zum Deklarieren von Bodys verwenden, können wir es auch überall sonst verwenden:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="5 12-16"
|
||||
{!> ../../docs_src/security/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="5 12-16"
|
||||
{!> ../../docs_src/security/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="5 13-17"
|
||||
{!> ../../docs_src/security/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="3 10-14"
|
||||
{!> ../../docs_src/security/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="5 12-16"
|
||||
{!> ../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial002_an_py310.py hl[5,12:16] *}
|
||||
|
||||
## Eine `get_current_user`-Abhängigkeit erstellen
|
||||
|
||||
@@ -104,169 +26,19 @@ Erinnern Sie sich, dass Abhängigkeiten Unterabhängigkeiten haben können?
|
||||
|
||||
So wie wir es zuvor in der *Pfadoperation* direkt gemacht haben, erhält unsere neue Abhängigkeit `get_current_user` von der Unterabhängigkeit `oauth2_scheme` einen `token` vom Typ `str`:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="25"
|
||||
{!> ../../docs_src/security/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="25"
|
||||
{!> ../../docs_src/security/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="26"
|
||||
{!> ../../docs_src/security/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="23"
|
||||
{!> ../../docs_src/security/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="25"
|
||||
{!> ../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial002_an_py310.py hl[25] *}
|
||||
|
||||
## Den Benutzer holen
|
||||
|
||||
`get_current_user` wird eine von uns erstellte (gefakte) Hilfsfunktion verwenden, welche einen Token vom Typ `str` entgegennimmt und unser Pydantic-`User`-Modell zurückgibt:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="19-22 26-27"
|
||||
{!> ../../docs_src/security/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="19-22 26-27"
|
||||
{!> ../../docs_src/security/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="20-23 27-28"
|
||||
{!> ../../docs_src/security/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="17-20 24-25"
|
||||
{!> ../../docs_src/security/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="19-22 26-27"
|
||||
{!> ../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial002_an_py310.py hl[19:22,26:27] *}
|
||||
|
||||
## Den aktuellen Benutzer einfügen
|
||||
|
||||
Und jetzt können wir wiederum `Depends` mit unserem `get_current_user` in der *Pfadoperation* verwenden:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="31"
|
||||
{!> ../../docs_src/security/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="31"
|
||||
{!> ../../docs_src/security/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="32"
|
||||
{!> ../../docs_src/security/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="29"
|
||||
{!> ../../docs_src/security/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="31"
|
||||
{!> ../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial002_an_py310.py hl[31] *}
|
||||
|
||||
Beachten Sie, dass wir als Typ von `current_user` das Pydantic-Modell `User` deklarieren.
|
||||
|
||||
@@ -320,57 +92,7 @@ Und alle (oder beliebige Teile davon) können Vorteil ziehen aus der Wiederverwe
|
||||
|
||||
Und alle diese Tausenden von *Pfadoperationen* können nur drei Zeilen lang sein:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="30-32"
|
||||
{!> ../../docs_src/security/tutorial002_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="30-32"
|
||||
{!> ../../docs_src/security/tutorial002_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="31-33"
|
||||
{!> ../../docs_src/security/tutorial002_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="28-30"
|
||||
{!> ../../docs_src/security/tutorial002_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="30-32"
|
||||
{!> ../../docs_src/security/tutorial002.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial002_an_py310.py hl[30:32] *}
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ Es handelt sich um eine recht umfangreiche Spezifikation, und sie deckt mehrere
|
||||
|
||||
Sie umfasst Möglichkeiten zur Authentifizierung mithilfe eines „Dritten“ („third party“).
|
||||
|
||||
Das ist es, was alle diese „Login mit Facebook, Google, Twitter, GitHub“-Systeme unter der Haube verwenden.
|
||||
Das ist es, was alle diese „Login mit Facebook, Google, X (Twitter), GitHub“-Systeme unter der Haube verwenden.
|
||||
|
||||
### OAuth 1
|
||||
|
||||
@@ -79,7 +79,7 @@ OpenAPI definiert die folgenden Sicherheitsschemas:
|
||||
* HTTP Basic Authentication.
|
||||
* HTTP Digest, usw.
|
||||
* `oauth2`: Alle OAuth2-Methoden zum Umgang mit Sicherheit (genannt „Flows“).
|
||||
* Mehrere dieser Flows eignen sich zum Aufbau eines OAuth 2.0-Authentifizierungsanbieters (wie Google, Facebook, Twitter, GitHub usw.):
|
||||
* Mehrere dieser Flows eignen sich zum Aufbau eines OAuth 2.0-Authentifizierungsanbieters (wie Google, Facebook, X (Twitter), GitHub usw.):
|
||||
* `implicit`
|
||||
* `clientCredentials`
|
||||
* `authorizationCode`
|
||||
@@ -91,7 +91,7 @@ OpenAPI definiert die folgenden Sicherheitsschemas:
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Auch die Integration anderer Authentifizierungs-/Autorisierungsanbieter wie Google, Facebook, Twitter, GitHub, usw. ist möglich und relativ einfach.
|
||||
Auch die Integration anderer Authentifizierungs-/Autorisierungsanbieter wie Google, Facebook, X (Twitter), GitHub, usw. ist möglich und relativ einfach.
|
||||
|
||||
Das komplexeste Problem besteht darin, einen Authentifizierungs-/Autorisierungsanbieter wie solche aufzubauen, aber **FastAPI** reicht Ihnen die Tools, das einfach zu erledigen, während Ihnen die schwere Arbeit abgenommen wird.
|
||||
|
||||
|
||||
@@ -118,57 +118,7 @@ Und eine weitere, um zu überprüfen, ob ein empfangenes Passwort mit dem gespei
|
||||
|
||||
Und noch eine, um einen Benutzer zu authentifizieren und zurückzugeben.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="7 48 55-56 59-60 69-75"
|
||||
{!> ../../docs_src/security/tutorial004_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="7 48 55-56 59-60 69-75"
|
||||
{!> ../../docs_src/security/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="7 49 56-57 60-61 70-76"
|
||||
{!> ../../docs_src/security/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="6 47 54-55 58-59 68-74"
|
||||
{!> ../../docs_src/security/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="7 48 55-56 59-60 69-75"
|
||||
{!> ../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[7,48,55:56,59:60,69:75] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
@@ -204,57 +154,7 @@ Definieren Sie ein Pydantic-Modell, das im Token-Endpunkt für die Response verw
|
||||
|
||||
Erstellen Sie eine Hilfsfunktion, um einen neuen Zugriffstoken zu generieren.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="6 12-14 28-30 78-86"
|
||||
{!> ../../docs_src/security/tutorial004_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="6 12-14 28-30 78-86"
|
||||
{!> ../../docs_src/security/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="6 13-15 29-31 79-87"
|
||||
{!> ../../docs_src/security/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="5 11-13 27-29 77-85"
|
||||
{!> ../../docs_src/security/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="6 12-14 28-30 78-86"
|
||||
{!> ../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[6,12:14,28:30,78:86] *}
|
||||
|
||||
## Die Abhängigkeiten aktualisieren
|
||||
|
||||
@@ -264,57 +164,7 @@ Dekodieren Sie den empfangenen Token, validieren Sie ihn und geben Sie den aktue
|
||||
|
||||
Wenn der Token ungültig ist, geben Sie sofort einen HTTP-Fehler zurück.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="89-106"
|
||||
{!> ../../docs_src/security/tutorial004_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="89-106"
|
||||
{!> ../../docs_src/security/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="90-107"
|
||||
{!> ../../docs_src/security/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="88-105"
|
||||
{!> ../../docs_src/security/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="89-106"
|
||||
{!> ../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[89:106] *}
|
||||
|
||||
## Die *Pfadoperation* `/token` aktualisieren
|
||||
|
||||
@@ -322,57 +172,7 @@ Erstellen Sie ein <abbr title="Zeitdifferenz">`timedelta`</abbr> mit der Ablaufz
|
||||
|
||||
Erstellen Sie einen echten JWT-Zugriffstoken und geben Sie ihn zurück.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="117-132"
|
||||
{!> ../../docs_src/security/tutorial004_an_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="117-132"
|
||||
{!> ../../docs_src/security/tutorial004_an_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="118-133"
|
||||
{!> ../../docs_src/security/tutorial004_an.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="114-129"
|
||||
{!> ../../docs_src/security/tutorial004_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="115-130"
|
||||
{!> ../../docs_src/security/tutorial004.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/security/tutorial004_an_py310.py hl[117:132] *}
|
||||
|
||||
### Technische Details zum JWT-„Subjekt“ `sub`
|
||||
|
||||
@@ -472,4 +272,4 @@ Aber es bietet Ihnen die Werkzeuge, um den Prozess so weit wie möglich zu verei
|
||||
|
||||
Und Sie können sichere Standardprotokolle wie OAuth2 auf relativ einfache Weise verwenden und implementieren.
|
||||
|
||||
Im **Handbuch für fortgeschrittene Benutzer** erfahren Sie mehr darüber, wie Sie OAuth2-„Scopes“ für ein feingranuliertes Berechtigungssystem verwenden, das denselben Standards folgt. OAuth2 mit Scopes ist der Mechanismus, der von vielen großen Authentifizierungsanbietern wie Facebook, Google, GitHub, Microsoft, Twitter, usw. verwendet wird, um Drittanbieteranwendungen zu autorisieren, im Namen ihrer Benutzer mit ihren APIs zu interagieren.
|
||||
Im **Handbuch für fortgeschrittene Benutzer** erfahren Sie mehr darüber, wie Sie OAuth2-„Scopes“ für ein feingranuliertes Berechtigungssystem verwenden, das denselben Standards folgt. OAuth2 mit Scopes ist der Mechanismus, der von vielen großen Authentifizierungsanbietern wie Facebook, Google, GitHub, Microsoft, X (Twitter), usw. verwendet wird, um Drittanbieteranwendungen zu autorisieren, im Namen ihrer Benutzer mit ihren APIs zu interagieren.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user