mirror of
https://github.com/fastapi/fastapi.git
synced 2026-02-13 15:51:14 -05:00
Compare commits
679 Commits
0.118.0
...
sync-trans
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
116bd2dc45 | ||
|
|
248671ebf0 | ||
|
|
fdbbf74908 | ||
|
|
b93c964d7f | ||
|
|
7c4b134464 | ||
|
|
db328270aa | ||
|
|
6fa573ce0b | ||
|
|
55a9eee13a | ||
|
|
c206f19b5d | ||
|
|
d11f820ac3 | ||
|
|
a2e51363c7 | ||
|
|
b7ce02ae86 | ||
|
|
31d9750ace | ||
|
|
109cc8aff1 | ||
|
|
c82a3d8a13 | ||
|
|
0e460654af | ||
|
|
c9e2277d8b | ||
|
|
d06ab3f5c7 | ||
|
|
3da206c06d | ||
|
|
cc903bd440 | ||
|
|
ad4e8e0060 | ||
|
|
bdd20051c4 | ||
|
|
1ed9bd4923 | ||
|
|
aac30fd707 | ||
|
|
417f1ee078 | ||
|
|
ffb8965260 | ||
|
|
93fa935fb8 | ||
|
|
f0f3e7a113 | ||
|
|
8f82c94de0 | ||
|
|
5bb3423205 | ||
|
|
6ce5e3e961 | ||
|
|
65da3dde12 | ||
|
|
81f82fd955 | ||
|
|
ff721017df | ||
|
|
ca76a4eba9 | ||
|
|
1133a4594d | ||
|
|
38f965985e | ||
|
|
3f1cc8f8f5 | ||
|
|
25270fcee0 | ||
|
|
8bdb0d2242 | ||
|
|
df950111fe | ||
|
|
363aced75a | ||
|
|
66dc695071 | ||
|
|
e94028ab60 | ||
|
|
8fd291465b | ||
|
|
fbca586c1d | ||
|
|
4e879799dd | ||
|
|
0a4033aeee | ||
|
|
ed2512a5ec | ||
|
|
0c0f6332e2 | ||
|
|
227cb85a03 | ||
|
|
cd31576d57 | ||
|
|
376e108580 | ||
|
|
dedf1409fe | ||
|
|
79d4dfb37f | ||
|
|
9f4ecf562c | ||
|
|
c48539f4c6 | ||
|
|
2e7d3754cd | ||
|
|
8eac94bd91 | ||
|
|
58cdfc7f4b | ||
|
|
d59fbc3494 | ||
|
|
cc6ced6345 | ||
|
|
cf55bade7e | ||
|
|
ac8362c447 | ||
|
|
3c49346238 | ||
|
|
512c3ad88c | ||
|
|
cba537ab71 | ||
|
|
2eb454ab04 | ||
|
|
0f5987b560 | ||
|
|
266a3138b5 | ||
|
|
5a31b37cc7 | ||
|
|
36985f5f25 | ||
|
|
661cdfb8a4 | ||
|
|
f6cc650a12 | ||
|
|
201feedd68 | ||
|
|
19f13ead4c | ||
|
|
01e85c03bd | ||
|
|
08233d7ffc | ||
|
|
fe8c33ea64 | ||
|
|
f9f7992604 | ||
|
|
8e50c55fd9 | ||
|
|
3b8b310eda | ||
|
|
79406a4b04 | ||
|
|
de56c96c64 | ||
|
|
570e592a03 | ||
|
|
110b45d9b2 | ||
|
|
72325f698f | ||
|
|
8bdbd3725f | ||
|
|
23ddf09dd1 | ||
|
|
6646e2b94f | ||
|
|
c5fd75a321 | ||
|
|
54f8aeeb9a | ||
|
|
97145588f5 | ||
|
|
0dd42b746e | ||
|
|
b49435becd | ||
|
|
464c359bb0 | ||
|
|
457cd75c23 | ||
|
|
2838dcb4a8 | ||
|
|
b82993643e | ||
|
|
b892c3126c | ||
|
|
3578270af4 | ||
|
|
2224b4e63b | ||
|
|
136d5f0a56 | ||
|
|
afb44f0ff8 | ||
|
|
4fe06cc24a | ||
|
|
cae2659678 | ||
|
|
da9e101d50 | ||
|
|
8488d31aff | ||
|
|
dcfd432c36 | ||
|
|
c7682a198a | ||
|
|
b5d276bda8 | ||
|
|
2c5a844c44 | ||
|
|
6ff8ff5b57 | ||
|
|
f23ea3bd95 | ||
|
|
b4ed7e5b06 | ||
|
|
c00cebc5c6 | ||
|
|
31faba8e41 | ||
|
|
64d0ee9104 | ||
|
|
2e170b9585 | ||
|
|
5ca11c59e3 | ||
|
|
0e68d36cd5 | ||
|
|
1de0de56c8 | ||
|
|
734c95b05a | ||
|
|
84a5bcf82d | ||
|
|
0e064009fb | ||
|
|
ad29e44c81 | ||
|
|
71ceac20da | ||
|
|
b0e99d66e8 | ||
|
|
cec4be00ba | ||
|
|
aea61373ae | ||
|
|
fe5b617aec | ||
|
|
ee0c12521f | ||
|
|
4a3a71f1c1 | ||
|
|
75c47187f3 | ||
|
|
1e5e8b44cb | ||
|
|
440bfd70a9 | ||
|
|
5d50b74915 | ||
|
|
09f5941f0e | ||
|
|
c944add5a9 | ||
|
|
1d96b3e3f1 | ||
|
|
3675e284ab | ||
|
|
741f77d571 | ||
|
|
9656e925a9 | ||
|
|
0748214c43 | ||
|
|
a1bb70e5a5 | ||
|
|
9df1f8293d | ||
|
|
b134f406d1 | ||
|
|
3ee652dd0c | ||
|
|
a4297066c2 | ||
|
|
61f95c9606 | ||
|
|
9e0f4ca77a | ||
|
|
41352de24c | ||
|
|
ca4692a8c6 | ||
|
|
08dad5c69f | ||
|
|
6ab68c62b8 | ||
|
|
3a41403ccd | ||
|
|
c9e512d808 | ||
|
|
4414286f2c | ||
|
|
938c5f3500 | ||
|
|
21b7b0893b | ||
|
|
5083f27e03 | ||
|
|
741c7345ea | ||
|
|
f6ba0141f4 | ||
|
|
27b91d4ad6 | ||
|
|
e3a66494c9 | ||
|
|
dc3278654f | ||
|
|
573c593dd0 | ||
|
|
261736ab4c | ||
|
|
dd780f8caa | ||
|
|
7621a3aa4b | ||
|
|
eacbce24c9 | ||
|
|
f3f498100f | ||
|
|
2247750d74 | ||
|
|
ec07e62e1c | ||
|
|
82959de14c | ||
|
|
bc9ad6b134 | ||
|
|
608ff552ba | ||
|
|
87b5333e8a | ||
|
|
ecb1444738 | ||
|
|
5c3f0307ae | ||
|
|
f2487ce88c | ||
|
|
a0e34c7473 | ||
|
|
da4083c30f | ||
|
|
b833e53ade | ||
|
|
6173733200 | ||
|
|
20ff394d75 | ||
|
|
779f7ddc37 | ||
|
|
3626d764c1 | ||
|
|
07f08fc79a | ||
|
|
df6530e002 | ||
|
|
08924400c2 | ||
|
|
c9629e0eb2 | ||
|
|
9348a5e2cf | ||
|
|
a3dccaeb14 | ||
|
|
8c32e91c10 | ||
|
|
7a0589466c | ||
|
|
442d007e76 | ||
|
|
eaf07c5d84 | ||
|
|
597b435ae7 | ||
|
|
74cc27fd5a | ||
|
|
f1a39cab12 | ||
|
|
509afeb475 | ||
|
|
6e47171e9c | ||
|
|
b9b75ba5f1 | ||
|
|
e0abd210f6 | ||
|
|
2eb978b87a | ||
|
|
50a78bf840 | ||
|
|
2d459e4845 | ||
|
|
7faa7089d6 | ||
|
|
0ab68a762f | ||
|
|
7443bc7a46 | ||
|
|
6afb15c518 | ||
|
|
ad6b2901a6 | ||
|
|
463a3a24d7 | ||
|
|
db5441eba1 | ||
|
|
536a5bafe7 | ||
|
|
0c7f2b66d7 | ||
|
|
9fec72687f | ||
|
|
8fa635c718 | ||
|
|
fb15bba819 | ||
|
|
23bcfa094d | ||
|
|
f317ede223 | ||
|
|
c597d9cb53 | ||
|
|
a96dd013a4 | ||
|
|
a456e92a21 | ||
|
|
1be80f4885 | ||
|
|
e63f382b0f | ||
|
|
7b864acf37 | ||
|
|
e9e0419ed0 | ||
|
|
249a776b70 | ||
|
|
97aa825422 | ||
|
|
1054fbd256 | ||
|
|
effe493ae0 | ||
|
|
612a2d20bc | ||
|
|
14f3068762 | ||
|
|
d05b18ec40 | ||
|
|
9a76f2fec9 | ||
|
|
0383fb3ab9 | ||
|
|
50fa3f7c88 | ||
|
|
5ec2615b1a | ||
|
|
16e583413c | ||
|
|
1fedd1c73b | ||
|
|
cf8dc98aad | ||
|
|
6f977366a4 | ||
|
|
154ce03ff0 | ||
|
|
49653aa295 | ||
|
|
f03a1502a0 | ||
|
|
a2912ffa26 | ||
|
|
8183e748ee | ||
|
|
cefd50702a | ||
|
|
3d1f9268fc | ||
|
|
7eac6e3169 | ||
|
|
21d2c5cea0 | ||
|
|
c75ae058e4 | ||
|
|
961b2e844a | ||
|
|
b4ba7f4652 | ||
|
|
c35e1fd4b4 | ||
|
|
d1c67c0055 | ||
|
|
18762e38a9 | ||
|
|
b1db1395b6 | ||
|
|
f2687dc1bb | ||
|
|
862c3f4f94 | ||
|
|
052d6e86c2 | ||
|
|
31c7ffcdfe | ||
|
|
6854be9ebc | ||
|
|
258deb925d | ||
|
|
53d2453d1a | ||
|
|
d9b7b65b81 | ||
|
|
9ed5f246ed | ||
|
|
edf7995775 | ||
|
|
47391ea8fb | ||
|
|
3b1b4f034b | ||
|
|
f362fdc234 | ||
|
|
4ce34686d9 | ||
|
|
dbe83f3919 | ||
|
|
13743e115a | ||
|
|
52842fb8d3 | ||
|
|
4d4fb28f9f | ||
|
|
a1735d6d11 | ||
|
|
1b42639296 | ||
|
|
ded035a421 | ||
|
|
44c849c4fc | ||
|
|
8322a4445a | ||
|
|
4b2cfcfd34 | ||
|
|
e300630551 | ||
|
|
1b3bea8b6b | ||
|
|
34e884156f | ||
|
|
cd90c78391 | ||
|
|
93f4dfd88b | ||
|
|
535b5daa31 | ||
|
|
6b53786f62 | ||
|
|
d98f4eb56e | ||
|
|
8cefc4b7cc | ||
|
|
3063ada72f | ||
|
|
5eb8d6ed8a | ||
|
|
7c751a2e1c | ||
|
|
55b556a7d1 | ||
|
|
a4d04c9b7e | ||
|
|
23caa2709b | ||
|
|
c264467efe | ||
|
|
2b212ddd76 | ||
|
|
7203e860b3 | ||
|
|
e55f223b46 | ||
|
|
a329baaa54 | ||
|
|
a7a0aee984 | ||
|
|
6539b80d9f | ||
|
|
e1bd9f3e33 | ||
|
|
b9b2793bda | ||
|
|
c4a1ab5036 | ||
|
|
22c7200ebb | ||
|
|
6e42bcd8ce | ||
|
|
6513d4daa1 | ||
|
|
1d93d531bc | ||
|
|
c2c1cc8aec | ||
|
|
5289259275 | ||
|
|
5783910d0c | ||
|
|
026b43e5d3 | ||
|
|
6b591ddd7e | ||
|
|
10252b1937 | ||
|
|
55ec28b81b | ||
|
|
1cb4e25651 | ||
|
|
eac57f6908 | ||
|
|
e2cd8a4201 | ||
|
|
5c7dceb80f | ||
|
|
d70ed5eceb | ||
|
|
261c11b218 | ||
|
|
75d4f9c098 | ||
|
|
19abc42efe | ||
|
|
09ab90ed35 | ||
|
|
f58d846015 | ||
|
|
caee1d3123 | ||
|
|
c75f17d483 | ||
|
|
241ca9a533 | ||
|
|
3f75f51255 | ||
|
|
1c4fc96c91 | ||
|
|
7f9709d75e | ||
|
|
84668c2acc | ||
|
|
e0fd79139e | ||
|
|
ed97d9dc0c | ||
|
|
99ef383398 | ||
|
|
56a549b4d5 | ||
|
|
330f0ba571 | ||
|
|
06273e48c8 | ||
|
|
a2997a8f7d | ||
|
|
ed5c5bef5e | ||
|
|
493ff37fc0 | ||
|
|
1a1c29e57d | ||
|
|
e32eed7599 | ||
|
|
6400e5ee29 | ||
|
|
d68892ab02 | ||
|
|
6a8a2d62c4 | ||
|
|
e675b25c60 | ||
|
|
353b8b29fa | ||
|
|
272204c0c7 | ||
|
|
818ce0fa2f | ||
|
|
ed20bf6bf3 | ||
|
|
58bc4a15ac | ||
|
|
9be5063396 | ||
|
|
4a6a87674a | ||
|
|
01bb87275b | ||
|
|
9a03503542 | ||
|
|
e5d0e78bd4 | ||
|
|
c4fb93f9c2 | ||
|
|
98bee09a6a | ||
|
|
c68dc2d419 | ||
|
|
ec287a329b | ||
|
|
c0e4b9cd67 | ||
|
|
c98485514c | ||
|
|
6281f8721a | ||
|
|
75ad0a0f8c | ||
|
|
da83d79546 | ||
|
|
f43cba7e78 | ||
|
|
cbbb11f4df | ||
|
|
532ba725a5 | ||
|
|
886b367a8c | ||
|
|
41d1b84bd5 | ||
|
|
5da1cb0792 | ||
|
|
f9397e93b5 | ||
|
|
2e7aaea524 | ||
|
|
4414cd849d | ||
|
|
c548348386 | ||
|
|
61ffa3eb82 | ||
|
|
59917ab679 | ||
|
|
1163dbd17f | ||
|
|
435d839c72 | ||
|
|
b1d9769f97 | ||
|
|
89157a803c | ||
|
|
d86c47477e | ||
|
|
3fe6522aae | ||
|
|
80d1f732e5 | ||
|
|
c0556ac3a5 | ||
|
|
1fcec88ad2 | ||
|
|
f8b216df30 | ||
|
|
4b905b614c | ||
|
|
6c54bcefd3 | ||
|
|
475ce41268 | ||
|
|
564a4ac1b8 | ||
|
|
931e80f20c | ||
|
|
a7ba9932ba | ||
|
|
009c8af7fe | ||
|
|
4c4d520198 | ||
|
|
1cf7cd8af0 | ||
|
|
4a9f13763d | ||
|
|
30747a69c8 | ||
|
|
cd9d093f60 | ||
|
|
4a98a66778 | ||
|
|
442cb306f6 | ||
|
|
7b0b915749 | ||
|
|
96bdde376f | ||
|
|
7ba042e069 | ||
|
|
60699f306b | ||
|
|
ae7af59c6d | ||
|
|
42b250d14d | ||
|
|
71a17b5932 | ||
|
|
9475024640 | ||
|
|
5b28a04d55 | ||
|
|
8cedb742cb | ||
|
|
320e7ce8fd | ||
|
|
81517f66cc | ||
|
|
b5ca13249e | ||
|
|
a2cef707e3 | ||
|
|
5b6245666b | ||
|
|
dbd34f1578 | ||
|
|
e1117f7550 | ||
|
|
08b09e5236 | ||
|
|
e7d7038dfa | ||
|
|
da0ffab0b2 | ||
|
|
516169428d | ||
|
|
812a1926f0 | ||
|
|
f0dd1046a6 | ||
|
|
188d631011 | ||
|
|
0b5fa563cd | ||
|
|
eb1d50479b | ||
|
|
e248a4d22b | ||
|
|
0ec4bafca2 | ||
|
|
603df6e36f | ||
|
|
6c565482cf | ||
|
|
861598b4e3 | ||
|
|
811fa89875 | ||
|
|
6c6b9d7a2b | ||
|
|
bba4d4c95e | ||
|
|
c57ac7bdf3 | ||
|
|
3c440c762a | ||
|
|
9824486616 | ||
|
|
aee8e78078 | ||
|
|
f4a17b7568 | ||
|
|
4ade6d62e2 | ||
|
|
1c1e584abd | ||
|
|
930b27e5fa | ||
|
|
80d69ae0bb | ||
|
|
cff2236dac | ||
|
|
a79ae3d66f | ||
|
|
f636513390 | ||
|
|
247ef32e79 | ||
|
|
13a98c9988 | ||
|
|
73c411e1b9 | ||
|
|
4976568fc7 | ||
|
|
fb30cc2f50 | ||
|
|
f95a174288 | ||
|
|
5126e099bd | ||
|
|
dcf0299195 | ||
|
|
c516c9904b | ||
|
|
b49c05ec22 | ||
|
|
015b4fae9c | ||
|
|
eead41bf4c | ||
|
|
0f613d9051 | ||
|
|
3c54a8f07b | ||
|
|
e1a2933739 | ||
|
|
00b97526e7 | ||
|
|
2ca7709c24 | ||
|
|
bb05007f55 | ||
|
|
0f7ce0b78a | ||
|
|
cdafd64c15 | ||
|
|
c6c7b72096 | ||
|
|
cb3792d39e | ||
|
|
10eed3806a | ||
|
|
de5bec637c | ||
|
|
2330e2de75 | ||
|
|
6cf40df24d | ||
|
|
740ec2787b | ||
|
|
d68c066246 | ||
|
|
c3373205d0 | ||
|
|
3b4b5ab8c8 | ||
|
|
8f99a2b734 | ||
|
|
74b4c3c9a1 | ||
|
|
bf322d0e94 | ||
|
|
327bad18aa | ||
|
|
20f40b29c0 | ||
|
|
ee490906d8 | ||
|
|
6e82df816d | ||
|
|
e752224bce | ||
|
|
0dee714026 | ||
|
|
938f471079 | ||
|
|
6400d8a623 | ||
|
|
f8e46d98a0 | ||
|
|
8a7ad3d255 | ||
|
|
d661bb1324 | ||
|
|
32aba57b49 | ||
|
|
f2bab95267 | ||
|
|
c38e3e0108 | ||
|
|
7fbd30460f | ||
|
|
63d7a2b997 | ||
|
|
7681f2904d | ||
|
|
378ad688b7 | ||
|
|
c6487ed632 | ||
|
|
62a6974004 | ||
|
|
998288261a | ||
|
|
8ab7167eaf | ||
|
|
5b0625df96 | ||
|
|
8732c53478 | ||
|
|
a4ef97afd9 | ||
|
|
51ad909ffe | ||
|
|
e2354a0a06 | ||
|
|
cc66dee55c | ||
|
|
ecfb752487 | ||
|
|
8b18522205 | ||
|
|
a2395e0243 | ||
|
|
c7d05a903c | ||
|
|
ab33b45718 | ||
|
|
5265c4f5cb | ||
|
|
4f3ff79736 | ||
|
|
79bc4b9ca0 | ||
|
|
ae951f6981 | ||
|
|
cbe5bdb85f | ||
|
|
2909f8a628 | ||
|
|
32b375c5e4 | ||
|
|
456008a52b | ||
|
|
be5a6311f5 | ||
|
|
325fd16d32 | ||
|
|
7659b70da0 | ||
|
|
85701631a0 | ||
|
|
566e3157a5 | ||
|
|
569226e753 | ||
|
|
33a75f4817 | ||
|
|
89baa704a9 | ||
|
|
827ed1e6a2 | ||
|
|
df83eb7278 | ||
|
|
4e84f31694 | ||
|
|
994d6cc912 | ||
|
|
02e108d166 | ||
|
|
d3b75974f4 | ||
|
|
5d40dfbc9b | ||
|
|
eaf611f9ee | ||
|
|
004ab1a9d1 | ||
|
|
d1be85c728 | ||
|
|
42930fe600 | ||
|
|
9e362d9f6e | ||
|
|
540a83da65 | ||
|
|
1a2e4152ed | ||
|
|
0878361f6b | ||
|
|
6fae64ff49 | ||
|
|
c09ba719ba | ||
|
|
409e7b503c | ||
|
|
db488f3220 | ||
|
|
1c7e2540c2 | ||
|
|
9e5439959a | ||
|
|
282f372eda | ||
|
|
972a967d5d | ||
|
|
4170f621a5 | ||
|
|
67c8dfaf0f | ||
|
|
34db1e2e2c | ||
|
|
b787103226 | ||
|
|
289b4aa2fa | ||
|
|
4efae81a76 | ||
|
|
3690140555 | ||
|
|
ad4d8f24ca | ||
|
|
ac438b9934 | ||
|
|
425a4c5bb1 | ||
|
|
3a223b9073 | ||
|
|
566e0d60b2 | ||
|
|
940ee0c9c3 | ||
|
|
f8df43d734 | ||
|
|
dbb7020a4d | ||
|
|
32da8ca78b | ||
|
|
8c42d0ce16 | ||
|
|
2a25f6d3a3 | ||
|
|
8be5867de7 | ||
|
|
fad35ef43f | ||
|
|
4d57c13055 | ||
|
|
496de1816a | ||
|
|
2cf04ee30d | ||
|
|
ec00f5a90f | ||
|
|
8b46d8821b | ||
|
|
17fcbbe910 | ||
|
|
dcfb8b9dda | ||
|
|
1fc586c3a5 | ||
|
|
bb88a0f94a | ||
|
|
9d1a384f4f | ||
|
|
c144f9fbd3 | ||
|
|
22ccca21fc | ||
|
|
d2a703d5cc | ||
|
|
35aa12b9bd | ||
|
|
c01b5dd96f | ||
|
|
6a657f360d | ||
|
|
7132a69046 | ||
|
|
db7feb5a3e | ||
|
|
448ea5ec82 | ||
|
|
b618e0f9d4 | ||
|
|
ccf50ca477 | ||
|
|
a0ef245067 | ||
|
|
78c94c3f56 | ||
|
|
4b0301b280 | ||
|
|
436932aef5 | ||
|
|
3ea6a4a0b1 | ||
|
|
96dd32718b | ||
|
|
cd40c5b40f | ||
|
|
1c6ee57bbf | ||
|
|
09f40968cb | ||
|
|
d390f2e41f | ||
|
|
cb7018d782 | ||
|
|
a578ea1fd3 | ||
|
|
9c912d1dd6 | ||
|
|
da011f212a | ||
|
|
046d49b5a9 | ||
|
|
847280450a | ||
|
|
864b569cf8 | ||
|
|
43f15d3b43 | ||
|
|
d8c691f7f0 | ||
|
|
6e49dc0295 | ||
|
|
7df594d284 | ||
|
|
81f85831f5 | ||
|
|
7f810ca93b | ||
|
|
414f961f1f | ||
|
|
dde7bd1ceb | ||
|
|
2e721e1b02 | ||
|
|
fc7a0686af | ||
|
|
3a3879b2c3 | ||
|
|
d34918abf0 | ||
|
|
352dbefc63 | ||
|
|
96e7d6eaa4 | ||
|
|
3611c3fc5b | ||
|
|
942fce394b | ||
|
|
13b067c9b6 | ||
|
|
185cecd891 | ||
|
|
27c0f7e75f | ||
|
|
05dbfebce5 | ||
|
|
01be148429 | ||
|
|
fca8564ea0 | ||
|
|
485bfedf5d | ||
|
|
32b93b53fc | ||
|
|
c970d8a735 | ||
|
|
22b38099ce | ||
|
|
bc5e877c9c | ||
|
|
1cd8717818 | ||
|
|
6df0358b80 | ||
|
|
56c0632f86 | ||
|
|
61596ebe5b | ||
|
|
e820049caa | ||
|
|
3e97c96b60 | ||
|
|
beef83d871 | ||
|
|
d421feadf2 | ||
|
|
407a6a4a7c | ||
|
|
ece783d217 | ||
|
|
45bfb89ea2 | ||
|
|
6046849249 | ||
|
|
597c2f42c6 | ||
|
|
975e7190e4 | ||
|
|
65b9bc24ef | ||
|
|
46b7bfc478 | ||
|
|
28f910a10b | ||
|
|
9d920d616f | ||
|
|
a2bde2b297 | ||
|
|
69a69cc828 | ||
|
|
4f0d9d0cf1 | ||
|
|
796601bddb | ||
|
|
ef24ee4c39 | ||
|
|
c623291929 | ||
|
|
3a18a6d620 | ||
|
|
90e567a6d9 | ||
|
|
a83a8e7a45 | ||
|
|
04d5e659bc | ||
|
|
88a5554a44 | ||
|
|
977abe2396 | ||
|
|
3d70b26788 | ||
|
|
e7fc394e15 | ||
|
|
3481aad827 | ||
|
|
2f6fb12258 | ||
|
|
36a3830ba2 | ||
|
|
06367347e6 |
2
.github/dependabot.yml
vendored
2
.github/dependabot.yml
vendored
@@ -8,7 +8,7 @@ updates:
|
||||
commit-message:
|
||||
prefix: ⬆
|
||||
# Python
|
||||
- package-ecosystem: "pip"
|
||||
- package-ecosystem: "uv"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
|
||||
2
.github/labeler.yml
vendored
2
.github/labeler.yml
vendored
@@ -17,6 +17,7 @@ lang-all:
|
||||
- docs/*/docs/**
|
||||
- all-globs-to-all-files:
|
||||
- '!docs/en/docs/**'
|
||||
- '!docs/*/**/_*.md'
|
||||
- '!fastapi/**'
|
||||
- '!pyproject.toml'
|
||||
|
||||
@@ -30,6 +31,7 @@ internal:
|
||||
- .pre-commit-config.yaml
|
||||
- pdm_build.py
|
||||
- requirements*.txt
|
||||
- uv.lock
|
||||
- docs/en/data/sponsors.yml
|
||||
- docs/en/overrides/main.html
|
||||
- all-globs-to-all-files:
|
||||
|
||||
58
.github/workflows/build-docs.yml
vendored
58
.github/workflows/build-docs.yml
vendored
@@ -8,9 +8,6 @@ on:
|
||||
- opened
|
||||
- synchronize
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -21,7 +18,7 @@ jobs:
|
||||
outputs:
|
||||
docs: ${{ steps.filter.outputs.docs }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
# 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
|
||||
@@ -31,15 +28,13 @@ jobs:
|
||||
- README.md
|
||||
- docs/**
|
||||
- docs_src/**
|
||||
- requirements-docs.txt
|
||||
- requirements-docs-insiders.txt
|
||||
- pyproject.toml
|
||||
- uv.lock
|
||||
- mkdocs.yml
|
||||
- mkdocs.insiders.yml
|
||||
- mkdocs.maybe-insiders.yml
|
||||
- mkdocs.no-insiders.yml
|
||||
- mkdocs.env.yml
|
||||
- .github/workflows/build-docs.yml
|
||||
- .github/workflows/deploy-docs.yml
|
||||
- scripts/mkdocs_hooks.py
|
||||
langs:
|
||||
needs:
|
||||
- changes
|
||||
@@ -47,33 +42,24 @@ jobs:
|
||||
outputs:
|
||||
langs: ${{ steps.show-langs.outputs.langs }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install docs extras
|
||||
run: uv pip install -r requirements-docs.txt
|
||||
# Install MkDocs Material Insiders here just to put it in the cache for the rest of the steps
|
||||
- name: Install Material for MkDocs Insiders
|
||||
if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' )
|
||||
run: uv pip install -r requirements-docs-insiders.txt
|
||||
env:
|
||||
TOKEN: ${{ secrets.FASTAPI_MKDOCS_MATERIAL_INSIDERS }}
|
||||
- name: Verify Docs
|
||||
run: python ./scripts/docs.py verify-docs
|
||||
run: uv sync --locked --no-dev --group docs
|
||||
- name: Export Language Codes
|
||||
id: show-langs
|
||||
run: |
|
||||
echo "langs=$(python ./scripts/docs.py langs-json)" >> $GITHUB_OUTPUT
|
||||
echo "langs=$(uv run ./scripts/docs.py langs-json)" >> $GITHUB_OUTPUT
|
||||
|
||||
build-docs:
|
||||
needs:
|
||||
@@ -89,35 +75,29 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install docs extras
|
||||
run: uv pip install -r requirements-docs.txt
|
||||
- name: Install Material for MkDocs Insiders
|
||||
if: ( github.event_name != 'pull_request' || github.secret_source == 'Actions' )
|
||||
run: uv pip install -r requirements-docs-insiders.txt
|
||||
env:
|
||||
TOKEN: ${{ secrets.FASTAPI_MKDOCS_MATERIAL_INSIDERS }}
|
||||
run: uv sync --locked --no-dev --group docs
|
||||
- name: Update Languages
|
||||
run: python ./scripts/docs.py update-languages
|
||||
- uses: actions/cache@v4
|
||||
run: uv run ./scripts/docs.py update-languages
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
key: mkdocs-cards-${{ matrix.lang }}-${{ github.ref }}
|
||||
path: docs/${{ matrix.lang }}/.cache
|
||||
- name: Build Docs
|
||||
run: python ./scripts/docs.py build-lang ${{ matrix.lang }}
|
||||
- uses: actions/upload-artifact@v4
|
||||
run: uv run ./scripts/docs.py build-lang ${{ matrix.lang }}
|
||||
- uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: docs-site-${{ matrix.lang }}
|
||||
path: ./site/**
|
||||
|
||||
16
.github/workflows/contributors.yml
vendored
16
.github/workflows/contributors.yml
vendored
@@ -10,9 +10,6 @@ on:
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
job:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
@@ -24,21 +21,20 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
run: uv sync --locked --no-dev --group github-actions
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
@@ -48,6 +44,6 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
||||
- name: FastAPI People Contributors
|
||||
run: python ./scripts/contributors.py
|
||||
run: uv run ./scripts/contributors.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
||||
|
||||
31
.github/workflows/deploy-docs.yml
vendored
31
.github/workflows/deploy-docs.yml
vendored
@@ -12,9 +12,6 @@ permissions:
|
||||
pull-requests: write
|
||||
statuses: write
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
deploy-docs:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -23,32 +20,32 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install GitHub Actions dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
run: uv sync --locked --no-dev --group github-actions
|
||||
- name: Deploy Docs Status Pending
|
||||
run: python ./scripts/deploy_docs_status.py
|
||||
run: uv run ./scripts/deploy_docs_status.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
RUN_ID: ${{ github.run_id }}
|
||||
STATE: "pending"
|
||||
- name: Clean site
|
||||
run: |
|
||||
rm -rf ./site
|
||||
mkdir ./site
|
||||
- uses: actions/download-artifact@v5
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
path: ./site/
|
||||
pattern: docs-site-*
|
||||
@@ -67,11 +64,19 @@ jobs:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: pages deploy ./site --project-name=${{ env.PROJECT_NAME }} --branch=${{ env.BRANCH }}
|
||||
- name: Deploy Docs Status Error
|
||||
if: failure()
|
||||
run: uv run ./scripts/deploy_docs_status.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
RUN_ID: ${{ github.run_id }}
|
||||
STATE: "error"
|
||||
- name: Comment Deploy
|
||||
run: python ./scripts/deploy_docs_status.py
|
||||
run: uv run ./scripts/deploy_docs_status.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DEPLOY_URL: ${{ steps.deploy.outputs.deployment-url }}
|
||||
COMMIT_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
RUN_ID: ${{ github.run_id }}
|
||||
IS_DONE: "true"
|
||||
STATE: "success"
|
||||
|
||||
12
.github/workflows/issue-manager.yml
vendored
12
.github/workflows/issue-manager.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: tiangolo/issue-manager@0.5.1
|
||||
- uses: tiangolo/issue-manager@0.6.0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
config: >
|
||||
@@ -38,10 +38,18 @@ jobs:
|
||||
},
|
||||
"waiting": {
|
||||
"delay": 2628000,
|
||||
"message": "As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR."
|
||||
"message": "As this PR has been waiting for the original user for a while but seems to be inactive, it's now going to be closed. But if there's anyone interested, feel free to create a new PR.",
|
||||
"reminder": {
|
||||
"before": "P3D",
|
||||
"message": "Heads-up: this will be closed in 3 days unless there's new activity."
|
||||
}
|
||||
},
|
||||
"invalid": {
|
||||
"delay": 0,
|
||||
"message": "This was marked as invalid and will be closed now. If this is an error, please provide additional details."
|
||||
},
|
||||
"maybe-ai": {
|
||||
"delay": 0,
|
||||
"message": "This was marked as potentially AI generated and will be closed now. If this is an error, please provide additional details, make sure to read the docs about contributing and AI."
|
||||
}
|
||||
}
|
||||
|
||||
16
.github/workflows/label-approved.yml
vendored
16
.github/workflows/label-approved.yml
vendored
@@ -8,9 +8,6 @@ on:
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
label-approved:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
@@ -20,23 +17,22 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install GitHub Actions dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
run: uv sync --locked --no-dev --group github-actions
|
||||
- name: Label Approved
|
||||
run: python ./scripts/label_approved.py
|
||||
run: uv run ./scripts/label_approved.py
|
||||
env:
|
||||
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CONFIG: >
|
||||
|
||||
4
.github/workflows/latest-changes.yml
vendored
4
.github/workflows/latest-changes.yml
vendored
@@ -24,6 +24,8 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
# pin to actions/checkout@v5 for compatibility with latest-changes
|
||||
# Ref: https://github.com/actions/checkout/issues/2313
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
# To allow latest-changes to commit to the main branch
|
||||
@@ -34,7 +36,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.4.0
|
||||
- uses: tiangolo/latest-changes@0.4.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
latest_changes_file: docs/en/docs/release-notes.md
|
||||
|
||||
16
.github/workflows/notify-translations.yml
vendored
16
.github/workflows/notify-translations.yml
vendored
@@ -15,9 +15,6 @@ on:
|
||||
required: false
|
||||
default: 'false'
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -28,21 +25,20 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
run: uv sync --locked --no-dev --group github-actions
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
@@ -52,7 +48,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Notify Translations
|
||||
run: python ./scripts/notify_translations.py
|
||||
run: uv run ./scripts/notify_translations.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NUMBER: ${{ github.event.inputs.number || null }}
|
||||
|
||||
16
.github/workflows/people.yml
vendored
16
.github/workflows/people.yml
vendored
@@ -10,9 +10,6 @@ on:
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
job:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
@@ -24,21 +21,20 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
run: uv sync --locked --no-dev --group github-actions
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
@@ -48,7 +44,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
|
||||
- name: FastAPI People Experts
|
||||
run: python ./scripts/people.py
|
||||
run: uv run ./scripts/people.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PEOPLE }}
|
||||
SLEEP_INTERVAL: ${{ vars.PEOPLE_SLEEP_INTERVAL }}
|
||||
|
||||
90
.github/workflows/pre-commit.yml
vendored
Normal file
90
.github/workflows/pre-commit.yml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
name: pre-commit
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
|
||||
env:
|
||||
# Forks and Dependabot don't have access to secrets
|
||||
HAS_SECRETS: ${{ secrets.PRE_COMMIT != '' }}
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
name: Checkout PR for own repo
|
||||
if: env.HAS_SECRETS == 'true'
|
||||
with:
|
||||
# To be able to commit it needs to fetch the head of the branch, not the
|
||||
# merge commit
|
||||
ref: ${{ github.head_ref }}
|
||||
# And it needs the full history to be able to compute diffs
|
||||
fetch-depth: 0
|
||||
# A token other than the default GITHUB_TOKEN is needed to be able to trigger CI
|
||||
token: ${{ secrets.PRE_COMMIT }}
|
||||
# pre-commit lite ci needs the default checkout configs to work
|
||||
- uses: actions/checkout@v5
|
||||
name: Checkout PR for fork
|
||||
if: env.HAS_SECRETS == 'false'
|
||||
with:
|
||||
# To be able to commit it needs the head branch of the PR, the remote one
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
cache-dependency-glob: |
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install Dependencies
|
||||
run: uv sync --locked --extra all
|
||||
- name: Run prek - pre-commit
|
||||
id: precommit
|
||||
run: uvx prek run --from-ref origin/${GITHUB_BASE_REF} --to-ref HEAD --show-diff-on-failure
|
||||
continue-on-error: true
|
||||
- name: Commit and push changes
|
||||
if: env.HAS_SECRETS == 'true'
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git add -A
|
||||
if git diff --staged --quiet; then
|
||||
echo "No changes to commit"
|
||||
else
|
||||
git commit -m "🎨 Auto format"
|
||||
git push
|
||||
fi
|
||||
- uses: pre-commit-ci/lite-action@v1.1.0
|
||||
if: env.HAS_SECRETS == 'false'
|
||||
with:
|
||||
msg: 🎨 Auto format
|
||||
- name: Error out on pre-commit errors
|
||||
if: steps.precommit.outcome == 'failure'
|
||||
run: exit 1
|
||||
|
||||
# https://github.com/marketplace/actions/alls-green#why
|
||||
pre-commit-alls-green: # This job does nothing and is only used for the branch protection
|
||||
if: always()
|
||||
needs:
|
||||
- pre-commit
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- name: Decide whether the needed jobs succeeded or failed
|
||||
uses: re-actors/alls-green@release/v1
|
||||
with:
|
||||
jobs: ${{ toJSON(needs) }}
|
||||
17
.github/workflows/publish.yml
vendored
17
.github/workflows/publish.yml
vendored
@@ -15,28 +15,25 @@ jobs:
|
||||
- fastapi-slim
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version-file: ".python-version"
|
||||
# Issue ref: https://github.com/actions/setup-python/issues/436
|
||||
# cache: "pip"
|
||||
# cache-dependency-path: pyproject.toml
|
||||
- name: Install build dependencies
|
||||
run: pip install build
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v7
|
||||
- name: Build distribution
|
||||
run: uv build
|
||||
env:
|
||||
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
|
||||
run: python -m build
|
||||
- name: Publish
|
||||
uses: pypa/gh-action-pypi-publish@v1.13.0
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
run: uv publish
|
||||
|
||||
20
.github/workflows/smokeshow.yml
vendored
20
.github/workflows/smokeshow.yml
vendored
@@ -8,12 +8,8 @@ on:
|
||||
permissions:
|
||||
statuses: write
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
smokeshow:
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -21,20 +17,18 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.9'
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
- run: uv pip install -r requirements-github-actions.txt
|
||||
- uses: actions/download-artifact@v5
|
||||
uv.lock
|
||||
- run: uv sync --locked --no-dev --group github-actions
|
||||
- uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: coverage-html
|
||||
path: htmlcov
|
||||
@@ -44,7 +38,7 @@ jobs:
|
||||
- name: Upload coverage to Smokeshow
|
||||
run: |
|
||||
for i in 1 2 3 4 5; do
|
||||
if smokeshow upload htmlcov; then
|
||||
if uv run smokeshow upload htmlcov; then
|
||||
echo "Smokeshow upload success!"
|
||||
break
|
||||
fi
|
||||
|
||||
16
.github/workflows/sponsors.yml
vendored
16
.github/workflows/sponsors.yml
vendored
@@ -10,9 +10,6 @@ on:
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
job:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
@@ -24,21 +21,20 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
run: uv sync --locked --no-dev --group github-actions
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
@@ -46,7 +42,7 @@ jobs:
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
- name: FastAPI People Sponsors
|
||||
run: python ./scripts/sponsors.py
|
||||
run: uv run ./scripts/sponsors.py
|
||||
env:
|
||||
SPONSORS_TOKEN: ${{ secrets.SPONSORS_TOKEN }}
|
||||
PR_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
||||
|
||||
15
.github/workflows/test-redistribute.yml
vendored
15
.github/workflows/test-redistribute.yml
vendored
@@ -12,26 +12,19 @@ on:
|
||||
jobs:
|
||||
test-redistribute:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
package:
|
||||
- fastapi
|
||||
- fastapi-slim
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.10"
|
||||
python-version-file: ".python-version"
|
||||
- name: Install build dependencies
|
||||
run: pip install build
|
||||
- name: Build source distribution
|
||||
env:
|
||||
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
|
||||
run: python -m build --sdist
|
||||
- name: Decompress source distribution
|
||||
run: |
|
||||
@@ -40,9 +33,7 @@ jobs:
|
||||
- name: Install test dependencies
|
||||
run: |
|
||||
cd dist/fastapi*/
|
||||
pip install -r requirements-tests.txt
|
||||
env:
|
||||
TIANGOLO_BUILD_PACKAGE: ${{ matrix.package }}
|
||||
pip install --group tests --editable .[all]
|
||||
- name: Run source distribution tests
|
||||
run: |
|
||||
cd dist/fastapi*/
|
||||
|
||||
164
.github/workflows/test.yml
vendored
164
.github/workflows/test.yml
vendored
@@ -13,130 +13,163 @@ on:
|
||||
- cron: "0 0 * * 1"
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
UV_NO_SYNC: true
|
||||
INLINE_SNAPSHOT_DEFAULT_FLAGS: review
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
# Required permissions
|
||||
permissions:
|
||||
pull-requests: read
|
||||
# Set job outputs to values from filter step
|
||||
outputs:
|
||||
src: ${{ steps.filter.outputs.src }}
|
||||
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-tests.txt
|
||||
- name: Install Pydantic v2
|
||||
run: uv pip install --upgrade "pydantic>=2.0.2,<3.0.0"
|
||||
- name: Lint
|
||||
run: bash scripts/lint.sh
|
||||
- uses: actions/checkout@v6
|
||||
# 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
|
||||
with:
|
||||
filters: |
|
||||
src:
|
||||
- .github/workflows/test.yml
|
||||
- docs_src/**
|
||||
- fastapi/**
|
||||
- scripts/**
|
||||
- tests/**
|
||||
- .python-version
|
||||
- pyproject.toml
|
||||
- uv.lock
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- changes
|
||||
if: needs.changes.outputs.src == 'true'
|
||||
strategy:
|
||||
matrix:
|
||||
python-version:
|
||||
- "3.13"
|
||||
- "3.12"
|
||||
- "3.11"
|
||||
- "3.10"
|
||||
- "3.9"
|
||||
- "3.8"
|
||||
pydantic-version: ["pydantic-v1", "pydantic-v2"]
|
||||
os: [ windows-latest, macos-latest ]
|
||||
python-version: [ "3.14" ]
|
||||
uv-resolution:
|
||||
- highest
|
||||
starlette-src:
|
||||
- starlette-pypi
|
||||
- starlette-git
|
||||
include:
|
||||
- os: macos-latest
|
||||
python-version: "3.10"
|
||||
coverage: coverage
|
||||
uv-resolution: lowest-direct
|
||||
- os: windows-latest
|
||||
python-version: "3.12"
|
||||
coverage: coverage
|
||||
uv-resolution: lowest-direct
|
||||
- os: ubuntu-latest
|
||||
python-version: "3.13"
|
||||
coverage: coverage
|
||||
uv-resolution: highest
|
||||
# Ubuntu with 3.13 needs coverage for CodSpeed benchmarks
|
||||
- os: ubuntu-latest
|
||||
python-version: "3.13"
|
||||
coverage: coverage
|
||||
uv-resolution: highest
|
||||
codspeed: codspeed
|
||||
- os: ubuntu-latest
|
||||
python-version: "3.14"
|
||||
coverage: coverage
|
||||
uv-resolution: highest
|
||||
starlette-src: starlette-git
|
||||
fail-fast: false
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
UV_PYTHON: ${{ matrix.python-version }}
|
||||
UV_RESOLUTION: ${{ matrix.uv-resolution }}
|
||||
STARLETTE_SRC: ${{ matrix.starlette-src }}
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-tests.txt
|
||||
- name: Install Pydantic v1
|
||||
if: matrix.pydantic-version == 'pydantic-v1'
|
||||
run: uv pip install "pydantic>=1.10.0,<2.0.0"
|
||||
- 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: uv sync --no-dev --group tests --extra all
|
||||
- name: Install Starlette from source
|
||||
if: matrix.starlette-src == 'starlette-git'
|
||||
run: uv pip install "git+https://github.com/Kludex/starlette@main"
|
||||
- run: mkdir coverage
|
||||
- name: Test
|
||||
run: bash scripts/test.sh
|
||||
if: matrix.codspeed != 'codspeed'
|
||||
run: uv run --no-sync bash scripts/test.sh
|
||||
env:
|
||||
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
|
||||
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
|
||||
- name: Store coverage files
|
||||
uses: actions/upload-artifact@v4
|
||||
- name: CodSpeed benchmarks
|
||||
if: matrix.codspeed == 'codspeed'
|
||||
uses: CodSpeedHQ/action@v4
|
||||
env:
|
||||
COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
|
||||
CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
|
||||
with:
|
||||
name: coverage-${{ matrix.python-version }}-${{ matrix.pydantic-version }}
|
||||
mode: simulation
|
||||
run: uv run --no-sync coverage run -m pytest tests/ --codspeed
|
||||
# Do not store coverage for all possible combinations to avoid file size max errors in Smokeshow
|
||||
- name: Store coverage files
|
||||
if: matrix.coverage == 'coverage'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: coverage-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/coverage/.coverage.*') }}
|
||||
path: coverage
|
||||
include-hidden-files: true
|
||||
|
||||
coverage-combine:
|
||||
needs: [test]
|
||||
needs:
|
||||
- test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.8'
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-tests.txt
|
||||
run: uv sync --locked --no-dev --group tests --extra all
|
||||
- name: Get coverage files
|
||||
uses: actions/download-artifact@v5
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: coverage-*
|
||||
path: coverage
|
||||
merge-multiple: true
|
||||
- run: ls -la coverage
|
||||
- run: coverage combine coverage
|
||||
- run: coverage report
|
||||
- run: coverage html --title "Coverage for ${{ github.sha }}"
|
||||
- run: uv run coverage combine coverage
|
||||
- run: uv run coverage html --title "Coverage for ${{ github.sha }}"
|
||||
- name: Store coverage HTML
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: coverage-html
|
||||
path: htmlcov
|
||||
include-hidden-files: true
|
||||
- run: uv run coverage report --fail-under=100
|
||||
|
||||
# https://github.com/marketplace/actions/alls-green#why
|
||||
check: # This job does nothing and is only used for the branch protection
|
||||
@@ -153,3 +186,4 @@ jobs:
|
||||
uses: re-actors/alls-green@release/v1
|
||||
with:
|
||||
jobs: ${{ toJSON(needs) }}
|
||||
allowed-skips: coverage-combine,test
|
||||
|
||||
16
.github/workflows/topic-repos.yml
vendored
16
.github/workflows/topic-repos.yml
vendored
@@ -5,9 +5,6 @@ on:
|
||||
- cron: "0 12 1 * *"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
|
||||
jobs:
|
||||
topic-repos:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
@@ -19,22 +16,21 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install GitHub Actions dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt
|
||||
run: uv sync --locked --no-dev --group github-actions
|
||||
- name: Update Topic Repos
|
||||
run: python ./scripts/topic_repos.py
|
||||
run: uv run ./scripts/topic_repos.py
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_PR_TOKEN }}
|
||||
|
||||
78
.github/workflows/translate.yml
vendored
78
.github/workflows/translate.yml
vendored
@@ -1,6 +1,9 @@
|
||||
name: Translate
|
||||
|
||||
on:
|
||||
# schedule:
|
||||
# - cron: "0 5 15 * *" # Run at 05:00 on the 15 of every month
|
||||
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug_enabled:
|
||||
@@ -16,7 +19,7 @@ on:
|
||||
- update-outdated
|
||||
- add-missing
|
||||
- update-and-add
|
||||
- remove-all-removable
|
||||
- remove-removable
|
||||
language:
|
||||
description: Language to translate to as a letter code (e.g. "es" for Spanish)
|
||||
type: string
|
||||
@@ -27,14 +30,54 @@ on:
|
||||
type: string
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
env:
|
||||
UV_SYSTEM_PYTHON: 1
|
||||
commit_in_place:
|
||||
description: Commit changes directly instead of making a PR
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
max:
|
||||
description: Maximum number of items to translate (e.g. 10)
|
||||
type: number
|
||||
required: false
|
||||
default: 10
|
||||
|
||||
jobs:
|
||||
job:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
langs:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
langs: ${{ steps.show-langs.outputs.langs }}
|
||||
commands: ${{ steps.show-langs.outputs.commands }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
cache-dependency-glob: |
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install Dependencies
|
||||
run: uv sync --locked --no-dev --group github-actions --group translations
|
||||
- name: Export Language Codes
|
||||
id: show-langs
|
||||
run: |
|
||||
echo "langs=$(uv run ./scripts/translate.py llm-translatable-json)" >> $GITHUB_OUTPUT
|
||||
echo "commands=$(uv run ./scripts/translate.py commands-json)" >> $GITHUB_OUTPUT
|
||||
env:
|
||||
LANGUAGE: ${{ github.event.inputs.language }}
|
||||
COMMAND: ${{ github.event.inputs.command }}
|
||||
|
||||
translate:
|
||||
if: github.repository_owner == 'fastapi'
|
||||
needs: langs
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
lang: ${{ fromJson(needs.langs.outputs.langs) }}
|
||||
command: ${{ fromJson(needs.langs.outputs.commands) }}
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
@@ -42,21 +85,21 @@ jobs:
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
python-version-file: ".python-version"
|
||||
- name: Setup uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
uses: astral-sh/setup-uv@v7
|
||||
with:
|
||||
version: "0.4.15"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: |
|
||||
requirements**.txt
|
||||
pyproject.toml
|
||||
uv.lock
|
||||
- name: Install Dependencies
|
||||
run: uv pip install -r requirements-github-actions.txt -r requirements-translations.txt
|
||||
run: uv sync --locked --no-dev --group github-actions --group translations
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
@@ -68,10 +111,13 @@ jobs:
|
||||
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
|
||||
uv run ./scripts/translate.py ${{ matrix.command }}
|
||||
uv run ./scripts/translate.py make-pr
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.FASTAPI_TRANSLATIONS }}
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
LANGUAGE: ${{ github.event.inputs.language }}
|
||||
LANGUAGE: ${{ matrix.lang }}
|
||||
EN_PATH: ${{ github.event.inputs.en_path }}
|
||||
COMMAND: ${{ matrix.command }}
|
||||
COMMIT_IN_PLACE: ${{ github.event.inputs.commit_in_place }}
|
||||
MAX: ${{ github.event.inputs.max }}
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -28,3 +28,5 @@ archive.zip
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
.codspeed
|
||||
|
||||
@@ -1,25 +1,73 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
default_language_version:
|
||||
python: python3.10
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v6.0.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
args: ['--maxkb=750']
|
||||
exclude: ^uv.lock$
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
args:
|
||||
- --unsafe
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.13.1
|
||||
- --unsafe
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: ruff
|
||||
- id: local-ruff-check
|
||||
name: ruff check
|
||||
entry: uv run ruff check --force-exclude --fix --exit-non-zero-on-fix
|
||||
require_serial: true
|
||||
language: unsupported
|
||||
types: [python]
|
||||
|
||||
- id: local-ruff-format
|
||||
name: ruff format
|
||||
entry: uv run ruff format --force-exclude --exit-non-zero-on-format
|
||||
require_serial: true
|
||||
language: unsupported
|
||||
types: [python]
|
||||
|
||||
- id: local-mypy
|
||||
name: mypy check
|
||||
entry: uv run mypy fastapi
|
||||
require_serial: true
|
||||
language: unsupported
|
||||
pass_filenames: false
|
||||
|
||||
- id: add-permalinks-pages
|
||||
language: unsupported
|
||||
name: add-permalinks-pages
|
||||
entry: uv run ./scripts/docs.py add-permalinks-pages
|
||||
args:
|
||||
- --fix
|
||||
- id: ruff-format
|
||||
ci:
|
||||
autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
|
||||
autoupdate_commit_msg: ⬆ [pre-commit.ci] pre-commit autoupdate
|
||||
- --update-existing
|
||||
files: ^docs/en/docs/.*\.md$
|
||||
|
||||
- id: generate-readme
|
||||
language: unsupported
|
||||
name: generate README.md from index.md
|
||||
entry: uv run ./scripts/docs.py generate-readme
|
||||
files: ^docs/en/docs/index\.md|docs/en/data/sponsors\.yml|scripts/docs\.py$
|
||||
pass_filenames: false
|
||||
|
||||
- id: update-languages
|
||||
language: unsupported
|
||||
name: update languages
|
||||
entry: uv run ./scripts/docs.py update-languages
|
||||
files: ^docs/.*|scripts/docs\.py$
|
||||
pass_filenames: false
|
||||
|
||||
- id: ensure-non-translated
|
||||
language: unsupported
|
||||
name: ensure non-translated files are not modified
|
||||
entry: uv run ./scripts/docs.py ensure-non-translated
|
||||
files: ^docs/(?!en/).*|^scripts/docs\.py$
|
||||
pass_filenames: false
|
||||
|
||||
- id: fix-translations
|
||||
language: unsupported
|
||||
name: fix translations
|
||||
entry: uv run ./scripts/translation_fixer.py fix-pages
|
||||
files: ^docs/(?!en/).*/docs/.*\.md$
|
||||
|
||||
1
.python-version
Normal file
1
.python-version
Normal file
@@ -0,0 +1 @@
|
||||
3.11
|
||||
101
README.md
101
README.md
@@ -34,17 +34,22 @@ The key features are:
|
||||
* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
|
||||
* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
|
||||
* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
|
||||
* **Intuitive**: Great editor support. <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> everywhere. Less time debugging.
|
||||
* **Intuitive**: Great editor support. <dfn title="also known as auto-complete, autocompletion, IntelliSense">Completion</dfn> everywhere. Less time debugging.
|
||||
* **Easy**: Designed to be easy to use and learn. Less time reading docs.
|
||||
* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
|
||||
* **Robust**: Get production-ready code. With automatic interactive documentation.
|
||||
* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (previously known as Swagger) and <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
||||
|
||||
<small>* estimation based on tests on an internal development team, building production applications.</small>
|
||||
<small>* estimation based on tests conducted by an internal development team, building production applications.</small>
|
||||
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
### Keystone Sponsor
|
||||
|
||||
<a href="https://fastapicloud.com" target="_blank" title="FastAPI Cloud. By the same team behind FastAPI. You code. We Cloud."><img src="https://fastapi.tiangolo.com/img/sponsors/fastapicloud.png"></a>
|
||||
|
||||
### Gold and Silver Sponsors
|
||||
|
||||
<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>
|
||||
@@ -55,6 +60,8 @@ The key features are:
|
||||
<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://serpapi.com/?utm_source=fastapi_website" target="_blank" title="SerpApi: Web Search API"><img src="https://fastapi.tiangolo.com/img/sponsors/serpapi.png"></a>
|
||||
<a href="https://www.greptile.com/?utm_source=fastapi&utm_medium=sponsorship&utm_campaign=fastapi_sponsor_page" target="_blank" title="Greptile: The AI Code Reviewer"><img src="https://fastapi.tiangolo.com/img/sponsors/greptile.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>
|
||||
@@ -113,6 +120,12 @@ The key features are:
|
||||
|
||||
---
|
||||
|
||||
## FastAPI mini documentary
|
||||
|
||||
There's a <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">FastAPI mini documentary</a> released at the end of 2025, you can watch it online:
|
||||
|
||||
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini Documentary"></a>
|
||||
|
||||
## **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>
|
||||
@@ -125,7 +138,7 @@ If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be
|
||||
|
||||
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://www.starlette.dev/" 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
|
||||
@@ -151,8 +164,6 @@ $ pip install "fastapi[standard]"
|
||||
Create a file `main.py` with:
|
||||
|
||||
```Python
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
@@ -164,7 +175,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
def read_item(item_id: int, q: str | None = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -173,9 +184,7 @@ def read_item(item_id: int, q: Union[str, None] = None):
|
||||
|
||||
If your code uses `async` / `await`, use `async def`:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Union
|
||||
|
||||
```Python hl_lines="7 12"
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
@@ -187,7 +196,7 @@ async def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||
async def read_item(item_id: int, q: str | None = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -231,7 +240,7 @@ INFO: Application startup complete.
|
||||
<details markdown="1">
|
||||
<summary>About the command <code>fastapi dev main.py</code>...</summary>
|
||||
|
||||
The command `fastapi dev` reads your `main.py` file, detects the **FastAPI** app in it, and starts a server using <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a>.
|
||||
The command `fastapi dev` reads your `main.py` file, detects the **FastAPI** app in it, and starts a server using <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>.
|
||||
|
||||
By default, `fastapi dev` will start with auto-reload enabled for local development.
|
||||
|
||||
@@ -278,9 +287,7 @@ Now modify the file `main.py` to receive a body from a `PUT` request.
|
||||
|
||||
Declare the body using standard Python types, thanks to Pydantic.
|
||||
|
||||
```Python hl_lines="4 9-12 25-27"
|
||||
from typing import Union
|
||||
|
||||
```Python hl_lines="2 7-10 23-25"
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -290,7 +297,7 @@ app = FastAPI()
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: Union[bool, None] = None
|
||||
is_offer: bool | None = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
@@ -299,7 +306,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
def read_item(item_id: int, q: str | None = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
|
||||
|
||||
@@ -364,7 +371,7 @@ item: Item
|
||||
* Validation of data:
|
||||
* Automatic and clear errors when the data is invalid.
|
||||
* Validation even for deeply nested JSON objects.
|
||||
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of input data: coming from the network to Python data and types. Reading from:
|
||||
* <dfn title="also known as: serialization, parsing, marshalling">Conversion</dfn> of input data: coming from the network to Python data and types. Reading from:
|
||||
* JSON.
|
||||
* Path parameters.
|
||||
* Query parameters.
|
||||
@@ -372,7 +379,7 @@ item: Item
|
||||
* Headers.
|
||||
* Forms.
|
||||
* Files.
|
||||
* <abbr title="also known as: serialization, parsing, marshalling">Conversion</abbr> of output data: converting from Python data and types to network data (as JSON):
|
||||
* <dfn title="also known as: serialization, parsing, marshalling">Conversion</dfn> of output data: converting from Python data and types to network data (as JSON):
|
||||
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
|
||||
* `datetime` objects.
|
||||
* `UUID` objects.
|
||||
@@ -435,7 +442,7 @@ For a more complete example including more features, see the <a href="https://fa
|
||||
|
||||
* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
|
||||
* How to set **validation constraints** as `maximum_length` or `regex`.
|
||||
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** system.
|
||||
* A very powerful and easy to use **<dfn title="also known as components, resources, providers, services, injectables">Dependency Injection</dfn>** system.
|
||||
* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
|
||||
* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
|
||||
* **GraphQL** integration with <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> and other libraries.
|
||||
@@ -446,6 +453,58 @@ For a more complete example including more features, see the <a href="https://fa
|
||||
* **Cookie Sessions**
|
||||
* ...and more.
|
||||
|
||||
### Deploy your app (optional)
|
||||
|
||||
You can optionally deploy your FastAPI app to <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>, go and join the waiting list if you haven't. 🚀
|
||||
|
||||
If you already have a **FastAPI Cloud** account (we invited you from the waiting list 😉), you can deploy your application with one command.
|
||||
|
||||
Before deploying, make sure you are logged in:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi login
|
||||
|
||||
You are logged in to FastAPI Cloud 🚀
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Then deploy your app:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi deploy
|
||||
|
||||
Deploying to FastAPI Cloud...
|
||||
|
||||
✅ Deployment successful!
|
||||
|
||||
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
That's it! Now you can access your app at that URL. ✨
|
||||
|
||||
#### About FastAPI Cloud
|
||||
|
||||
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** is built by the same author and team behind **FastAPI**.
|
||||
|
||||
It streamlines the process of **building**, **deploying**, and **accessing** an API with minimal effort.
|
||||
|
||||
It brings the same **developer experience** of building apps with FastAPI to **deploying** them to the cloud. 🎉
|
||||
|
||||
FastAPI Cloud is the primary sponsor and funding provider for the *FastAPI and friends* open source projects. ✨
|
||||
|
||||
#### Deploy to other cloud providers
|
||||
|
||||
FastAPI is open source and based on standards. You can deploy FastAPI apps to any cloud provider you choose.
|
||||
|
||||
Follow your cloud provider's guides to deploy FastAPI apps with them. 🤓
|
||||
|
||||
## 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). (*)
|
||||
@@ -468,11 +527,11 @@ Used by Starlette:
|
||||
|
||||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Required if you want to use the `TestClient`.
|
||||
* <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()`.
|
||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - Required if you want to support form <dfn title="converting the string that comes from an HTTP request into Python data">"parsing"</dfn>, with `request.form()`.
|
||||
|
||||
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.
|
||||
* <a href="https://www.uvicorn.dev" 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[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>.
|
||||
|
||||
|
||||
@@ -1,467 +0,0 @@
|
||||
<p align="center">
|
||||
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<em>FastAPI framework, yüksək məshuldarlı, öyrənməsi asan, çevik kodlama, istifadəyə hazırdır</em>
|
||||
</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/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ə">
|
||||
</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="Paket versiyası">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/pypi/pyversions/fastapi.svg?color=%2334D058" alt="Dəstəklənən Python versiyaları">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
**Sənədlər**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
|
||||
|
||||
**Qaynaq Kodu**: <a href="https://github.com/fastapi/fastapi" target="_blank">https://github.com/fastapi/fastapi</a>
|
||||
|
||||
---
|
||||
|
||||
FastAPI Python ilə API yaratmaq üçün standart Python <abbr title="Tip Məsləhətləri: Type Hints">tip məsləhətlərinə</abbr> əsaslanan, müasir, sürətli (yüksək performanslı) framework-dür.
|
||||
|
||||
Əsas xüsusiyyətləri bunlardır:
|
||||
|
||||
* **Sürətli**: Çox yüksək performans, **NodeJS** və **Go** səviyyəsində (Starlette və Pydantic-ə təşəkkürlər). [Ən sürətli Python frameworklərindən biridir](#performans).
|
||||
* **Çevik kodlama**: Funksiyanallıqları inkişaf etdirmək sürətini təxminən 200%-dən 300%-ə qədər artırın. *
|
||||
* **Daha az xəta**: İnsan (developer) tərəfindən törədilən səhvlərin təxminən 40% -ni azaldın. *
|
||||
* **İntuitiv**: Əla redaktor dəstəyi. Hər yerdə <abbr title="auto-complete, autocompletion, IntelliSense olaraq da bilinir">otomatik tamamlama</abbr>. Xətaları müəyyənləşdirməyə daha az vaxt sərf edəcəksiniz.
|
||||
* **Asan**: İstifadəsi və öyrənilməsi asan olması üçün nəzərdə tutulmuşdur. Sənədləri oxumaq üçün daha az vaxt ayıracaqsınız.
|
||||
* **Qısa**: Kod təkrarlanmasını minimuma endirin. Hər bir parametr tərifində birdən çox xüsusiyyət ilə və daha az səhvlə qarşılaşacaqsınız.
|
||||
* **Güclü**: Avtomatik və interaktiv sənədlərlə birlikdə istifadəyə hazır kod əldə edə bilərsiniz.
|
||||
* **Standartlara əsaslanan**: API-lar üçün açıq standartlara əsaslanır (və tam uyğun gəlir): <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (əvvəlki adı ilə Swagger) və <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
||||
|
||||
<small>* Bu fikirlər daxili development komandasının hazırladıqları məhsulların sınaqlarına əsaslanır.</small>
|
||||
|
||||
## Sponsorlar
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor -%}`
|
||||
{%- for sponsor in sponsors.silver -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<!-- /sponsors -->
|
||||
|
||||
<a href="https://fastapi.tiangolo.com/az/fastapi-people/#sponsors" class="external-link" target="_blank">Digər sponsorlar</a>
|
||||
|
||||
## Rəylər
|
||||
|
||||
"_[...] Son günlərdə **FastAPI**-ı çox istifadə edirəm. [...] Əslində onu komandamın bütün **Microsoftda ML sevislərində** istifadə etməyi planlayıram. Onların bəziləri **windows**-un əsas məhsuluna və bəzi **Office** məhsullarına inteqrasiya olunurlar._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_**FastAPI** kitabxanasını **Proqnozlar** əldə etmək üçün sorğulana bilən **REST** serverini yaratmaqda istifadə etdik._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - <strong>Uber</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_**Netflix** **böhran idarəçiliyi** orkestrləşmə framework-nün açıq qaynaqlı buraxılışını elan etməkdən məmnundur: **Dispatch**! [**FastAPI** ilə quruldu]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kevin Glisson, Marc Vilanova, Forest Monsen - <strong>Netflix</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_**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://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_Düzünü desəm, sizin qurduğunuz şey həqiqətən möhkəm və peşəkar görünür. Bir çox cəhətdən **Hug**-un olmasını istədiyim kimdir - kiminsə belə bir şey qurduğunu görmək həqiqətən ruhlandırıcıdır._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_Əgər REST API-lər yaratmaq üçün **müasir framework** öyrənmək istəyirsinizsə, **FastAPI**-a baxın [...] Sürətli, istifadəsi və öyrənməsi asandır. [...]_"
|
||||
|
||||
"_**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://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>
|
||||
|
||||
---
|
||||
|
||||
"_Python ilə istifadəyə hazır API qurmaq istəyən hər kəsə **FastAPI**-ı tövsiyə edirəm. **Möhtəşəm şəkildə dizayn edilmiş**, **istifadəsi asan** və **yüksək dərəcədə genişlənə bilən**-dir, API əsaslı inkişaf strategiyamızın **əsas komponentinə** çevrilib və Virtual TAC Engineer kimi bir çox avtomatlaşdırma və servisləri idarə edir._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Deon Pillsbury - <strong>Cisco</strong> <a href="https://www.linkedin.com/posts/deonpillsbury_cisco-cx-python-activity-6963242628536487936-trAp/" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
## **Typer**, CLI-ların FastAPI-ı
|
||||
|
||||
<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>
|
||||
|
||||
Əgər siz veb API əvəzinə terminalda istifadə ediləcək <abbr title="Command Line Interface">CLI</abbr> proqramı qurursunuzsa, <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>-a baxa bilərsiniz.
|
||||
|
||||
**Typer** FastAPI-ın kiçik qardaşıdır. Və o, CLI-lərin **FastAPI**-ı olmaq üçün nəzərdə tutulub. ⌨️ 🚀
|
||||
|
||||
## Tələblər
|
||||
|
||||
FastAPI nəhənglərin çiyinlərində dayanır:
|
||||
|
||||
* Web tərəfi üçün <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a>.
|
||||
* Data tərəfi üçün <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a>.
|
||||
|
||||
## Quraşdırma
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install fastapi
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Tətbiqimizi əlçatan etmək üçün bizə <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> və ya <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a> kimi ASGI server lazımdır.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Nümunə
|
||||
|
||||
### Kodu yaradaq
|
||||
|
||||
* `main.py` adlı fayl yaradaq və ona aşağıdakı kodu yerləşdirək:
|
||||
|
||||
```Python
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Və ya <code>async def</code>...</summary>
|
||||
|
||||
Əgər kodunuzda `async` və ya `await` vardırsa `async def` istifadə edə bilərik:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
**Qeyd**:
|
||||
|
||||
Əgər bu mövzu haqqında məlumatınız yoxdursa <a href="https://fastapi.tiangolo.com/az/async/#in-a-hurry" target="_blank">`async` və `await` sənədindəki</a> _"Tələsirsən?"_ bölməsinə baxa bilərsiniz.
|
||||
|
||||
</details>
|
||||
|
||||
### Kodu işə salaq
|
||||
|
||||
Serveri aşağıdakı əmr ilə işə salaq:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
INFO: Started reloader process [28720]
|
||||
INFO: Started server process [28722]
|
||||
INFO: Waiting for application startup.
|
||||
INFO: Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<details markdown="1">
|
||||
<summary><code>uvicorn main:app --reload</code> əmri haqqında...</summary>
|
||||
|
||||
`uvicorn main:app` əmri aşağıdakılara instinad edir:
|
||||
|
||||
* `main`: `main.py` faylı (yəni Python "modulu").
|
||||
* `app`: `main.py` faylında `app = FastAPI()` sətrində yaratdığımız `FastAPI` obyektidir.
|
||||
* `--reload`: kod dəyişikliyindən sonra avtomatik olaraq serveri yenidən işə salır. Bu parametrdən yalnız development mərhələsində istifadə etməliyik.
|
||||
|
||||
</details>
|
||||
|
||||
### İndi yoxlayaq
|
||||
|
||||
Bu linki brauzerimizdə açaq <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>.
|
||||
|
||||
Aşağıdakı kimi bir JSON cavabı görəcəksiniz:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
Siz artıq bir API yaratmısınız, hansı ki:
|
||||
|
||||
* `/` və `/items/{item_id}` <abbr title="Yol: Path ">_yollarında_</abbr> HTTP sorğularını qəbul edir.
|
||||
* Hər iki _yolda_ `GET` <em>əməliyyatlarını</em> (həmçinin HTTP _metodları_ kimi bilinir) aparır.
|
||||
* `/items/{item_id}` _yolu_ `item_id` adlı `int` qiyməti almalı olan _yol parametrinə_ sahibdir.
|
||||
* `/items/{item_id}` _yolunun_ `q` adlı yol parametri var və bu parametr istəyə bağlı olsa da, `str` qiymətini almalıdır.
|
||||
|
||||
### İnteraktiv API Sənədləri
|
||||
|
||||
İndi <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> ünvanına daxil olun.
|
||||
|
||||
Avtomatik interaktiv API sənədlərini görəcəksiniz (<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> tərəfindən təmin edilir):
|
||||
|
||||

|
||||
|
||||
### Alternativ API sənədləri
|
||||
|
||||
İndi isə <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> ünvanına daxil olun.
|
||||
|
||||
<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> tərəfindən təqdim edilən avtomatik sənədləri görəcəksiniz:
|
||||
|
||||

|
||||
|
||||
## Nümunəni Yeniləyək
|
||||
|
||||
İndi gəlin `main.py` faylını `PUT` sorğusu ilə birlikdə <abbr title="Gövdə: Body ">gövdə</abbr> qəbul edəcək şəkildə dəyişdirək.
|
||||
|
||||
Pydantic sayəsində standart Python tiplərindən istifadə edərək <abbr title="Gövdə: Body ">gövdə</abbr>ni müəyyən edək.
|
||||
|
||||
```Python hl_lines="4 9-12 25-27"
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: Union[bool, None] = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
|
||||
|
||||
@app.put("/items/{item_id}")
|
||||
def update_item(item_id: int, item: Item):
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
Server avtomatik olaraq yenidən işə salınmalı idi (çünki biz yuxarıda `uvicorn` əmri ilə `--reload` parametrindən istifadə etmişik).
|
||||
|
||||
### İnteraktiv API sənədlərindəki dəyişikliyə baxaq
|
||||
|
||||
Yenidən <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> ünvanına daxil olun.
|
||||
|
||||
* İnteraktiv API sənədləri yeni gövdə də daxil olmaq ilə avtomatik olaraq yenilənəcək:
|
||||
|
||||

|
||||
|
||||
* "Try it out" düyməsini klikləyin, bu, parametrləri doldurmağa və API ilə birbaşa əlaqə saxlamağa imkan verir:
|
||||
|
||||

|
||||
|
||||
* Sonra "Execute" düyməsini klikləyin, istifadəçi interfeysi API ilə əlaqə quracaq, parametrləri göndərəcək, nəticələri əldə edəcək və onları ekranda göstərəcək:
|
||||
|
||||

|
||||
|
||||
### Alternativ API Sənədlərindəki Dəyişikliyə Baxaq
|
||||
|
||||
İndi isə yenidən <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> ünvanına daxil olun.
|
||||
|
||||
* Alternativ sənədlər həm də yeni sorğu parametri və gövdəsini əks etdirəcək:
|
||||
|
||||

|
||||
|
||||
### Xülasə
|
||||
|
||||
Ümumiləşdirsək, parametrlər, gövdə və s. Biz məlumat növlərini **bir dəfə** funksiya parametrləri kimi təyin edirik.
|
||||
|
||||
Bunu standart müasir Python tipləri ilə edirsiniz.
|
||||
|
||||
Yeni sintaksis, müəyyən bir kitabxananın metodlarını və ya siniflərini və s. öyrənmək məcburiyyətində deyilsiniz.
|
||||
|
||||
Sadəcə standart **Python**.
|
||||
|
||||
Məsələn, `int` üçün:
|
||||
|
||||
```Python
|
||||
item_id: int
|
||||
```
|
||||
|
||||
və ya daha mürəkkəb `Item` modeli üçün:
|
||||
|
||||
```Python
|
||||
item: Item
|
||||
```
|
||||
|
||||
...və yalnız parametr tipini təyin etməklə bunları əldə edirsiniz:
|
||||
|
||||
* Redaktor dəstəyi ilə:
|
||||
* Avtomatik tamamlama.
|
||||
* Tip yoxlanması.
|
||||
* Məlumatların Təsdiqlənməsi:
|
||||
* Məlumat etibarsız olduqda avtomatik olaraq aydın xətalar göstərir.
|
||||
* Hətta çox dərin JSON obyektlərində belə doğrulama aparır.
|
||||
* Daxil olan məlumatları <abbr title="Çevrilmə: serialization, parsing, marshalling olaraq da bilinir">çevirmək</abbr> üçün aşağıdakı məlumat növlərindən istifadə edilir:
|
||||
* JSON.
|
||||
* <abbr title="Yol: Path">Yol</abbr> parametrləri.
|
||||
* <abbr title="Sorğu: Query">Sorğu</abbr> parametrləri.
|
||||
* <abbr title="Çərəz: Cookie">Çərəzlər</abbr>.
|
||||
* <abbr title="Başlıq: Header">Başlıqlaq</abbr>.
|
||||
* <abbr title="Forma: Form">Formalar</abbr>.
|
||||
* Fayllar.
|
||||
* Daxil olan məlumatları <abbr title="Çevrilmə: serialization, parsing, marshalling olaraq da bilinir">çevirmək</abbr> üçün aşağıdakı məlumat növlərindən istifadə edilir (JSON olaraq):
|
||||
* Python tiplərinin (`str`, `int`, `float`, `bool`, `list`, və s) çevrilməsi.
|
||||
* `datetime` obyektləri.
|
||||
* `UUID` obyektləri.
|
||||
* Verilənlər bazası modelləri.
|
||||
* və daha çoxu...
|
||||
* 2 alternativ istifadəçi interfeysi daxil olmaqla avtomatik interaktiv API sənədlərini təmin edir:
|
||||
* Swagger UI.
|
||||
* ReDoc.
|
||||
|
||||
---
|
||||
|
||||
Gəlin əvvəlki nümunəyə qayıdaq və **FastAPI**-nin nələr edəcəyinə nəzər salaq:
|
||||
|
||||
* `GET` və `PUT` sorğuları üçün `item_id`-nin <abbr title="Yol: Path">yolda</abbr> olub-olmadığını yoxlayacaq.
|
||||
* `item_id`-nin `GET` və `PUT` sorğuları üçün növünün `int` olduğunu yoxlayacaq.
|
||||
* Əgər `int` deyilsə, səbəbini göstərən bir xəta mesajı göstərəcəkdir.
|
||||
* <abbr title="Məcburi olmayan: Optional">məcburi olmayan</abbr> `q` parametrinin `GET` (`http://127.0.0.1:8000/items/foo?q=somequery` burdakı kimi) sorğusu içərisində olub olmadığını yoxlayacaq.
|
||||
* `q` parametrini `= None` ilə yaratdığımız üçün, <abbr title="Məcburi olmayan: Optional">məcburi olmayan</abbr> parametr olacaq.
|
||||
* Əgər `None` olmasaydı, bu məcburi parametr olardı (`PUT` metodunun gövdəsində olduğu kimi).
|
||||
* `PUT` sorğusu üçün, `/items/{item_id}` gövdəsini JSON olaraq oxuyacaq:
|
||||
* `name` adında məcburi bir parametr olub olmadığını və əgər varsa, tipinin `str` olub olmadığını yoxlayacaq.
|
||||
* `price` adında məcburi bir parametr olub olmadığını və əgər varsa, tipinin `float` olub olmadığını yoxlayacaq.
|
||||
* `is_offer` adında <abbr title="Məcburi olmayan: Optional">məcburi olmayan</abbr> bir parametr olub olmadığını və əgər varsa, tipinin `float` olub olmadığını yoxlayacaq.
|
||||
* Bütün bunlar ən dərin JSON obyektlərində belə işləyəcək.
|
||||
* Məlumatların JSON-a və JSON-un Python obyektinə çevrilməsi avtomatik həyata keçiriləcək.
|
||||
* Hər şeyi OpenAPI ilə uyğun olacaq şəkildə avtomatik olaraq sənədləşdirəcək və onları aşağıdakı kimi istifadə edə biləcək:
|
||||
* İnteraktiv sənədləşmə sistemləri.
|
||||
* Bir çox proqramlaşdırma dilləri üçün avtomatlaşdırılmış <abbr title="Müştəri: Client">müştəri</abbr> kodu yaratma sistemləri.
|
||||
* 2 interaktiv sənədləşmə veb interfeysini birbaşa təmin edəcək.
|
||||
|
||||
---
|
||||
|
||||
Yeni başlamışıq, amma siz artıq işin məntiqini başa düşmüsünüz.
|
||||
|
||||
İndi aşağıdakı sətri dəyişdirməyə çalışın:
|
||||
|
||||
```Python
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
...bundan:
|
||||
|
||||
```Python
|
||||
... "item_name": item.name ...
|
||||
```
|
||||
|
||||
...buna:
|
||||
|
||||
```Python
|
||||
... "item_price": item.price ...
|
||||
```
|
||||
|
||||
...və redaktorun məlumat tiplərini bildiyini və avtomatik tamaladığını görəcəksiniz:
|
||||
|
||||

|
||||
|
||||
Daha çox funksiyaya malik daha dolğun nümunə üçün <a href="https://fastapi.tiangolo.com/az/tutorial/">Öyrədici - İstifadəçi Təlimatı</a> səhifəsinə baxa bilərsiniz.
|
||||
|
||||
**Spoiler xəbərdarlığı**: Öyrədici - istifadəçi təlimatına bunlar daxildir:
|
||||
|
||||
* **Parametrlərin**, <abbr title="Başlıq: Header">**başlıqlar**</abbr>, <abbr title="Çərəz: Cookie">çərəzlər</abbr>, **forma sahələri** və **fayllar** olaraq müəyyən edilməsi.
|
||||
* `maximum_length` və ya `regex` kimi **doğrulama məhdudiyyətlərinin** necə təyin ediləcəyi.
|
||||
* Çox güclü və istifadəsi asan **<abbr title="components, resources, providers, services, injectables olaraq da bilinir">Dependency Injection</abbr>** sistemi.
|
||||
* Təhlükəsizlik və autentifikasiya, **JWT tokenləri** ilə **OAuth2** dəstəyi və **HTTP Basic** autentifikasiyası.
|
||||
* **çox dərin JSON modellərini** müəyyən etmək üçün daha irəli səviyyə (lakin eyni dərəcədə asan) üsullar (Pydantic sayəsində).
|
||||
* <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> və digər kitabxanalar ilə **GraphQL** inteqrasiyası.
|
||||
* Digər əlavə xüsusiyyətlər (Starlette sayəsində):
|
||||
* **WebSockets**
|
||||
* HTTPX və `pytest` sayəsində çox asan testlər
|
||||
* **CORS**
|
||||
* **Cookie Sessions**
|
||||
* ...və daha çoxu.
|
||||
|
||||
## Performans
|
||||
|
||||
Müstəqil TechEmpower meyarları göstərir ki, Uvicorn üzərində işləyən **FastAPI** proqramları <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">ən sürətli Python kitabxanalarından biridir</a>, yalnız Starlette və Uvicorn-un özündən yavaşdır, ki FastAPI bunların üzərinə qurulmuş bir framework-dür. (*)
|
||||
|
||||
Ətraflı məlumat üçün bu bölməyə nəzər salın <a href="https://fastapi.tiangolo.com/az/benchmarks/" class="internal-link" target="_blank"><abbr title="Müqayisələr: Benchmarks">Müqayisələr</abbr></a>.
|
||||
|
||||
## Məcburi Olmayan Tələblər
|
||||
|
||||
Pydantic tərəfindən istifadə olunanlar:
|
||||
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - e-poçtun yoxlanılması üçün.
|
||||
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - parametrlərin idarə edilməsi üçün.
|
||||
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - Pydantic ilə istifadə edilə bilən əlavə tiplər üçün.
|
||||
|
||||
Starlette tərəfindən istifadə olunanlar:
|
||||
|
||||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - Əgər `TestClient` strukturundan istifadə edəcəksinizsə, tələb olunur.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - Standart <abbr title="Şablon: Template">şablon</abbr> konfiqurasiyasından istifadə etmək istəyirsinizsə, tələb olunur.
|
||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - `request.form()` ilə forma <abbr title="HTTP sorğusu ilə alınan string məlumatın Python obyektinə çevrilməsi">"çevirmə"</abbr> dəstəyindən istifadə etmək istəyirsinizsə, tələb olunur.
|
||||
* <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - `SessionMiddleware` dəstəyi üçün tələb olunur.
|
||||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - `SchemaGenerator` dəstəyi üçün tələb olunur (Çox güman ki, FastAPI istifadə edərkən buna ehtiyacınız olmayacaq).
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - `UJSONResponse` istifadə etmək istəyirsinizsə, tələb olunur.
|
||||
|
||||
Həm FastAPI, həm də Starlette tərəfindən istifadə olunur:
|
||||
|
||||
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - Yaratdığımız proqramı servis edəcək veb server kimi fəaliyyət göstərir.
|
||||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - `ORJSONResponse` istifadə edəcəksinizsə tələb olunur.
|
||||
|
||||
Bütün bunları `pip install fastapi[all]` ilə quraşdıra bilərsiniz.
|
||||
|
||||
## Lisenziya
|
||||
|
||||
Bu layihə MIT lisenziyasının şərtlərinə əsasən lisenziyalaşdırılıb.
|
||||
@@ -1,5 +0,0 @@
|
||||
# Öyrən
|
||||
|
||||
Burada **FastAPI** öyrənmək üçün giriş bölmələri və dərsliklər yer alır.
|
||||
|
||||
Siz bunu kitab, kurs, FastAPI öyrənmək üçün rəsmi və tövsiyə olunan üsul hesab edə bilərsiniz. 😎
|
||||
@@ -1 +0,0 @@
|
||||
INHERIT: ../en/mkdocs.yml
|
||||
@@ -1,3 +0,0 @@
|
||||
# সম্পর্কে
|
||||
|
||||
**FastAPI** সম্পর্কে বিস্তারিত — এর ডিজাইন, অনুপ্রেরণা ও আরও অনেক কিছু। 🤓
|
||||
@@ -1,298 +0,0 @@
|
||||
# এনভায়রনমেন্ট ভেরিয়েবলস
|
||||
|
||||
/// 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) অংশে দরকার হবে।
|
||||
@@ -1,466 +0,0 @@
|
||||
<p align="center">
|
||||
<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" alt="FastAPI"></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<em>FastAPI উচ্চক্ষমতা সম্পন্ন, সহজে শেখার এবং দ্রুত কোড করে প্রোডাকশনের জন্য ফ্রামওয়ার্ক।</em>
|
||||
</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/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">
|
||||
</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>
|
||||
|
||||
---
|
||||
|
||||
**নির্দেশিকা নথি**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
|
||||
|
||||
**সোর্স কোড**: <a href="https://github.com/fastapi/fastapi" target="_blank">https://github.com/fastapi/fastapi</a>
|
||||
|
||||
---
|
||||
|
||||
FastAPI একটি আধুনিক, দ্রুত ( বেশি ক্ষমতা ) সম্পন্ন, Python 3.6+ দিয়ে API তৈরির জন্য স্ট্যান্ডার্ড পাইথন টাইপ ইঙ্গিত ভিত্তিক ওয়েব ফ্রেমওয়ার্ক।
|
||||
|
||||
এর মূল বৈশিষ্ট্য গুলো হলঃ
|
||||
|
||||
- **গতি**: এটি **NodeJS** এবং **Go** এর মত কার্যক্ষমতা সম্পন্ন (Starlette এবং Pydantic এর সাহায্যে)। [পাইথন এর দ্রুততম ফ্রেমওয়ার্ক গুলোর মধ্যে এটি একটি](#_11)।
|
||||
- **দ্রুত কোড করা**:বৈশিষ্ট্য তৈরির গতি ২০০% থেকে ৩০০% বৃদ্ধি করে৷ \*
|
||||
- **স্বল্প bugs**: মানুব (ডেভেলপার) সৃষ্ট ত্রুটির প্রায় ৪০% হ্রাস করে। \*
|
||||
- **স্বজ্ঞাত**: দুর্দান্ত এডিটর সাহায্য <abbr title="also known as auto-complete, autocompletion, IntelliSense">Completion</abbr> নামেও পরিচিত। দ্রুত ডিবাগ করা যায়।
|
||||
|
||||
- **সহজ**: এটি এমন ভাবে সজানো হয়েছে যেন নির্দেশিকা নথি পড়ে সহজে শেখা এবং ব্যবহার করা যায়।
|
||||
- **সংক্ষিপ্ত**: কোড পুনরাবৃত্তি কমানোর পাশাপাশি, bug কমায় এবং প্রতিটি প্যারামিটার ঘোষণা থেকে একাধিক ফিচার পাওয়া যায় ।
|
||||
- **জোরালো**: স্বয়ংক্রিয় ভাবে তৈরি ক্রিয়াশীল নির্দেশনা নথি (documentation) সহ উৎপাদন উপযোগি (Production-ready) কোড পাওয়া যায়।
|
||||
- **মান-ভিত্তিক**: এর ভিত্তি <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (যা পুর্বে Swagger নামে পরিচিত ছিল) এবং <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a> এর আদর্শের মানের ওপর
|
||||
|
||||
<small>\* উৎপাদনমুখি এপ্লিকেশন বানানোর এক দল ডেভেলপার এর মতামত ভিত্তিক ফলাফল।</small>
|
||||
|
||||
## স্পনসর গণ
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor -%}
|
||||
{%- for sponsor in sponsors.silver -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<!-- /sponsors -->
|
||||
|
||||
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">অন্যান্য স্পনসর গণ</a>
|
||||
|
||||
## মতামত সমূহ
|
||||
|
||||
"_আমি আজকাল **FastAPI** ব্যবহার করছি। [...] আমরা ভাবছি মাইক্রোসফ্টে **ML সার্ভিস** এ সকল দলের জন্য এটি ব্যবহার করব। যার মধ্যে কিছু পণ্য **Windows** এ সংযোযন হয় এবং কিছু **Office** এর সাথে সংযোযন হচ্ছে।_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">কবির খান - <strong>মাইক্রোসফ্টে</strong> <a href="https://github.com/fastapi/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_আমরা **FastAPI** লাইব্রেরি গ্রহণ করেছি একটি **REST** সার্ভার তৈরি করতে, যা **ভবিষ্যদ্বাণী** পাওয়ার জন্য কুয়েরি করা যেতে পারে। [লুডউইগের জন্য]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">পিয়েরো মোলিনো, ইয়ারোস্লাভ দুদিন, এবং সাই সুমন্থ মিরিয়ালা - <strong>উবার</strong> <a href="https://eng.uber.com/ludwig-v0-2/" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_**Netflix** আমাদের **ক্রাইসিস ম্যানেজমেন্ট** অর্কেস্ট্রেশন ফ্রেমওয়ার্ক: **ডিসপ্যাচ** এর ওপেন সোর্স রিলিজ ঘোষণা করতে পেরে আনন্দিত! [যাকিনা **FastAPI** দিয়ে নির্মিত]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">কেভিন গ্লিসন, মার্ক ভিলানোভা, ফরেস্ট মনসেন - <strong>নেটফ্লিক্স</strong> <a href="https://netflixtechblog.com/introducing-dispatch-da4b8a2a8072" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_আমি **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://x.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"\_সত্যিই, আপনি যা তৈরি করেছেন তা খুব মজবুত এবং পরিপূর্ন৷ অনেক উপায়ে, আমি যা **Hug** এ করতে চেয়েছিলাম - তা কাউকে তৈরি করতে দেখে আমি সত্যিই অনুপ্রানিত৷\_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">টিমোথি ক্রসলে - <strong><a href="https://github.com/hugapi/hug" target="_blank">Hug</a> স্রষ্টা</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"আপনি যদি REST API তৈরির জন্য একটি **আধুনিক ফ্রেমওয়ার্ক** শিখতে চান, তাহলে **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://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>
|
||||
|
||||
---
|
||||
|
||||
## **Typer**, CLI এর জন্য FastAPI
|
||||
|
||||
<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>
|
||||
|
||||
আপনি যদি <abbr title="Command Line Interface">CLI</abbr> অ্যাপ বানাতে চান, যা কিনা ওয়েব API এর পরিবর্তে টার্মিনালে ব্যবহার হবে, তাহলে দেখুন<a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
|
||||
|
||||
**টাইপার** হল FastAPI এর ছোট ভাইয়ের মত। এবং এটির উদ্দেশ্য ছিল **CLIs এর FastAPI** হওয়া। ⌨️ 🚀
|
||||
|
||||
## প্রয়োজনীয়তা গুলো
|
||||
|
||||
Python 3.7+
|
||||
|
||||
FastAPI কিছু দানবেদের কাঁধে দাঁড়িয়ে আছে:
|
||||
|
||||
- <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> ওয়েব অংশের জন্য.
|
||||
- <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> ডেটা অংশগুলির জন্য.
|
||||
|
||||
## ইনস্টলেশন প্রক্রিয়া
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install fastapi
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
আপনার একটি ASGI সার্ভারেরও প্রয়োজন হবে, প্রোডাকশনের জন্য <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> অথবা <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## উদাহরণ
|
||||
|
||||
### তৈরি
|
||||
|
||||
- `main.py` নামে একটি ফাইল তৈরি করুন:
|
||||
|
||||
```Python
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
<summary>অথবা ব্যবহার করুন <code>async def</code>...</summary>
|
||||
|
||||
যদি আপনার কোড `async` / `await`, ব্যবহার করে তাহলে `async def` ব্যবহার করুন:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
**টীকা**:
|
||||
|
||||
আপনি যদি না জানেন, _"তাড়াহুড়ো?"_ বিভাগটি দেখুন <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` এবং `await` নথির মধ্যে দেখুন </a>.
|
||||
|
||||
</details>
|
||||
|
||||
### এটি চালান
|
||||
|
||||
সার্ভার চালু করুন:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
INFO: Started reloader process [28720]
|
||||
INFO: Started server process [28722]
|
||||
INFO: Waiting for application startup.
|
||||
INFO: Application startup complete.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>নির্দেশনা সম্পর্কে <code>uvicorn main:app --reload</code>...</summary>
|
||||
|
||||
`uvicorn main:app` নির্দেশনাটি দ্বারা বোঝায়:
|
||||
|
||||
- `main`: ফাইল `main.py` (পাইথন "মডিউল")।
|
||||
- `app`: `app = FastAPI()` লাইন দিয়ে `main.py` এর ভিতরে তৈরি করা অবজেক্ট।
|
||||
- `--reload`: কোড পরিবর্তনের পরে সার্ভার পুনরায় চালু করুন। এটি শুধুমাত্র ডেভেলপমেন্ট এর সময় ব্যবহার করুন।
|
||||
|
||||
</details>
|
||||
|
||||
### এটা চেক করুন
|
||||
|
||||
আপনার ব্রাউজার খুলুন <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> এ।
|
||||
|
||||
আপনি JSON রেসপন্স দেখতে পাবেন:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
আপনি ইতিমধ্যে একটি API তৈরি করেছেন যা:
|
||||
|
||||
- `/` এবং `/items/{item_id}` _paths_ এ HTTP অনুরোধ গ্রহণ করে।
|
||||
- উভয় *path*ই `GET` <em>অপারেশন</em> নেয় ( যা HTTP _methods_ নামেও পরিচিত)।
|
||||
- _path_ `/items/{item_id}`-এ একটি _path প্যারামিটার_ `item_id` আছে যা কিনা `int` হতে হবে।
|
||||
- _path_ `/items/{item_id}`-এর একটি ঐচ্ছিক `str` _query প্যারামিটার_ `q` আছে।
|
||||
|
||||
### ক্রিয়াশীল API নির্দেশিকা নথি
|
||||
|
||||
এখন যান <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
আপনি স্বয়ংক্রিয় ভাবে প্রস্তুত ক্রিয়াশীল API নির্দেশিকা নথি দেখতে পাবেন (<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a> প্রদত্ত):
|
||||
|
||||

|
||||
|
||||
### বিকল্প API নির্দেশিকা নথি
|
||||
|
||||
এবং এখন <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> এ যান.
|
||||
|
||||
আপনি স্বয়ংক্রিয় ভাবে প্রস্তুত বিকল্প নির্দেশিকা নথি দেখতে পাবেন (<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a> প্রদত্ত):
|
||||
|
||||

|
||||
|
||||
## উদাহরণস্বরূপ আপগ্রেড
|
||||
|
||||
এখন `main.py` ফাইলটি পরিবর্তন করুন যেন এটি `PUT` রিকুয়েস্ট থেকে বডি পেতে পারে।
|
||||
|
||||
Python স্ট্যান্ডার্ড লাইব্রেরি, Pydantic এর সাহায্যে বডি ঘোষণা করুন।
|
||||
|
||||
```Python hl_lines="4 9-12 25-27"
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: Union[bool, None] = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
|
||||
|
||||
@app.put("/items/{item_id}")
|
||||
def update_item(item_id: int, item: Item):
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
সার্ভারটি স্বয়ংক্রিয়ভাবে পুনরায় লোড হওয়া উচিত (কারণ আপনি উপরের `uvicorn` কমান্ডে `--reload` যোগ করেছেন)।
|
||||
|
||||
### ক্রিয়াশীল API নির্দেশিকা নথি উন্নীতকরণ
|
||||
|
||||
এখন <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> এডড্রেসে যান.
|
||||
|
||||
- ক্রিয়াশীল API নির্দেশিকা নথিটি স্বয়ংক্রিয়ভাবে উন্নীত হযে যাবে, নতুন বডি সহ:
|
||||
|
||||

|
||||
|
||||
- "Try it out" বাটনে চাপুন, এটি আপনাকে পেরামিটারগুলো পূরণ করতে এবং API এর সাথে সরাসরি ক্রিয়া-কলাপ করতে দিবে:
|
||||
|
||||

|
||||
|
||||
- তারপরে "Execute" বাটনে চাপুন, ব্যবহারকারীর ইন্টারফেস আপনার API এর সাথে যোগাযোগ করবে, পেরামিটার পাঠাবে, ফলাফলগুলি পাবে এবং সেগুলি পর্রদায় দেখাবে:
|
||||
|
||||

|
||||
|
||||
### বিকল্প API নির্দেশিকা নথি আপগ্রেড
|
||||
|
||||
এবং এখন <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> এ যান।
|
||||
|
||||
- বিকল্প নির্দেশিকা নথিতেও নতুন কুয়েরি প্যারামিটার এবং বডি প্রতিফলিত হবে:
|
||||
|
||||

|
||||
|
||||
### সংক্ষিপ্তকরণ
|
||||
|
||||
সংক্ষেপে, আপনি **শুধু একবার** প্যারামিটারের ধরন, বডি ইত্যাদি ফাংশন প্যারামিটার হিসেবে ঘোষণা করেন।
|
||||
|
||||
আপনি সেটি আধুনিক পাইথনের সাথে করেন।
|
||||
|
||||
আপনাকে নতুন করে নির্দিষ্ট কোন লাইব্রেরির বাক্য গঠন, ফাংশন বা ক্লাস কিছুই শিখতে হচ্ছে না।
|
||||
|
||||
শুধুই আধুনিক **Python 3.6+**
|
||||
|
||||
উদাহরণস্বরূপ, `int` এর জন্য:
|
||||
|
||||
```Python
|
||||
item_id: int
|
||||
```
|
||||
|
||||
অথবা আরও জটিল `Item` মডেলের জন্য:
|
||||
|
||||
```Python
|
||||
item: Item
|
||||
```
|
||||
|
||||
...এবং সেই একই ঘোষণার সাথে আপনি পাবেন:
|
||||
|
||||
- এডিটর সাহায্য, যেমন
|
||||
- সমাপ্তি।
|
||||
- ধরণ যাচাই
|
||||
- তথ্য যাচাইকরণ:
|
||||
- ডেটা অবৈধ হলে স্বয়ংক্রিয় এবং পরিষ্কার ত্রুটির নির্দেশনা।
|
||||
- এমনকি গভীরভাবে নেস্ট করা JSON অবজেক্টের জন্য বৈধতা।
|
||||
- প্রেরিত তথ্য <abbr title="যা পরিচিত: serialization, parsing, marshalling">রূপান্তর</abbr>: যা নেটওয়ার্ক থেকে পাইথনের তথ্য এবং ধরনে আসে, এবং সেখান থেকে পড়া:
|
||||
|
||||
- JSON।
|
||||
- পাথ প্যারামিটার।
|
||||
- কুয়েরি প্যারামিটার।
|
||||
- কুকিজ
|
||||
- হেডার
|
||||
- ফর্ম
|
||||
- ফাইল
|
||||
|
||||
- আউটপুট ডেটার <abbr title="যা পরিচিত: serialization, parsing, marshalling">রূপান্তর</abbr>: পাইথন ডেটা এবং টাইপ থেকে নেটওয়ার্ক ডেটাতে রূপান্তর করা (JSON হিসাবে):
|
||||
-পাইথন টাইপে রূপান্তর করুন (`str`, `int`, `float`, `bool`, `list`, ইত্যাদি)।
|
||||
- `datetime` অবজেক্ট।
|
||||
- `UUID` objeঅবজেক্টcts।
|
||||
- ডাটাবেস মডেল।
|
||||
- ...এবং আরো অনেক।
|
||||
- স্বয়ংক্রিয় ক্রিয়াশীল API নির্দেশিকা নথি, 2টি বিকল্প ব্যবহারকারীর ইন্টারফেস সহ:
|
||||
- সোয়াগার ইউ আই (Swagger UI)।
|
||||
- রিডক (ReDoc)।
|
||||
|
||||
---
|
||||
|
||||
পূর্ববর্তী কোড উদাহরণে ফিরে আসা যাক, **FastAPI** যা করবে:
|
||||
|
||||
- `GET` এবং `PUT` অনুরোধের জন্য পথে `item_id` আছে কিনা তা যাচাই করবে।
|
||||
- `GET` এবং `PUT` অনুরোধের জন্য `item_id` টাইপ `int` এর হতে হবে তা যাচাই করবে।
|
||||
- যদি না হয় তবে ক্লায়েন্ট একটি উপযুক্ত, পরিষ্কার ত্রুটি দেখতে পাবেন।
|
||||
- `GET` অনুরোধের জন্য একটি ঐচ্ছিক ক্যুয়েরি প্যারামিটার নামক `q` (যেমন `http://127.0.0.1:8000/items/foo?q=somequery`) আছে কি তা চেক করবে।
|
||||
- যেহেতু `q` প্যারামিটারটি `= None` দিয়ে ঘোষণা করা হয়েছে, তাই এটি ঐচ্ছিক।
|
||||
- `None` ছাড়া এটি প্রয়োজনীয় হতো (যেমন `PUT` এর ক্ষেত্রে হয়েছে)।
|
||||
- `/items/{item_id}` এর জন্য `PUT` অনুরোধের বডি JSON হিসাবে পড়ুন:
|
||||
- লক্ষ করুন, `name` একটি প্রয়োজনীয় অ্যাট্রিবিউট হিসাবে বিবেচনা করেছে এবং এটি `str` হতে হবে।
|
||||
- লক্ষ করুন এখানে, `price` অ্যাট্রিবিউটটি আবশ্যক এবং এটি `float` হতে হবে।
|
||||
- লক্ষ করুন `is_offer` একটি ঐচ্ছিক অ্যাট্রিবিউট এবং এটি `bool` হতে হবে যদি উপস্থিত থাকে।
|
||||
- এই সবটি গভীরভাবে অবস্থানরত JSON অবজেক্টগুলিতেও কাজ করবে।
|
||||
- স্বয়ংক্রিয়ভাবে JSON হতে এবং JSON থেকে কনভার্ট করুন।
|
||||
- OpenAPI দিয়ে সবকিছু ডকুমেন্ট করুন, যা ব্যবহার করা যেতে পারে:
|
||||
- ক্রিয়াশীল নির্দেশিকা নথি।
|
||||
- অনেক ভাষার জন্য স্বয়ংক্রিয় ক্লায়েন্ট কোড তৈরির ব্যবস্থা।
|
||||
- সরাসরি 2টি ক্রিয়াশীল নির্দেশিকা নথি ওয়েব পৃষ্ঠ প্রদান করা হয়েছে।
|
||||
|
||||
---
|
||||
|
||||
আমরা এতক্ষন শুধু এর পৃষ্ঠ তৈরি করেছি, কিন্তু আপনি ইতমধ্যেই এটি কিভাবে কাজ করে তার ধারণাও পেয়ে গিয়েছেন।
|
||||
|
||||
নিম্নোক্ত লাইন গুলো পরিবর্তন করার চেষ্টা করুন:
|
||||
|
||||
```Python
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
...পুর্বে:
|
||||
|
||||
```Python
|
||||
... "item_name": item.name ...
|
||||
```
|
||||
|
||||
...পরবর্তীতে:
|
||||
|
||||
```Python
|
||||
... "item_price": item.price ...
|
||||
```
|
||||
|
||||
...এবং দেখুন কিভাবে আপনার এডিটর উপাদানগুলোকে সয়ংক্রিয়ভাবে-সম্পন্ন করবে এবং তাদের ধরন জানতে পারবে:
|
||||
|
||||

|
||||
|
||||
আরও বৈশিষ্ট্য সম্পন্ন উদাহরণের জন্য, দেখুন <a href="https://fastapi.tiangolo.com/tutorial/">টিউটোরিয়াল - ব্যবহারকারীর গাইড</a>.
|
||||
|
||||
**স্পয়লার সতর্কতা**: টিউটোরিয়াল - ব্যবহারকারীর গাইড নিম্নোক্ত বিষয়গুলি অন্তর্ভুক্ত করে:
|
||||
|
||||
- **হেডার**, **কুকিজ**, **ফর্ম ফিল্ড** এবং **ফাইলগুলি** এমন অন্যান্য জায়গা থেকে প্যারামিটার ঘোষণা করা।
|
||||
- `maximum_length` বা `regex` এর মতো **যাচাইকরণ বাধামুক্তি** সেট করা হয় কিভাবে, তা নিয়ে আলোচনা করা হবে।
|
||||
- একটি খুব শক্তিশালী এবং ব্যবহার করা সহজ <abbr title="also known as components, resources, providers, services, injectables">ডিপেন্ডেন্সি ইনজেকশন</abbr> পদ্ধতি
|
||||
- **OAuth2** এবং **JWT টোকেন** এবং **HTTP Basic** auth সহ নিরাপত্তা এবং অনুমোদনপ্রাপ্তি সম্পর্কিত বিষয়সমূহের উপর।
|
||||
- **গভীরভাবে অবস্থানরত JSON মডেল** ঘোষণা করার জন্য আরও উন্নত (কিন্তু সমান সহজ) কৌশল (Pydantic কে ধন্যবাদ)।
|
||||
- আরো অতিরিক্ত বৈশিষ্ট্য (স্টারলেটকে ধন্যবাদ) হিসাবে:
|
||||
- **WebSockets**
|
||||
- **GraphQL**
|
||||
- HTTPX এবং `pytest` ভিত্তিক অত্যন্ত সহজ পরীক্ষা
|
||||
- **CORS**
|
||||
- **Cookie Sessions**
|
||||
- ...এবং আরো।
|
||||
|
||||
## কর্মক্ষমতা
|
||||
|
||||
স্বাধীন TechEmpower Benchmarks দেখায় যে **FastAPI** অ্যাপ্লিকেশনগুলি Uvicorn-এর অধীনে চলমান দ্রুততম<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">পাইথন ফ্রেমওয়ার্কগুলির মধ্যে একটি,</a> শুধুমাত্র Starlette এবং Uvicorn-এর পর (FastAPI দ্বারা অভ্যন্তরীণভাবে ব্যবহৃত)। (\*)
|
||||
|
||||
এটি সম্পর্কে আরও বুঝতে, দেখুন <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
|
||||
|
||||
## ঐচ্ছিক নির্ভরশীলতা
|
||||
|
||||
Pydantic দ্বারা ব্যবহৃত:
|
||||
|
||||
- <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email-validator</code></a> - ইমেল যাচাইকরণের জন্য।
|
||||
|
||||
স্টারলেট দ্বারা ব্যবহৃত:
|
||||
|
||||
- <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> - আপনি যদি `TestClient` ব্যবহার করতে চান তাহলে আবশ্যক।
|
||||
- <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> - আপনি যদি প্রদত্ত টেমপ্লেট রূপরেখা ব্যবহার করতে চান তাহলে প্রয়োজন।
|
||||
- <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> - আপনি যদি ফর্ম সহায়তা করতে চান তাহলে প্রয়োজন <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>, `request.form()` সহ।
|
||||
- <a href="https://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - `SessionMiddleware` সহায়তার জন্য প্রয়োজন।
|
||||
- <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - স্টারলেটের SchemaGenerator সাপোর্ট এর জন্য প্রয়োজন (আপনার সম্ভাবত FastAPI প্রয়োজন নেই)।
|
||||
- <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - `GraphQLApp` সহায়তার জন্য প্রয়োজন।
|
||||
|
||||
FastAPI / Starlette দ্বারা ব্যবহৃত:
|
||||
|
||||
- <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - সার্ভারের জন্য যা আপনার অ্যাপ্লিকেশন লোড করে এবং পরিবেশন করে।
|
||||
- <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - আপনি `ORJSONResponse` ব্যবহার করতে চাইলে প্রয়োজন।
|
||||
- <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - আপনি `UJSONResponse` ব্যবহার করতে চাইলে প্রয়োজন।
|
||||
|
||||
আপনি এই সব ইনস্টল করতে পারেন `pip install fastapi[all]` দিয়ে.
|
||||
|
||||
## লাইসেন্স
|
||||
|
||||
এই প্রজেক্ট MIT লাইসেন্স নীতিমালার অধীনে শর্তায়িত।
|
||||
@@ -1,5 +0,0 @@
|
||||
# শিখুন
|
||||
|
||||
এখানে **FastAPI** শিখার জন্য প্রাথমিক বিভাগগুলি এবং টিউটোরিয়ালগুলি রয়েছে।
|
||||
|
||||
আপনি এটিকে একটি **বই**, একটি **কোর্স**, এবং FastAPI শিখার **অফিসিয়াল** এবং প্রস্তাবিত উপায় বিবেচনা করতে পারেন। 😎
|
||||
@@ -1,586 +0,0 @@
|
||||
# পাইথন এর <abbr title="একটি ভেরিয়েবল কি ধরনের ডেটা ধারণ করতে পারে।">টাইপ্স</abbr> পরিচিতি
|
||||
|
||||
Python-এ ঐচ্ছিক "টাইপ হিন্ট" (যা "টাইপ অ্যানোটেশন" নামেও পরিচিত) এর জন্য সাপোর্ট রয়েছে।
|
||||
|
||||
এই **"টাইপ হিন্ট"** বা অ্যানোটেশনগুলি এক ধরণের বিশেষ <abbr title="সিনট্যাক্স হল প্রোগ্রামিং ভাষায় কোড লেখার নিয়ম ও গঠন।">সিনট্যাক্স</abbr> যা একটি ভেরিয়েবলের <abbr title="যেমন: str, int, float, bool">টাইপ</abbr> ঘোষণা করতে দেয়।
|
||||
|
||||
ভেরিয়েবলগুলির জন্য টাইপ ঘোষণা করলে, এডিটর এবং টুলগুলি আপনাকে আরও ভালো সাপোর্ট দিতে পারে।
|
||||
|
||||
এটি পাইথন টাইপ হিন্ট সম্পর্কে একটি দ্রুত **টিউটোরিয়াল / রিফ্রেশার** মাত্র। এটি **FastAPI** এর সাথে ব্যবহার করার জন্য শুধুমাত্র ন্যূনতম প্রয়োজনীয়তা কভার করে... যা আসলে খুব একটা বেশি না।
|
||||
|
||||
**FastAPI** এই টাইপ হিন্টগুলির উপর ভিত্তি করে নির্মিত, যা এটিকে অনেক সুবিধা এবং লাভ প্রদান করে।
|
||||
|
||||
তবে, আপনি যদি কখনো **FastAPI** ব্যবহার নাও করেন, তবুও এগুলি সম্পর্কে একটু শেখা আপনার উপকারে আসবে।
|
||||
|
||||
/// note
|
||||
|
||||
যদি আপনি একজন Python বিশেষজ্ঞ হন, এবং টাইপ হিন্ট সম্পর্কে সবকিছু জানেন, তাহলে পরবর্তী অধ্যায়ে চলে যান।
|
||||
|
||||
///
|
||||
|
||||
## প্রেরণা
|
||||
|
||||
চলুন একটি সাধারণ উদাহরণ দিয়ে শুরু করি:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial001.py *}
|
||||
|
||||
|
||||
এই প্রোগ্রামটি কল করলে আউটপুট হয়:
|
||||
|
||||
```
|
||||
John Doe
|
||||
```
|
||||
|
||||
ফাংশনটি নিম্নলিখিত কাজ করে:
|
||||
|
||||
* `first_name` এবং `last_name` নেয়।
|
||||
* প্রতিটির প্রথম অক্ষরকে `title()` ব্যবহার করে বড় হাতের অক্ষরে রূপান্তর করে।
|
||||
* তাদেরকে মাঝখানে একটি স্পেস দিয়ে <abbr title="একটার পরে একটা একত্রিত করা">concatenate</abbr> করে।
|
||||
|
||||
{* ../../docs_src/python_types/tutorial001.py hl[2] *}
|
||||
|
||||
|
||||
### এটি সম্পাদনা করুন
|
||||
|
||||
এটি একটি খুব সাধারণ প্রোগ্রাম।
|
||||
|
||||
কিন্তু এখন কল্পনা করুন যে আপনি এটি শুরু থেকে লিখছিলেন।
|
||||
|
||||
এক পর্যায়ে আপনি ফাংশনের সংজ্ঞা শুরু করেছিলেন, আপনার প্যারামিটারগুলি প্রস্তুত ছিল...
|
||||
|
||||
কিন্তু তারপর আপনাকে "সেই method কল করতে হবে যা প্রথম অক্ষরকে বড় হাতের অক্ষরে রূপান্তর করে"।
|
||||
|
||||
এটা কি `upper` ছিল? নাকি `uppercase`? `first_uppercase`? `capitalize`?
|
||||
|
||||
তারপর, আপনি পুরোনো প্রোগ্রামারের বন্ধু, এডিটর অটোকমপ্লিশনের সাহায্যে নেওয়ার চেষ্টা করেন।
|
||||
|
||||
আপনি ফাংশনের প্রথম প্যারামিটার `first_name` টাইপ করেন, তারপর একটি ডট (`.`) টাইপ করেন এবং `Ctrl+Space` চাপেন অটোকমপ্লিশন ট্রিগার করার জন্য।
|
||||
|
||||
কিন্তু, দুর্ভাগ্যবশত, আপনি কিছুই উপযোগী পান না:
|
||||
|
||||
<img src="/img/python-types/image01.png">
|
||||
|
||||
### টাইপ যোগ করুন
|
||||
|
||||
আসুন আগের সংস্করণ থেকে একটি লাইন পরিবর্তন করি।
|
||||
|
||||
আমরা ঠিক এই অংশটি পরিবর্তন করব অর্থাৎ ফাংশনের প্যারামিটারগুলি, এইগুলি:
|
||||
|
||||
```Python
|
||||
first_name, last_name
|
||||
```
|
||||
|
||||
থেকে এইগুলি:
|
||||
|
||||
```Python
|
||||
first_name: str, last_name: str
|
||||
```
|
||||
|
||||
ব্যাস।
|
||||
|
||||
এগুলিই "টাইপ হিন্ট":
|
||||
|
||||
{* ../../docs_src/python_types/tutorial002.py hl[1] *}
|
||||
|
||||
|
||||
এটি ডিফল্ট ভ্যালু ঘোষণা করার মত নয় যেমন:
|
||||
|
||||
```Python
|
||||
first_name="john", last_name="doe"
|
||||
```
|
||||
|
||||
এটি একটি ভিন্ন জিনিস।
|
||||
|
||||
আমরা সমান (`=`) নয়, কোলন (`:`) ব্যবহার করছি।
|
||||
|
||||
এবং টাইপ হিন্ট যোগ করা সাধারণত তেমন কিছু পরিবর্তন করে না যা টাইপ হিন্ট ছাড়াই ঘটত।
|
||||
|
||||
কিন্তু এখন, কল্পনা করুন আপনি আবার সেই ফাংশন তৈরির মাঝখানে আছেন, কিন্তু টাইপ হিন্ট সহ।
|
||||
|
||||
একই পর্যায়ে, আপনি অটোকমপ্লিট ট্রিগার করতে `Ctrl+Space` চাপেন এবং আপনি দেখতে পান:
|
||||
|
||||
<img src="/img/python-types/image02.png">
|
||||
|
||||
এর সাথে, আপনি অপশনগুলি দেখে, স্ক্রল করতে পারেন, যতক্ষণ না আপনি এমন একটি অপশন খুঁজে পান যা কিছু মনে পরিয়ে দেয়:
|
||||
|
||||
<img src="/img/python-types/image03.png">
|
||||
|
||||
## আরও প্রেরণা
|
||||
|
||||
এই ফাংশনটি দেখুন, এটিতে ইতিমধ্যে টাইপ হিন্ট রয়েছে:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial003.py hl[1] *}
|
||||
|
||||
|
||||
এডিটর ভেরিয়েবলগুলির টাইপ জানার কারণে, আপনি শুধুমাত্র অটোকমপ্লিশনই পান না, আপনি এরর চেকও পান:
|
||||
|
||||
<img src="/img/python-types/image04.png">
|
||||
|
||||
এখন আপনি জানেন যে আপনাকে এটি ঠিক করতে হবে, `age`-কে একটি স্ট্রিং হিসেবে রূপান্তর করতে `str(age)` ব্যবহার করতে হবে:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial004.py hl[2] *}
|
||||
|
||||
|
||||
## টাইপ ঘোষণা
|
||||
|
||||
আপনি এতক্ষন টাইপ হিন্ট ঘোষণা করার মূল স্থানটি দেখে ফেলেছেন-- ফাংশন প্যারামিটার হিসেবে।
|
||||
|
||||
সাধারণত এটি **FastAPI** এর ক্ষেত্রেও একই।
|
||||
|
||||
### সিম্পল টাইপ
|
||||
|
||||
আপনি `str` ছাড়াও সমস্ত স্ট্যান্ডার্ড পাইথন টাইপ ঘোষণা করতে পারেন।
|
||||
|
||||
উদাহরণস্বরূপ, আপনি এগুলো ব্যবহার করতে পারেন:
|
||||
|
||||
* `int`
|
||||
* `float`
|
||||
* `bool`
|
||||
* `bytes`
|
||||
|
||||
{* ../../docs_src/python_types/tutorial005.py hl[1] *}
|
||||
|
||||
|
||||
### টাইপ প্যারামিটার সহ জেনেরিক টাইপ
|
||||
|
||||
কিছু ডাটা স্ট্রাকচার অন্যান্য মান ধারণ করতে পারে, যেমন `dict`, `list`, `set` এবং `tuple`। এবং অভ্যন্তরীণ মানগুলোরও নিজেদের টাইপ থাকতে পারে।
|
||||
|
||||
এই ধরনের টাইপগুলিকে বলা হয় "**জেনেরিক**" টাইপ এবং এগুলিকে তাদের অভ্যন্তরীণ টাইপগুলি সহ ঘোষণা করা সম্ভব।
|
||||
|
||||
এই টাইপগুলি এবং অভ্যন্তরীণ টাইপগুলি ঘোষণা করতে, আপনি Python মডিউল `typing` ব্যবহার করতে পারেন। এটি বিশেষভাবে এই টাইপ হিন্টগুলি সমর্থন করার জন্য রয়েছে।
|
||||
|
||||
#### Python এর নতুন সংস্করণ
|
||||
|
||||
`typing` ব্যবহার করা সিনট্যাক্সটি Python 3.6 থেকে সর্বশেষ সংস্করণগুলি পর্যন্ত, অর্থাৎ Python 3.9, Python 3.10 ইত্যাদি সহ সকল সংস্করণের সাথে **সামঞ্জস্যপূর্ণ**।
|
||||
|
||||
Python যত এগিয়ে যাচ্ছে, **নতুন সংস্করণগুলি** এই টাইপ অ্যানোটেশনগুলির জন্য তত উন্নত সাপোর্ট নিয়ে আসছে এবং অনেক ক্ষেত্রে আপনাকে টাইপ অ্যানোটেশন ঘোষণা করতে `typing` মডিউল ইম্পোর্ট এবং ব্যবহার করার প্রয়োজন হবে না।
|
||||
|
||||
যদি আপনি আপনার প্রজেক্টের জন্য Python-এর আরও সাম্প্রতিক সংস্করণ নির্বাচন করতে পারেন, তাহলে আপনি সেই অতিরিক্ত সরলতা থেকে সুবিধা নিতে পারবেন।
|
||||
|
||||
ডক্সে রয়েছে Python-এর প্রতিটি সংস্করণের সাথে সামঞ্জস্যপূর্ণ উদাহরণগুলি (যখন পার্থক্য আছে)।
|
||||
|
||||
উদাহরণস্বরূপ, "**Python 3.6+**" মানে এটি Python 3.6 বা তার উপরে সামঞ্জস্যপূর্ণ (যার মধ্যে 3.7, 3.8, 3.9, 3.10, ইত্যাদি অন্তর্ভুক্ত)। এবং "**Python 3.9+**" মানে এটি Python 3.9 বা তার উপরে সামঞ্জস্যপূর্ণ (যার মধ্যে 3.10, ইত্যাদি অন্তর্ভুক্ত)।
|
||||
|
||||
যদি আপনি Python-এর **সর্বশেষ সংস্করণগুলি ব্যবহার করতে পারেন**, তাহলে সর্বশেষ সংস্করণের জন্য উদাহরণগুলি ব্যবহার করুন, সেগুলি আপনাকে **সর্বোত্তম এবং সহজতম সিনট্যাক্স** প্রদান করবে, যেমন, "**Python 3.10+**"।
|
||||
|
||||
#### লিস্ট
|
||||
|
||||
উদাহরণস্বরূপ, একটি ভেরিয়েবলকে `str`-এর একটি `list` হিসেবে সংজ্ঞায়িত করা যাক।
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
ভেরিয়েবলটি ঘোষণা করুন, একই কোলন (`:`) সিনট্যাক্স ব্যবহার করে।
|
||||
|
||||
টাইপ হিসেবে, `list` ব্যবহার করুন।
|
||||
|
||||
যেহেতু লিস্ট এমন একটি টাইপ যা অভ্যন্তরীণ টাইপগুলি ধারণ করে, আপনি তাদের স্কোয়ার ব্রাকেটের ভিতরে ব্যবহার করুন:
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial006_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
`typing` থেকে `List` (বড় হাতের `L` দিয়ে) ইমপোর্ট করুন:
|
||||
|
||||
``` Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
|
||||
ভেরিয়েবলটি ঘোষণা করুন, একই কোলন (`:`) সিনট্যাক্স ব্যবহার করে।
|
||||
|
||||
টাইপ হিসেবে, `typing` থেকে আপনার ইম্পোর্ট করা `List` ব্যবহার করুন।
|
||||
|
||||
যেহেতু লিস্ট এমন একটি টাইপ যা অভ্যন্তরীণ টাইপগুলি ধারণ করে, আপনি তাদের স্কোয়ার ব্রাকেটের ভিতরে করুন:
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!> ../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// info
|
||||
|
||||
স্কোয়ার ব্রাকেট এর ভিতরে ব্যবহৃত এইসব অভন্তরীন টাইপগুলোকে "ইন্টারনাল টাইপ" বলে।
|
||||
|
||||
এই উদাহরণে, এটি হচ্ছে `List`(অথবা পাইথন ৩.৯ বা তার উপরের সংস্করণের ক্ষেত্রে `list`) এ পাস করা টাইপ প্যারামিটার।
|
||||
|
||||
///
|
||||
|
||||
এর অর্থ হচ্ছে: "ভেরিয়েবল `items` একটি `list`, এবং এই লিস্টের প্রতিটি আইটেম একটি `str`।"
|
||||
|
||||
/// tip
|
||||
|
||||
যদি আপনি Python 3.9 বা তার উপরে ব্যবহার করেন, আপনার `typing` থেকে `List` আমদানি করতে হবে না, আপনি সাধারণ `list` ওই টাইপের পরিবর্তে ব্যবহার করতে পারেন।
|
||||
|
||||
///
|
||||
|
||||
এর মাধ্যমে, আপনার এডিটর লিস্ট থেকে আইটেম প্রসেস করার সময় সাপোর্ট প্রদান করতে পারবে:
|
||||
|
||||
<img src="/img/python-types/image05.png">
|
||||
|
||||
টাইপগুলি ছাড়া, এটি করা প্রায় অসম্ভব।
|
||||
|
||||
লক্ষ্য করুন যে ভেরিয়েবল `item` হল `items` লিস্টের একটি এলিমেন্ট।
|
||||
|
||||
তবুও, এডিটর জানে যে এটি একটি `str`, এবং তার জন্য সাপোর্ট প্রদান করে।
|
||||
|
||||
#### টাপল এবং সেট
|
||||
|
||||
আপনি `tuple` এবং `set` ঘোষণা করার জন্য একই প্রক্রিয়া অনুসরণ করবেন:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial007_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial007.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
এর মানে হল:
|
||||
|
||||
* ভেরিয়েবল `items_t` হল একটি `tuple` যা ৩টি আইটেম ধারণ করে, একটি `int`, অন্য একটি `int`, এবং একটি `str`।
|
||||
* ভেরিয়েবল `items_s` হল একটি `set`, এবং এর প্রতিটি আইটেম হল `bytes` টাইপের।
|
||||
|
||||
#### ডিক্ট
|
||||
|
||||
একটি `dict` সংজ্ঞায়িত করতে, আপনি ২টি টাইপ প্যারামিটার কমা দ্বারা পৃথক করে দেবেন।
|
||||
|
||||
প্রথম টাইপ প্যারামিটারটি হল `dict`-এর কীগুলির জন্য।
|
||||
|
||||
দ্বিতীয় টাইপ প্যারামিটারটি হল `dict`-এর মানগুলির জন্য:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial008_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial008.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
এর মানে হল:
|
||||
|
||||
* ভেরিয়েবল `prices` হল একটি `dict`:
|
||||
* এই `dict`-এর কীগুলি হল `str` টাইপের (ধরা যাক, প্রতিটি আইটেমের নাম)।
|
||||
* এই `dict`-এর মানগুলি হল `float` টাইপের (ধরা যাক, প্রতিটি আইটেমের দাম)।
|
||||
|
||||
#### ইউনিয়ন
|
||||
|
||||
আপনি একটি ভেরিয়েবলকে এমনভাবে ঘোষণা করতে পারেন যেন তা **একাধিক টাইপের** হয়, উদাহরণস্বরূপ, একটি `int` অথবা `str`।
|
||||
|
||||
Python 3.6 এবং তার উপরের সংস্করণগুলিতে (Python 3.10 অন্তর্ভুক্ত) আপনি `typing` থেকে `Union` টাইপ ব্যবহার করতে পারেন এবং স্কোয়ার ব্র্যাকেটের মধ্যে গ্রহণযোগ্য টাইপগুলি রাখতে পারেন।
|
||||
|
||||
Python 3.10-এ একটি **নতুন সিনট্যাক্স** আছে যেখানে আপনি সম্ভাব্য টাইপগুলিকে একটি <abbr title="উল্লম্ব বারালকে 'বিটওয়াইজ বা অপারেটর' বলা হয়, কিন্তু সেই অর্থ এখানে প্রাসঙ্গিক নয়">ভার্টিকাল বার (`|`)</abbr> দ্বারা পৃথক করতে পারেন।
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial008b.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
উভয় ক্ষেত্রেই এর মানে হল যে `item` হতে পারে একটি `int` অথবা `str`।
|
||||
|
||||
#### সম্ভবত `None`
|
||||
|
||||
আপনি এমনভাবে ঘোষণা করতে পারেন যে একটি মান হতে পারে এক টাইপের, যেমন `str`, আবার এটি `None`-ও হতে পারে।
|
||||
|
||||
Python 3.6 এবং তার উপরের সংস্করণগুলিতে (Python 3.10 অনতর্ভুক্ত) আপনি `typing` মডিউল থেকে `Optional` ইমপোর্ট করে এটি ঘোষণা এবং ব্যবহার করতে পারেন।
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../docs_src/python_types/tutorial009.py!}
|
||||
```
|
||||
|
||||
`Optional[str]` ব্যবহার করা মানে হল শুধু `str` নয়, এটি হতে পারে `None`-ও, যা আপনার এডিটরকে সেই ত্রুটিগুলি শনাক্ত করতে সাহায্য করবে যেখানে আপনি ধরে নিচ্ছেন যে একটি মান সবসময় `str` হবে, অথচ এটি `None`-ও হতে পারেও।
|
||||
|
||||
`Optional[Something]` মূলত `Union[Something, None]`-এর একটি শর্টকাট, এবং তারা সমতুল্য।
|
||||
|
||||
এর মানে হল, Python 3.10-এ, আপনি টাইপগুলির ইউনিয়ন ঘোষণা করতে `Something | None` ব্যবহার করতে পারেন:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial009_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial009.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ বিকল্প
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial009b.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
#### `Union` বা `Optional` ব্যবহার
|
||||
|
||||
যদি আপনি Python 3.10-এর নীচের সংস্করণ ব্যবহার করেন, তবে এখানে আমার খুবই **ব্যক্তিগত** দৃষ্টিভঙ্গি থেকে একটি টিপস:
|
||||
|
||||
* 🚨 `Optional[SomeType]` ব্যবহার এড়িয়ে চলুন।
|
||||
* এর পরিবর্তে ✨ **`Union[SomeType, None]` ব্যবহার করুন** ✨।
|
||||
|
||||
উভয়ই সমতুল্য এবং মূলে একই, কিন্তু আমি `Union`-এর পক্ষে সুপারিশ করব কারণ "**অপশনাল**" শব্দটি মনে হতে পারে যে মানটি ঐচ্ছিক,অথচ এটি আসলে মানে "এটি হতে পারে `None`", এমনকি যদি এটি ঐচ্ছিক না হয়েও আবশ্যিক হয়।
|
||||
|
||||
আমি মনে করি `Union[SomeType, None]` এর অর্থ আরও স্পষ্টভাবে প্রকাশ করে।
|
||||
|
||||
এটি কেবল শব্দ এবং নামের ব্যাপার। কিন্তু সেই শব্দগুলি আপনি এবং আপনার সহকর্মীরা কোড সম্পর্কে কীভাবে চিন্তা করেন তা প্রভাবিত করতে পারে।
|
||||
|
||||
একটি উদাহরণ হিসেবে, এই ফাংশনটি নিন:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
|
||||
|
||||
|
||||
`name` প্যারামিটারটি `Optional[str]` হিসেবে সংজ্ঞায়িত হয়েছে, কিন্তু এটি **অপশনাল নয়**, আপনি প্যারামিটার ছাড়া ফাংশনটি কল করতে পারবেন না:
|
||||
|
||||
```Python
|
||||
say_hi() # ওহ না, এটি একটি ত্রুটি নিক্ষেপ করবে! 😱
|
||||
```
|
||||
|
||||
`name` প্যারামিটারটি **এখনও আবশ্যিক** (নন-অপশনাল) কারণ এটির কোনো ডিফল্ট মান নেই। তবুও, `name` এর মান হিসেবে `None` গ্রহণযোগ্য:
|
||||
|
||||
```Python
|
||||
say_hi(name=None) # এটি কাজ করে, None বৈধ 🎉
|
||||
```
|
||||
|
||||
সুখবর হল, একবার আপনি Python 3.10 ব্যবহার করা শুরু করলে, আপনাকে এগুলোর ব্যাপারে আর চিন্তা করতে হবে না, যেহুতু আপনি | ব্যবহার করেই ইউনিয়ন ঘোষণা করতে পারবেন:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
|
||||
|
||||
|
||||
এবং তারপর আপনাকে নামগুলি যেমন `Optional` এবং `Union` নিয়ে আর চিন্তা করতে হবে না। 😎
|
||||
|
||||
#### জেনেরিক টাইপস
|
||||
|
||||
স্কোয়ার ব্র্যাকেটে টাইপ প্যারামিটার নেওয়া এই টাইপগুলিকে **জেনেরিক টাইপ** বা **জেনেরিকস** বলা হয়, যেমন:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
আপনি সেই একই বিল্টইন টাইপ জেনেরিক্স হিসেবে ব্যবহার করতে পারবেন(ভিতরে টাইপ সহ স্কয়ারে ব্রাকেট দিয়ে):
|
||||
|
||||
* `list`
|
||||
* `tuple`
|
||||
* `set`
|
||||
* `dict`
|
||||
|
||||
এবং Python 3.8 এর মতোই, `typing` মডিউল থেকে:
|
||||
|
||||
* `Union`
|
||||
* `Optional` (Python 3.8 এর মতোই)
|
||||
* ...এবং অন্যান্য।
|
||||
|
||||
Python 3.10-এ, `Union` এবং `Optional` জেনেরিকস ব্যবহার করার বিকল্প হিসেবে, আপনি টাইপগুলির ইউনিয়ন ঘোষণা করতে <abbr title="উল্লম্ব বারালকে 'বিটওয়াইজ বা অপারেটর' বলা হয়, কিন্তু সেই অর্থ এখানে প্রাসঙ্গিক নয়">ভার্টিকাল বার (`|`)</abbr> ব্যবহার করতে পারেন, যা ওদের থেকে অনেক ভালো এবং সহজ।
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
আপনি সেই একই বিল্টইন টাইপ জেনেরিক্স হিসেবে ব্যবহার করতে পারবেন(ভিতরে টাইপ সহ স্কয়ারে ব্রাকেট দিয়ে):
|
||||
|
||||
* `list`
|
||||
* `tuple`
|
||||
* `set`
|
||||
* `dict`
|
||||
|
||||
এবং Python 3.8 এর মতোই, `typing` মডিউল থেকে:
|
||||
|
||||
* `Union`
|
||||
* `Optional`
|
||||
* ...এবং অন্যান্য।
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
* `List`
|
||||
* `Tuple`
|
||||
* `Set`
|
||||
* `Dict`
|
||||
* `Union`
|
||||
* `Optional`
|
||||
* ...এবং অন্যান্য।
|
||||
|
||||
////
|
||||
|
||||
### ক্লাস হিসেবে টাইপস
|
||||
|
||||
আপনি একটি ভেরিয়েবলের টাইপ হিসেবে একটি ক্লাস ঘোষণা করতে পারেন।
|
||||
|
||||
ধরুন আপনার কাছে `Person` নামে একটি ক্লাস আছে, যার একটি নাম আছে:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
|
||||
|
||||
|
||||
তারপর আপনি একটি ভেরিয়েবলকে `Person` টাইপের হিসেবে ঘোষণা করতে পারেন:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial010.py hl[6] *}
|
||||
|
||||
|
||||
এবং তারপর, আবার, আপনি এডিটর সাপোর্ট পেয়ে যাবেন:
|
||||
|
||||
<img src="/img/python-types/image06.png">
|
||||
|
||||
লক্ষ্য করুন যে এর মানে হল "`one_person` হল ক্লাস `Person`-এর একটি **ইন্সট্যান্স**।"
|
||||
|
||||
এর মানে এটি নয় যে "`one_person` হল **ক্লাস** যাকে বলা হয় `Person`।"
|
||||
|
||||
## Pydantic মডেল
|
||||
|
||||
[Pydantic](https://docs.pydantic.dev/) হল একটি Python লাইব্রেরি যা ডাটা ভ্যালিডেশন সম্পাদন করে।
|
||||
|
||||
আপনি ডাটার "আকার" এট্রিবিউট সহ ক্লাস হিসেবে ঘোষণা করেন।
|
||||
|
||||
এবং প্রতিটি এট্রিবিউট এর একটি টাইপ থাকে।
|
||||
|
||||
তারপর আপনি যদি কিছু মান দিয়ে সেই ক্লাসের একটি ইন্সট্যান্স তৈরি করেন-- এটি মানগুলিকে ভ্যালিডেট করবে, প্রয়োজন অনুযায়ী তাদেরকে উপযুক্ত টাইপে রূপান্তর করবে এবং আপনাকে সমস্ত ডাটা সহ একটি অবজেক্ট প্রদান করবে।
|
||||
|
||||
এবং আপনি সেই ফলাফল অবজেক্টের সাথে এডিটর সাপোর্ট পাবেন।
|
||||
|
||||
অফিসিয়াল Pydantic ডক্স থেকে একটি উদাহরণ:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/python_types/tutorial011_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/python_types/tutorial011_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/python_types/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
/// info
|
||||
|
||||
[Pydantic সম্পর্কে আরও জানতে, এর ডকুমেন্টেশন দেখুন](https://docs.pydantic.dev/)।
|
||||
|
||||
///
|
||||
|
||||
**FastAPI** মূলত Pydantic-এর উপর নির্মিত।
|
||||
|
||||
আপনি এই সমস্ত কিছুর অনেক বাস্তবসম্মত উদাহরণ পাবেন [টিউটোরিয়াল - ইউজার গাইডে](https://fastapi.tiangolo.com/tutorial/)।
|
||||
|
||||
/// tip
|
||||
|
||||
যখন আপনি `Optional` বা `Union[Something, None]` ব্যবহার করেন এবং কোনো ডিফল্ট মান না থাকে, Pydantic-এর একটি বিশেষ আচরণ রয়েছে, আপনি Pydantic ডকুমেন্টেশনে [Required Optional fields](https://docs.pydantic.dev/latest/concepts/models/#required-optional-fields) সম্পর্কে আরও পড়তে পারেন।
|
||||
|
||||
///
|
||||
|
||||
## মেটাডাটা অ্যানোটেশন সহ টাইপ হিন্টস
|
||||
|
||||
Python-এ এমন একটি ফিচার আছে যা `Annotated` ব্যবহার করে এই টাইপ হিন্টগুলিতে **অতিরিক্ত মেটাডাটা** রাখতে দেয়।
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
Python 3.9-এ, `Annotated` স্ট্যান্ডার্ড লাইব্রেরিতে অন্তর্ভুক্ত, তাই আপনি এটি `typing` থেকে ইমপোর্ট করতে পারেন।
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial013_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
Python 3.9-এর নীচের সংস্করণগুলিতে, আপনি `Annotated`-কে `typing_extensions` থেকে ইমপোর্ট করেন।
|
||||
|
||||
এটি **FastAPI** এর সাথে ইতিমদ্ধে ইনস্টল হয়ে থাকবে।
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial013.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
Python নিজে এই `Annotated` দিয়ে কিছুই করে না। এবং এডিটর এবং অন্যান্য টুলগুলির জন্য, টাইপটি এখনও `str`।
|
||||
|
||||
কিন্তু আপনি এই `Annotated` এর মধ্যকার জায়গাটির মধ্যে **FastAPI**-এ কীভাবে আপনার অ্যাপ্লিকেশন আচরণ করুক তা সম্পর্কে অতিরিক্ত মেটাডাটা প্রদান করার জন্য ব্যবহার করতে পারেন।
|
||||
|
||||
মনে রাখার গুরুত্বপূর্ণ বিষয় হল যে **প্রথম *টাইপ প্যারামিটার*** আপনি `Annotated`-এ পাস করেন সেটি হল **আসল টাইপ**। বাকি শুধুমাত্র অন্যান্য টুলগুলির জন্য মেটাডাটা।
|
||||
|
||||
এখন আপনার কেবল জানা প্রয়োজন যে `Annotated` বিদ্যমান, এবং এটি স্ট্যান্ডার্ড Python। 😎
|
||||
|
||||
পরবর্তীতে আপনি দেখবেন এটি কতটা **শক্তিশালী** হতে পারে।
|
||||
|
||||
/// tip
|
||||
|
||||
এটি **স্ট্যান্ডার্ড Python** হওয়ার মানে হল আপনি আপনার এডিটরে, আপনি যে টুলগুলি কোড বিশ্লেষণ এবং রিফ্যাক্টর করার জন্য ব্যবহার করেন তাতে **সেরা সম্ভাব্য ডেভেলপার এক্সপেরিয়েন্স** পাবেন। ✨
|
||||
|
||||
এবং এছাড়াও আপনার কোড অন্যান্য অনেক Python টুল এবং লাইব্রেরিগুলির সাথে খুব সামঞ্জস্যপূর্ণ হবে। 🚀
|
||||
|
||||
///
|
||||
|
||||
## **FastAPI**-এ টাইপ হিন্টস
|
||||
|
||||
**FastAPI** এই টাইপ হিন্টগুলি ব্যবহার করে বেশ কিছু জিনিস করে।
|
||||
|
||||
**FastAPI**-এ আপনি টাইপ হিন্টগুলি সহ প্যারামিটার ঘোষণা করেন এবং আপনি পান:
|
||||
|
||||
* **এডিটর সাপোর্ট**।
|
||||
* **টাইপচেক**।
|
||||
|
||||
...এবং **FastAPI** একই ঘোষণাগুলি ব্যবহার করে:
|
||||
|
||||
* **রিকুইরেমেন্টস সংজ্ঞায়িত করে**: রিকোয়েস্ট পাথ প্যারামিটার, কুয়েরি প্যারামিটার, হেডার, বডি, ডিপেন্ডেন্সিস, ইত্যাদি থেকে।
|
||||
* **ডেটা রূপান্তর করে**: রিকোয়েস্ট থেকে প্রয়োজনীয় টাইপে ডেটা।
|
||||
* **ডেটা যাচাই করে**: প্রতিটি রিকোয়েস্ট থেকে আসা ডেটা:
|
||||
* যখন ডেটা অবৈধ হয় তখন **স্বয়ংক্রিয় ত্রুটি** গ্রাহকের কাছে ফেরত পাঠানো।
|
||||
* **API ডকুমেন্টেশন তৈরি করে**: OpenAPI ব্যবহার করে:
|
||||
* যা স্বয়ংক্রিয় ইন্টার্যাক্টিভ ডকুমেন্টেশন ইউজার ইন্টারফেস দ্বারা ব্যবহৃত হয়।
|
||||
|
||||
এই সব কিছু আপনার কাছে অস্পষ্ট মনে হতে পারে। চিন্তা করবেন না। আপনি [টিউটোরিয়াল - ইউজার গাইড](https://fastapi.tiangolo.com/tutorial/) এ এই সব কিছু প্র্যাকটিসে দেখতে পাবেন।
|
||||
|
||||
গুরুত্বপূর্ণ বিষয় হল, আপনি যদি স্ট্যান্ডার্ড Python টাইপগুলি ব্যবহার করেন, তবে আরও বেশি ক্লাস, ডেকোরেটর ইত্যাদি যোগ না করেই একই স্থানে **FastAPI** আপনার অনেক কাজ করে দিবে।
|
||||
|
||||
/// info
|
||||
|
||||
যদি আপনি টিউটোরিয়ালের সমস্ত বিষয় পড়ে ফেলে থাকেন এবং টাইপ সম্পর্কে আরও জানতে চান, তবে একটি ভালো রিসোর্স হল [mypy এর "cheat sheet"](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html)। এই "cheat sheet" এ আপনি Python টাইপ হিন্ট সম্পর্কে বেসিক থেকে উন্নত লেভেলের ধারণা পেতে পারেন, যা আপনার কোডে টাইপ সেফটি এবং স্পষ্টতা বাড়াতে সাহায্য করবে।
|
||||
|
||||
///
|
||||
@@ -1 +0,0 @@
|
||||
INHERIT: ../en/mkdocs.yml
|
||||
@@ -1,12 +1,12 @@
|
||||
# LLM-Testdatei { #llm-test-file }
|
||||
|
||||
Dieses Dokument testet, ob das <abbr title="Large Language Model – Großes Sprachmodell">LLM</abbr>, das die Dokumentation übersetzt, den <abbr title="General Prompt – Allgemeiner Prompt">`general_prompt`</abbr> in `scripts/translate.py` und den sprachspezifischen Prompt in `docs/{language code}/llm-prompt.md` versteht. Der sprachspezifische Prompt wird an `general_prompt` angehängt.
|
||||
Dieses Dokument testet, ob das <abbr title="Large Language Model – Großes Sprachmodell">LLM</abbr>, das die Dokumentation übersetzt, den <abbr title="General Prompt – Allgemeiner Prompt">`general_prompt`</abbr> in `scripts/translate.py` und den sprachspezifischen Prompt in `docs/{language code}/llm-prompt.md` versteht. Der sprachsspezifische Prompt wird an `general_prompt` angehängt.
|
||||
|
||||
Hier hinzugefügte Tests werden von allen Erstellern sprachspezifischer Prompts gesehen.
|
||||
|
||||
So verwenden:
|
||||
|
||||
* Einen sprachspezifischen Prompt haben – `docs/{language code}/llm-prompt.md`.
|
||||
* Einen sprachsspezifischen Prompt haben – `docs/{language code}/llm-prompt.md`.
|
||||
* Eine frische Übersetzung dieses Dokuments in die gewünschte Zielsprache durchführen (siehe z. B. das Kommando `translate-page` der `translate.py`). Dadurch wird die Übersetzung unter `docs/{language code}/docs/_llm-test.md` erstellt.
|
||||
* Prüfen Sie, ob in der Übersetzung alles in Ordnung ist.
|
||||
* Verbessern Sie bei Bedarf Ihren sprachsspezifischen Prompt, den allgemeinen Prompt oder das englische Dokument.
|
||||
@@ -15,7 +15,7 @@ So verwenden:
|
||||
|
||||
Die Tests:
|
||||
|
||||
## Codeschnipsel { #code-snippets}
|
||||
## Codeschnipsel { #code-snippets }
|
||||
|
||||
//// tab | Test
|
||||
|
||||
@@ -35,7 +35,7 @@ Siehe Abschnitt `### Content of code snippets` im allgemeinen Prompt in `scripts
|
||||
|
||||
//// tab | Test
|
||||
|
||||
Gestern schrieb mein Freund: „Wenn man unkorrekt korrekt schreibt, hat man es unkorrekt geschrieben“. Worauf ich antwortete: „Korrekt, aber ‚unkorrekt‘ ist unkorrekterweise nicht ‚„unkorrekt“‘“.
|
||||
Gestern schrieb mein Freund: „Wenn man ‚incorrectly‘ korrekt schreibt, hat man es falsch geschrieben“. Worauf ich antwortete: „Korrekt, aber ‚incorrectly‘ ist inkorrekterweise nicht ‚„incorrectly“‘“.
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
@@ -47,13 +47,13 @@ Das LLM wird dies wahrscheinlich falsch übersetzen. Interessant ist nur, ob es
|
||||
|
||||
//// tab | Info
|
||||
|
||||
Der Prompt-Designer kann entscheiden, ob neutrale Anführungszeichen in typografische Anführungszeichen umgewandelt werden sollen. Es ist in Ordnung, sie unverändert zu lassen.
|
||||
Der Promptdesigner kann entscheiden, ob neutrale Anführungszeichen in typografische Anführungszeichen umgewandelt werden sollen. Es ist in Ordnung, sie unverändert zu lassen.
|
||||
|
||||
Siehe zum Beispiel den Abschnitt `### Quotes` in `docs/de/llm-prompt.md`.
|
||||
|
||||
////
|
||||
|
||||
## Anführungszeichen in Codeschnipseln { #quotes-in-code-snippets}
|
||||
## Anführungszeichen in Codeschnipseln { #quotes-in-code-snippets }
|
||||
|
||||
//// tab | Test
|
||||
|
||||
@@ -189,7 +189,7 @@ Siehe Abschnitt `### Links` im allgemeinen Prompt in `scripts/translate.py`.
|
||||
|
||||
////
|
||||
|
||||
## HTML „abbr“-Elemente { #html-abbr-elements }
|
||||
## HTML-„abbr“-Elemente { #html-abbr-elements }
|
||||
|
||||
//// tab | Test
|
||||
|
||||
@@ -202,11 +202,6 @@ Hier einige Dinge, die in HTML-„abbr“-Elemente gepackt sind (einige sind erf
|
||||
* <abbr title="XML Web Token">XWT</abbr>
|
||||
* <abbr title="Paralleles Server-Gateway-Interface">PSGI</abbr>
|
||||
|
||||
### Das abbr gibt eine Erklärung { #the-abbr-gives-an-explanation }
|
||||
|
||||
* <abbr title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</abbr>
|
||||
* <abbr title="Eine Methode des Machine Learning, die künstliche neuronale Netze mit zahlreichen versteckten Schichten zwischen Eingabe- und Ausgabeschicht verwendet und so eine umfassende interne Struktur entwickelt">Deep Learning</abbr>
|
||||
|
||||
### Das abbr gibt eine vollständige Phrase und eine Erklärung { #the-abbr-gives-a-full-phrase-and-an-explanation }
|
||||
|
||||
* <abbr title="Mozilla Developer Network – Mozilla-Entwicklernetzwerk: Dokumentation für Entwickler, geschrieben von den Firefox-Leuten">MDN</abbr>
|
||||
@@ -224,6 +219,11 @@ Siehe Abschnitt `### HTML abbr elements` im allgemeinen Prompt in `scripts/trans
|
||||
|
||||
////
|
||||
|
||||
## HTML „dfn“-Elemente { #html-dfn-elements }
|
||||
|
||||
* <dfn title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und in irgendeiner Weise zusammenarbeiten.">Cluster</dfn>
|
||||
* <dfn title="Eine Methode des Machine Learning, die künstliche neuronale Netze mit zahlreichen versteckten Schichten zwischen Eingabe- und Ausgabeschicht verwendet und so eine umfassende interne Struktur entwickelt">Deep Learning</dfn>
|
||||
|
||||
## Überschriften { #headings }
|
||||
|
||||
//// tab | Test
|
||||
@@ -248,7 +248,7 @@ Die einzige strenge Regel für Überschriften ist, dass das LLM den Hash-Teil in
|
||||
|
||||
Siehe Abschnitt `### Headings` im allgemeinen Prompt in `scripts/translate.py`.
|
||||
|
||||
Für einige sprachspezifische Anweisungen, siehe z. B. den Abschnitt `### Headings` in `docs/de/llm-prompt.md`.
|
||||
Für einige sprachsspezifische Anweisungen, siehe z. B. den Abschnitt `### Headings` in `docs/de/llm-prompt.md`.
|
||||
|
||||
////
|
||||
|
||||
@@ -443,7 +443,7 @@ Für einige sprachspezifische Anweisungen, siehe z. B. den Abschnitt `### Headin
|
||||
* die Workload
|
||||
|
||||
* das Deployment
|
||||
* bereitstellen
|
||||
* deployen
|
||||
|
||||
* das SDK
|
||||
* das Software Development Kit
|
||||
@@ -459,7 +459,7 @@ Für einige sprachspezifische Anweisungen, siehe z. B. den Abschnitt `### Headin
|
||||
* der Commit
|
||||
* der Contextmanager
|
||||
* die Coroutine
|
||||
* die Datenbank-Session
|
||||
* die Datenbanksession
|
||||
* die Festplatte
|
||||
* die Domain
|
||||
* die Engine
|
||||
@@ -496,7 +496,7 @@ Für einige sprachspezifische Anweisungen, siehe z. B. den Abschnitt `### Headin
|
||||
|
||||
//// tab | Info
|
||||
|
||||
Dies ist eine nicht vollständige und nicht normative Liste von (meist) technischen Begriffen, die in der Dokumentation vorkommen. Sie kann dem Prompt-Designer helfen herauszufinden, bei welchen Begriffen das LLM Unterstützung braucht. Zum Beispiel, wenn es eine gute Übersetzung immer wieder auf eine suboptimale Übersetzung zurücksetzt. Oder wenn es Probleme hat, einen Begriff in Ihrer Sprache zu konjugieren/deklinieren.
|
||||
Dies ist eine nicht vollständige und nicht normative Liste von (meist) technischen Begriffen, die in der Dokumentation vorkommen. Sie kann dem Promptdesigner helfen herauszufinden, bei welchen Begriffen das LLM Unterstützung braucht. Zum Beispiel, wenn es eine gute Übersetzung immer wieder auf eine suboptimale Übersetzung zurücksetzt. Oder wenn es Probleme hat, einen Begriff in Ihrer Sprache zu konjugieren/deklinieren.
|
||||
|
||||
Siehe z. B. den Abschnitt `### List of English terms and their preferred German translations` in `docs/de/llm-prompt.md`.
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ Jedes dieser Response-`dict`s kann einen Schlüssel `model` haben, welcher ein P
|
||||
|
||||
Um beispielsweise eine weitere Response mit dem Statuscode `404` und einem Pydantic-Modell `Message` zu deklarieren, können Sie schreiben:
|
||||
|
||||
{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
|
||||
{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
@@ -175,7 +175,7 @@ Sie können denselben `responses`-Parameter verwenden, um verschiedene Medientyp
|
||||
|
||||
Sie können beispielsweise einen zusätzlichen Medientyp `image/png` hinzufügen und damit deklarieren, dass Ihre *Pfadoperation* ein JSON-Objekt (mit dem Medientyp `application/json`) oder ein PNG-Bild zurückgeben kann:
|
||||
|
||||
{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *}
|
||||
{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
@@ -203,7 +203,7 @@ Sie können beispielsweise eine Response mit dem Statuscode `404` deklarieren, d
|
||||
|
||||
Und eine Response mit dem Statuscode `200`, die Ihr `response_model` verwendet, aber ein benutzerdefiniertes Beispiel (`example`) enthält:
|
||||
|
||||
{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
|
||||
{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}
|
||||
|
||||
Es wird alles kombiniert und in Ihre OpenAPI eingebunden und in der API-Dokumentation angezeigt:
|
||||
|
||||
@@ -237,7 +237,7 @@ Mit dieser Technik können Sie einige vordefinierte Responses in Ihren *Pfadoper
|
||||
|
||||
Zum Beispiel:
|
||||
|
||||
{* ../../docs_src/additional_responses/tutorial004.py hl[13:17,26] *}
|
||||
{* ../../docs_src/additional_responses/tutorial004_py310.py hl[11:15,24] *}
|
||||
|
||||
## Weitere Informationen zu OpenAPI-Responses { #more-information-about-openapi-responses }
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Nicht die Klasse selbst (die bereits aufrufbar ist), sondern eine Instanz dieser
|
||||
|
||||
Dazu deklarieren wir eine Methode `__call__`:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py310.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.
|
||||
|
||||
@@ -26,7 +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:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py310.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.
|
||||
|
||||
@@ -34,7 +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:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py310.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`.
|
||||
|
||||
@@ -50,7 +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`:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
|
||||
{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -63,3 +63,101 @@ In den Kapiteln zum Thema Sicherheit gibt es Hilfsfunktionen, die auf die gleich
|
||||
Wenn Sie das hier alles verstanden haben, wissen Sie bereits, wie diese Sicherheits-Hilfswerkzeuge unter der Haube funktionieren.
|
||||
|
||||
///
|
||||
|
||||
## Abhängigkeiten mit `yield`, `HTTPException`, `except` und Hintergrundtasks { #dependencies-with-yield-httpexception-except-and-background-tasks }
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
Sie benötigen diese technischen Details höchstwahrscheinlich nicht.
|
||||
|
||||
Diese Details sind hauptsächlich nützlich, wenn Sie eine FastAPI-Anwendung haben, die älter als 0.121.0 ist, und Sie auf Probleme mit Abhängigkeiten mit `yield` stoßen.
|
||||
|
||||
///
|
||||
|
||||
Abhängigkeiten mit `yield` haben sich im Laufe der Zeit weiterentwickelt, um verschiedene Anwendungsfälle abzudecken und einige Probleme zu beheben, hier ist eine Zusammenfassung der Änderungen.
|
||||
|
||||
### Abhängigkeiten mit `yield` und `scope` { #dependencies-with-yield-and-scope }
|
||||
|
||||
In Version 0.121.0 hat FastAPI Unterstützung für `Depends(scope="function")` für Abhängigkeiten mit `yield` hinzugefügt.
|
||||
|
||||
Mit `Depends(scope="function")` wird der Exit-Code nach `yield` direkt nach dem Ende der *Pfadoperation-Funktion* ausgeführt, bevor die Response an den Client gesendet wird.
|
||||
|
||||
Und bei Verwendung von `Depends(scope="request")` (dem Default) wird der Exit-Code nach `yield` ausgeführt, nachdem die Response gesendet wurde.
|
||||
|
||||
Mehr dazu finden Sie in der Dokumentation zu [Abhängigkeiten mit `yield` – Frühes Beenden und `scope`](../tutorial/dependencies/dependencies-with-yield.md#early-exit-and-scope).
|
||||
|
||||
### Abhängigkeiten mit `yield` und `StreamingResponse`, Technische Details { #dependencies-with-yield-and-streamingresponse-technical-details }
|
||||
|
||||
Vor FastAPI 0.118.0 wurde bei Verwendung einer Abhängigkeit mit `yield` der Exit-Code nach der *Pfadoperation-Funktion* ausgeführt, aber unmittelbar bevor die Response gesendet wurde.
|
||||
|
||||
Die Absicht war, Ressourcen nicht länger als nötig zu halten, während darauf gewartet wird, dass die Response durchs Netzwerk reist.
|
||||
|
||||
Diese Änderung bedeutete auch, dass bei Rückgabe einer `StreamingResponse` der Exit-Code der Abhängigkeit mit `yield` bereits ausgeführt worden wäre.
|
||||
|
||||
Wenn Sie beispielsweise eine Datenbanksession in einer Abhängigkeit mit `yield` hatten, konnte die `StreamingResponse` diese Session während des Streamens von Daten nicht verwenden, weil die Session im Exit-Code nach `yield` bereits geschlossen worden wäre.
|
||||
|
||||
Dieses Verhalten wurde in 0.118.0 zurückgenommen, sodass der Exit-Code nach `yield` ausgeführt wird, nachdem die Response gesendet wurde.
|
||||
|
||||
/// info | Info
|
||||
|
||||
Wie Sie unten sehen werden, ähnelt dies sehr dem Verhalten vor Version 0.106.0, jedoch mit mehreren Verbesserungen und Bugfixes für Sonderfälle.
|
||||
|
||||
///
|
||||
|
||||
#### Anwendungsfälle mit frühem Exit-Code { #use-cases-with-early-exit-code }
|
||||
|
||||
Es gibt einige Anwendungsfälle mit spezifischen Bedingungen, die vom alten Verhalten profitieren könnten, den Exit-Code von Abhängigkeiten mit `yield` vor dem Senden der Response auszuführen.
|
||||
|
||||
Stellen Sie sich zum Beispiel vor, Sie haben Code, der in einer Abhängigkeit mit `yield` eine Datenbanksession verwendet, nur um einen Benutzer zu verifizieren, die Datenbanksession wird aber in der *Pfadoperation-Funktion* nie wieder verwendet, sondern nur in der Abhängigkeit, und die Response benötigt lange, um gesendet zu werden, wie eine `StreamingResponse`, die Daten langsam sendet, aus irgendeinem Grund aber die Datenbank nicht verwendet.
|
||||
|
||||
In diesem Fall würde die Datenbanksession gehalten, bis das Senden der Response abgeschlossen ist, aber wenn Sie sie nicht verwenden, wäre es nicht notwendig, sie zu halten.
|
||||
|
||||
So könnte es aussehen:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial013_an_py310.py *}
|
||||
|
||||
Der Exit-Code, das automatische Schließen der `Session` in:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[19:21] *}
|
||||
|
||||
... würde ausgeführt, nachdem die Response das langsame Senden der Daten beendet:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial013_an_py310.py ln[30:38] hl[31:33] *}
|
||||
|
||||
Da `generate_stream()` die Datenbanksession jedoch nicht verwendet, ist es nicht wirklich notwendig, die Session während des Sendens der Response offen zu halten.
|
||||
|
||||
Wenn Sie diesen spezifischen Anwendungsfall mit SQLModel (oder SQLAlchemy) haben, könnten Sie die Session explizit schließen, nachdem Sie sie nicht mehr benötigen:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial014_an_py310.py ln[24:28] hl[28] *}
|
||||
|
||||
Auf diese Weise würde die Session die Datenbankverbindung freigeben, sodass andere Requests sie verwenden könnten.
|
||||
|
||||
Wenn Sie einen anderen Anwendungsfall haben, der ein frühes Beenden aus einer Abhängigkeit mit `yield` benötigt, erstellen Sie bitte eine <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub-Diskussion-Frage</a> mit Ihrem spezifischen Anwendungsfall und warum Sie von einem frühen Schließen für Abhängigkeiten mit `yield` profitieren würden.
|
||||
|
||||
Wenn es überzeugende Anwendungsfälle für ein frühes Schließen bei Abhängigkeiten mit `yield` gibt, würde ich erwägen, eine neue Möglichkeit hinzuzufügen, um ein frühes Schließen optional zu aktivieren.
|
||||
|
||||
### Abhängigkeiten mit `yield` und `except`, Technische Details { #dependencies-with-yield-and-except-technical-details }
|
||||
|
||||
Vor FastAPI 0.110.0 war es so, dass wenn Sie eine Abhängigkeit mit `yield` verwendet und dann in dieser Abhängigkeit mit `except` eine Exception abgefangen haben und die Exception nicht erneut geworfen haben, die Exception automatisch an beliebige Exceptionhandler oder den Handler für interne Serverfehler weitergereicht/weitergeworfen wurde.
|
||||
|
||||
Dies wurde in Version 0.110.0 geändert, um unbehandelten Speicherverbrauch durch weitergeleitete Exceptions ohne Handler (interne Serverfehler) zu beheben und um es mit dem Verhalten von normalem Python-Code konsistent zu machen.
|
||||
|
||||
### Hintergrundtasks und Abhängigkeiten mit `yield`, Technische Details { #background-tasks-and-dependencies-with-yield-technical-details }
|
||||
|
||||
Vor FastAPI 0.106.0 war das Werfen von Exceptions nach `yield` nicht möglich, der Exit-Code in Abhängigkeiten mit `yield` wurde ausgeführt, nachdem die Response gesendet wurde, sodass [Exceptionhandler](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} bereits ausgeführt worden wären.
|
||||
|
||||
Dies war so designt, hauptsächlich um die Verwendung derselben von Abhängigkeiten „geyieldeten“ Objekte in Hintergrundtasks zu ermöglichen, da der Exit-Code erst ausgeführt wurde, nachdem die Hintergrundtasks abgeschlossen waren.
|
||||
|
||||
Dies wurde in FastAPI 0.106.0 geändert mit der Absicht, keine Ressourcen zu halten, während darauf gewartet wird, dass die Response durchs Netzwerk reist.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Zusätzlich ist ein Hintergrundtask normalerweise ein unabhängiger Logikblock, der separat gehandhabt werden sollte, mit eigenen Ressourcen (z. B. eigener Datenbankverbindung).
|
||||
|
||||
So haben Sie wahrscheinlich saubereren Code.
|
||||
|
||||
///
|
||||
|
||||
Wenn Sie sich bisher auf dieses Verhalten verlassen haben, sollten Sie jetzt die Ressourcen für Hintergrundtasks innerhalb des Hintergrundtasks selbst erstellen und intern nur Daten verwenden, die nicht von den Ressourcen von Abhängigkeiten mit `yield` abhängen.
|
||||
|
||||
Anstatt beispielsweise dieselbe Datenbanksession zu verwenden, würden Sie innerhalb des Hintergrundtasks eine neue Datenbanksession erstellen und die Objekte aus der Datenbank mithilfe dieser neuen Session beziehen. Und anstatt das Objekt aus der Datenbank als Parameter an die Hintergrundtask-Funktion zu übergeben, würden Sie die ID dieses Objekts übergeben und das Objekt dann innerhalb der Hintergrundtask-Funktion erneut beziehen.
|
||||
|
||||
61
docs/de/docs/advanced/advanced-python-types.md
Normal file
61
docs/de/docs/advanced/advanced-python-types.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Fortgeschrittene Python-Typen { #advanced-python-types }
|
||||
|
||||
Hier sind einige zusätzliche Ideen, die beim Arbeiten mit Python-Typen nützlich sein könnten.
|
||||
|
||||
## `Union` oder `Optional` verwenden { #using-union-or-optional }
|
||||
|
||||
Wenn Ihr Code aus irgendeinem Grund nicht `|` verwenden kann, z. B. wenn es nicht in einer Typannotation ist, sondern in etwas wie `response_model=`, können Sie anstelle des senkrechten Strichs (`|`) `Union` aus `typing` verwenden.
|
||||
|
||||
Zum Beispiel könnten Sie deklarieren, dass etwas ein `str` oder `None` sein könnte:
|
||||
|
||||
```python
|
||||
from typing import Union
|
||||
|
||||
|
||||
def say_hi(name: Union[str, None]):
|
||||
print(f"Hi {name}!")
|
||||
```
|
||||
|
||||
`typing` hat außerdem eine Abkürzung, um zu deklarieren, dass etwas `None` sein könnte, mit `Optional`.
|
||||
|
||||
Hier ist ein Tipp aus meiner sehr **subjektiven** Perspektive:
|
||||
|
||||
* 🚨 Vermeiden Sie die Verwendung von `Optional[SomeType]`
|
||||
* Verwenden Sie stattdessen ✨ **`Union[SomeType, None]`** ✨.
|
||||
|
||||
Beides ist äquivalent und unter der Haube identisch, aber ich würde `Union` statt `Optional` empfehlen, weil das Wort „**optional**“ implizieren könnte, dass der Wert optional ist; tatsächlich bedeutet es jedoch „es kann `None` sein“, selbst wenn es nicht optional ist und weiterhin erforderlich bleibt.
|
||||
|
||||
Ich finde, `Union[SomeType, None]` ist expliziter in dem, was es bedeutet.
|
||||
|
||||
Es geht nur um Wörter und Namen. Aber diese Wörter können beeinflussen, wie Sie und Ihr Team über den Code denken.
|
||||
|
||||
Als Beispiel nehmen wir diese Funktion:
|
||||
|
||||
```python
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def say_hi(name: Optional[str]):
|
||||
print(f"Hey {name}!")
|
||||
```
|
||||
|
||||
Der Parameter `name` ist als `Optional[str]` definiert, aber er ist **nicht optional**, Sie können die Funktion nicht ohne den Parameter aufrufen:
|
||||
|
||||
```Python
|
||||
say_hi() # Oh nein, das löst einen Fehler aus! 😱
|
||||
```
|
||||
|
||||
Der Parameter `name` ist **weiterhin erforderlich** (nicht *optional*), weil er keinen Defaultwert hat. Dennoch akzeptiert `name` den Wert `None`:
|
||||
|
||||
```Python
|
||||
say_hi(name=None) # Das funktioniert, None ist gültig 🎉
|
||||
```
|
||||
|
||||
Die gute Nachricht ist: In den meisten Fällen können Sie einfach `|` verwenden, um Unions von Typen zu definieren:
|
||||
|
||||
```python
|
||||
def say_hi(name: str | None):
|
||||
print(f"Hey {name}!")
|
||||
```
|
||||
|
||||
Sie müssen sich also normalerweise keine Gedanken über Namen wie `Optional` und `Union` machen. 😎
|
||||
@@ -32,11 +32,11 @@ Betrachten wir als einfaches Beispiel eine Dateistruktur ähnlich der in [Größ
|
||||
|
||||
Die Datei `main.py` hätte als Inhalt:
|
||||
|
||||
{* ../../docs_src/async_tests/main.py *}
|
||||
{* ../../docs_src/async_tests/app_a_py310/main.py *}
|
||||
|
||||
Die Datei `test_main.py` hätte die Tests für `main.py`, das könnte jetzt so aussehen:
|
||||
|
||||
{* ../../docs_src/async_tests/test_main.py *}
|
||||
{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
|
||||
|
||||
## Es ausführen { #run-it }
|
||||
|
||||
@@ -56,7 +56,7 @@ $ pytest
|
||||
|
||||
Der Marker `@pytest.mark.anyio` teilt pytest mit, dass diese Testfunktion asynchron aufgerufen werden soll:
|
||||
|
||||
{* ../../docs_src/async_tests/test_main.py hl[7] *}
|
||||
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -66,7 +66,7 @@ Beachten Sie, dass die Testfunktion jetzt `async def` ist und nicht nur `def` wi
|
||||
|
||||
Dann können wir einen `AsyncClient` mit der App erstellen und mit `await` asynchrone Requests an ihn senden.
|
||||
|
||||
{* ../../docs_src/async_tests/test_main.py hl[9:12] *}
|
||||
{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}
|
||||
|
||||
Das ist das Äquivalent zu:
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
|
||||
|
||||
Angenommen, Sie definieren eine *Pfadoperation* `/items/`:
|
||||
|
||||
{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *}
|
||||
{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}
|
||||
|
||||
Wenn der Client versucht, zu `/items` zu gehen, würde er standardmäßig zu `/items/` umgeleitet.
|
||||
|
||||
@@ -64,7 +64,7 @@ Wenn Sie mehr über HTTPS erfahren möchten, lesen Sie den Leitfaden [Über HTTP
|
||||
|
||||
///
|
||||
|
||||
### Wie Proxy-Forwarded-Header funktionieren
|
||||
### Wie Proxy-Forwarded-Header funktionieren { #how-proxy-forwarded-headers-work }
|
||||
|
||||
Hier ist eine visuelle Darstellung, wie der **Proxy** weitergeleitete Header zwischen dem Client und dem **Anwendungsserver** hinzufügt:
|
||||
|
||||
@@ -115,7 +115,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.
|
||||
|
||||
{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *}
|
||||
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
|
||||
|
||||
Und der Proxy würde das **Pfadpräfix** on-the-fly **„entfernen“**, bevor er den <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> an den Anwendungsserver (wahrscheinlich Uvicorn via FastAPI CLI) ü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.
|
||||
|
||||
@@ -193,7 +193,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.
|
||||
|
||||
{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *}
|
||||
{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
|
||||
|
||||
Wenn Sie Uvicorn dann starten mit:
|
||||
|
||||
@@ -220,7 +220,7 @@ wäre die <abbr title="Response – Antwort: Daten, die der Server zum anfragend
|
||||
|
||||
Falls Sie keine Möglichkeit haben, eine Kommandozeilenoption wie `--root-path` oder ähnlich zu übergeben, können Sie, alternativ dazu, beim Erstellen Ihrer FastAPI-Anwendung den Parameter `root_path` setzen:
|
||||
|
||||
{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *}
|
||||
{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
|
||||
|
||||
Die Übergabe des `root_path` an `FastAPI` wäre das Äquivalent zur Übergabe der `--root-path`-Kommandozeilenoption an Uvicorn oder Hypercorn.
|
||||
|
||||
@@ -228,7 +228,7 @@ Die Übergabe des `root_path` an `FastAPI` wäre das Äquivalent zur Übergabe d
|
||||
|
||||
Beachten Sie, dass der Server (Uvicorn) diesen `root_path` für nichts anderes verwendet als für die Weitergabe an die Anwendung.
|
||||
|
||||
Aber wenn Sie mit Ihrem Browser auf <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> gehen, sehen Sie die normale Response:
|
||||
Aber wenn Sie mit Ihrem Browser auf <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> gehen, sehen Sie die normale Response:
|
||||
|
||||
```JSON
|
||||
{
|
||||
@@ -400,7 +400,7 @@ Wenn Sie eine benutzerdefinierte Liste von Servern (`servers`) übergeben und es
|
||||
|
||||
Zum Beispiel:
|
||||
|
||||
{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *}
|
||||
{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
|
||||
|
||||
Erzeugt ein OpenAPI-Schema, wie:
|
||||
|
||||
@@ -443,11 +443,19 @@ Die Dokumentationsoberfläche interagiert mit dem von Ihnen ausgewählten Server
|
||||
|
||||
///
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
Die Eigenschaft `servers` in der OpenAPI-Spezifikation ist optional.
|
||||
|
||||
Wenn Sie den Parameter `servers` nicht angeben und `root_path` den Wert `/` hat, wird die Eigenschaft `servers` im generierten OpenAPI-Schema standardmäßig vollständig weggelassen, was dem Äquivalent eines einzelnen Servers mit einem `url`-Wert von `/` entspricht.
|
||||
|
||||
///
|
||||
|
||||
### Den automatischen Server von `root_path` deaktivieren { #disable-automatic-server-from-root-path }
|
||||
|
||||
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:
|
||||
|
||||
{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *}
|
||||
{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
|
||||
|
||||
Dann wird er nicht in das OpenAPI-Schema aufgenommen.
|
||||
|
||||
|
||||
@@ -30,7 +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.
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
|
||||
{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
|
||||
|
||||
/// info | Info
|
||||
|
||||
@@ -55,7 +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*.
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
|
||||
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
|
||||
|
||||
/// info | Info
|
||||
|
||||
@@ -73,7 +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:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
|
||||
{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
@@ -97,7 +97,7 @@ Die `response_class` wird dann nur zur Dokumentation der OpenAPI-*Pfadoperation*
|
||||
|
||||
Es könnte zum Beispiel so etwas sein:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
|
||||
{* ../../docs_src/custom_response/tutorial004_py310.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.
|
||||
|
||||
@@ -136,7 +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.
|
||||
|
||||
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
|
||||
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
|
||||
|
||||
### `HTMLResponse` { #htmlresponse }
|
||||
|
||||
@@ -146,7 +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.
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
|
||||
{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
|
||||
|
||||
### `JSONResponse` { #jsonresponse }
|
||||
|
||||
@@ -180,7 +180,7 @@ Dazu muss `ujson` installiert werden, z. B. mit `pip install ujson`.
|
||||
|
||||
///
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
|
||||
{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -194,13 +194,13 @@ Gibt eine HTTP-Weiterleitung (HTTP-Redirect) zurück. Verwendet standardmäßig
|
||||
|
||||
Sie können eine `RedirectResponse` direkt zurückgeben:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
|
||||
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
|
||||
|
||||
---
|
||||
|
||||
Oder Sie können sie im Parameter `response_class` verwenden:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
|
||||
{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
|
||||
|
||||
Wenn Sie das tun, können Sie die URL direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
|
||||
|
||||
@@ -210,13 +210,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:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
|
||||
{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
|
||||
|
||||
### `StreamingResponse` { #streamingresponse }
|
||||
|
||||
Nimmt einen asynchronen Generator oder einen normalen Generator/Iterator und streamt den Responsebody.
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
|
||||
{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
|
||||
|
||||
#### Verwendung von `StreamingResponse` mit dateiartigen Objekten { #using-streamingresponse-with-file-like-objects }
|
||||
|
||||
@@ -226,7 +226,7 @@ Auf diese Weise müssen Sie nicht alles zuerst in den Arbeitsspeicher lesen und
|
||||
|
||||
Das umfasst viele Bibliotheken zur Interaktion mit Cloud-Speicher, Videoverarbeitung und anderen.
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *}
|
||||
{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
|
||||
|
||||
1. Das ist die Generatorfunktion. Es handelt sich um eine „Generatorfunktion“, da sie `yield`-Anweisungen enthält.
|
||||
2. Durch die Verwendung eines `with`-Blocks stellen wir sicher, dass das dateiartige Objekt geschlossen wird, nachdem die Generatorfunktion fertig ist. Also, nachdem sie mit dem Senden der Response fertig ist.
|
||||
@@ -255,11 +255,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.
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
|
||||
{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
|
||||
|
||||
Sie können auch den Parameter `response_class` verwenden:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
|
||||
{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
|
||||
|
||||
In diesem Fall können Sie den Dateipfad direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
|
||||
|
||||
@@ -273,7 +273,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:
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *}
|
||||
{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
|
||||
|
||||
Statt:
|
||||
|
||||
@@ -299,7 +299,7 @@ Der Parameter, der das definiert, ist `default_response_class`.
|
||||
|
||||
Im folgenden Beispiel verwendet **FastAPI** standardmäßig `ORJSONResponse` in allen *Pfadoperationen*, anstelle von `JSONResponse`.
|
||||
|
||||
{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
|
||||
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Verwendung von Datenklassen { #using-dataclasses }
|
||||
# Datenklassen verwenden { #using-dataclasses }
|
||||
|
||||
FastAPI basiert auf **Pydantic**, und ich habe Ihnen gezeigt, wie Sie Pydantic-Modelle verwenden können, um <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> und <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Responses</abbr> zu deklarieren.
|
||||
|
||||
Aber FastAPI unterstützt auf die gleiche Weise auch die Verwendung von <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a>:
|
||||
|
||||
{* ../../docs_src/dataclasses/tutorial001.py hl[1,7:12,19:20] *}
|
||||
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
|
||||
|
||||
Das ist dank **Pydantic** ebenfalls möglich, da es <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">`dataclasses` intern unterstützt</a>.
|
||||
|
||||
@@ -32,7 +32,7 @@ Wenn Sie jedoch eine Menge Datenklassen herumliegen haben, ist dies ein guter Tr
|
||||
|
||||
Sie können `dataclasses` auch im Parameter `response_model` verwenden:
|
||||
|
||||
{* ../../docs_src/dataclasses/tutorial002.py hl[1,7:13,19] *}
|
||||
{* ../../docs_src/dataclasses_/tutorial002_py310.py hl[1,6:12,18] *}
|
||||
|
||||
Die Datenklasse wird automatisch in eine Pydantic-Datenklasse konvertiert.
|
||||
|
||||
@@ -48,7 +48,7 @@ In einigen Fällen müssen Sie möglicherweise immer noch Pydantics Version von
|
||||
|
||||
In diesem Fall können Sie einfach die Standard-`dataclasses` durch `pydantic.dataclasses` ersetzen, was einen direkten Ersatz darstellt:
|
||||
|
||||
{* ../../docs_src/dataclasses/tutorial003.py hl[1,5,8:11,14:17,23:25,28] *}
|
||||
{* ../../docs_src/dataclasses_/tutorial003_py310.py hl[1,4,7:10,13:16,22:24,27] *}
|
||||
|
||||
1. Wir importieren `field` weiterhin von Standard-`dataclasses`.
|
||||
|
||||
@@ -64,7 +64,7 @@ In diesem Fall können Sie einfach die Standard-`dataclasses` durch `pydantic.da
|
||||
|
||||
6. Hier geben wir ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> zurück, das `items` enthält, welches eine Liste von Datenklassen ist.
|
||||
|
||||
FastAPI ist weiterhin in der Lage, die Daten nach JSON zu <abbr title="Konvertieren der Daten in ein übertragbares Format">serialisieren</abbr>.
|
||||
FastAPI ist weiterhin in der Lage, die Daten nach JSON zu <dfn title="Konvertieren der Daten in ein übertragbares Format">Serialisieren</dfn>.
|
||||
|
||||
7. Hier verwendet das `response_model` als Typannotation eine Liste von `Author`-Datenklassen.
|
||||
|
||||
|
||||
@@ -30,7 +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:
|
||||
|
||||
{* ../../docs_src/events/tutorial003.py hl[16,19] *}
|
||||
{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
|
||||
|
||||
Hier simulieren wir den langsamen *Startup*, das Laden des Modells, indem wir die (Fake-)Modellfunktion vor dem `yield` in das <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> mit Modellen für maschinelles Lernen einfügen. Dieser Code wird ausgeführt, **bevor** die Anwendung **beginnt, Requests entgegenzunehmen**, während des *Startups*.
|
||||
|
||||
@@ -48,7 +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`.
|
||||
|
||||
{* ../../docs_src/events/tutorial003.py hl[14:19] *}
|
||||
{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
|
||||
|
||||
Der erste Teil der Funktion, vor dem `yield`, wird ausgeführt **bevor** die Anwendung startet.
|
||||
|
||||
@@ -60,7 +60,7 @@ Wie Sie sehen, ist die Funktion mit einem `@asynccontextmanager` versehen.
|
||||
|
||||
Dadurch wird die Funktion in einen sogenannten „**asynchronen Kontextmanager**“ umgewandelt.
|
||||
|
||||
{* ../../docs_src/events/tutorial003.py hl[1,13] *}
|
||||
{* ../../docs_src/events/tutorial003_py310.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:
|
||||
|
||||
@@ -82,7 +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.
|
||||
|
||||
{* ../../docs_src/events/tutorial003.py hl[22] *}
|
||||
{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
|
||||
|
||||
## Alternative Events (<abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr>) { #alternative-events-deprecated }
|
||||
|
||||
@@ -104,7 +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`:
|
||||
|
||||
{* ../../docs_src/events/tutorial001.py hl[8] *}
|
||||
{* ../../docs_src/events/tutorial001_py310.py hl[8] *}
|
||||
|
||||
In diesem Fall initialisiert die Eventhandler-Funktion `startup` die „Datenbank“ der Items (nur ein `dict`) mit einigen Werten.
|
||||
|
||||
@@ -116,7 +116,7 @@ Und Ihre Anwendung empfängt erst dann Requests, wenn alle `startup`-Eventhandle
|
||||
|
||||
Um eine Funktion hinzuzufügen, die beim Shutdown der Anwendung ausgeführt werden soll, deklarieren Sie sie mit dem Event `shutdown`:
|
||||
|
||||
{* ../../docs_src/events/tutorial002.py hl[6] *}
|
||||
{* ../../docs_src/events/tutorial002_py310.py hl[6] *}
|
||||
|
||||
Hier schreibt die `shutdown`-Eventhandler-Funktion eine Textzeile `"Application shutdown"` in eine Datei `log.txt`.
|
||||
|
||||
@@ -154,7 +154,7 @@ In der technischen ASGI-Spezifikation ist dies Teil des <a href="https://asgi.re
|
||||
|
||||
/// info | Info
|
||||
|
||||
Weitere Informationen zu Starlettes `lifespan`-Handlern finden Sie in <a href="https://www.starlette.io/lifespan/" class="external-link" target="_blank">Starlettes Lifespan-Dokumentation</a>.
|
||||
Weitere Informationen zu Starlettes `lifespan`-Handlern finden Sie in <a href="https://www.starlette.dev/lifespan/" class="external-link" target="_blank">Starlettes Lifespan-Dokumentation</a>.
|
||||
|
||||
Einschließlich, wie man Lifespan-Zustand handhabt, der in anderen Bereichen Ihres Codes verwendet werden kann.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Da **FastAPI** auf der **OpenAPI**-Spezifikation basiert, können dessen APIs in einem standardisierten Format beschrieben werden, das viele Tools verstehen.
|
||||
|
||||
Dies vereinfacht es, aktuelle **Dokumentation** und Client-Bibliotheken (<abbr title="Software Development Kit – Software-Entwicklungspaket">**SDKs**</abbr>) in verschiedenen Sprachen zu generieren sowie **Test-** oder **Automatisierungs-Workflows**, die mit Ihrem Code synchron bleiben.
|
||||
Dies vereinfacht es, aktuelle **Dokumentation** und Client-Bibliotheken (<abbr title="Software Development Kits - Software-Entwicklungspakete">**SDKs**</abbr>) in verschiedenen Sprachen zu generieren sowie **Test-** oder **Automatisierungs-Workflows**, die mit Ihrem Code synchron bleiben.
|
||||
|
||||
In diesem Leitfaden erfahren Sie, wie Sie ein **TypeScript-SDK** für Ihr FastAPI-Backend generieren.
|
||||
|
||||
@@ -40,7 +40,7 @@ Einige dieser Lösungen sind möglicherweise auch Open Source oder bieten kosten
|
||||
|
||||
Beginnen wir mit einer einfachen FastAPI-Anwendung:
|
||||
|
||||
{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
|
||||
{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
|
||||
|
||||
Beachten Sie, dass die *Pfadoperationen* die Modelle definieren, die sie für die <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>- und <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-<abbr title="Die eigentlichen Nutzdaten, abzüglich der Metadaten">Payload</abbr> verwenden, indem sie die Modelle `Item` und `ResponseMessage` verwenden.
|
||||
|
||||
@@ -98,7 +98,7 @@ In vielen Fällen wird Ihre FastAPI-App größer sein und Sie werden wahrscheinl
|
||||
|
||||
Zum Beispiel 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:
|
||||
|
||||
{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
|
||||
{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
|
||||
|
||||
### Einen TypeScript-Client mit Tags generieren { #generate-a-typescript-client-with-tags }
|
||||
|
||||
@@ -145,7 +145,7 @@ Hier verwendet sie beispielsweise den ersten Tag (Sie werden wahrscheinlich nur
|
||||
|
||||
Anschließend können Sie diese benutzerdefinierte Funktion als `generate_unique_id_function`-Parameter an **FastAPI** übergeben:
|
||||
|
||||
{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
|
||||
{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
|
||||
|
||||
### Einen TypeScript-Client mit benutzerdefinierten Operation-IDs generieren { #generate-a-typescript-client-with-custom-operation-ids }
|
||||
|
||||
@@ -167,7 +167,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 präfixierten Tag entfernen**:
|
||||
|
||||
{* ../../docs_src/generate_clients/tutorial004.py *}
|
||||
{* ../../docs_src/generate_clients/tutorial004_py310.py *}
|
||||
|
||||
//// tab | Node.js
|
||||
|
||||
@@ -179,7 +179,7 @@ Wir könnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dan
|
||||
|
||||
Damit würden die Operation-IDs von Dingen wie `items-get_items` in `get_items` umbenannt, sodass der Client-Generator einfachere Methodennamen generieren kann.
|
||||
|
||||
### Einen TypeScript-Client mit der modifizierten OpenAPI generieren { #generate-a-typescript-client-with-the-preprocessed-openapi }
|
||||
### Einen TypeScript-Client mit der vorverarbeiteten OpenAPI generieren { #generate-a-typescript-client-with-the-preprocessed-openapi }
|
||||
|
||||
Da das Endergebnis nun in einer `openapi.json`-Datei vorliegt, müssen Sie Ihren Eingabeort aktualisieren:
|
||||
|
||||
|
||||
@@ -57,13 +57,13 @@ Erzwingt, dass alle eingehenden <abbr title="Request – Anfrage: Daten, die der
|
||||
|
||||
Alle eingehenden Requests an `http` oder `ws` werden stattdessen an das sichere Schema umgeleitet.
|
||||
|
||||
{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
|
||||
{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
|
||||
|
||||
## `TrustedHostMiddleware` { #trustedhostmiddleware }
|
||||
|
||||
Erzwingt, dass alle eingehenden Requests einen korrekt gesetzten `Host`-Header haben, um sich vor HTTP-Host-Header-Angriffen zu schützen.
|
||||
|
||||
{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *}
|
||||
{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
|
||||
|
||||
Die folgenden Argumente werden unterstützt:
|
||||
|
||||
@@ -74,11 +74,11 @@ Wenn ein eingehender Request nicht korrekt validiert wird, wird eine `400`-<abbr
|
||||
|
||||
## `GZipMiddleware` { #gzipmiddleware }
|
||||
|
||||
Verarbeitet GZip-Responses für alle Requests, die `"gzip"` im `Accept-Encoding`-Header enthalten.
|
||||
Verarbeitet GZip-Responses für alle Requests, die „gzip“ im `Accept-Encoding`-Header enthalten.
|
||||
|
||||
Diese Middleware verarbeitet sowohl Standard- als auch Streaming-Responses.
|
||||
|
||||
{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *}
|
||||
{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
|
||||
|
||||
Die folgenden Argumente werden unterstützt:
|
||||
|
||||
@@ -94,4 +94,4 @@ Zum Beispiel:
|
||||
* <a href="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py" class="external-link" target="_blank">Uvicorns `ProxyHeadersMiddleware`</a>
|
||||
* <a href="https://github.com/florimondmanca/msgpack-asgi" class="external-link" target="_blank">MessagePack</a>
|
||||
|
||||
Um mehr über weitere verfügbare Middlewares herauszufinden, besuchen Sie <a href="https://www.starlette.io/middleware/" class="external-link" target="_blank">Starlettes Middleware-Dokumentation</a> und die <a href="https://github.com/florimondmanca/awesome-asgi" class="external-link" target="_blank">ASGI Awesome List</a>.
|
||||
Um mehr über weitere verfügbare Middlewares herauszufinden, besuchen Sie <a href="https://www.starlette.dev/middleware/" class="external-link" target="_blank">Starlettes Middleware-Dokumentation</a> und die <a href="https://github.com/florimondmanca/awesome-asgi" class="external-link" target="_blank">ASGI Awesome List</a>.
|
||||
|
||||
@@ -31,7 +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:
|
||||
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[9:13,36:53] *}
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[7:11,34:51] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -90,7 +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.
|
||||
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[3,25] *}
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[1,23] *}
|
||||
|
||||
### Die Callback-*Pfadoperation* erstellen { #create-the-callback-path-operation }
|
||||
|
||||
@@ -101,7 +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`.
|
||||
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[16:18,21:22,28:32] *}
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[14:16,19:20,26:30] *}
|
||||
|
||||
Es gibt zwei Hauptunterschiede zu einer normalen *Pfadoperation*:
|
||||
|
||||
@@ -169,7 +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:
|
||||
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001.py hl[35] *}
|
||||
{* ../../docs_src/openapi_callbacks/tutorial001_py310.py hl[33] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Das wird normalerweise als **Web<abbr title="Haken, Einhängepunkt">hook</abbr>*
|
||||
|
||||
## Webhooks-Schritte { #webhooks-steps }
|
||||
|
||||
Der Prozess besteht normalerweise darin, dass **Sie in Ihrem Code definieren**, welche Nachricht Sie senden möchten, den **Body des Requests**.
|
||||
Der Prozess besteht normalerweise darin, dass **Sie in Ihrem Code definieren**, welche Nachricht Sie senden möchten, den **Requestbody**.
|
||||
|
||||
Sie definieren auch auf irgendeine Weise, in welchen **Momenten** Ihre App diese Requests oder Events senden wird.
|
||||
|
||||
@@ -18,7 +18,7 @@ Die gesamte **Logik** zur Registrierung der URLs für Webhooks und der Code zum
|
||||
|
||||
## Webhooks mit **FastAPI** und OpenAPI dokumentieren { #documenting-webhooks-with-fastapi-and-openapi }
|
||||
|
||||
Mit **FastAPI**, mithilfe von OpenAPI, können Sie die Namen dieser Webhooks, die Arten von HTTP-Operationen, die Ihre App senden kann (z. B. `POST`, `PUT`, usw.) und die Request**bodys** definieren, die Ihre App senden würde.
|
||||
Mit **FastAPI**, mithilfe von OpenAPI, können Sie die Namen dieser Webhooks, die Arten von HTTP-Operationen, die Ihre App senden kann (z. B. `POST`, `PUT`, usw.) und die **Requestbodys** definieren, die Ihre App senden würde.
|
||||
|
||||
Dies kann es Ihren Benutzern viel einfacher machen, **deren APIs zu implementieren**, um Ihre **Webhook**-Requests zu empfangen. Möglicherweise können diese sogar einen Teil ihres eigenen API-Codes automatisch generieren.
|
||||
|
||||
@@ -32,7 +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, das Sie verwenden können, um *Webhooks* zu definieren, genauso wie Sie *Pfadoperationen* definieren würden, zum Beispiel mit `@app.webhooks.post()`.
|
||||
|
||||
{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *}
|
||||
{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:12,15:20] *}
|
||||
|
||||
Die von Ihnen definierten Webhooks landen im **OpenAPI**-Schema und der automatischen **Dokumentations-Oberfläche**.
|
||||
|
||||
|
||||
@@ -12,7 +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.
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
|
||||
|
||||
### Verwendung des Namens der *Pfadoperation-Funktion* als operationId { #using-the-path-operation-function-name-as-the-operationid }
|
||||
|
||||
@@ -20,7 +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.
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -40,7 +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`:
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
|
||||
|
||||
## Fortgeschrittene Beschreibung mittels Docstring { #advanced-description-from-docstring }
|
||||
|
||||
@@ -48,9 +48,9 @@ Sie können die verwendeten Zeilen aus dem Docstring einer *Pfadoperation-Funkti
|
||||
|
||||
Das Hinzufügen eines `\f` (ein maskiertes „Form Feed“-Zeichen) führt dazu, dass **FastAPI** die für OpenAPI verwendete Ausgabe an dieser Stelle abschneidet.
|
||||
|
||||
Sie wird nicht in der Dokumentation angezeigt, aber andere Tools (z. B. Sphinx) können den Rest verwenden.
|
||||
Sie wird nicht in der Dokumentation angezeigt, aber andere Tools (wie z. B. Sphinx) können den Rest verwenden.
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial004.py hl[19:29] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial004_py310.py hl[17:27] *}
|
||||
|
||||
## Zusätzliche Responses { #additional-responses }
|
||||
|
||||
@@ -92,7 +92,7 @@ Sie können das OpenAPI-Schema für eine *Pfadoperation* erweitern, indem Sie de
|
||||
|
||||
Dieses `openapi_extra` kann beispielsweise hilfreich sein, um [OpenAPI-Erweiterungen](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) zu deklarieren:
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
|
||||
|
||||
Wenn Sie die automatische API-Dokumentation öffnen, wird Ihre Erweiterung am Ende der spezifischen *Pfadoperation* angezeigt.
|
||||
|
||||
@@ -135,13 +135,13 @@ Das <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash
|
||||
|
||||
Sie können dem automatisch generierten Schema also zusätzliche Daten hinzufügen.
|
||||
|
||||
Sie könnten sich beispielsweise dafür entscheiden, den <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> mit Ihrem eigenen Code zu lesen und zu validieren, ohne die automatischen Funktionen von FastAPI mit Pydantic zu verwenden, aber Sie könnten den Request trotzdem im OpenAPI-Schema definieren wollen.
|
||||
Sie könnten sich beispielsweise dafür entscheiden, den <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> mit Ihrem eigenen Code zu lesen und zu validieren, ohne FastAPIs automatische Funktionen mit Pydantic zu verwenden, aber Sie könnten den Request trotzdem im OpenAPI-Schema definieren wollen.
|
||||
|
||||
Das könnte man mit `openapi_extra` machen:
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *}
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 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.
|
||||
In diesem Beispiel haben wir kein Pydantic-Modell deklariert. Tatsächlich wird der Requestbody nicht einmal als JSON <dfn title="von einem einfachen Format, wie Bytes, in Python-Objekte konvertiert">geparst</dfn>, sondern direkt als `bytes` gelesen und die Funktion `magic_data_reader()` wäre dafür verantwortlich, ihn in irgendeiner Weise zu parsen.
|
||||
|
||||
Dennoch können wir das zu erwartende Schema für den Requestbody deklarieren.
|
||||
|
||||
@@ -151,49 +151,17 @@ Mit demselben Trick könnten Sie ein Pydantic-Modell verwenden, um das JSON-Sche
|
||||
|
||||
Und Sie könnten dies auch tun, wenn der Datentyp im Request nicht JSON ist.
|
||||
|
||||
In der folgenden Anwendung verwenden wir beispielsweise weder die integrierte Funktionalität von FastAPI zum Extrahieren des JSON-Schemas aus Pydantic-Modellen noch die automatische Validierung für JSON. Tatsächlich deklarieren wir den Request-Content-Type als YAML und nicht als JSON:
|
||||
In der folgenden Anwendung verwenden wir beispielsweise weder FastAPIs integrierte Funktionalität zum Extrahieren des JSON-Schemas aus Pydantic-Modellen noch die automatische Validierung für JSON. Tatsächlich deklarieren wir den Request-Content-Type als YAML und nicht als JSON:
|
||||
|
||||
//// tab | Pydantic v2
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[17:22, 24] *}
|
||||
|
||||
////
|
||||
|
||||
//// tab | Pydantic v1
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *}
|
||||
|
||||
////
|
||||
|
||||
/// info | Info
|
||||
|
||||
In Pydantic Version 1 hieß die Methode zum Abrufen des JSON-Schemas für ein Modell `Item.schema()`, in Pydantic Version 2 heißt die Methode `Item.model_json_schema()`.
|
||||
|
||||
///
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
|
||||
|
||||
Obwohl wir nicht die standardmäßig integrierte Funktionalität verwenden, verwenden wir dennoch ein Pydantic-Modell, um das JSON-Schema für die Daten, die wir in YAML empfangen möchten, manuell zu generieren.
|
||||
|
||||
Dann verwenden wir den Request direkt und extrahieren den Body als `bytes`. Das bedeutet, dass FastAPI nicht einmal versucht, den Request-Payload als JSON zu parsen.
|
||||
Dann verwenden wir den Request direkt und extrahieren den Body als `bytes`. Das bedeutet, dass FastAPI nicht einmal versucht, die Request-Payload als JSON zu parsen.
|
||||
|
||||
Und dann parsen wir in unserem Code diesen YAML-Inhalt direkt und verwenden dann wieder dasselbe Pydantic-Modell, um den YAML-Inhalt zu validieren:
|
||||
|
||||
//// tab | Pydantic v2
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007.py hl[26:33] *}
|
||||
|
||||
////
|
||||
|
||||
//// tab | Pydantic v1
|
||||
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *}
|
||||
|
||||
////
|
||||
|
||||
/// info | Info
|
||||
|
||||
In Pydantic Version 1 war die Methode zum Parsen und Validieren eines Objekts `Item.parse_obj()`, in Pydantic Version 2 heißt die Methode `Item.model_validate()`.
|
||||
|
||||
///
|
||||
{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -20,7 +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* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt festlegen.
|
||||
|
||||
{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *}
|
||||
{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}
|
||||
|
||||
Und dann können Sie jedes benötigte Objekt zurückgeben, wie Sie es normalerweise tun würden (ein `dict`, ein Datenbankmodell usw.).
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
|
||||
|
||||
Und dann können Sie Cookies in diesem *vorübergehenden* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt setzen.
|
||||
|
||||
{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *}
|
||||
{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}
|
||||
|
||||
Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
|
||||
|
||||
@@ -24,7 +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:
|
||||
|
||||
{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *}
|
||||
{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -48,4 +48,4 @@ Und da die `Response` häufig zum Setzen von Headern und Cookies verwendet wird,
|
||||
|
||||
///
|
||||
|
||||
Um alle verfügbaren Parameter und Optionen anzuzeigen, sehen Sie sich deren <a href="https://www.starlette.io/responses/#set-cookie" class="external-link" target="_blank">Dokumentation in Starlette</a> an.
|
||||
Um alle verfügbaren Parameter und Optionen anzuzeigen, sehen Sie sich deren <a href="https://www.starlette.dev/responses/#set-cookie" class="external-link" target="_blank">Dokumentation in Starlette</a> an.
|
||||
|
||||
@@ -34,7 +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:
|
||||
|
||||
{* ../../docs_src/response_directly/tutorial001.py hl[6:7,21:22] *}
|
||||
{* ../../docs_src/response_directly/tutorial001_py310.py hl[5:6,20:21] *}
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
@@ -54,7 +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:
|
||||
|
||||
{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
|
||||
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
|
||||
|
||||
## Anmerkungen { #notes }
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
|
||||
|
||||
Und dann können Sie Header in diesem *vorübergehenden* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt festlegen.
|
||||
|
||||
{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *}
|
||||
{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *}
|
||||
|
||||
Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
|
||||
|
||||
@@ -22,7 +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:
|
||||
|
||||
{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *}
|
||||
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
@@ -38,4 +38,4 @@ Und da die `Response` häufig zum Setzen von Headern und Cookies verwendet wird,
|
||||
|
||||
Beachten Sie, dass benutzerdefinierte proprietäre Header <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">mittels des Präfix `X-`</a> hinzugefügt werden können.
|
||||
|
||||
Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser sehen können soll, müssen Sie diese zu Ihrer CORS-Konfiguration hinzufügen (weitere Informationen finden Sie unter [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), unter Verwendung des Parameters `expose_headers`, dokumentiert in <a href="https://www.starlette.io/middleware/#corsmiddleware" class="external-link" target="_blank">Starlettes CORS-Dokumentation</a>.
|
||||
Wenn Sie jedoch benutzerdefinierte Header haben, die ein Client in einem Browser sehen können soll, müssen Sie diese zu Ihrer CORS-Konfiguration hinzufügen (weitere Informationen finden Sie unter [CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}), unter Verwendung des Parameters `expose_headers`, dokumentiert in <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">Starlettes CORS-Dokumentation</a>.
|
||||
|
||||
@@ -20,7 +20,7 @@ Wenn Sie dann den Benutzernamen und das Passwort eingeben, sendet der Browser di
|
||||
* Diese gibt ein Objekt vom Typ `HTTPBasicCredentials` zurück:
|
||||
* Es enthält den gesendeten `username` und das gesendete `password`.
|
||||
|
||||
{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
|
||||
{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
|
||||
|
||||
Wenn Sie versuchen, die URL zum ersten Mal zu öffnen (oder in der Dokumentation auf den Button „Execute“ zu klicken), wird der Browser Sie nach Ihrem Benutzernamen und Passwort fragen:
|
||||
|
||||
@@ -40,7 +40,7 @@ Um dies zu lösen, konvertieren wir zunächst den `username` und das `password`
|
||||
|
||||
Dann können wir `secrets.compare_digest()` verwenden, um sicherzustellen, dass `credentials.username` `"stanleyjobson"` und `credentials.password` `"swordfish"` ist.
|
||||
|
||||
{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
|
||||
{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
|
||||
|
||||
Dies wäre das gleiche wie:
|
||||
|
||||
@@ -104,4 +104,4 @@ So ist Ihr Anwendungscode, dank der Verwendung von `secrets.compare_digest()`, v
|
||||
|
||||
Nachdem Sie festgestellt haben, dass die Anmeldeinformationen falsch sind, geben Sie eine `HTTPException` mit dem Statuscode 401 zurück (derselbe, der auch zurückgegeben wird, wenn keine Anmeldeinformationen angegeben werden) und fügen den Header `WWW-Authenticate` hinzu, damit der Browser die Anmeldeaufforderung erneut anzeigt:
|
||||
|
||||
{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
|
||||
{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}
|
||||
|
||||
@@ -46,12 +46,6 @@ $ pip install "fastapi[all]"
|
||||
|
||||
</div>
|
||||
|
||||
/// info | Info
|
||||
|
||||
In Pydantic v1 war es im Hauptpackage enthalten. Jetzt wird es als unabhängiges Package verteilt, sodass Sie wählen können, ob Sie es installieren möchten oder nicht, falls Sie die Funktionalität nicht benötigen.
|
||||
|
||||
///
|
||||
|
||||
### Das `Settings`-Objekt erstellen { #create-the-settings-object }
|
||||
|
||||
Importieren Sie `BaseSettings` aus Pydantic und erstellen Sie eine Unterklasse, ganz ähnlich wie bei einem Pydantic-Modell.
|
||||
@@ -60,23 +54,7 @@ Auf die gleiche Weise wie bei Pydantic-Modellen deklarieren Sie Klassenattribute
|
||||
|
||||
Sie können dieselben Validierungs-Funktionen und -Tools verwenden, die Sie für Pydantic-Modelle verwenden, z. B. verschiedene Datentypen und zusätzliche Validierungen mit `Field()`.
|
||||
|
||||
//// tab | Pydantic v2
|
||||
|
||||
{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *}
|
||||
|
||||
////
|
||||
|
||||
//// tab | Pydantic v1
|
||||
|
||||
/// info | Info
|
||||
|
||||
In Pydantic v1 würden Sie `BaseSettings` direkt von `pydantic` statt von `pydantic_settings` importieren.
|
||||
|
||||
///
|
||||
|
||||
{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *}
|
||||
|
||||
////
|
||||
{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -92,7 +70,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:
|
||||
|
||||
{* ../../docs_src/settings/tutorial001.py hl[18:20] *}
|
||||
{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}
|
||||
|
||||
### Den Server ausführen { #run-the-server }
|
||||
|
||||
@@ -126,11 +104,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:
|
||||
|
||||
{* ../../docs_src/settings/app01/config.py *}
|
||||
{* ../../docs_src/settings/app01_py310/config.py *}
|
||||
|
||||
Und dann verwenden Sie diese in einer Datei `main.py`:
|
||||
|
||||
{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
|
||||
{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -148,7 +126,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:
|
||||
|
||||
{* ../../docs_src/settings/app02/config.py hl[10] *}
|
||||
{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
|
||||
|
||||
Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erstellen.
|
||||
|
||||
@@ -156,7 +134,7 @@ Beachten Sie, dass wir jetzt keine Standardinstanz `settings = Settings()` erste
|
||||
|
||||
Jetzt erstellen wir eine Abhängigkeit, die ein neues `config.Settings()` zurückgibt.
|
||||
|
||||
{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
|
||||
{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -168,13 +146,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.
|
||||
|
||||
{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
|
||||
{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
|
||||
|
||||
### Einstellungen und Tests { #settings-and-testing }
|
||||
|
||||
Dann wäre es sehr einfach, beim Testen ein anderes Einstellungsobjekt bereitzustellen, indem man eine Abhängigkeitsüberschreibung für `get_settings` erstellt:
|
||||
|
||||
{* ../../docs_src/settings/app02/test_main.py hl[9:10,13,21] *}
|
||||
{* ../../docs_src/settings/app02_an_py310/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.
|
||||
|
||||
@@ -215,9 +193,7 @@ APP_NAME="ChimichangApp"
|
||||
|
||||
Und dann aktualisieren Sie Ihre `config.py` mit:
|
||||
|
||||
//// tab | Pydantic v2
|
||||
|
||||
{* ../../docs_src/settings/app03_an/config.py hl[9] *}
|
||||
{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -225,26 +201,6 @@ Das Attribut `model_config` wird nur für die Pydantic-Konfiguration verwendet.
|
||||
|
||||
///
|
||||
|
||||
////
|
||||
|
||||
//// tab | Pydantic v1
|
||||
|
||||
{* ../../docs_src/settings/app03_an/config_pv1.py hl[9:10] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Die Klasse `Config` wird nur für die Pydantic-Konfiguration verwendet. Weitere Informationen finden Sie unter <a href="https://docs.pydantic.dev/1.10/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>.
|
||||
|
||||
///
|
||||
|
||||
////
|
||||
|
||||
/// info | Info
|
||||
|
||||
In Pydantic Version 1 erfolgte die Konfiguration in einer internen Klasse `Config`, in Pydantic Version 2 erfolgt sie in einem Attribut `model_config`. Dieses Attribut akzeptiert ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr>. Um automatische Codevervollständigung und Inline-Fehlerberichte zu erhalten, können Sie `SettingsConfigDict` importieren und verwenden, um dieses `dict` zu definieren.
|
||||
|
||||
///
|
||||
|
||||
Hier definieren wir die Konfiguration `env_file` innerhalb Ihrer Pydantic-`Settings`-Klasse und setzen den Wert auf den Dateinamen mit der dotenv-Datei, die wir verwenden möchten.
|
||||
|
||||
### Die `Settings` nur einmal laden mittels `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
|
||||
@@ -270,7 +226,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. ✔️
|
||||
|
||||
{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
|
||||
{* ../../docs_src/settings/app03_an_py310/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,7 +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*:
|
||||
|
||||
{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *}
|
||||
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
|
||||
|
||||
### Unteranwendung { #sub-application }
|
||||
|
||||
@@ -18,7 +18,7 @@ Erstellen Sie dann Ihre Unteranwendung und deren *Pfadoperationen*.
|
||||
|
||||
Diese Unteranwendung ist nur eine weitere Standard-FastAPI-Anwendung, aber diese wird „gemountet“:
|
||||
|
||||
{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *}
|
||||
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
|
||||
|
||||
### Die Unteranwendung mounten { #mount-the-sub-application }
|
||||
|
||||
@@ -26,7 +26,7 @@ Mounten Sie in Ihrer Top-Level-Anwendung `app` die Unteranwendung `subapi`.
|
||||
|
||||
In diesem Fall wird sie im Pfad `/subapi` gemountet:
|
||||
|
||||
{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *}
|
||||
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *}
|
||||
|
||||
### Die automatische API-Dokumentation testen { #check-the-automatic-api-docs }
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ $ pip install jinja2
|
||||
* Deklarieren Sie einen `<abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>`-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“-<abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> mit Schlüssel-Wert-Paaren, die innerhalb des Jinja2-Templates verwendet werden sollen.
|
||||
|
||||
{* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *}
|
||||
{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
@@ -123,4 +123,4 @@ Und da Sie `StaticFiles` verwenden, wird diese CSS-Datei automatisch von Ihrer *
|
||||
|
||||
## Mehr Details { #more-details }
|
||||
|
||||
Weitere Informationen, einschließlich, wie man Templates testet, finden Sie in <a href="https://www.starlette.io/templates/" class="external-link" target="_blank">Starlettes Dokumentation zu Templates</a>.
|
||||
Weitere Informationen, einschließlich, wie man Templates testet, finden Sie in <a href="https://www.starlette.dev/templates/" class="external-link" target="_blank">Starlettes Dokumentation zu Templates</a>.
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
Wenn Sie `lifespan` in Ihren Tests ausführen müssen, können Sie den `TestClient` mit einer `with`-Anweisung verwenden:
|
||||
|
||||
{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *}
|
||||
{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
|
||||
|
||||
|
||||
Sie können mehr Details unter [„Lifespan in Tests ausführen in der offiziellen Starlette-Dokumentation.“](https://www.starlette.io/lifespan/#running-lifespan-in-tests) nachlesen.
|
||||
Sie können mehr Details unter [„Lifespan in Tests ausführen in der offiziellen Starlette-Dokumentation.“](https://www.starlette.dev/lifespan/#running-lifespan-in-tests) nachlesen.
|
||||
|
||||
Für die deprecateten Events <abbr title="Hochfahren">`startup`</abbr> und <abbr title="Herunterfahren">`shutdown`</abbr> können Sie den `TestClient` wie folgt verwenden:
|
||||
|
||||
{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *}
|
||||
{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *}
|
||||
|
||||
@@ -4,10 +4,10 @@ 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:
|
||||
|
||||
{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
|
||||
{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
Weitere Informationen finden Sie in Starlettes Dokumentation zum <a href="https://www.starlette.io/testclient/#testing-websocket-sessions" class="external-link" target="_blank">Testen von WebSockets</a>.
|
||||
Weitere Informationen finden Sie in Starlettes Dokumentation zum <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">Testen von WebSockets</a>.
|
||||
|
||||
///
|
||||
|
||||
@@ -15,7 +15,7 @@ Es gibt jedoch Situationen, in denen Sie möglicherweise direkt auf das `Request
|
||||
|
||||
## Details zum `Request`-Objekt { #details-about-the-request-object }
|
||||
|
||||
Da **FastAPI** unter der Haube eigentlich **Starlette** ist, mit einer Ebene von mehreren Tools darüber, können Sie Starlettes <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">`Request`</a>-Objekt direkt verwenden, wenn Sie es benötigen.
|
||||
Da **FastAPI** unter der Haube eigentlich **Starlette** ist, mit einer Ebene von mehreren Tools darüber, können Sie Starlettes <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">`Request`</a>-Objekt direkt verwenden, wenn Sie es benötigen.
|
||||
|
||||
Das bedeutet allerdings auch, dass, wenn Sie Daten direkt vom `Request`-Objekt nehmen (z. B. dessen Body lesen), diese von FastAPI nicht validiert, konvertiert oder dokumentiert werden (mit OpenAPI, für die automatische API-Benutzeroberfläche).
|
||||
|
||||
@@ -29,7 +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.
|
||||
|
||||
{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *}
|
||||
{* ../../docs_src/using_request_directly/tutorial001_py310.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.
|
||||
|
||||
@@ -45,7 +45,7 @@ Auf die gleiche Weise können Sie wie gewohnt jeden anderen Parameter deklariere
|
||||
|
||||
## `Request`-Dokumentation { #request-documentation }
|
||||
|
||||
Weitere Details zum <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">`Request`-Objekt finden Sie in der offiziellen Starlette-Dokumentation</a>.
|
||||
Weitere Details zum <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">`Request`-Objekt finden Sie in der offiziellen Starlette-Dokumentation</a>.
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
|
||||
@@ -38,13 +38,13 @@ In der Produktion hätten Sie eine der oben genannten Optionen.
|
||||
|
||||
Aber es ist der einfachste Weg, sich auf die Serverseite von WebSockets zu konzentrieren und ein funktionierendes Beispiel zu haben:
|
||||
|
||||
{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
|
||||
{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
|
||||
|
||||
## Einen `websocket` erstellen { #create-a-websocket }
|
||||
|
||||
Erstellen Sie in Ihrer **FastAPI**-Anwendung einen `websocket`:
|
||||
|
||||
{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
|
||||
{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
@@ -58,7 +58,7 @@ Sie könnten auch `from starlette.websockets import WebSocket` verwenden.
|
||||
|
||||
In Ihrer WebSocket-Route können Sie Nachrichten `await`en und Nachrichten senden.
|
||||
|
||||
{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}
|
||||
{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
|
||||
|
||||
Sie können Binär-, Text- und JSON-Daten empfangen und senden.
|
||||
|
||||
@@ -154,7 +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.
|
||||
|
||||
{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
|
||||
{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
|
||||
|
||||
Zum Ausprobieren:
|
||||
|
||||
@@ -182,5 +182,5 @@ Wenn Sie etwas benötigen, das sich leicht in FastAPI integrieren lässt, aber r
|
||||
|
||||
Weitere Informationen zu Optionen finden Sie in der Dokumentation von Starlette:
|
||||
|
||||
* <a href="https://www.starlette.io/websockets/" class="external-link" target="_blank">Die `WebSocket`-Klasse</a>.
|
||||
* <a href="https://www.starlette.io/endpoints/#websocketendpoint" class="external-link" target="_blank">Klassen-basierte Handhabung von WebSockets</a>.
|
||||
* <a href="https://www.starlette.dev/websockets/" class="external-link" target="_blank">Die `WebSocket`-Klasse</a>.
|
||||
* <a href="https://www.starlette.dev/endpoints/#websocketendpoint" class="external-link" target="_blank">Klassen-basierte Handhabung von WebSockets</a>.
|
||||
|
||||
@@ -6,13 +6,29 @@ Dazu können Sie die `WSGIMiddleware` verwenden und damit Ihre WSGI-Anwendung wr
|
||||
|
||||
## `WSGIMiddleware` verwenden { #using-wsgimiddleware }
|
||||
|
||||
Sie müssen `WSGIMiddleware` importieren.
|
||||
/// info | Info
|
||||
|
||||
Dafür muss `a2wsgi` installiert sein, z. B. mit `pip install a2wsgi`.
|
||||
|
||||
///
|
||||
|
||||
Sie müssen `WSGIMiddleware` aus `a2wsgi` importieren.
|
||||
|
||||
Wrappen Sie dann die WSGI-Anwendung (z. B. Flask) mit der Middleware.
|
||||
|
||||
Und dann mounten Sie das auf einem Pfad.
|
||||
|
||||
{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *}
|
||||
{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *}
|
||||
|
||||
/// note | Hinweis
|
||||
|
||||
Früher wurde empfohlen, `WSGIMiddleware` aus `fastapi.middleware.wsgi` zu verwenden, dies ist jetzt deprecatet.
|
||||
|
||||
Stattdessen wird empfohlen, das Paket `a2wsgi` zu verwenden. Die Nutzung bleibt gleich.
|
||||
|
||||
Stellen Sie lediglich sicher, dass das Paket `a2wsgi` installiert ist und importieren Sie `WSGIMiddleware` korrekt aus `a2wsgi`.
|
||||
|
||||
///
|
||||
|
||||
## Es testen { #check-it }
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Es ist das beliebteste Python-Framework und genießt großes Vertrauen. Es wird
|
||||
|
||||
Es ist relativ eng mit relationalen Datenbanken (wie MySQL oder PostgreSQL) gekoppelt, daher ist es nicht sehr einfach, eine NoSQL-Datenbank (wie Couchbase, MongoDB, Cassandra, usw.) als Hauptspeicherengine zu verwenden.
|
||||
|
||||
Es wurde erstellt, um den HTML-Code im Backend zu generieren, nicht um APIs zu erstellen, die von einem modernen Frontend (wie React, Vue.js und Angular) oder von anderen Systemen (wie <abbr title="Internet of Things – Internet der Dinge">IoT</abbr>-Geräten) verwendet werden, um mit ihm zu kommunizieren.
|
||||
Es wurde erstellt, um den HTML-Code im Backend zu generieren, nicht um APIs zu erstellen, die von einem modernen Frontend (wie React, Vue.js und Angular) oder von anderen Systemen (wie <abbr title="Internet of Things - Internet der Dinge">IoT</abbr>-Geräten) verwendet werden, um mit ihm zu kommunizieren.
|
||||
|
||||
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">Django REST Framework</a> { #django-rest-framework }
|
||||
|
||||
@@ -82,7 +82,7 @@ Aus diesem Grund heißt es auf der offiziellen Website:
|
||||
|
||||
> Requests ist eines der am häufigsten heruntergeladenen Python-Packages aller Zeiten
|
||||
|
||||
Die Art und Weise, wie Sie es verwenden, ist sehr einfach. Um beispielsweise einen `GET`-<abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> zu machen, würden Sie schreiben:
|
||||
Die Art und Weise, wie Sie es verwenden, ist sehr einfach. Um beispielsweise einen `GET`-<abbr title="Request - Anfrage: Daten, die der Client zum Server sendet">Request</abbr> zu machen, würden Sie schreiben:
|
||||
|
||||
```Python
|
||||
response = requests.get("http://example.com/some/url")
|
||||
@@ -137,7 +137,7 @@ Es gibt mehrere Flask REST Frameworks, aber nachdem ich die Zeit und Arbeit inve
|
||||
|
||||
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">Marshmallow</a> { #marshmallow }
|
||||
|
||||
Eine der von API-Systemen benötigten Hauptfunktionen ist die Daten-<abbr title="Auch „Marshalling“, „Konvertierung“ genannt">„Serialisierung“</abbr>, welche Daten aus dem Code (Python) entnimmt und in etwas umwandelt, was durch das Netzwerk gesendet werden kann. Beispielsweise das Konvertieren eines Objekts, welches Daten aus einer Datenbank enthält, in ein JSON-Objekt. Konvertieren von `datetime`-Objekten in Strings, usw.
|
||||
Eine der von API-Systemen benötigten Hauptfunktionen ist die Daten-<dfn title="auch genannt: Marshalling, Konvertierung">„Serialisierung“</dfn>, welche Daten aus dem Code (Python) entnimmt und in etwas umwandelt, was durch das Netzwerk gesendet werden kann. Beispielsweise das Konvertieren eines Objekts, welches Daten aus einer Datenbank enthält, in ein JSON-Objekt. Konvertieren von `datetime`-Objekten in Strings, usw.
|
||||
|
||||
Eine weitere wichtige Funktion, benötigt von APIs, ist die Datenvalidierung, welche sicherstellt, dass die Daten unter gegebenen Umständen gültig sind. Zum Beispiel, dass ein Feld ein `int` ist und kein zufälliger String. Das ist besonders nützlich für hereinkommende Daten.
|
||||
|
||||
@@ -145,7 +145,7 @@ Ohne ein Datenvalidierungssystem müssten Sie alle Prüfungen manuell im Code du
|
||||
|
||||
Für diese Funktionen wurde Marshmallow entwickelt. Es ist eine großartige Bibliothek und ich habe sie schon oft genutzt.
|
||||
|
||||
Aber sie wurde erstellt, bevor Typhinweise in Python existierten. Um also ein <abbr title="die Definition, wie Daten geformt sein sollen">Schema</abbr> zu definieren, müssen Sie bestimmte Werkzeuge und Klassen verwenden, die von Marshmallow bereitgestellt werden.
|
||||
Aber sie wurde erstellt, bevor Typhinweise in Python existierten. Um also ein <dfn title="die Definition, wie Daten geformt sein sollen">Schema</dfn> zu definieren, müssen Sie bestimmte Werkzeuge und Klassen verwenden, die von Marshmallow bereitgestellt werden.
|
||||
|
||||
/// check | Inspirierte **FastAPI**
|
||||
|
||||
@@ -155,7 +155,7 @@ Code zu verwenden, um „Schemas“ zu definieren, welche Datentypen und Validie
|
||||
|
||||
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webargs</a> { #webargs }
|
||||
|
||||
Eine weitere wichtige Funktion, die von APIs benötigt wird, ist das <abbr title="Lesen und Konvertieren nach Python-Daten">Parsen</abbr> von Daten aus eingehenden Requests.
|
||||
Eine weitere wichtige Funktion, die von APIs benötigt wird, ist das <dfn title="Lesen und Konvertieren nach Python-Daten">Parsen</dfn> von Daten aus eingehenden Requests.
|
||||
|
||||
Webargs wurde entwickelt, um dieses für mehrere Frameworks, einschließlich Flask, bereitzustellen.
|
||||
|
||||
@@ -283,7 +283,7 @@ Aus diesem Grund basiert **FastAPI** auf Starlette, da dieses das schnellste ver
|
||||
|
||||
Falcon ist ein weiteres leistungsstarkes Python-Framework. Es ist minimalistisch konzipiert und dient als Grundlage für andere Frameworks wie Hug.
|
||||
|
||||
Es ist so konzipiert, dass es über Funktionen verfügt, welche zwei Parameter empfangen, einen <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">„Request“</abbr> und eine <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">„Response“</abbr>. Dann „lesen“ Sie Teile des Requests und „schreiben“ Teile der Response. Aufgrund dieses Designs ist es nicht möglich, Request-Parameter und -Bodys mit Standard-Python-Typhinweisen als Funktionsparameter zu deklarieren.
|
||||
Es ist so konzipiert, dass es über Funktionen verfügt, welche zwei Parameter empfangen, einen <abbr title="Request - Anfrage: Daten, die der Client zum Server sendet">„Request“</abbr> und eine <abbr title="Response - Antwort: Daten, die der Server zum anfragenden Client zurücksendet">„Response“</abbr>. Dann „lesen“ Sie Teile des Requests und „schreiben“ Teile der Response. Aufgrund dieses Designs ist es nicht möglich, Request-Parameter und -Bodys mit Standard-Python-Typhinweisen als Funktionsparameter zu deklarieren.
|
||||
|
||||
Daher müssen Datenvalidierung, Serialisierung und Dokumentation im Code und nicht automatisch erfolgen. Oder sie müssen als Framework oberhalb von Falcon implementiert werden, so wie Hug. Dieselbe Unterscheidung findet auch in anderen Frameworks statt, die vom Design von Falcon inspiriert sind und ein Requestobjekt und ein Responseobjekt als Parameter haben.
|
||||
|
||||
@@ -417,9 +417,9 @@ Die gesamte Datenvalidierung, Datenserialisierung und automatische Modelldokumen
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> { #starlette }
|
||||
### <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> { #starlette }
|
||||
|
||||
Starlette ist ein leichtgewichtiges <abbr title="Der neue Standard für die Erstellung asynchroner Python-Webanwendungen">ASGI</abbr>-Framework/Toolkit, welches sich ideal für die Erstellung hochperformanter asynchroner Dienste eignet.
|
||||
Starlette ist ein leichtgewichtiges <dfn title="Der neue Standard für die Erstellung asynchroner Python-Webanwendungen">ASGI</dfn>-Framework/Toolkit, welches sich ideal für die Erstellung hochperformanter asynchroner Dienste eignet.
|
||||
|
||||
Es ist sehr einfach und intuitiv. Es ist so konzipiert, dass es leicht erweiterbar ist und über modulare Komponenten verfügt.
|
||||
|
||||
@@ -462,7 +462,7 @@ Alles, was Sie also mit Starlette machen können, können Sie direkt mit **FastA
|
||||
|
||||
///
|
||||
|
||||
### <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a> { #uvicorn }
|
||||
### <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a> { #uvicorn }
|
||||
|
||||
Uvicorn ist ein blitzschneller ASGI-Server, der auf uvloop und httptools basiert.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ Die Hierarchie ist wie folgt:
|
||||
* Sie würden eine Anwendung nicht direkt in Uvicorn schreiben. Das würde bedeuten, dass Ihr Code zumindest mehr oder weniger den gesamten von Starlette (oder **FastAPI**) bereitgestellten Code enthalten müsste. Und wenn Sie das täten, hätte Ihre endgültige Anwendung den gleichen Overhead wie bei der Verwendung eines Frameworks und der Minimierung Ihres Anwendungscodes und der Fehler.
|
||||
* Wenn Sie Uvicorn vergleichen, vergleichen Sie es mit Anwendungsservern wie Daphne, Hypercorn, uWSGI, usw.
|
||||
* **Starlette**:
|
||||
* Wird nach Uvicorn die nächstbeste Performanz erbringen. Tatsächlich verwendet Starlette intern Uvicorn, um zu laufen. Daher kann es wahrscheinlich nur „langsamer“ als Uvicorn werden, weil mehr Code ausgeführt werden muss.
|
||||
* Wird nach Uvicorn die nächstbeste Performanz erbringen. Tatsächlich verwendet Starlette Uvicorn, um zu laufen. Daher kann es wahrscheinlich nur „langsamer“ als Uvicorn werden, weil mehr Code ausgeführt werden muss.
|
||||
* Aber es bietet Ihnen die Werkzeuge, um einfache Webanwendungen zu erstellen, mit Routing basierend auf Pfaden, usw.
|
||||
* Wenn Sie Starlette vergleichen, vergleichen Sie es mit Webframeworks (oder Mikroframeworks) wie Sanic, Flask, Django, usw.
|
||||
* **FastAPI**:
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
# FastAPI bei Cloudanbietern bereitstellen { #deploy-fastapi-on-cloud-providers }
|
||||
# FastAPI bei Cloudanbietern deployen { #deploy-fastapi-on-cloud-providers }
|
||||
|
||||
Sie können praktisch **jeden Cloudanbieter** verwenden, um Ihre FastAPI-Anwendung bereitzustellen.
|
||||
Sie können praktisch **jeden Cloudanbieter** verwenden, um Ihre FastAPI-Anwendung zu deployen.
|
||||
|
||||
In den meisten Fällen bieten die großen Cloudanbieter Anleitungen zum Bereitstellen von FastAPI an.
|
||||
In den meisten Fällen bieten die großen Cloudanbieter Anleitungen zum Deployment von FastAPI an.
|
||||
|
||||
## FastAPI Cloud { #fastapi-cloud }
|
||||
|
||||
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** wurde vom selben Autor und Team hinter **FastAPI** entwickelt.
|
||||
|
||||
Es vereinfacht den Prozess des **Erstellens**, **Deployens** und **Zugreifens** auf eine API mit minimalem Aufwand.
|
||||
|
||||
Es bringt die gleiche **Developer-Experience** beim Erstellen von Apps mit FastAPI auch zum **Deployment** in der Cloud. 🎉
|
||||
|
||||
FastAPI Cloud ist der Hauptsponsor und Finanzierungsgeber für die *FastAPI and friends* Open-Source-Projekte. ✨
|
||||
|
||||
## Cloudanbieter – Sponsoren { #cloud-providers-sponsors }
|
||||
|
||||
Einige Cloudanbieter ✨ [**sponsern FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨, dies stellt die kontinuierliche und gesunde **Entwicklung** von FastAPI und seinem **Ökosystem** sicher.
|
||||
Einige andere Cloudanbieter ✨ [**sponsern FastAPI**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} ✨ ebenfalls. 🙇
|
||||
|
||||
Und es zeigt ihr wahres Engagement für FastAPI und seine **Community** (Sie), da sie Ihnen nicht nur einen **guten Service** bieten möchten, sondern auch sicherstellen möchten, dass Sie ein **gutes und gesundes Framework**, FastAPI, haben. 🙇
|
||||
|
||||
Vielleicht möchten Sie deren Dienste ausprobieren und deren Anleitungen folgen:
|
||||
Sie könnten diese ebenfalls in Betracht ziehen, deren Anleitungen folgen und ihre Dienste ausprobieren:
|
||||
|
||||
* <a href="https://docs.render.com/deploy-fastapi?utm_source=deploydoc&utm_medium=referral&utm_campaign=fastapi" class="external-link" target="_blank">Render</a>
|
||||
* <a href="https://docs.railway.com/guides/fastapi?utm_medium=integration&utm_source=docs&utm_campaign=fastapi" class="external-link" target="_blank">Railway</a>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Deployment-Konzepte { #deployments-concepts }
|
||||
|
||||
Bei dem Deployment – der Bereitstellung – einer **FastAPI**-Anwendung, oder eigentlich jeder Art von Web-API, gibt es mehrere Konzepte, die Sie wahrscheinlich interessieren, und mithilfe der Sie die **am besten geeignete** Methode zur **Bereitstellung Ihrer Anwendung** finden können.
|
||||
Bei dem Deployment – der Bereitstellung – einer **FastAPI**-Anwendung, oder eigentlich jeder Art von Web-API, gibt es mehrere Konzepte, die Sie wahrscheinlich interessieren, und mithilfe der Sie die **am besten geeignete** Methode zum **Deployment Ihrer Anwendung** finden können.
|
||||
|
||||
Einige wichtige Konzepte sind:
|
||||
|
||||
@@ -15,11 +15,11 @@ Wir werden sehen, wie diese sich auf das **Deployment** auswirken.
|
||||
|
||||
Letztendlich besteht das ultimative Ziel darin, **Ihre API-Clients** auf **sichere** Weise zu versorgen, um **Unterbrechungen** zu vermeiden und die **Rechenressourcen** (z. B. entfernte Server/virtuelle Maschinen) so effizient wie möglich zu nutzen. 🚀
|
||||
|
||||
Ich erzähle Ihnen hier etwas mehr über diese **Konzepte**, was Ihnen hoffentlich die **Intuition** gibt, die Sie benötigen, um zu entscheiden, wie Sie Ihre API in sehr unterschiedlichen Umgebungen bereitstellen, möglicherweise sogar in **zukünftigen**, die jetzt noch nicht existieren.
|
||||
Ich erzähle Ihnen hier etwas mehr über diese **Konzepte**, was Ihnen hoffentlich die **Intuition** gibt, die Sie benötigen, um zu entscheiden, wie Sie Ihre API in sehr unterschiedlichen Umgebungen deployen, möglicherweise sogar in **zukünftigen**, die jetzt noch nicht existieren.
|
||||
|
||||
Durch die Berücksichtigung dieser Konzepte können Sie die beste Variante der Bereitstellung **Ihrer eigenen APIs** **evaluieren und konzipieren**.
|
||||
Durch die Berücksichtigung dieser Konzepte können Sie die beste Variante des Deployments **Ihrer eigenen APIs** **evaluieren und konzipieren**.
|
||||
|
||||
In den nächsten Kapiteln werde ich Ihnen mehr **konkrete Rezepte** für die Bereitstellung von FastAPI-Anwendungen geben.
|
||||
In den nächsten Kapiteln werde ich Ihnen mehr **konkrete Rezepte** für das Deployment von FastAPI-Anwendungen geben.
|
||||
|
||||
Aber schauen wir uns zunächst einmal diese grundlegenden **konzeptionellen Ideen** an. Diese Konzepte gelten auch für jede andere Art von Web-API. 💡
|
||||
|
||||
@@ -271,7 +271,7 @@ In diesem Fall müssen Sie sich darüber keine Sorgen machen. 🤷
|
||||
|
||||
### Beispiele für Strategien für Vorab-Schritte { #examples-of-previous-steps-strategies }
|
||||
|
||||
Es hängt **stark** davon ab, wie Sie **Ihr System bereitstellen**, und hängt wahrscheinlich mit der Art und Weise zusammen, wie Sie Programme starten, Neustarts durchführen, usw.
|
||||
Es hängt **stark** davon ab, wie Sie **Ihr System deployen**, und hängt wahrscheinlich mit der Art und Weise zusammen, wie Sie Programme starten, Neustarts durchführen, usw.
|
||||
|
||||
Hier sind einige mögliche Ideen:
|
||||
|
||||
@@ -307,7 +307,7 @@ Sie können einfache Tools wie `htop` verwenden, um die in Ihrem Server verwende
|
||||
|
||||
## Zusammenfassung { #recap }
|
||||
|
||||
Sie haben hier einige der wichtigsten Konzepte gelesen, die Sie wahrscheinlich berücksichtigen müssen, wenn Sie entscheiden, wie Sie Ihre Anwendung bereitstellen:
|
||||
Sie haben hier einige der wichtigsten Konzepte gelesen, die Sie wahrscheinlich berücksichtigen müssen, wenn Sie entscheiden, wie Sie Ihre Anwendung deployen:
|
||||
|
||||
* Sicherheit – HTTPS
|
||||
* Beim Hochfahren ausführen
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# FastAPI in Containern – Docker { #fastapi-in-containers-docker }
|
||||
|
||||
Beim Deployment von FastAPI-Anwendungen besteht ein gängiger Ansatz darin, ein **Linux-Containerimage** zu erstellen. Normalerweise erfolgt dies mit <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>. Sie können dieses Containerimage dann auf eine von mehreren möglichen Arten bereitstellen.
|
||||
Beim Deployment von FastAPI-Anwendungen besteht ein gängiger Ansatz darin, ein **Linux-Containerimage** zu erstellen. Normalerweise erfolgt dies mit <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a>. Sie können dieses Containerimage dann auf eine von mehreren möglichen Arten deployen.
|
||||
|
||||
Die Verwendung von Linux-Containern bietet mehrere Vorteile, darunter **Sicherheit**, **Replizierbarkeit**, **Einfachheit** und andere.
|
||||
|
||||
@@ -14,7 +14,7 @@ Sie haben es eilig und kennen sich bereits aus? Springen Sie zum [`Dockerfile` u
|
||||
<summary>Dockerfile-Vorschau 👀</summary>
|
||||
|
||||
```Dockerfile
|
||||
FROM python:3.9
|
||||
FROM python:3.14
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
@@ -40,7 +40,7 @@ Linux-Container werden mit demselben Linux-Kernel des Hosts (Maschine, virtuelle
|
||||
|
||||
Auf diese Weise verbrauchen Container **wenig Ressourcen**, eine Menge vergleichbar mit der direkten Ausführung der Prozesse (eine virtuelle Maschine würde viel mehr verbrauchen).
|
||||
|
||||
Container verfügen außerdem über ihre eigenen **isoliert** laufenden Prozesse (üblicherweise nur einen Prozess), über ihr eigenes Dateisystem und ihr eigenes Netzwerk, was die Bereitstellung, Sicherheit, Entwicklung usw. vereinfacht.
|
||||
Container verfügen außerdem über ihre eigenen **isoliert** laufenden Prozesse (üblicherweise nur einen Prozess), über ihr eigenes Dateisystem und ihr eigenes Netzwerk, was Deployment, Sicherheit, Entwicklung usw. vereinfacht.
|
||||
|
||||
## Was ist ein Containerimage { #what-is-a-container-image }
|
||||
|
||||
@@ -145,8 +145,6 @@ Es gibt andere Formate und Tools zum Definieren und Installieren von Paketabhän
|
||||
* Erstellen Sie eine `main.py`-Datei mit:
|
||||
|
||||
```Python
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
@@ -158,7 +156,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
def read_item(item_id: int, q: str | None = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -168,7 +166,7 @@ Erstellen Sie nun im selben Projektverzeichnis eine Datei `Dockerfile` mit:
|
||||
|
||||
```{ .dockerfile .annotate }
|
||||
# (1)!
|
||||
FROM python:3.9
|
||||
FROM python:3.14
|
||||
|
||||
# (2)!
|
||||
WORKDIR /code
|
||||
@@ -392,7 +390,7 @@ Wenn Ihr FastAPI eine einzelne Datei ist, zum Beispiel `main.py` ohne ein `./app
|
||||
Dann müssten Sie nur noch die entsprechenden Pfade ändern, um die Datei im `Dockerfile` zu kopieren:
|
||||
|
||||
```{ .dockerfile .annotate hl_lines="10 13" }
|
||||
FROM python:3.9
|
||||
FROM python:3.14
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
@@ -456,7 +454,7 @@ Ohne die Verwendung von Containern kann es umständlich und schwierig sein, Anwe
|
||||
|
||||
## Replikation – Anzahl der Prozesse { #replication-number-of-processes }
|
||||
|
||||
Wenn Sie einen <abbr title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und auf irgendeine Weise zusammenarbeiten.">Cluster</abbr> von Maschinen mit **Kubernetes**, Docker Swarm Mode, Nomad verwenden, oder einem anderen, ähnlich komplexen System zur Verwaltung verteilter Container auf mehreren Maschinen, möchten Sie wahrscheinlich die **Replikation auf Cluster-Ebene abwickeln**, anstatt in jedem Container einen **Prozessmanager** (wie Uvicorn mit Workern) zu verwenden.
|
||||
Wenn Sie einen <dfn title="Eine Gruppe von Maschinen, die so konfiguriert sind, dass sie verbunden sind und auf irgendeine Weise zusammenarbeiten.">Cluster</dfn> von Maschinen mit **Kubernetes**, Docker Swarm Mode, Nomad verwenden, oder einem anderen, ähnlich komplexen System zur Verwaltung verteilter Container auf mehreren Maschinen, möchten Sie wahrscheinlich die **Replikation auf Cluster-Ebene abwickeln**, anstatt in jedem Container einen **Prozessmanager** (wie Uvicorn mit Workern) zu verwenden.
|
||||
|
||||
Diese verteilten Containerverwaltungssysteme wie Kubernetes verfügen normalerweise über eine integrierte Möglichkeit, die **Replikation von Containern** zu handhaben und gleichzeitig **Load Balancing** für die eingehenden <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> zu unterstützen. Alles auf **Cluster-Ebene**.
|
||||
|
||||
@@ -501,7 +499,7 @@ Natürlich gibt es **Sonderfälle**, in denen Sie **einen Container** mit mehrer
|
||||
In diesen Fällen können Sie die `--workers` Befehlszeilenoption verwenden, um die Anzahl der zu startenden Worker festzulegen:
|
||||
|
||||
```{ .dockerfile .annotate }
|
||||
FROM python:3.9
|
||||
FROM python:3.14
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
@@ -572,7 +570,7 @@ Wenn Sie ein einfaches Setup mit einem **einzelnen Container** haben, welcher da
|
||||
|
||||
### Docker-Basisimage { #base-docker-image }
|
||||
|
||||
Es gab ein offizielles FastAPI-Docker-Image: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>. Dieses ist jedoch jetzt veraltet. ⛔️
|
||||
Es gab ein offizielles FastAPI-Docker-Image: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>. Dieses ist jedoch jetzt deprecatet. ⛔️
|
||||
|
||||
Sie sollten wahrscheinlich **nicht** dieses Basis-Docker-Image (oder ein anderes ähnliches) verwenden.
|
||||
|
||||
@@ -598,7 +596,7 @@ Zum Beispiel:
|
||||
* Mit einem **Kubernetes**-Cluster
|
||||
* Mit einem Docker Swarm Mode-Cluster
|
||||
* Mit einem anderen Tool wie Nomad
|
||||
* Mit einem Cloud-Dienst, der Ihr Containerimage nimmt und es bereitstellt
|
||||
* Mit einem Cloud-Dienst, der Ihr Containerimage nimmt und es deployt
|
||||
|
||||
## Docker-Image mit `uv` { #docker-image-with-uv }
|
||||
|
||||
|
||||
65
docs/de/docs/deployment/fastapicloud.md
Normal file
65
docs/de/docs/deployment/fastapicloud.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# FastAPI Cloud { #fastapi-cloud }
|
||||
|
||||
Sie können Ihre FastAPI-App in der <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> mit **einem einzigen Befehl** deployen – tragen Sie sich in die Warteliste ein, falls noch nicht geschehen. 🚀
|
||||
|
||||
## Anmelden { #login }
|
||||
|
||||
Stellen Sie sicher, dass Sie bereits ein **FastAPI-Cloud-Konto** haben (wir haben Sie von der Warteliste eingeladen 😉).
|
||||
|
||||
Melden Sie sich dann an:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi login
|
||||
|
||||
You are logged in to FastAPI Cloud 🚀
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Deployen { #deploy }
|
||||
|
||||
Stellen Sie Ihre App jetzt mit **einem einzigen Befehl** bereit:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi deploy
|
||||
|
||||
Deploying to FastAPI Cloud...
|
||||
|
||||
✅ Deployment successful!
|
||||
|
||||
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Das war’s! Jetzt können Sie Ihre App unter dieser URL aufrufen. ✨
|
||||
|
||||
## Über FastAPI Cloud { #about-fastapi-cloud }
|
||||
|
||||
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** wird vom gleichen Autor und Team hinter **FastAPI** entwickelt.
|
||||
|
||||
Es vereinfacht den Prozess des **Erstellens**, **Deployens** und **Nutzens** einer API mit minimalem Aufwand.
|
||||
|
||||
Es bringt die gleiche **Developer-Experience** beim Erstellen von Apps mit FastAPI auch zum **Deployment** in der Cloud. 🎉
|
||||
|
||||
Es kümmert sich außerdem um das meiste, was beim Deployen einer App nötig ist, zum Beispiel:
|
||||
|
||||
* HTTPS
|
||||
* Replikation, mit Autoscaling basierend auf Requests
|
||||
* usw.
|
||||
|
||||
FastAPI Cloud ist Hauptsponsor und Finanzierer der Open-Source-Projekte *FastAPI and friends*. ✨
|
||||
|
||||
## Bei anderen Cloudanbietern deployen { #deploy-to-other-cloud-providers }
|
||||
|
||||
FastAPI ist Open Source und basiert auf Standards. Sie können FastAPI-Apps bei jedem Cloudanbieter Ihrer Wahl deployen.
|
||||
|
||||
Folgen Sie den Anleitungen Ihres Cloudanbieters, um dort FastAPI-Apps zu deployen. 🤓
|
||||
|
||||
## Auf den eigenen Server deployen { #deploy-your-own-server }
|
||||
|
||||
Ich werde Ihnen später in diesem **Deployment-Leitfaden** auch alle Details zeigen, sodass Sie verstehen, was passiert, was geschehen muss und wie Sie FastAPI-Apps selbst deployen können, auch auf Ihre eigenen Server. 🤓
|
||||
@@ -65,7 +65,7 @@ Hier ist ein Beispiel, wie eine HTTPS-API aussehen könnte, Schritt für Schritt
|
||||
|
||||
Alles beginnt wahrscheinlich damit, dass Sie einen **Domainnamen erwerben**. Anschließend konfigurieren Sie ihn in einem DNS-Server (wahrscheinlich beim selben Cloudanbieter).
|
||||
|
||||
Sie würden wahrscheinlich einen Cloud-Server (eine virtuelle Maschine) oder etwas Ähnliches bekommen, und dieser hätte eine <abbr title="Sie ändert sich nicht">feste</abbr> **öffentliche IP-Adresse**.
|
||||
Sie würden wahrscheinlich einen Cloud-Server (eine virtuelle Maschine) oder etwas Ähnliches bekommen, und dieser hätte eine <dfn title="Ändert sich im Laufe der Zeit nicht. Nicht dynamisch.">feste</dfn> **öffentliche IP-Adresse**.
|
||||
|
||||
In dem oder den DNS-Server(n) würden Sie einen Eintrag (einen „`A record`“) konfigurieren, um mit **Ihrer Domain** auf die öffentliche **IP-Adresse Ihres Servers** zu verweisen.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Das Deployment einer **FastAPI**-Anwendung ist relativ einfach.
|
||||
|
||||
## Was bedeutet Deployment { #what-does-deployment-mean }
|
||||
|
||||
<abbr title="Bereitstellen der Anwendung">**Deployment**</abbr> bedeutet, die notwendigen Schritte durchzuführen, um die Anwendung **für die Endbenutzer verfügbar** zu machen.
|
||||
<abbr title="Bereitstellen der Anwendung">**Deployment**</abbr> bedeutet, die notwendigen Schritte durchzuführen, um die Anwendung **für die Benutzer verfügbar** zu machen.
|
||||
|
||||
Bei einer **Web-API** bedeutet das normalerweise, diese auf einem **entfernten Rechner** zu platzieren, mit einem **Serverprogramm**, welches gute Leistung, Stabilität, usw. bietet, damit Ihre **Benutzer** auf die Anwendung effizient und ohne Unterbrechungen oder Probleme **zugreifen** können.
|
||||
|
||||
@@ -14,7 +14,9 @@ Das steht im Gegensatz zu den **Entwicklungsphasen**, in denen Sie ständig den
|
||||
|
||||
Es gibt mehrere Möglichkeiten, dies zu tun, abhängig von Ihrem spezifischen Anwendungsfall und den von Ihnen verwendeten Tools.
|
||||
|
||||
Sie könnten mithilfe einer Kombination von Tools selbst **einen Server bereitstellen**, Sie könnten einen **Cloud-Dienst** nutzen, der einen Teil der Arbeit für Sie erledigt, oder andere mögliche Optionen.
|
||||
Sie könnten mithilfe einer Kombination von Tools selbst **einen Server deployen**, Sie könnten einen **Cloud-Dienst** nutzen, der einen Teil der Arbeit für Sie erledigt, oder andere mögliche Optionen.
|
||||
|
||||
Zum Beispiel haben wir, das Team hinter FastAPI, <a href="https://fastapicloud.com" class="external-link" target="_blank">**FastAPI Cloud**</a> entwickelt, um das Deployment von FastAPI-Apps in der Cloud so reibungslos wie möglich zu gestalten, mit derselben Developer-Experience wie beim Arbeiten mit FastAPI.
|
||||
|
||||
Ich zeige Ihnen einige der wichtigsten Konzepte, die Sie beim Deployment einer **FastAPI**-Anwendung wahrscheinlich berücksichtigen sollten (obwohl das meiste davon auch für jede andere Art von Webanwendung gilt).
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ Das Wichtigste, was Sie benötigen, um eine **FastAPI**-Anwendung (oder eine and
|
||||
|
||||
Es gibt mehrere Alternativen, einschließlich:
|
||||
|
||||
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>: ein hochperformanter ASGI-Server.
|
||||
* <a href="https://www.uvicorn.dev/" class="external-link" target="_blank">Uvicorn</a>: ein hochperformanter ASGI-Server.
|
||||
* <a href="https://hypercorn.readthedocs.io/" class="external-link" target="_blank">Hypercorn</a>: ein ASGI-Server, der unter anderem kompatibel mit HTTP/2 und Trio ist.
|
||||
* <a href="https://github.com/django/daphne" class="external-link" target="_blank">Daphne</a>: der für Django Channels entwickelte ASGI-Server.
|
||||
* <a href="https://github.com/emmett-framework/granian" class="external-link" target="_blank">Granian</a>: Ein Rust HTTP-Server für Python-Anwendungen.
|
||||
|
||||
@@ -11,7 +11,7 @@ Schauen wir uns die Deployment-Konzepte von früher noch einmal an:
|
||||
|
||||
Bis zu diesem Punkt, in allen Tutorials in der Dokumentation, haben Sie wahrscheinlich ein **Serverprogramm** ausgeführt, zum Beispiel mit dem `fastapi`-Befehl, der Uvicorn startet, und einen **einzelnen Prozess** ausführt.
|
||||
|
||||
Wenn Sie Anwendungen bereitstellen, möchten Sie wahrscheinlich eine gewisse **Replikation von Prozessen**, um **mehrere Kerne** zu nutzen und mehr <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> bearbeiten zu können.
|
||||
Wenn Sie Anwendungen deployen, möchten Sie wahrscheinlich eine gewisse **Replikation von Prozessen**, um **mehrere Kerne** zu nutzen und mehr <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> bearbeiten zu können.
|
||||
|
||||
Wie Sie im vorherigen Kapitel über [Deployment-Konzepte](concepts.md){.internal-link target=_blank} gesehen haben, gibt es mehrere Strategien, die Sie anwenden können.
|
||||
|
||||
@@ -119,7 +119,7 @@ In der Liste der Deployment-Konzepte von oben würde die Verwendung von Workern
|
||||
|
||||
* **Sicherheit – HTTPS**
|
||||
* **Beim Hochfahren ausführen**
|
||||
* **Neustarts**
|
||||
* ***Neustarts***
|
||||
* Replikation (die Anzahl der laufenden Prozesse)
|
||||
* **Arbeitsspeicher**
|
||||
* **Schritte vor dem Start**
|
||||
|
||||
@@ -52,7 +52,7 @@ FastAPI CLI nimmt den Pfad zu Ihrem Python-Programm (z. B. `main.py`), erkennt a
|
||||
|
||||
Für die Produktion würden Sie stattdessen `fastapi run` verwenden. 🚀
|
||||
|
||||
Intern verwendet das **FastAPI CLI** <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a>, einen leistungsstarken, produktionsreifen, ASGI-Server. 😎
|
||||
Intern verwendet das **FastAPI CLI** <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>, einen leistungsstarken, produktionsreifen, ASGI-Server. 😎
|
||||
|
||||
## `fastapi dev` { #fastapi-dev }
|
||||
|
||||
@@ -66,7 +66,7 @@ Das Ausführen von `fastapi run` startet FastAPI standardmäßig im Produktionsm
|
||||
|
||||
Standardmäßig ist **Autoreload** deaktiviert. Es horcht auch auf der IP-Adresse `0.0.0.0`, was alle verfügbaren IP-Adressen bedeutet, so wird es öffentlich zugänglich für jeden, der mit der Maschine kommunizieren kann. So würden Sie es normalerweise in der Produktion ausführen, beispielsweise in einem Container.
|
||||
|
||||
In den meisten Fällen würden (und sollten) Sie einen „Terminierungsproxy“ haben, der HTTPS für Sie verwaltet. Dies hängt davon ab, wie Sie Ihre Anwendung bereitstellen. Ihr Anbieter könnte dies für Sie erledigen, oder Sie müssen es selbst einrichten.
|
||||
In den meisten Fällen würden (und sollten) Sie einen „Terminierungsproxy“ haben, der HTTPS für Sie verwaltet. Dies hängt davon ab, wie Sie Ihre Anwendung deployen. Ihr Anbieter könnte dies für Sie erledigen, oder Sie müssen es selbst einrichten.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
### Basiert auf offenen Standards { #based-on-open-standards }
|
||||
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> für die Erstellung von APIs, inklusive Deklarationen von <abbr title="auch bekannt als: Endpunkte, Routen">Pfad</abbr>-<abbr title="auch bekannt als HTTP-Methoden, wie POST, GET, PUT, DELETE">Operationen</abbr>, Parametern, <abbr title="Anfragekörper">Requestbodys</abbr>, Sicherheit, usw.
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> für die Erstellung von APIs, inklusive Deklarationen von <dfn title="auch bekannt als: Endpunkte, Routen">Pfad</dfn>-<dfn title="auch bekannt als HTTP-Methoden, wie POST, GET, PUT, DELETE">Operationen</dfn>, Parametern, <abbr title="Anfragekörper">Requestbodys</abbr>, Sicherheit, usw.
|
||||
* Automatische Dokumentation der Datenmodelle mit <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (da OpenAPI selbst auf JSON Schema basiert).
|
||||
* Um diese Standards herum entworfen, nach sorgfältigem Studium. Statt einer nachträglichen Schicht darüber.
|
||||
* Dies ermöglicht auch automatische **Client-Code-Generierung** in vielen Sprachen.
|
||||
@@ -136,7 +136,7 @@ Alles als wiederverwendbare Tools und Komponenten gebaut, die einfach in Ihre Sy
|
||||
|
||||
### Dependency Injection { #dependency-injection }
|
||||
|
||||
FastAPI enthält ein extrem einfach zu verwendendes, aber extrem mächtiges <abbr title='auch bekannt als „Komponenten“, „Resourcen“, „Dienste“, „Dienstanbieter“'><strong>Dependency Injection</strong></abbr> System.
|
||||
FastAPI enthält ein extrem einfach zu verwendendes, aber extrem mächtiges <dfn title='auch bekannt als: Komponenten, Ressourcen, Dienste, Dienstanbieter'><strong>Dependency Injection</strong></dfn> System.
|
||||
|
||||
* Selbst Abhängigkeiten können Abhängigkeiten haben, woraus eine Hierarchie oder ein **„Graph“ von Abhängigkeiten** entsteht.
|
||||
* Alles **automatisch gehandhabt** durch das Framework.
|
||||
@@ -153,13 +153,13 @@ Jede Integration wurde so entworfen, dass sie so einfach zu nutzen ist (mit Abh
|
||||
|
||||
### Getestet { #tested }
|
||||
|
||||
* 100 % <abbr title="Der Prozentsatz an Code, der automatisch getestet wird">Testabdeckung</abbr>.
|
||||
* 100 % <abbr title="Python-Typannotationen, mit denen Ihr Editor und andere externe Werkzeuge Sie besser unterstützen können">Typen annotiert</abbr>.
|
||||
* 100 % <dfn title="Der Prozentsatz an Code, der automatisch getestet wird">Testabdeckung</dfn>.
|
||||
* 100 % <dfn title="Python-Typannotationen, mit denen Ihr Editor und andere externe Werkzeuge Sie besser unterstützen können">Typen annotiert</dfn>.
|
||||
* Verwendet in Produktionsanwendungen.
|
||||
|
||||
## Starlette Merkmale { #starlette-features }
|
||||
|
||||
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://www.starlette.io/" class="external-link" target="_blank"><strong>Starlette</strong></a>. Das bedeutet, wenn Sie eigenen Starlette Quellcode haben, funktioniert der.
|
||||
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://www.starlette.dev/" class="external-link" target="_blank"><strong>Starlette</strong></a>. Das bedeutet, wenn Sie eigenen Starlette Quellcode haben, funktioniert der.
|
||||
|
||||
`FastAPI` ist tatsächlich eine Unterklasse von `Starlette`. Wenn Sie also bereits Starlette kennen oder benutzen, das meiste funktioniert genau so.
|
||||
|
||||
@@ -179,7 +179,7 @@ Mit **FastAPI** bekommen Sie alles von **Starlette** (da FastAPI nur Starlette a
|
||||
|
||||
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://docs.pydantic.dev/" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Das bedeutet, wenn Sie eigenen Pydantic Quellcode haben, funktioniert der.
|
||||
|
||||
Inklusive externer Bibliotheken, die auf Pydantic basieren, wie <abbr title="Object-Relational Mapper – Objektrelationaler Abbilder">ORM</abbr>s, <abbr title="Object-Document Mapper – Objekt-Dokument-Abbilder">ODM</abbr>s für Datenbanken.
|
||||
Inklusive externer Bibliotheken, die auf Pydantic basieren, wie <abbr title="Object-Relational Mapper - Objektrelationaler Mapper">ORM</abbr>s, <abbr title="Object-Document Mapper - Objekt-Dokument-Mapper">ODM</abbr>s für Datenbanken.
|
||||
|
||||
Daher können Sie in vielen Fällen das Objekt eines Requests **direkt zur Datenbank** schicken, weil alles automatisch validiert wird.
|
||||
|
||||
@@ -190,7 +190,7 @@ Mit **FastAPI** bekommen Sie alle Funktionen von **Pydantic** (da FastAPI für d
|
||||
* **Kein Kopfzerbrechen**:
|
||||
* Keine neue Schemadefinition-Mikrosprache zu lernen.
|
||||
* Wenn Sie Pythons Typen kennen, wissen Sie, wie man Pydantic verwendet.
|
||||
* Gutes Zusammenspiel mit Ihrer/Ihrem **<abbr title="Integrated Development Environment – Integrierte Entwicklungsumgebung: Ähnlich einem Code-Editor">IDE</abbr>/<abbr title="Ein Programm, das Fehler im Quellcode sucht">Linter</abbr>/Gehirn**:
|
||||
* Gutes Zusammenspiel mit Ihrer/Ihrem **<abbr title="Integrated Development Environment - Integrierte Entwicklungsumgebung: Ähnlich einem Code-Editor">IDE</abbr>/<dfn title="Ein Programm, das Fehler im Quellcode sucht">Linter</dfn>/Gehirn**:
|
||||
* Weil Pydantics Datenstrukturen einfach nur Instanzen ihrer definierten Klassen sind; Autovervollständigung, Linting, mypy und Ihre Intuition sollten alle einwandfrei mit Ihren validierten Daten funktionieren.
|
||||
* Validierung von **komplexen Strukturen**:
|
||||
* Benutzung von hierarchischen Pydantic-Modellen, Python-`typing`s `List` und `Dict`, etc.
|
||||
|
||||
@@ -58,7 +58,7 @@ Nachdem ich mehrere Alternativen getestet hatte, entschied ich, dass ich <a href
|
||||
|
||||
Dann habe ich zu dessen Code beigetragen, um es vollständig mit JSON Schema kompatibel zu machen, und so verschiedene Möglichkeiten zum Definieren von einschränkenden Deklarationen (Constraints) zu unterstützen, und die Editorunterstützung (Typprüfungen, Codevervollständigung) zu verbessern, basierend auf den Tests in mehreren Editoren.
|
||||
|
||||
Während der Entwicklung habe ich auch zu <a href="https://www.starlette.io/" class="external-link" target="_blank">**Starlette**</a> beigetragen, der anderen Schlüsselanforderung.
|
||||
Während der Entwicklung habe ich auch zu <a href="https://www.starlette.dev/" class="external-link" target="_blank">**Starlette**</a> beigetragen, die andere Schlüsselanforderung.
|
||||
|
||||
## Entwicklung { #development }
|
||||
|
||||
|
||||
17
docs/de/docs/how-to/authentication-error-status-code.md
Normal file
17
docs/de/docs/how-to/authentication-error-status-code.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Alte 403-Authentifizierungsfehler-Statuscodes verwenden { #use-old-403-authentication-error-status-codes }
|
||||
|
||||
Vor FastAPI-Version `0.122.0` verwendeten die integrierten Sicherheits-Utilities den HTTP-Statuscode `403 Forbidden`, wenn sie dem Client nach einer fehlgeschlagenen Authentifizierung einen Fehler zurückgaben.
|
||||
|
||||
Ab FastAPI-Version `0.122.0` verwenden sie den passenderen HTTP-Statuscode `401 Unauthorized` und geben in der Response einen sinnvollen `WWW-Authenticate`-Header zurück, gemäß den HTTP-Spezifikationen, <a href="https://datatracker.ietf.org/doc/html/rfc7235#section-3.1" class="external-link" target="_blank">RFC 7235</a>, <a href="https://datatracker.ietf.org/doc/html/rfc9110#name-401-unauthorized" class="external-link" target="_blank">RFC 9110</a>.
|
||||
|
||||
Aber falls Ihre Clients aus irgendeinem Grund vom alten Verhalten abhängen, können Sie darauf zurückgreifen, indem Sie in Ihren Sicherheitsklassen die Methode `make_not_authenticated_error` überschreiben.
|
||||
|
||||
Sie können beispielsweise eine Unterklasse von `HTTPBearer` erstellen, die einen Fehler `403 Forbidden` zurückgibt, statt des Default-`401 Unauthorized`-Fehlers:
|
||||
|
||||
{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Beachten Sie, dass die Funktion die Exception-Instanz zurückgibt; sie wirft sie nicht. Das Werfen erfolgt im restlichen internen Code.
|
||||
|
||||
///
|
||||
@@ -17,7 +17,7 @@ Wenn Sie Ihre API sichern möchten, gibt es mehrere bessere Dinge, die Sie tun k
|
||||
* Stellen Sie sicher, dass Sie über gut definierte Pydantic-Modelle für Ihre <abbr title="Anfragekörper">Requestbodys</abbr> und <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Responses</abbr> verfügen.
|
||||
* Konfigurieren Sie alle erforderlichen Berechtigungen und Rollen mithilfe von Abhängigkeiten.
|
||||
* Speichern Sie niemals Klartext-Passwörter, sondern nur Passwort-Hashes.
|
||||
* Implementieren und verwenden Sie gängige kryptografische Tools wie Passlib und JWT-Tokens, usw.
|
||||
* Implementieren und verwenden Sie gängige kryptografische Tools wie pwdlib und JWT-Tokens, usw.
|
||||
* Fügen Sie bei Bedarf detailliertere Berechtigungskontrollen mit OAuth2-Scopes hinzu.
|
||||
* ... usw.
|
||||
|
||||
@@ -29,7 +29,7 @@ Sie können problemlos dieselben Pydantic-Einstellungen verwenden, um Ihre gener
|
||||
|
||||
Zum Beispiel:
|
||||
|
||||
{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *}
|
||||
{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
|
||||
|
||||
Hier deklarieren wir die Einstellung `openapi_url` mit dem gleichen Defaultwert `"/openapi.json"`.
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Ohne Änderung der Einstellungen ist die Syntaxhervorhebung standardmäßig akti
|
||||
|
||||
Sie können sie jedoch deaktivieren, indem Sie `syntaxHighlight` auf `False` setzen:
|
||||
|
||||
{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *}
|
||||
{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *}
|
||||
|
||||
... und dann zeigt die Swagger-Oberfläche die Syntaxhervorhebung nicht mehr an:
|
||||
|
||||
@@ -28,7 +28,7 @@ Sie können sie jedoch deaktivieren, indem Sie `syntaxHighlight` auf `False` set
|
||||
|
||||
Auf die gleiche Weise könnten Sie das Theme der Syntaxhervorhebung mit dem Schlüssel `"syntaxHighlight.theme"` festlegen (beachten Sie, dass er einen Punkt in der Mitte hat):
|
||||
|
||||
{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *}
|
||||
{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *}
|
||||
|
||||
Obige Konfiguration würde das Theme für die Farbe der Syntaxhervorhebung ändern:
|
||||
|
||||
@@ -40,13 +40,13 @@ FastAPI enthält einige Defaultkonfigurationsparameter, die für die meisten Anw
|
||||
|
||||
Es umfasst die folgenden Defaultkonfigurationen:
|
||||
|
||||
{* ../../fastapi/openapi/docs.py ln[8:23] hl[17:23] *}
|
||||
{* ../../fastapi/openapi/docs.py ln[9:24] hl[18:24] *}
|
||||
|
||||
Sie können jede davon überschreiben, indem Sie im Argument `swagger_ui_parameters` einen anderen Wert festlegen.
|
||||
|
||||
Um beispielsweise `deepLinking` zu deaktivieren, könnten Sie folgende Einstellungen an `swagger_ui_parameters` übergeben:
|
||||
|
||||
{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
|
||||
{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *}
|
||||
|
||||
## Andere Parameter der Swagger-Oberfläche { #other-swagger-ui-parameters }
|
||||
|
||||
|
||||
@@ -18,7 +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`:
|
||||
|
||||
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *}
|
||||
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *}
|
||||
|
||||
### Die benutzerdefinierten Dokumentationen hinzufügen { #include-the-custom-docs }
|
||||
|
||||
@@ -34,7 +34,7 @@ Sie können die internen Funktionen von FastAPI wiederverwenden, um die HTML-Sei
|
||||
|
||||
Und ähnlich für ReDoc ...
|
||||
|
||||
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *}
|
||||
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -50,7 +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*:
|
||||
|
||||
{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *}
|
||||
{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *}
|
||||
|
||||
### Es testen { #test-it }
|
||||
|
||||
@@ -118,7 +118,7 @@ Danach könnte Ihre Dateistruktur wie folgt aussehen:
|
||||
* Importieren Sie `StaticFiles`.
|
||||
* „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
|
||||
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *}
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *}
|
||||
|
||||
### Die statischen Dateien testen { #test-the-static-files }
|
||||
|
||||
@@ -144,7 +144,7 @@ Wie bei der Verwendung eines benutzerdefinierten CDN besteht der erste Schritt d
|
||||
|
||||
Um sie zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
|
||||
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *}
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *}
|
||||
|
||||
### Die benutzerdefinierten Dokumentationen für statische Dateien hinzufügen { #include-the-custom-docs-for-static-files }
|
||||
|
||||
@@ -160,7 +160,7 @@ Auch hier können Sie die internen Funktionen von FastAPI wiederverwenden, um di
|
||||
|
||||
Und ähnlich für ReDoc ...
|
||||
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *}
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -176,7 +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*:
|
||||
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *}
|
||||
{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *}
|
||||
|
||||
### Benutzeroberfläche mit statischen Dateien testen { #test-static-files-ui }
|
||||
|
||||
|
||||
@@ -42,7 +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.
|
||||
|
||||
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[8:15] *}
|
||||
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[9:16] *}
|
||||
|
||||
### Eine benutzerdefinierte `GzipRoute`-Klasse erstellen { #create-a-custom-gziproute-class }
|
||||
|
||||
@@ -54,7 +54,7 @@ Diese Methode gibt eine Funktion zurück. Und diese Funktion empfängt einen <ab
|
||||
|
||||
Hier verwenden wir sie, um aus dem ursprünglichen Request einen `GzipRequest` zu erstellen.
|
||||
|
||||
{* ../../docs_src/custom_request_and_route/tutorial001.py hl[18:26] *}
|
||||
{* ../../docs_src/custom_request_and_route/tutorial001_an_py310.py hl[19:27] *}
|
||||
|
||||
/// note | Technische Details
|
||||
|
||||
@@ -66,7 +66,7 @@ Das `scope`-`dict` und die `receive`-Funktion sind beide Teil der ASGI-Spezifika
|
||||
|
||||
Und diese beiden Dinge, `scope` und `receive`, werden benötigt, um eine neue `Request`-Instanz zu erstellen.
|
||||
|
||||
Um mehr über den `Request` zu erfahren, schauen Sie sich <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">Starlettes Dokumentation zu Requests</a> an.
|
||||
Um mehr über den `Request` zu erfahren, schauen Sie sich <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">Starlettes Dokumentation zu Requests</a> an.
|
||||
|
||||
///
|
||||
|
||||
@@ -92,18 +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:
|
||||
|
||||
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[13,15] *}
|
||||
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[14,16] *}
|
||||
|
||||
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:
|
||||
|
||||
{* ../../docs_src/custom_request_and_route/tutorial002.py hl[16:18] *}
|
||||
{* ../../docs_src/custom_request_and_route/tutorial002_an_py310.py hl[17:19] *}
|
||||
|
||||
## Benutzerdefinierte `APIRoute`-Klasse in einem Router { #custom-apiroute-class-in-a-router }
|
||||
|
||||
Sie können auch den Parameter `route_class` eines `APIRouter` festlegen:
|
||||
|
||||
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[26] *}
|
||||
{* ../../docs_src/custom_request_and_route/tutorial003_py310.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:
|
||||
|
||||
{* ../../docs_src/custom_request_and_route/tutorial003.py hl[13:20] *}
|
||||
{* ../../docs_src/custom_request_and_route/tutorial003_py310.py hl[13:20] *}
|
||||
|
||||
@@ -43,19 +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:
|
||||
|
||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *}
|
||||
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *}
|
||||
|
||||
### Das OpenAPI-Schema generieren { #generate-the-openapi-schema }
|
||||
|
||||
Verwenden Sie dann dieselbe Hilfsfunktion, um das OpenAPI-Schema innerhalb einer `custom_openapi()`-Funktion zu generieren:
|
||||
|
||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *}
|
||||
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *}
|
||||
|
||||
### Das OpenAPI-Schema ändern { #modify-the-openapi-schema }
|
||||
|
||||
Jetzt können Sie die ReDoc-Erweiterung hinzufügen und dem `info`-„Objekt“ im OpenAPI-Schema ein benutzerdefiniertes `x-logo` hinzufügen:
|
||||
|
||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *}
|
||||
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *}
|
||||
|
||||
### Zwischenspeichern des OpenAPI-Schemas { #cache-the-openapi-schema }
|
||||
|
||||
@@ -65,13 +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 <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> verwendet.
|
||||
|
||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *}
|
||||
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
|
||||
|
||||
### Die Methode überschreiben { #override-the-method }
|
||||
|
||||
Jetzt können Sie die Methode `.openapi()` durch Ihre neue Funktion ersetzen.
|
||||
|
||||
{* ../../docs_src/extending_openapi/tutorial001.py hl[29] *}
|
||||
{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
|
||||
|
||||
### Es testen { #check-it }
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ Abhängig von Ihrem Anwendungsfall könnten Sie eine andere Bibliothek vorziehen
|
||||
|
||||
Hier ist eine kleine Vorschau, wie Sie Strawberry mit FastAPI integrieren können:
|
||||
|
||||
{* ../../docs_src/graphql/tutorial001.py hl[3,22,25] *}
|
||||
{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
|
||||
|
||||
Weitere Informationen zu Strawberry finden Sie in der <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry-Dokumentation</a>.
|
||||
|
||||
|
||||
135
docs/de/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md
Normal file
135
docs/de/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md
Normal file
@@ -0,0 +1,135 @@
|
||||
# Von Pydantic v1 zu Pydantic v2 migrieren { #migrate-from-pydantic-v1-to-pydantic-v2 }
|
||||
|
||||
Wenn Sie eine ältere FastAPI-App haben, nutzen Sie möglicherweise Pydantic Version 1.
|
||||
|
||||
FastAPI Version 0.100.0 unterstützte sowohl Pydantic v1 als auch v2. Es verwendete, was auch immer Sie installiert hatten.
|
||||
|
||||
FastAPI Version 0.119.0 führte eine teilweise Unterstützung für Pydantic v1 innerhalb von Pydantic v2 (als `pydantic.v1`) ein, um die Migration zu v2 zu erleichtern.
|
||||
|
||||
FastAPI 0.126.0 entfernte die Unterstützung für Pydantic v1, während `pydantic.v1` noch eine Weile unterstützt wurde.
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
Das Pydantic-Team hat die Unterstützung für Pydantic v1 in den neuesten Python-Versionen eingestellt, beginnend mit **Python 3.14**.
|
||||
|
||||
Dies schließt `pydantic.v1` ein, das unter Python 3.14 und höher nicht mehr unterstützt wird.
|
||||
|
||||
Wenn Sie die neuesten Features von Python nutzen möchten, müssen Sie sicherstellen, dass Sie Pydantic v2 verwenden.
|
||||
|
||||
///
|
||||
|
||||
Wenn Sie eine ältere FastAPI-App mit Pydantic v1 haben, zeige ich Ihnen hier, wie Sie sie zu Pydantic v2 migrieren, und die **Features in FastAPI 0.119.0**, die Ihnen bei einer schrittweisen Migration helfen.
|
||||
|
||||
## Offizieller Leitfaden { #official-guide }
|
||||
|
||||
Pydantic hat einen offiziellen <a href="https://docs.pydantic.dev/latest/migration/" class="external-link" target="_blank">Migrationsleitfaden</a> von v1 zu v2.
|
||||
|
||||
Er enthält auch, was sich geändert hat, wie Validierungen nun korrekter und strikter sind, mögliche Stolpersteine, usw.
|
||||
|
||||
Sie können ihn lesen, um besser zu verstehen, was sich geändert hat.
|
||||
|
||||
## Tests { #tests }
|
||||
|
||||
Stellen Sie sicher, dass Sie [Tests](../tutorial/testing.md){.internal-link target=_blank} für Ihre App haben und diese in Continuous Integration (CI) ausführen.
|
||||
|
||||
Auf diese Weise können Sie das Update durchführen und sicherstellen, dass weiterhin alles wie erwartet funktioniert.
|
||||
|
||||
## `bump-pydantic` { #bump-pydantic }
|
||||
|
||||
In vielen Fällen, wenn Sie reguläre Pydantic-Modelle ohne Anpassungen verwenden, können Sie den Großteil des Prozesses der Migration von Pydantic v1 auf Pydantic v2 automatisieren.
|
||||
|
||||
Sie können <a href="https://github.com/pydantic/bump-pydantic" class="external-link" target="_blank">`bump-pydantic`</a> vom selben Pydantic-Team verwenden.
|
||||
|
||||
Dieses Tool hilft Ihnen, den Großteil des zu ändernden Codes automatisch anzupassen.
|
||||
|
||||
Danach können Sie die Tests ausführen und prüfen, ob alles funktioniert. Falls ja, sind Sie fertig. 😎
|
||||
|
||||
## Pydantic v1 in v2 { #pydantic-v1-in-v2 }
|
||||
|
||||
Pydantic v2 enthält alles aus Pydantic v1 als Untermodul `pydantic.v1`. Dies wird aber in Versionen oberhalb von Python 3.13 nicht mehr unterstützt.
|
||||
|
||||
Das bedeutet, Sie können die neueste Version von Pydantic v2 installieren und die alten Pydantic‑v1‑Komponenten aus diesem Untermodul importieren und verwenden, als hätten Sie das alte Pydantic v1 installiert.
|
||||
|
||||
{* ../../docs_src/pydantic_v1_in_v2/tutorial001_an_py310.py hl[1,4] *}
|
||||
|
||||
### FastAPI-Unterstützung für Pydantic v1 in v2 { #fastapi-support-for-pydantic-v1-in-v2 }
|
||||
|
||||
Seit FastAPI 0.119.0 gibt es außerdem eine teilweise Unterstützung für Pydantic v1 innerhalb von Pydantic v2, um die Migration auf v2 zu erleichtern.
|
||||
|
||||
Sie könnten also Pydantic auf die neueste Version 2 aktualisieren und die Importe so ändern, dass das Untermodul `pydantic.v1` verwendet wird, und in vielen Fällen würde es einfach funktionieren.
|
||||
|
||||
{* ../../docs_src/pydantic_v1_in_v2/tutorial002_an_py310.py hl[2,5,15] *}
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
Beachten Sie, dass, da das Pydantic‑Team Pydantic v1 in neueren Python‑Versionen nicht mehr unterstützt, beginnend mit Python 3.14, auch die Verwendung von `pydantic.v1` unter Python 3.14 und höher nicht unterstützt wird.
|
||||
|
||||
///
|
||||
|
||||
### Pydantic v1 und v2 in derselben App { #pydantic-v1-and-v2-on-the-same-app }
|
||||
|
||||
Es wird von Pydantic **nicht unterstützt**, dass ein Pydantic‑v2‑Modell Felder hat, die als Pydantic‑v1‑Modelle definiert sind, und umgekehrt.
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "❌ Nicht unterstützt"
|
||||
direction TB
|
||||
subgraph V2["Pydantic-v2-Modell"]
|
||||
V1Field["Pydantic-v1-Modell"]
|
||||
end
|
||||
subgraph V1["Pydantic-v1-Modell"]
|
||||
V2Field["Pydantic-v2-Modell"]
|
||||
end
|
||||
end
|
||||
|
||||
style V2 fill:#f9fff3
|
||||
style V1 fill:#fff6f0
|
||||
style V1Field fill:#fff6f0
|
||||
style V2Field fill:#f9fff3
|
||||
```
|
||||
|
||||
... aber Sie können getrennte Modelle, die Pydantic v1 bzw. v2 nutzen, in derselben App verwenden.
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "✅ Unterstützt"
|
||||
direction TB
|
||||
subgraph V2["Pydantic-v2-Modell"]
|
||||
V2Field["Pydantic-v2-Modell"]
|
||||
end
|
||||
subgraph V1["Pydantic-v1-Modell"]
|
||||
V1Field["Pydantic-v1-Modell"]
|
||||
end
|
||||
end
|
||||
|
||||
style V2 fill:#f9fff3
|
||||
style V1 fill:#fff6f0
|
||||
style V1Field fill:#fff6f0
|
||||
style V2Field fill:#f9fff3
|
||||
```
|
||||
|
||||
In einigen Fällen ist es sogar möglich, sowohl Pydantic‑v1‑ als auch Pydantic‑v2‑Modelle in derselben **Pfadoperation** Ihrer FastAPI‑App zu verwenden:
|
||||
|
||||
{* ../../docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py hl[2:3,6,12,21:22] *}
|
||||
|
||||
Im obigen Beispiel ist das Eingabemodell ein Pydantic‑v1‑Modell, und das Ausgabemodell (definiert in `response_model=ItemV2`) ist ein Pydantic‑v2‑Modell.
|
||||
|
||||
### Pydantic v1 Parameter { #pydantic-v1-parameters }
|
||||
|
||||
Wenn Sie einige der FastAPI-spezifischen Tools für Parameter wie `Body`, `Query`, `Form`, usw. zusammen mit Pydantic‑v1‑Modellen verwenden müssen, können Sie die aus `fastapi.temp_pydantic_v1_params` importieren, während Sie die Migration zu Pydantic v2 abschließen:
|
||||
|
||||
{* ../../docs_src/pydantic_v1_in_v2/tutorial004_an_py310.py hl[4,18] *}
|
||||
|
||||
### In Schritten migrieren { #migrate-in-steps }
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Probieren Sie zuerst `bump-pydantic` aus. Wenn Ihre Tests erfolgreich sind und das funktioniert, sind Sie mit einem einzigen Befehl fertig. ✨
|
||||
|
||||
///
|
||||
|
||||
Wenn `bump-pydantic` für Ihren Anwendungsfall nicht funktioniert, können Sie die Unterstützung für Pydantic‑v1‑ und Pydantic‑v2‑Modelle in derselben App nutzen, um die Migration zu Pydantic v2 schrittweise durchzuführen.
|
||||
|
||||
Sie könnten zuerst Pydantic auf die neueste Version 2 aktualisieren und die Importe so ändern, dass für all Ihre Modelle `pydantic.v1` verwendet wird.
|
||||
|
||||
Anschließend können Sie beginnen, Ihre Modelle gruppenweise von Pydantic v1 auf v2 zu migrieren – in kleinen, schrittweisen Etappen. 🚶
|
||||
@@ -1,6 +1,6 @@
|
||||
# Separate OpenAPI-Schemas für Eingabe und Ausgabe oder nicht { #separate-openapi-schemas-for-input-and-output-or-not }
|
||||
|
||||
Bei Verwendung von **Pydantic v2** ist die generierte OpenAPI etwas genauer und **korrekter** als zuvor. 😎
|
||||
Seit der Veröffentlichung von **Pydantic v2** ist die generierte OpenAPI etwas genauer und **korrekter** als zuvor. 😎
|
||||
|
||||
Tatsächlich gibt es in einigen Fällen sogar **zwei JSON-Schemas** in OpenAPI für dasselbe Pydantic-Modell, für Eingabe und Ausgabe, je nachdem, ob sie **Defaultwerte** haben.
|
||||
|
||||
@@ -100,5 +100,3 @@ Und jetzt wird es ein einziges Schema für die Eingabe und Ausgabe des Modells g
|
||||
<div class="screenshot">
|
||||
<img src="/img/tutorial/separate-openapi-schemas/image05.png">
|
||||
</div>
|
||||
|
||||
Dies ist das gleiche Verhalten wie in Pydantic v1. 🤓
|
||||
|
||||
@@ -40,26 +40,32 @@ Seine Schlüssel-Merkmale sind:
|
||||
* **Schnell**: Sehr hohe Performanz, auf Augenhöhe mit **NodeJS** und **Go** (dank Starlette und Pydantic). [Eines der schnellsten verfügbaren Python-Frameworks](#performance).
|
||||
* **Schnell zu entwickeln**: Erhöhen Sie die Geschwindigkeit bei der Entwicklung von Features um etwa 200 % bis 300 %. *
|
||||
* **Weniger Bugs**: Verringern Sie die von Menschen (Entwicklern) verursachten Fehler um etwa 40 %. *
|
||||
* **Intuitiv**: Hervorragende Editor-Unterstützung. <abbr title="auch bekannt als Auto-Complete, Autovervollständigung, IntelliSense">Code-Vervollständigung</abbr> überall. Weniger Zeit mit Debuggen verbringen.
|
||||
* **Intuitiv**: Hervorragende Editor-Unterstützung. <dfn title="auch bekannt als Auto-Complete, Autovervollständigung, IntelliSense">Code-Vervollständigung</dfn> überall. Weniger Zeit mit Debuggen verbringen.
|
||||
* **Einfach**: So konzipiert, dass es einfach zu benutzen und zu erlernen ist. Weniger Zeit mit dem Lesen von Dokumentation verbringen.
|
||||
* **Kurz**: Minimieren Sie die Verdoppelung von Code. Mehrere Features aus jeder Parameterdeklaration. Weniger Bugs.
|
||||
* **Robust**: Erhalten Sie produktionsreifen Code. Mit automatischer, interaktiver Dokumentation.
|
||||
* **Standards-basiert**: Basierend auf (und vollständig kompatibel mit) den offenen Standards für APIs: <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank">OpenAPI</a> (früher bekannt als Swagger) und <a href="https://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
||||
|
||||
<small>* Schätzung basierend auf Tests in einem internen Entwicklungsteam, das Produktionsanwendungen erstellt.</small>
|
||||
<small>* Schätzung basierend auf Tests, die von einem internen Entwicklungsteam durchgeführt wurden, das Produktionsanwendungen erstellt.</small>
|
||||
|
||||
## Sponsoren { #sponsors }
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
{% if sponsors %}
|
||||
### Keystone-Sponsor { #keystone-sponsor }
|
||||
|
||||
{% for sponsor in sponsors.keystone -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor -%}
|
||||
|
||||
### Gold- und Silber-Sponsoren { #gold-and-silver-sponsors }
|
||||
|
||||
{% for sponsor in sponsors.gold -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor -%}
|
||||
{%- for sponsor in sponsors.silver -%}
|
||||
<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<!-- /sponsors -->
|
||||
|
||||
@@ -111,6 +117,12 @@ Seine Schlüssel-Merkmale sind:
|
||||
|
||||
---
|
||||
|
||||
## FastAPI Mini-Dokumentarfilm { #fastapi-mini-documentary }
|
||||
|
||||
Es gibt einen <a href="https://www.youtube.com/watch?v=mpR8ngthqiE" class="external-link" target="_blank">FastAPI-Mini-Dokumentarfilm</a>, veröffentlicht Ende 2025, Sie können ihn online ansehen:
|
||||
|
||||
<a href="https://www.youtube.com/watch?v=mpR8ngthqiE" target="_blank"><img src="https://fastapi.tiangolo.com/img/fastapi-documentary.jpg" alt="FastAPI Mini-Dokumentarfilm"></a>
|
||||
|
||||
## **Typer**, das FastAPI der 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>
|
||||
@@ -123,7 +135,7 @@ Wenn Sie eine <abbr title="Command Line Interface – Kommandozeilen-Schnittstel
|
||||
|
||||
FastAPI steht auf den Schultern von Giganten:
|
||||
|
||||
* <a href="https://www.starlette.io/" class="external-link" target="_blank">Starlette</a> für die Webanteile.
|
||||
* <a href="https://www.starlette.dev/" class="external-link" target="_blank">Starlette</a> für die Webanteile.
|
||||
* <a href="https://docs.pydantic.dev/" class="external-link" target="_blank">Pydantic</a> für die Datenanteile.
|
||||
|
||||
## Installation { #installation }
|
||||
@@ -149,8 +161,6 @@ $ pip install "fastapi[standard]"
|
||||
Erstellen Sie eine Datei `main.py` mit:
|
||||
|
||||
```Python
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
@@ -162,7 +172,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
def read_item(item_id: int, q: str | None = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -171,9 +181,7 @@ def read_item(item_id: int, q: Union[str, None] = None):
|
||||
|
||||
Wenn Ihr Code `async` / `await` verwendet, benutzen Sie `async def`:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Union
|
||||
|
||||
```Python hl_lines="7 12"
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
@@ -185,7 +193,7 @@ async def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||
async def read_item(item_id: int, q: str | None = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -227,9 +235,9 @@ INFO: Application startup complete.
|
||||
</div>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Was der Befehl <code>fastapi dev main.py</code> macht ...</summary>
|
||||
<summary>Über den Befehl <code>fastapi dev main.py</code> ...</summary>
|
||||
|
||||
Der Befehl `fastapi dev` liest Ihre `main.py`-Datei, erkennt die **FastAPI**-App darin und startet einen Server mit <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a>.
|
||||
Der Befehl `fastapi dev` liest Ihre `main.py`-Datei, erkennt die **FastAPI**-App darin und startet einen Server mit <a href="https://www.uvicorn.dev" class="external-link" target="_blank">Uvicorn</a>.
|
||||
|
||||
Standardmäßig wird `fastapi dev` mit aktiviertem Auto-Reload für die lokale Entwicklung gestartet.
|
||||
|
||||
@@ -270,15 +278,13 @@ Sie sehen die alternative automatische Dokumentation (bereitgestellt von <a href
|
||||
|
||||

|
||||
|
||||
## Beispiel Aktualisierung { #example-upgrade }
|
||||
## Beispielaktualisierung { #example-upgrade }
|
||||
|
||||
Ändern Sie jetzt die Datei `main.py`, um den <abbr title="Body – Körper, Inhalt: Der eigentliche Inhalt einer Nachricht, nicht die Metadaten">Body</abbr> eines `PUT`-Requests zu empfangen.
|
||||
|
||||
Deklarieren Sie den Body mit Standard-Python-Typen, dank Pydantic.
|
||||
|
||||
```Python hl_lines="4 9-12 25-27"
|
||||
from typing import Union
|
||||
|
||||
```Python hl_lines="2 7-10 23-25"
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -288,7 +294,7 @@ app = FastAPI()
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: Union[bool, None] = None
|
||||
is_offer: bool | None = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
@@ -297,7 +303,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
def read_item(item_id: int, q: str | None = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
|
||||
|
||||
@@ -320,7 +326,7 @@ Gehen Sie jetzt auf <a href="http://127.0.0.1:8000/docs" class="external-link" t
|
||||
|
||||

|
||||
|
||||
* Klicken Sie dann auf den Button „Execute“, die Benutzeroberfläche wird mit Ihrer API kommunizieren, sendet die Parameter, holt die Ergebnisse und zeigt sie auf dem Bildschirm an:
|
||||
* Klicken Sie dann auf den Button „Execute“, die Benutzeroberfläche wird mit Ihrer API kommunizieren, die Parameter senden, die Ergebnisse erhalten und sie auf dem Bildschirm anzeigen:
|
||||
|
||||

|
||||
|
||||
@@ -357,12 +363,12 @@ item: Item
|
||||
... und mit dieser einen Deklaration erhalten Sie:
|
||||
|
||||
* Editor-Unterstützung, einschließlich:
|
||||
* Code-Vervollständigung.
|
||||
* Vervollständigung.
|
||||
* Typprüfungen.
|
||||
* Validierung von Daten:
|
||||
* Automatische und eindeutige Fehler, wenn die Daten ungültig sind.
|
||||
* Validierung sogar für tief verschachtelte JSON-Objekte.
|
||||
* <abbr title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</abbr> von Eingabedaten: Aus dem Netzwerk kommend, zu Python-Daten und -Typen. Lesen von:
|
||||
* <dfn title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</dfn> von Eingabedaten: Aus dem Netzwerk kommend, zu Python-Daten und -Typen. Lesen von:
|
||||
* JSON.
|
||||
* Pfad-Parametern.
|
||||
* Query-Parametern.
|
||||
@@ -370,7 +376,7 @@ item: Item
|
||||
* Headern.
|
||||
* Formularen.
|
||||
* Dateien.
|
||||
* <abbr title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</abbr> von Ausgabedaten: Konvertierung von Python-Daten und -Typen zu Netzwerkdaten (als JSON):
|
||||
* <dfn title="auch bekannt als: Serialisierung, Parsen, Marshalling">Konvertierung</dfn> von Ausgabedaten: Konvertierung von Python-Daten und -Typen zu Netzwerkdaten (als JSON):
|
||||
* Konvertieren von Python-Typen (`str`, `int`, `float`, `bool`, `list`, usw.).
|
||||
* `datetime`-Objekte.
|
||||
* `UUID`-Objekte.
|
||||
@@ -433,7 +439,7 @@ Für ein vollständigeres Beispiel, mit weiteren Funktionen, siehe das <a href="
|
||||
|
||||
* Deklaration von **Parametern** von anderen verschiedenen Stellen wie: **Header**, **Cookies**, **Formularfelder** und **Dateien**.
|
||||
* Wie man **Validierungs-Constraints** wie `maximum_length` oder `regex` setzt.
|
||||
* Ein sehr leistungsfähiges und einfach zu bedienendes System für **<abbr title="Dependency Injection – Einbringen von Abhängigkeiten: Auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</abbr>**.
|
||||
* Ein sehr leistungsfähiges und einfach zu bedienendes System für **<dfn title="auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</dfn>**.
|
||||
* Sicherheit und Authentifizierung, einschließlich Unterstützung für **OAuth2** mit **JWT-Tokens** und **HTTP Basic** Authentifizierung.
|
||||
* Fortgeschrittenere (aber ebenso einfache) Techniken zur Deklaration **tief verschachtelter JSON-Modelle** (dank Pydantic).
|
||||
* **GraphQL**-Integration mit <a href="https://strawberry.rocks" class="external-link" target="_blank">Strawberry</a> und anderen Bibliotheken.
|
||||
@@ -444,6 +450,58 @@ Für ein vollständigeres Beispiel, mit weiteren Funktionen, siehe das <a href="
|
||||
* **Cookie-Sessions**
|
||||
* ... und mehr.
|
||||
|
||||
### Ihre App deployen (optional) { #deploy-your-app-optional }
|
||||
|
||||
Optional können Sie Ihre FastAPI-App in die <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> deployen, gehen Sie und treten Sie der Warteliste bei, falls noch nicht geschehen. 🚀
|
||||
|
||||
Wenn Sie bereits ein **FastAPI Cloud**-Konto haben (wir haben Sie von der Warteliste eingeladen 😉), können Sie Ihre Anwendung mit einem einzigen Befehl deployen.
|
||||
|
||||
Stellen Sie vor dem Deployen sicher, dass Sie eingeloggt sind:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi login
|
||||
|
||||
You are logged in to FastAPI Cloud 🚀
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Stellen Sie dann Ihre App bereit:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ fastapi deploy
|
||||
|
||||
Deploying to FastAPI Cloud...
|
||||
|
||||
✅ Deployment successful!
|
||||
|
||||
🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Das war’s! Jetzt können Sie unter dieser URL auf Ihre App zugreifen. ✨
|
||||
|
||||
#### Über FastAPI Cloud { #about-fastapi-cloud }
|
||||
|
||||
**<a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a>** wird vom selben Autor und Team hinter **FastAPI** entwickelt.
|
||||
|
||||
Es vereinfacht den Prozess des **Erstellens**, **Deployens** und **Zugreifens** auf eine API mit minimalem Aufwand.
|
||||
|
||||
Es bringt die gleiche **Developer-Experience** beim Erstellen von Apps mit FastAPI auch zum **Deployment** in der Cloud. 🎉
|
||||
|
||||
FastAPI Cloud ist der Hauptsponsor und Finanzierer der *FastAPI and friends* Open-Source-Projekte. ✨
|
||||
|
||||
#### Bei anderen Cloudanbietern deployen { #deploy-to-other-cloud-providers }
|
||||
|
||||
FastAPI ist Open Source und basiert auf Standards. Sie können FastAPI-Apps bei jedem Cloudanbieter Ihrer Wahl deployen.
|
||||
|
||||
Folgen Sie den Anleitungen Ihres Cloudanbieters, um FastAPI-Apps dort bereitzustellen. 🤓
|
||||
|
||||
## Performanz { #performance }
|
||||
|
||||
Unabhängige TechEmpower-Benchmarks zeigen **FastAPI**-Anwendungen, die unter Uvicorn laufen, als <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">eines der schnellsten verfügbaren Python-Frameworks</a>, nur hinter Starlette und Uvicorn selbst (intern von FastAPI verwendet). (*)
|
||||
@@ -466,11 +524,11 @@ Verwendet von Starlette:
|
||||
|
||||
* <a href="https://www.python-httpx.org" target="_blank"><code>httpx</code></a> – erforderlich, wenn Sie den `TestClient` verwenden möchten.
|
||||
* <a href="https://jinja.palletsprojects.com" target="_blank"><code>jinja2</code></a> – erforderlich, wenn Sie die Default-Template-Konfiguration verwenden möchten.
|
||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> – erforderlich, wenn Sie Formulare mittels `request.form()` <abbr title="Konvertieren des Strings, der aus einem HTTP-Request stammt, nach Python-Daten">„parsen“</abbr> möchten.
|
||||
* <a href="https://github.com/Kludex/python-multipart" target="_blank"><code>python-multipart</code></a> – erforderlich, wenn Sie Formulare mittels `request.form()` <dfn title="Konvertieren des Strings, der aus einem HTTP-Request stammt, nach Python-Daten">„parsen“</dfn> möchten.
|
||||
|
||||
Verwendet von FastAPI:
|
||||
|
||||
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> – für den Server, der Ihre Anwendung lädt und bereitstellt. Dies umfasst `uvicorn[standard]`, das einige Abhängigkeiten (z. B. `uvloop`) beinhaltet, die für eine Bereitstellung mit hoher Performanz benötigt werden.
|
||||
* <a href="https://www.uvicorn.dev" target="_blank"><code>uvicorn</code></a> – für den Server, der Ihre Anwendung lädt und bereitstellt. Dies umfasst `uvicorn[standard]`, das einige Abhängigkeiten (z. B. `uvloop`) beinhaltet, die für eine Bereitstellung mit hoher Performanz benötigt werden.
|
||||
* `fastapi-cli[standard]` – um den `fastapi`-Befehl bereitzustellen.
|
||||
* Dies beinhaltet `fastapi-cloud-cli`, das es Ihnen ermöglicht, Ihre FastAPI-Anwendung auf <a href="https://fastapicloud.com" class="external-link" target="_blank">FastAPI Cloud</a> bereitzustellen.
|
||||
|
||||
|
||||
@@ -9,20 +9,20 @@ GitHub-Repository: <a href="https://github.com/tiangolo/full-stack-fastapi-templ
|
||||
## Full Stack FastAPI Template – Technologiestack und Funktionen { #full-stack-fastapi-template-technology-stack-and-features }
|
||||
|
||||
- ⚡ [**FastAPI**](https://fastapi.tiangolo.com/de) für die Python-Backend-API.
|
||||
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) für die Interaktion mit der Python-SQL-Datenbank (ORM).
|
||||
- 🔍 [Pydantic](https://docs.pydantic.dev), verwendet von FastAPI, für die Datenvalidierung und das Einstellungsmanagement.
|
||||
- 💾 [PostgreSQL](https://www.postgresql.org) als SQL-Datenbank.
|
||||
- 🧰 [SQLModel](https://sqlmodel.tiangolo.com) für die Interaktion mit der Python-SQL-Datenbank (ORM).
|
||||
- 🔍 [Pydantic](https://docs.pydantic.dev), verwendet von FastAPI, für die Datenvalidierung und das Einstellungsmanagement.
|
||||
- 💾 [PostgreSQL](https://www.postgresql.org) als SQL-Datenbank.
|
||||
- 🚀 [React](https://react.dev) für das Frontend.
|
||||
- 💃 Verwendung von TypeScript, Hooks, [Vite](https://vitejs.dev) und anderen Teilen eines modernen Frontend-Stacks.
|
||||
- 🎨 [Chakra UI](https://chakra-ui.com) für die Frontend-Komponenten.
|
||||
- 🤖 Ein automatisch generierter Frontend-Client.
|
||||
- 🧪 [Playwright](https://playwright.dev) für End-to-End-Tests.
|
||||
- 🦇 Unterstützung des Dunkelmodus.
|
||||
- 💃 Verwendung von TypeScript, Hooks, Vite und anderen Teilen eines modernen Frontend-Stacks.
|
||||
- 🎨 [Tailwind CSS](https://tailwindcss.com) und [shadcn/ui](https://ui.shadcn.com) für die Frontend-Komponenten.
|
||||
- 🤖 Ein automatisch generierter Frontend-Client.
|
||||
- 🧪 [Playwright](https://playwright.dev) für End-to-End-Tests.
|
||||
- 🦇 „Dark-Mode“-Unterstützung.
|
||||
- 🐋 [Docker Compose](https://www.docker.com) für Entwicklung und Produktion.
|
||||
- 🔒 Sicheres Passwort-Hashing standardmäßig.
|
||||
- 🔑 JWT-Token-Authentifizierung.
|
||||
- 🔑 JWT (JSON Web Token)-Authentifizierung.
|
||||
- 📫 E-Mail-basierte Passwortwiederherstellung.
|
||||
- ✅ Tests mit [Pytest](https://pytest.org).
|
||||
- 📞 [Traefik](https://traefik.io) als Reverse-Proxy / Load Balancer.
|
||||
- 🚢 Deployment-Anleitungen unter Verwendung von Docker Compose, einschließlich der Einrichtung eines Frontend-Traefik-Proxys zur Handhabung automatischer HTTPS-Zertifikate.
|
||||
- 🏭 CI (kontinuierliche Integration) und CD (kontinuierliche Bereitstellung) basierend auf GitHub Actions.
|
||||
- 🏭 CI (kontinuierliche Integration) und CD (kontinuierliches Deployment) basierend auf GitHub Actions.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Einführung in Python-Typen { #python-types-intro }
|
||||
|
||||
Python hat Unterstützung für optionale <abbr title="englisch: Type hints">„Typhinweise“</abbr> (auch <abbr title="englisch: Type annotations">„Typannotationen“</abbr> genannt).
|
||||
Python hat Unterstützung für optionale „Typhinweise“ (auch „Typannotationen“ genannt).
|
||||
|
||||
Diese **„Typhinweise“** oder -Annotationen sind eine spezielle Syntax, die es erlaubt, den <abbr title="zum Beispiel: str, int, float, bool">Typ</abbr> einer Variablen zu deklarieren.
|
||||
Diese **„Typhinweise“** oder -Annotationen sind eine spezielle Syntax, die es erlaubt, den <dfn title="zum Beispiel: str, int, float, bool">Typ</dfn> einer Variablen zu deklarieren.
|
||||
|
||||
Durch das Deklarieren von Typen für Ihre Variablen können Editoren und Tools bessere Unterstützung bieten.
|
||||
|
||||
@@ -22,7 +22,7 @@ Wenn Sie ein Python-Experte sind und bereits alles über Typhinweise wissen, üb
|
||||
|
||||
Fangen wir mit einem einfachen Beispiel an:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial001.py *}
|
||||
{* ../../docs_src/python_types/tutorial001_py310.py *}
|
||||
|
||||
Dieses Programm gibt aus:
|
||||
|
||||
@@ -34,9 +34,9 @@ Die Funktion macht Folgendes:
|
||||
|
||||
* Nimmt einen `first_name` und `last_name`.
|
||||
* Schreibt den ersten Buchstaben eines jeden Wortes groß, mithilfe von `title()`.
|
||||
* <abbr title="Füge zu einer Einheit zusammen, eins nach dem anderen.">Verkettet</abbr> sie mit einem Leerzeichen in der Mitte.
|
||||
* <dfn title="Fügt sie zu einer Einheit zusammen. Mit dem Inhalt des einen nach dem anderen.">Verkettet</dfn> sie mit einem Leerzeichen in der Mitte.
|
||||
|
||||
{* ../../docs_src/python_types/tutorial001.py hl[2] *}
|
||||
{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *}
|
||||
|
||||
### Es bearbeiten { #edit-it }
|
||||
|
||||
@@ -78,7 +78,7 @@ Das war's.
|
||||
|
||||
Das sind die „Typhinweise“:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial002.py hl[1] *}
|
||||
{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
|
||||
|
||||
Das ist nicht das gleiche wie das Deklarieren von Defaultwerten, wie es hier der Fall ist:
|
||||
|
||||
@@ -106,7 +106,7 @@ Hier können Sie durch die Optionen blättern, bis Sie diejenige finden, bei der
|
||||
|
||||
Sehen Sie sich diese Funktion an, sie hat bereits Typhinweise:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial003.py hl[1] *}
|
||||
{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *}
|
||||
|
||||
Da der Editor die Typen der Variablen kennt, erhalten Sie nicht nur Code-Vervollständigung, sondern auch eine Fehlerprüfung:
|
||||
|
||||
@@ -114,7 +114,7 @@ Da der Editor die Typen der Variablen kennt, erhalten Sie nicht nur Code-Vervoll
|
||||
|
||||
Jetzt, da Sie wissen, dass Sie das reparieren müssen, konvertieren Sie `age` mittels `str(age)` in einen String:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial004.py hl[2] *}
|
||||
{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
|
||||
|
||||
## Deklarieren von Typen { #declaring-types }
|
||||
|
||||
@@ -133,84 +133,55 @@ Zum Beispiel diese:
|
||||
* `bool`
|
||||
* `bytes`
|
||||
|
||||
{* ../../docs_src/python_types/tutorial005.py hl[1] *}
|
||||
{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
|
||||
|
||||
### Generische Typen mit Typ-Parametern { #generic-types-with-type-parameters }
|
||||
### `typing`-Modul { #typing-module }
|
||||
|
||||
Es gibt Datenstrukturen, die andere Werte enthalten können, wie etwa `dict`, `list`, `set` und `tuple`. Die inneren Werte können auch ihren eigenen Typ haben.
|
||||
Für einige zusätzliche Anwendungsfälle müssen Sie möglicherweise Dinge aus dem Standardmodul `typing` importieren. Zum Beispiel, wenn Sie deklarieren möchten, dass etwas „jeden Typ“ haben kann, können Sie `Any` aus `typing` verwenden:
|
||||
|
||||
Diese Typen mit inneren Typen werden „**generische**“ Typen genannt. Es ist möglich, sie mit ihren inneren Typen zu deklarieren.
|
||||
```python
|
||||
from typing import Any
|
||||
|
||||
Um diese Typen und die inneren Typen zu deklarieren, können Sie Pythons Standardmodul `typing` verwenden. Es existiert speziell für die Unterstützung dieser Typhinweise.
|
||||
|
||||
#### Neuere Python-Versionen { #newer-versions-of-python }
|
||||
def some_function(data: Any):
|
||||
print(data)
|
||||
```
|
||||
|
||||
Die Syntax, welche `typing` verwendet, ist **kompatibel** mit allen Versionen, von Python 3.6 aufwärts zu den neuesten, inklusive Python 3.9, Python 3.10, usw.
|
||||
### Generische Typen { #generic-types }
|
||||
|
||||
Mit der Weiterentwicklung von Python kommen **neuere Versionen** heraus, mit verbesserter Unterstützung für Typannotationen, und in vielen Fällen müssen Sie gar nicht mehr das `typing`-Modul importieren, um Typannotationen zu schreiben.
|
||||
Einige Typen können „Typ-Parameter“ in eckigen Klammern annehmen, um ihre inneren Typen zu definieren, z. B. eine „Liste von Strings“ würde als `list[str]` deklariert.
|
||||
|
||||
Wenn Sie eine neuere Python-Version für Ihr Projekt wählen können, werden Sie aus dieser zusätzlichen Vereinfachung Nutzen ziehen können.
|
||||
Diese Typen, die Typ-Parameter annehmen können, werden **generische Typen** oder **Generics** genannt.
|
||||
|
||||
In der gesamten Dokumentation gibt es Beispiele, welche kompatibel mit unterschiedlichen Python-Versionen sind (wenn es Unterschiede gibt).
|
||||
Sie können dieselben eingebauten Typen als Generics verwenden (mit eckigen Klammern und Typen darin):
|
||||
|
||||
Zum Beispiel bedeutet „**Python 3.6+**“, dass das Beispiel kompatibel mit Python 3.6 oder höher ist (inklusive 3.7, 3.8, 3.9, 3.10, usw.). Und „**Python 3.9+**“ bedeutet, es ist kompatibel mit Python 3.9 oder höher (inklusive 3.10, usw.).
|
||||
|
||||
Wenn Sie über die **neueste Version von Python** verfügen, verwenden Sie die Beispiele für die neueste Version, diese werden die **beste und einfachste Syntax** haben, zum Beispiel, „**Python 3.10+**“.
|
||||
* `list`
|
||||
* `tuple`
|
||||
* `set`
|
||||
* `dict`
|
||||
|
||||
#### Liste { #list }
|
||||
|
||||
Definieren wir zum Beispiel eine Variable, die eine `list` von `str` – eine Liste von Strings – sein soll.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
Deklarieren Sie die Variable mit der gleichen Doppelpunkt-Syntax (`:`).
|
||||
|
||||
Als Typ nehmen Sie `list`.
|
||||
|
||||
Da die Liste ein Typ ist, welcher innere Typen enthält, werden diese von eckigen Klammern umfasst:
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial006_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
Von `typing` importieren Sie `List` (mit Großbuchstaben `L`):
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
|
||||
Deklarieren Sie die Variable mit der gleichen Doppelpunkt-Syntax (`:`).
|
||||
|
||||
Als Typ nehmen Sie das `List`, das Sie von `typing` importiert haben.
|
||||
|
||||
Da die Liste ein Typ ist, welcher innere Typen enthält, werden diese von eckigen Klammern umfasst:
|
||||
|
||||
```Python hl_lines="4"
|
||||
{!> ../../docs_src/python_types/tutorial006.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
|
||||
|
||||
/// info | Info
|
||||
|
||||
Die inneren Typen in den eckigen Klammern werden als „Typ-Parameter“ bezeichnet.
|
||||
|
||||
In diesem Fall ist `str` der Typ-Parameter, der an `List` übergeben wird (oder `list` in Python 3.9 und darüber).
|
||||
In diesem Fall ist `str` der Typ-Parameter, der an `list` übergeben wird.
|
||||
|
||||
///
|
||||
|
||||
Das bedeutet: Die Variable `items` ist eine Liste – `list` – und jedes der Elemente in dieser Liste ist ein String – `str`.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Wenn Sie Python 3.9 oder höher verwenden, müssen Sie `List` nicht von `typing` importieren, Sie können stattdessen den regulären `list`-Typ verwenden.
|
||||
|
||||
///
|
||||
|
||||
Auf diese Weise kann Ihr Editor Sie auch bei der Bearbeitung von Einträgen aus der Liste unterstützen:
|
||||
|
||||
<img src="/img/python-types/image05.png">
|
||||
@@ -225,21 +196,7 @@ Und trotzdem weiß der Editor, dass es sich um ein `str` handelt, und bietet ent
|
||||
|
||||
Das Gleiche gilt für die Deklaration eines Tupels – `tuple` – und einer Menge – `set`:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial007_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial007.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *}
|
||||
|
||||
Das bedeutet:
|
||||
|
||||
@@ -254,21 +211,7 @@ Der erste Typ-Parameter ist für die Schlüssel des `dict`.
|
||||
|
||||
Der zweite Typ-Parameter ist für die Werte des `dict`:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial008_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial008.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *}
|
||||
|
||||
Das bedeutet:
|
||||
|
||||
@@ -276,47 +219,23 @@ Das bedeutet:
|
||||
* Die Schlüssel dieses `dict` sind vom Typ `str` (z. B. die Namen der einzelnen Artikel).
|
||||
* Die Werte dieses `dict` sind vom Typ `float` (z. B. der Preis jedes Artikels).
|
||||
|
||||
#### <abbr title="Union – Verbund, Einheit‚ Vereinigung: Eines von Mehreren">Union</abbr> { #union }
|
||||
#### Union { #union }
|
||||
|
||||
Sie können deklarieren, dass eine Variable einer von **verschiedenen Typen** sein kann, zum Beispiel ein `int` oder ein `str`.
|
||||
|
||||
In Python 3.6 und höher (inklusive Python 3.10) können Sie den `Union`-Typ von `typing` verwenden und die möglichen Typen innerhalb der eckigen Klammern auflisten.
|
||||
Um das zu definieren, verwenden Sie den <dfn title="auch „bitweiser Oder-Operator“ genannt, aber diese Bedeutung ist hier nicht relevant">vertikalen Balken (`|`)</dfn>, um beide Typen zu trennen.
|
||||
|
||||
In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die möglichen Typen getrennt von einem <abbr title='Allgemein: „oder“. In anderem Zusammenhang auch „Bitweises ODER“, aber letztere Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> aufzulisten.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
Das wird „Union“ genannt, weil die Variable etwas aus der Vereinigung dieser beiden Typmengen sein kann.
|
||||
|
||||
```Python hl_lines="1"
|
||||
{!> ../../docs_src/python_types/tutorial008b_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial008b.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
In beiden Fällen bedeutet das, dass `item` ein `int` oder ein `str` sein kann.
|
||||
Das bedeutet, dass `item` ein `int` oder ein `str` sein könnte.
|
||||
|
||||
#### Vielleicht `None` { #possibly-none }
|
||||
|
||||
Sie können deklarieren, dass ein Wert ein `str`, aber vielleicht auch `None` sein kann.
|
||||
|
||||
In Python 3.6 und darüber (inklusive Python 3.10) können Sie das deklarieren, indem Sie `Optional` vom `typing` Modul importieren und verwenden.
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!../../docs_src/python_types/tutorial009.py!}
|
||||
```
|
||||
|
||||
Wenn Sie `Optional[str]` anstelle von nur `str` verwenden, wird Ihr Editor Ihnen dabei helfen, Fehler zu erkennen, bei denen Sie annehmen könnten, dass ein Wert immer eine String (`str`) ist, obwohl er auch `None` sein könnte.
|
||||
|
||||
`Optional[Something]` ist tatsächlich eine Abkürzung für `Union[Something, None]`, diese beiden sind äquivalent.
|
||||
|
||||
Das bedeutet auch, dass Sie in Python 3.10 `Something | None` verwenden können:
|
||||
Sie können deklarieren, dass ein Wert einen Typ haben könnte, wie `str`, dass er aber auch `None` sein könnte.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
@@ -326,108 +245,7 @@ Das bedeutet auch, dass Sie in Python 3.10 `Something | None` verwenden können:
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial009.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ Alternative
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial009b.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
#### `Union` oder `Optional` verwenden? { #using-union-or-optional }
|
||||
|
||||
Wenn Sie eine Python-Version unterhalb 3.10 verwenden, hier ist mein sehr **subjektiver** Standpunkt dazu:
|
||||
|
||||
* 🚨 Vermeiden Sie `Optional[SomeType]`
|
||||
* Stattdessen ✨ **verwenden Sie `Union[SomeType, None]`** ✨.
|
||||
|
||||
Beide sind äquivalent und im Hintergrund dasselbe, aber ich empfehle `Union` statt `Optional`, weil das Wort „**optional**“ impliziert, dass dieser Wert, zum Beispiel als Funktionsparameter, optional ist. Tatsächlich bedeutet es aber nur „Der Wert kann `None` sein“, selbst wenn der Wert nicht optional ist und benötigt wird.
|
||||
|
||||
Ich denke, `Union[SomeType, None]` ist expliziter bezüglich seiner Bedeutung.
|
||||
|
||||
Es geht nur um Wörter und Namen. Aber diese Worte können beeinflussen, wie Sie und Ihre Teamkollegen über den Code denken.
|
||||
|
||||
Nehmen wir zum Beispiel diese Funktion:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
|
||||
|
||||
Der Parameter `name` ist definiert als `Optional[str]`, aber er ist **nicht optional**, Sie können die Funktion nicht ohne diesen Parameter aufrufen:
|
||||
|
||||
```Python
|
||||
say_hi() # Oh, nein, das löst einen Fehler aus! 😱
|
||||
```
|
||||
|
||||
Der `name` Parameter wird **immer noch benötigt** (nicht *optional*), weil er keinen Default-Wert hat. `name` akzeptiert aber dennoch `None` als Wert:
|
||||
|
||||
```Python
|
||||
say_hi(name=None) # Das funktioniert, None ist gültig 🎉
|
||||
```
|
||||
|
||||
Die gute Nachricht ist, dass Sie sich darüber keine Sorgen mehr machen müssen, wenn Sie Python 3.10 verwenden, da Sie einfach `|` verwenden können, um Vereinigungen von Typen zu definieren:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial009c_py310.py hl[1,4] *}
|
||||
|
||||
Und dann müssen Sie sich nicht mehr um Namen wie `Optional` und `Union` kümmern. 😎
|
||||
|
||||
#### Generische Typen { #generic-types }
|
||||
|
||||
Diese Typen, die Typ-Parameter in eckigen Klammern akzeptieren, werden **generische Typen** oder **Generics** genannt.
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern und Typen darin):
|
||||
|
||||
* `list`
|
||||
* `tuple`
|
||||
* `set`
|
||||
* `dict`
|
||||
|
||||
Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul:
|
||||
|
||||
* `Union`
|
||||
* `Optional` (so wie unter Python 3.8)
|
||||
* ... und andere.
|
||||
|
||||
In Python 3.10 können Sie als Alternative zu den Generics `Union` und `Optional` den <abbr title='Allgemein: „oder“. In anderem Zusammenhang auch „Bitweises ODER“, aber letztere Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> verwenden, um Vereinigungen von Typen zu deklarieren, das ist besser und einfacher.
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern und Typen darin):
|
||||
|
||||
* `list`
|
||||
* `tuple`
|
||||
* `set`
|
||||
* `dict`
|
||||
|
||||
Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul:
|
||||
|
||||
* `Union`
|
||||
* `Optional`
|
||||
* ... und andere.
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
* `List`
|
||||
* `Tuple`
|
||||
* `Set`
|
||||
* `Dict`
|
||||
* `Union`
|
||||
* `Optional`
|
||||
* ... und andere.
|
||||
|
||||
////
|
||||
Wenn Sie `str | None` anstelle von nur `str` verwenden, wird Ihr Editor Ihnen dabei helfen, Fehler zu erkennen, bei denen Sie annehmen könnten, dass ein Wert immer ein `str` ist, obwohl er auch `None` sein könnte.
|
||||
|
||||
### Klassen als Typen { #classes-as-types }
|
||||
|
||||
@@ -435,11 +253,11 @@ Sie können auch eine Klasse als Typ einer Variablen deklarieren.
|
||||
|
||||
Nehmen wir an, Sie haben eine Klasse `Person`, mit einem Namen:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
|
||||
{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *}
|
||||
|
||||
Dann können Sie eine Variable vom Typ `Person` deklarieren:
|
||||
|
||||
{* ../../docs_src/python_types/tutorial010.py hl[6] *}
|
||||
{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *}
|
||||
|
||||
Und wiederum bekommen Sie die volle Editor-Unterstützung:
|
||||
|
||||
@@ -463,29 +281,7 @@ Und Sie erhalten volle Editor-Unterstützung für dieses Objekt.
|
||||
|
||||
Ein Beispiel aus der offiziellen Pydantic Dokumentation:
|
||||
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/python_types/tutorial011_py310.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/python_types/tutorial011_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python
|
||||
{!> ../../docs_src/python_types/tutorial011.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/python_types/tutorial011_py310.py *}
|
||||
|
||||
/// info | Info
|
||||
|
||||
@@ -497,37 +293,13 @@ Um mehr über <a href="https://docs.pydantic.dev/" class="external-link" target=
|
||||
|
||||
Viel mehr von all dem werden Sie in praktischer Anwendung im [Tutorial – Benutzerhandbuch](tutorial/index.md){.internal-link target=_blank} sehen.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Pydantic verhält sich speziell, wenn Sie `Optional` oder `Union[Something, None]` ohne einen Defaultwert verwenden. Sie können darüber in der Pydantic Dokumentation unter <a href="https://docs.pydantic.dev/2.3/usage/models/#required-fields" class="external-link" target="_blank">Erforderliche optionale Felder</a> mehr erfahren.
|
||||
|
||||
///
|
||||
|
||||
## Typhinweise mit Metadaten-Annotationen { #type-hints-with-metadata-annotations }
|
||||
|
||||
Python bietet auch die Möglichkeit, **zusätzliche <abbr title="Daten über die Daten, in diesem Fall Informationen über den Typ, z. B. eine Beschreibung.">Metadaten</abbr>** in Typhinweisen unterzubringen, mittels `Annotated`.
|
||||
Python bietet auch die Möglichkeit, **zusätzliche <dfn title="Daten über die Daten, in diesem Fall Informationen über den Typ, z. B. eine Beschreibung.">Metadaten</dfn>** in Typhinweisen unterzubringen, mittels `Annotated`.
|
||||
|
||||
//// tab | Python 3.9+
|
||||
Sie können `Annotated` von `typing` importieren.
|
||||
|
||||
In Python 3.9 ist `Annotated` ein Teil der Standardbibliothek, Sie können es von `typing` importieren.
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial013_py39.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
In Versionen niedriger als Python 3.9 importieren Sie `Annotated` von `typing_extensions`.
|
||||
|
||||
Es wird bereits mit **FastAPI** installiert sein.
|
||||
|
||||
```Python hl_lines="1 4"
|
||||
{!> ../../docs_src/python_types/tutorial013.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *}
|
||||
|
||||
Python selbst macht nichts mit `Annotated`. Für Editoren und andere Tools ist der Typ immer noch `str`.
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Ressourcen { #resources }
|
||||
|
||||
Zusätzliche Ressourcen, externe Links, Artikel und mehr. ✈️
|
||||
Zusätzliche Ressourcen, externe Links und mehr. ✈️
|
||||
|
||||
11
docs/de/docs/translation-banner.md
Normal file
11
docs/de/docs/translation-banner.md
Normal file
@@ -0,0 +1,11 @@
|
||||
/// details | 🌐 Übersetzung durch KI und Menschen
|
||||
|
||||
Diese Übersetzung wurde von KI erstellt, angeleitet von Menschen. 🤝
|
||||
|
||||
Sie könnte Fehler enthalten, etwa Missverständnisse des ursprünglichen Sinns oder unnatürliche Formulierungen, usw. 🤖
|
||||
|
||||
Sie können diese Übersetzung verbessern, indem Sie [uns helfen, die KI-LLM besser anzuleiten](https://fastapi.tiangolo.com/de/contributing/#translations).
|
||||
|
||||
[Englische Version](ENGLISH_VERSION_URL)
|
||||
|
||||
///
|
||||
@@ -15,7 +15,7 @@ Hierzu zählen beispielsweise:
|
||||
|
||||
Importieren Sie zunächst `BackgroundTasks` und definieren Sie einen Parameter in Ihrer *Pfadoperation-Funktion* mit der Typdeklaration `BackgroundTasks`:
|
||||
|
||||
{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
|
||||
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
|
||||
|
||||
**FastAPI** erstellt für Sie das Objekt vom Typ `BackgroundTasks` und übergibt es als diesen Parameter.
|
||||
|
||||
@@ -31,13 +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`:
|
||||
|
||||
{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
|
||||
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
|
||||
|
||||
## Den Hintergrundtask hinzufügen { #add-the-background-task }
|
||||
|
||||
Übergeben Sie innerhalb Ihrer *Pfadoperation-Funktion* Ihre Taskfunktion mit der Methode `.add_task()` an das *Hintergrundtasks*-Objekt:
|
||||
|
||||
{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
|
||||
{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
|
||||
|
||||
`.add_task()` erhält als Argumente:
|
||||
|
||||
@@ -63,7 +63,7 @@ Und dann schreibt ein weiterer Hintergrundtask, der in der *Pfadoperation-Funkti
|
||||
|
||||
## Technische Details { #technical-details }
|
||||
|
||||
Die Klasse `BackgroundTasks` stammt direkt von <a href="https://www.starlette.io/background/" class="external-link" target="_blank">`starlette.background`</a>.
|
||||
Die Klasse `BackgroundTasks` stammt direkt von <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">`starlette.background`</a>.
|
||||
|
||||
Sie wird direkt in FastAPI importiert/inkludiert, sodass Sie sie von `fastapi` importieren können und vermeiden, versehentlich das alternative `BackgroundTask` (ohne das `s` am Ende) von `starlette.background` zu importieren.
|
||||
|
||||
@@ -71,7 +71,7 @@ Indem Sie nur `BackgroundTasks` (und nicht `BackgroundTask`) verwenden, ist es d
|
||||
|
||||
Es ist immer noch möglich, `BackgroundTask` allein in FastAPI zu verwenden, aber Sie müssen das Objekt in Ihrem Code erstellen und eine Starlette-`Response` zurückgeben, die es enthält.
|
||||
|
||||
Weitere Details finden Sie in <a href="https://www.starlette.io/background/" class="external-link" target="_blank">Starlettes offizieller Dokumentation für Hintergrundtasks</a>.
|
||||
Weitere Details finden Sie in <a href="https://www.starlette.dev/background/" class="external-link" target="_blank">Starlettes offizieller Dokumentation für Hintergrundtasks</a>.
|
||||
|
||||
## Vorbehalt { #caveat }
|
||||
|
||||
|
||||
@@ -56,19 +56,19 @@ from app.routers import items
|
||||
|
||||
Die gleiche Dateistruktur mit Kommentaren:
|
||||
|
||||
```
|
||||
```bash
|
||||
.
|
||||
├── app # „app“ ist ein Python-Package
|
||||
│ ├── __init__.py # diese Datei macht „app“ zu einem „Python-Package“
|
||||
│ ├── main.py # „main“-Modul, z. B. import app.main
|
||||
│ ├── dependencies.py # „dependencies“-Modul, z. B. import app.dependencies
|
||||
│ └── routers # „routers“ ist ein „Python-Subpackage“
|
||||
│ │ ├── __init__.py # macht „routers“ zu einem „Python-Subpackage“
|
||||
│ │ ├── items.py # „items“-Submodul, z. B. import app.routers.items
|
||||
│ │ └── users.py # „users“-Submodul, z. B. import app.routers.users
|
||||
│ └── internal # „internal“ ist ein „Python-Subpackage“
|
||||
│ ├── __init__.py # macht „internal“ zu einem „Python-Subpackage“
|
||||
│ └── admin.py # „admin“-Submodul, z. B. import app.internal.admin
|
||||
├── app # "app" ist ein Python-Package
|
||||
│ ├── __init__.py # diese Datei macht "app" zu einem "Python-Package"
|
||||
│ ├── main.py # "main"-Modul, z. B. import app.main
|
||||
│ ├── dependencies.py # "dependencies"-Modul, z. B. import app.dependencies
|
||||
│ └── routers # "routers" ist ein "Python-Subpackage"
|
||||
│ │ ├── __init__.py # macht "routers" zu einem "Python-Subpackage"
|
||||
│ │ ├── items.py # "items"-Submodul, z. B. import app.routers.items
|
||||
│ │ └── users.py # "users"-Submodul, z. B. import app.routers.users
|
||||
│ └── internal # "internal" ist ein "Python-Subpackage"
|
||||
│ ├── __init__.py # macht "internal" zu einem "Python-Subpackage"
|
||||
│ └── admin.py # "admin"-Submodul, z. B. import app.internal.admin
|
||||
```
|
||||
|
||||
## `APIRouter` { #apirouter }
|
||||
@@ -85,9 +85,7 @@ Sie können die *Pfadoperationen* für dieses Modul mit `APIRouter` erstellen.
|
||||
|
||||
Sie importieren ihn und erstellen eine „Instanz“ auf die gleiche Weise wie mit der Klasse `FastAPI`:
|
||||
|
||||
```Python hl_lines="1 3" title="app/routers/users.py"
|
||||
{!../../docs_src/bigger_applications/app/routers/users.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[1,3] title["app/routers/users.py"] *}
|
||||
|
||||
### *Pfadoperationen* mit `APIRouter` { #path-operations-with-apirouter }
|
||||
|
||||
@@ -95,9 +93,7 @@ Und dann verwenden Sie ihn, um Ihre *Pfadoperationen* zu deklarieren.
|
||||
|
||||
Verwenden Sie ihn auf die gleiche Weise wie die Klasse `FastAPI`:
|
||||
|
||||
```Python hl_lines="6 11 16" title="app/routers/users.py"
|
||||
{!../../docs_src/bigger_applications/app/routers/users.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
|
||||
|
||||
Sie können sich `APIRouter` als eine „Mini-`FastAPI`“-Klasse vorstellen.
|
||||
|
||||
@@ -121,35 +117,7 @@ Also fügen wir sie in ihr eigenes `dependencies`-Modul (`app/dependencies.py`)
|
||||
|
||||
Wir werden nun eine einfache Abhängigkeit verwenden, um einen benutzerdefinierten `X-Token`-Header zu lesen:
|
||||
|
||||
//// tab | Python 3.9+
|
||||
|
||||
```Python hl_lines="3 6-8" title="app/dependencies.py"
|
||||
{!> ../../docs_src/bigger_applications/app_an_py39/dependencies.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+
|
||||
|
||||
```Python hl_lines="1 5-7" title="app/dependencies.py"
|
||||
{!> ../../docs_src/bigger_applications/app_an/dependencies.py!}
|
||||
```
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Bevorzugen Sie die `Annotated`-Version, falls möglich.
|
||||
|
||||
///
|
||||
|
||||
```Python hl_lines="1 4-6" title="app/dependencies.py"
|
||||
{!> ../../docs_src/bigger_applications/app/dependencies.py!}
|
||||
```
|
||||
|
||||
////
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -181,9 +149,7 @@ Wir wissen, dass alle *Pfadoperationen* in diesem Modul folgendes haben:
|
||||
|
||||
Anstatt also alles zu jeder *Pfadoperation* hinzuzufügen, können wir es dem `APIRouter` hinzufügen.
|
||||
|
||||
```Python hl_lines="5-10 16 21" title="app/routers/items.py"
|
||||
{!../../docs_src/bigger_applications/app/routers/items.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
|
||||
|
||||
Da der Pfad jeder *Pfadoperation* mit `/` beginnen muss, wie in:
|
||||
|
||||
@@ -242,9 +208,7 @@ Und wir müssen die Abhängigkeitsfunktion aus dem Modul `app.dependencies` impo
|
||||
|
||||
Daher verwenden wir einen relativen Import mit `..` für die Abhängigkeiten:
|
||||
|
||||
```Python hl_lines="3" title="app/routers/items.py"
|
||||
{!../../docs_src/bigger_applications/app/routers/items.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *}
|
||||
|
||||
#### Wie relative Importe funktionieren { #how-relative-imports-work }
|
||||
|
||||
@@ -315,9 +279,7 @@ Wir fügen weder das Präfix `/items` noch `tags=["items"]` zu jeder *Pfadoperat
|
||||
|
||||
Aber wir können immer noch _mehr_ `tags` hinzufügen, die auf eine bestimmte *Pfadoperation* angewendet werden, sowie einige zusätzliche `responses`, die speziell für diese *Pfadoperation* gelten:
|
||||
|
||||
```Python hl_lines="30-31" title="app/routers/items.py"
|
||||
{!../../docs_src/bigger_applications/app/routers/items.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -343,17 +305,13 @@ Sie importieren und erstellen wie gewohnt eine `FastAPI`-Klasse.
|
||||
|
||||
Und wir können sogar [globale Abhängigkeiten](dependencies/global-dependencies.md){.internal-link target=_blank} deklarieren, die mit den Abhängigkeiten für jeden `APIRouter` kombiniert werden:
|
||||
|
||||
```Python hl_lines="1 3 7" title="app/main.py"
|
||||
{!../../docs_src/bigger_applications/app/main.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
|
||||
|
||||
### Den `APIRouter` importieren { #import-the-apirouter }
|
||||
|
||||
Jetzt importieren wir die anderen Submodule, die `APIRouter` haben:
|
||||
|
||||
```Python hl_lines="4-5" title="app/main.py"
|
||||
{!../../docs_src/bigger_applications/app/main.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *}
|
||||
|
||||
Da es sich bei den Dateien `app/routers/users.py` und `app/routers/items.py` um Submodule handelt, die Teil desselben Python-Packages `app` sind, können wir einen einzelnen Punkt `.` verwenden, um sie mit „relativen Imports“ zu importieren.
|
||||
|
||||
@@ -416,17 +374,13 @@ würde der `router` von `users` den von `items` überschreiben und wir könnten
|
||||
|
||||
Um also beide in derselben Datei verwenden zu können, importieren wir die Submodule direkt:
|
||||
|
||||
```Python hl_lines="5" title="app/main.py"
|
||||
{!../../docs_src/bigger_applications/app/main.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *}
|
||||
|
||||
### Die `APIRouter` für `users` und `items` inkludieren { #include-the-apirouters-for-users-and-items }
|
||||
|
||||
Inkludieren wir nun die `router` aus diesen Submodulen `users` und `items`:
|
||||
|
||||
```Python hl_lines="10-11" title="app/main.py"
|
||||
{!../../docs_src/bigger_applications/app/main.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
|
||||
|
||||
/// info | Info
|
||||
|
||||
@@ -466,17 +420,13 @@ Sie enthält einen `APIRouter` mit einigen administrativen *Pfadoperationen*, di
|
||||
|
||||
In diesem Beispiel wird es ganz einfach sein. Nehmen wir jedoch an, dass wir, da sie mit anderen Projekten in der Organisation geteilt wird, sie nicht ändern und kein `prefix`, `dependencies`, `tags`, usw. direkt zum `APIRouter` hinzufügen können:
|
||||
|
||||
```Python hl_lines="3" title="app/internal/admin.py"
|
||||
{!../../docs_src/bigger_applications/app/internal/admin.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *}
|
||||
|
||||
Aber wir möchten immer noch ein benutzerdefiniertes `prefix` festlegen, wenn wir den `APIRouter` einbinden, sodass alle seine *Pfadoperationen* mit `/admin` beginnen, wir möchten es mit den `dependencies` sichern, die wir bereits für dieses Projekt haben, und wir möchten `tags` und `responses` hinzufügen.
|
||||
|
||||
Wir können das alles deklarieren, ohne den ursprünglichen `APIRouter` ändern zu müssen, indem wir diese Parameter an `app.include_router()` übergeben:
|
||||
|
||||
```Python hl_lines="14-17" title="app/main.py"
|
||||
{!../../docs_src/bigger_applications/app/main.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[14:17] title["app/main.py"] *}
|
||||
|
||||
Auf diese Weise bleibt der ursprüngliche `APIRouter` unverändert, sodass wir dieselbe `app/internal/admin.py`-Datei weiterhin mit anderen Projekten in der Organisation teilen können.
|
||||
|
||||
@@ -497,9 +447,7 @@ Wir können *Pfadoperationen* auch direkt zur `FastAPI`-App hinzufügen.
|
||||
|
||||
Hier machen wir es ... nur um zu zeigen, dass wir es können 🤷:
|
||||
|
||||
```Python hl_lines="21-23" title="app/main.py"
|
||||
{!../../docs_src/bigger_applications/app/main.py!}
|
||||
```
|
||||
{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
|
||||
|
||||
und es wird korrekt funktionieren, zusammen mit allen anderen *Pfadoperationen*, die mit `app.include_router()` hinzugefügt wurden.
|
||||
|
||||
@@ -531,7 +479,7 @@ $ fastapi dev app/main.py
|
||||
|
||||
</div>
|
||||
|
||||
und öffnen Sie die Dokumentation unter <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
Und öffnen Sie die Dokumentation unter <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
Sie sehen die automatische API-Dokumentation, einschließlich der Pfade aller Submodule, mit den richtigen Pfaden (und Präfixen) und den richtigen Tags:
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ Beachten Sie, wie jedes Attribut eines Modells mit einem Typ, Defaultwert und `F
|
||||
|
||||
Sie können zusätzliche Information in `Field`, `Query`, `Body`, usw. deklarieren. Und es wird im generierten JSON-Schema untergebracht.
|
||||
|
||||
Sie werden später mehr darüber lernen, wie man zusätzliche Information unterbringt, wenn Sie lernen, Beispiele zu deklarieren.
|
||||
Sie werden später in der Dokumentation mehr darüber lernen, wie man zusätzliche Information unterbringt, wenn Sie lernen, Beispiele zu deklarieren.
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Body – Mehrere Parameter { #body-multiple-parameters }
|
||||
|
||||
Nun, da wir gesehen haben, wie `Path` und `Query` verwendet werden, schauen wir uns fortgeschrittenere Verwendungsmöglichkeiten von <abbr title="Anfragekörper">Requestbody</abbr>-Deklarationen an.
|
||||
Nun, da wir gesehen haben, wie `Path` und `Query` verwendet werden, schauen wir uns fortgeschrittenere Verwendungsmöglichkeiten von <abbr title="Requestbody">Requestbody</abbr>-Deklarationen an.
|
||||
|
||||
## `Path`-, `Query`- und Body-Parameter vermischen { #mix-path-query-and-body-parameters }
|
||||
|
||||
@@ -100,12 +100,6 @@ Natürlich können Sie auch, wann immer Sie das brauchen, weitere Query-Paramete
|
||||
|
||||
Da einfache Werte standardmäßig als Query-Parameter interpretiert werden, müssen Sie `Query` nicht explizit hinzufügen, Sie können einfach schreiben:
|
||||
|
||||
```Python
|
||||
q: Union[str, None] = None
|
||||
```
|
||||
|
||||
Oder in Python 3.10 und darüber:
|
||||
|
||||
```Python
|
||||
q: str | None = None
|
||||
```
|
||||
|
||||
@@ -14,35 +14,14 @@ Das bewirkt, dass `tags` eine Liste ist, wenngleich es nichts über den Typ der
|
||||
|
||||
Aber Python erlaubt es, Listen mit inneren Typen, auch „Typ-Parameter“ genannt, zu deklarieren.
|
||||
|
||||
### `List` von `typing` importieren { #import-typings-list }
|
||||
|
||||
In Python 3.9 oder darüber können Sie einfach `list` verwenden, um diese Typannotationen zu deklarieren, wie wir unten sehen werden. 💡
|
||||
|
||||
In Python-Versionen vor 3.9 (3.6 und darüber), müssen Sie zuerst `List` von Pythons Standardmodul `typing` importieren.
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
|
||||
|
||||
### Eine `list` mit einem Typ-Parameter deklarieren { #declare-a-list-with-a-type-parameter }
|
||||
|
||||
Um Typen wie `list`, `dict`, `tuple` mit inneren Typ-Parametern (inneren Typen) zu deklarieren:
|
||||
|
||||
* Wenn Sie eine Python-Version kleiner als 3.9 verwenden, importieren Sie das Äquivalent zum entsprechenden Typ vom `typing`-Modul
|
||||
* Überreichen Sie den/die inneren Typ(en) von eckigen Klammern umschlossen, `[` und `]`, als „Typ-Parameter“
|
||||
|
||||
In Python 3.9 wäre das:
|
||||
Um Typen zu deklarieren, die Typ-Parameter (innere Typen) haben, wie `list`, `dict`, `tuple`, übergeben Sie den/die inneren Typ(en) als „Typ-Parameter“ in eckigen Klammern: `[` und `]`
|
||||
|
||||
```Python
|
||||
my_list: list[str]
|
||||
```
|
||||
|
||||
Und in Python-Versionen vor 3.9:
|
||||
|
||||
```Python
|
||||
from typing import List
|
||||
|
||||
my_list: List[str]
|
||||
```
|
||||
|
||||
Das ist alles Standard-Python-Syntax für Typdeklarationen.
|
||||
|
||||
Verwenden Sie dieselbe Standardsyntax für Modellattribute mit inneren Typen.
|
||||
@@ -178,19 +157,13 @@ Beachten Sie, wie `Offer` eine Liste von `Item`s hat, die ihrerseits eine option
|
||||
|
||||
Wenn das äußerste Element des JSON-Bodys, das Sie erwarten, ein JSON-`array` (eine Python-`list`) ist, können Sie den Typ im Funktionsparameter deklarieren, mit der gleichen Syntax wie in Pydantic-Modellen:
|
||||
|
||||
```Python
|
||||
images: List[Image]
|
||||
```
|
||||
|
||||
oder in Python 3.9 und darüber:
|
||||
|
||||
```Python
|
||||
images: list[Image]
|
||||
```
|
||||
|
||||
so wie in:
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
|
||||
{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
|
||||
|
||||
## Editor-Unterstützung überall { #editor-support-everywhere }
|
||||
|
||||
@@ -220,7 +193,7 @@ Das schauen wir uns mal an.
|
||||
|
||||
Im folgenden Beispiel akzeptieren Sie irgendein `dict`, solange es `int`-Schlüssel und `float`-Werte hat:
|
||||
|
||||
{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
|
||||
{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -50,14 +50,6 @@ Wenn Sie Teil-Aktualisierungen entgegennehmen, ist der `exclude_unset`-Parameter
|
||||
|
||||
Wie in `item.model_dump(exclude_unset=True)`.
|
||||
|
||||
/// info | Info
|
||||
|
||||
In Pydantic v1 hieß diese Methode `.dict()`, in Pydantic v2 wurde sie <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> (aber immer noch unterstützt) und in `.model_dump()` umbenannt.
|
||||
|
||||
Die Beispiele hier verwenden `.dict()` für die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 verwenden können.
|
||||
|
||||
///
|
||||
|
||||
Das wird ein <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">`dict`</abbr> erstellen, mit nur den Daten, die gesetzt wurden, als das `item`-Modell erstellt wurde, Defaultwerte ausgeschlossen.
|
||||
|
||||
Sie können das verwenden, um ein `dict` zu erstellen, das nur die (im <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>) gesendeten Daten enthält, ohne Defaultwerte:
|
||||
@@ -68,14 +60,6 @@ Sie können das verwenden, um ein `dict` zu erstellen, das nur die (im <abbr tit
|
||||
|
||||
Jetzt können Sie eine Kopie des existierenden Modells mittels `.model_copy()` erstellen, wobei Sie dem `update`-Parameter ein `dict` mit den zu ändernden Daten übergeben.
|
||||
|
||||
/// info | Info
|
||||
|
||||
In Pydantic v1 hieß diese Methode `.copy()`, in Pydantic v2 wurde sie <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> (aber immer noch unterstützt) und in `.model_copy()` umbenannt.
|
||||
|
||||
Die Beispiele hier verwenden `.copy()` für die Kompatibilität mit Pydantic v1, Sie sollten jedoch stattdessen `.model_copy()` verwenden, wenn Sie Pydantic v2 verwenden können.
|
||||
|
||||
///
|
||||
|
||||
Wie in `stored_item_model.model_copy(update=update_data)`:
|
||||
|
||||
{* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
|
||||
|
||||
@@ -127,14 +127,6 @@ Innerhalb der Funktion können Sie alle Attribute des Modellobjekts direkt verwe
|
||||
|
||||
{* ../../docs_src/body/tutorial002_py310.py *}
|
||||
|
||||
/// info | Info
|
||||
|
||||
In Pydantic v1 hieß die Methode `.dict()`, sie wurde in Pydantic v2 deprecatet (aber weiterhin unterstützt) und in `.model_dump()` umbenannt.
|
||||
|
||||
Die Beispiele hier verwenden `.dict()` zur Kompatibilität mit Pydantic v1, aber Sie sollten stattdessen `.model_dump()` verwenden, wenn Sie Pydantic v2 nutzen können.
|
||||
|
||||
///
|
||||
|
||||
## Requestbody- + Pfad-Parameter { #request-body-path-parameters }
|
||||
|
||||
Sie können Pfad-Parameter und den Requestbody gleichzeitig deklarieren.
|
||||
@@ -162,7 +154,7 @@ Die Funktionsparameter werden wie folgt erkannt:
|
||||
|
||||
FastAPI weiß, dass der Wert von `q` nicht erforderlich ist, aufgrund des definierten Defaultwertes `= None`.
|
||||
|
||||
Das `str | None` (Python 3.10+) oder `Union` in `Union[str, None]` (Python 3.8+) wird von FastAPI nicht verwendet, um zu bestimmen, dass der Wert nicht erforderlich ist. FastAPI weiß, dass er nicht erforderlich ist, weil er einen Defaultwert von `= None` hat.
|
||||
Das `str | None` wird von FastAPI nicht verwendet, um zu bestimmen, dass der Wert nicht erforderlich ist. FastAPI weiß, dass er nicht erforderlich ist, weil er einen Defaultwert von `= None` hat.
|
||||
|
||||
Das Hinzufügen der Typannotationen ermöglicht jedoch Ihrem Editor, Ihnen eine bessere Unterstützung zu bieten und Fehler zu erkennen.
|
||||
|
||||
|
||||
@@ -46,17 +46,17 @@ Aber selbst wenn Sie die **Daten ausfüllen** und auf „Ausführen“ klicken,
|
||||
|
||||
In einigen speziellen Anwendungsfällen (wahrscheinlich nicht sehr häufig) möchten Sie möglicherweise die Cookies, die Sie empfangen möchten, **einschränken**.
|
||||
|
||||
Ihre API hat jetzt die Macht, ihre eigene <abbr title="Das ist ein Scherz, nur für den Fall. Es hat nichts mit Cookie-Einwilligungen zu tun, aber es ist witzig, dass selbst die API jetzt die armen Cookies ablehnen kann. Haben Sie einen Keks. 🍪">Cookie-Einwilligung</abbr> zu kontrollieren. 🤪🍪
|
||||
Ihre API hat jetzt die Macht, ihre eigene <dfn title="Das ist ein Scherz, nur für den Fall. Es hat nichts mit Cookie-Einwilligungen zu tun, aber es ist witzig, dass selbst die API jetzt die armen Cookies ablehnen kann. Haben Sie einen Keks. 🍪">Cookie-Einwilligung</dfn> zu kontrollieren. 🤪🍪
|
||||
|
||||
Sie können die Modellkonfiguration von Pydantic verwenden, um `extra` Felder zu verbieten (`forbid`):
|
||||
|
||||
{* ../../docs_src/cookie_param_models/tutorial002_an_py39.py hl[10] *}
|
||||
{* ../../docs_src/cookie_param_models/tutorial002_an_py310.py hl[10] *}
|
||||
|
||||
Wenn ein Client versucht, einige **zusätzliche Cookies** zu senden, erhält er eine **Error-<abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>**.
|
||||
|
||||
Arme Cookie-Banner, wie sie sich mühen, Ihre Einwilligung zu erhalten, dass die <abbr title="Das ist ein weiterer Scherz. Beachten Sie mich nicht. Trinken Sie einen Kaffee zu Ihrem Keks. ☕">API sie ablehnen darf</abbr>. 🍪
|
||||
Arme Cookie-Banner, wie sie sich mühen, Ihre Einwilligung zu erhalten, dass die <dfn title="Das ist ein weiterer Scherz. Beachten Sie mich nicht. Trinken Sie einen Kaffee zu Ihrem Keks. ☕">API sie ablehnen darf</dfn>. 🍪
|
||||
|
||||
Wenn der Client beispielsweise versucht, ein `santa_tracker`-Cookie mit einem Wert von `good-list-please` zu senden, erhält der Client eine **Error-Response**, die ihm mitteilt, dass das `santa_tracker` <abbr title="Santa beschwert sich über den Mangel an Cookies. 🎅 Okay, keine Cookie-Witze mehr.">Cookie nicht erlaubt ist</abbr>:
|
||||
Wenn der Client beispielsweise versucht, ein `santa_tracker`-Cookie mit einem Wert von `good-list-please` zu senden, erhält der Client eine **Error-Response**, die ihm mitteilt, dass das `santa_tracker` <dfn title="Santa missbilligt den Mangel an Cookies. 🎅 Okay, keine Cookie-Witze mehr.">Cookie nicht erlaubt ist</dfn>:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -73,4 +73,4 @@ Wenn der Client beispielsweise versucht, ein `santa_tracker`-Cookie mit einem We
|
||||
|
||||
## Zusammenfassung { #summary }
|
||||
|
||||
Sie können **Pydantic-Modelle** verwenden, um <abbr title="Nehmen Sie einen letzten Keks, bevor Sie gehen. 🍪">**Cookies**</abbr> in **FastAPI** zu deklarieren. 😎
|
||||
Sie können **Pydantic-Modelle** verwenden, um <dfn title="Nehmen Sie einen letzten Keks, bevor Sie gehen. 🍪">**Cookies**</dfn> in **FastAPI** zu deklarieren. 😎
|
||||
|
||||
@@ -46,7 +46,7 @@ Sie können auch angeben, ob Ihr Backend erlaubt:
|
||||
* Bestimmte HTTP-Methoden (`POST`, `PUT`) oder alle mit der Wildcard `"*"`.
|
||||
* Bestimmte HTTP-Header oder alle mit der Wildcard `"*"`.
|
||||
|
||||
{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *}
|
||||
{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
|
||||
|
||||
Die von der `CORSMiddleware`-Implementierung verwendeten Defaultparameter sind standardmäßig restriktiv, daher müssen Sie bestimmte Origins, Methoden oder Header ausdrücklich aktivieren, damit Browser sie in einem Cross-Domain-Kontext verwenden dürfen.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ Sie können den Debugger in Ihrem Editor verbinden, zum Beispiel mit Visual Stud
|
||||
|
||||
Importieren und führen Sie `uvicorn` direkt in Ihrer FastAPI-Anwendung aus:
|
||||
|
||||
{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
|
||||
{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *}
|
||||
|
||||
### Über `__name__ == "__main__"` { #about-name-main }
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ Jetzt können Sie Ihre Abhängigkeit mithilfe dieser Klasse deklarieren.
|
||||
|
||||
Beachten Sie, wie wir `CommonQueryParams` im obigen Code zweimal schreiben:
|
||||
|
||||
//// tab | Python 3.8+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -137,7 +137,7 @@ Aus diesem extrahiert FastAPI die deklarierten Parameter, und dieses ist es, was
|
||||
|
||||
In diesem Fall hat das erste `CommonQueryParams` in:
|
||||
|
||||
//// tab | Python 3.8+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, ...
|
||||
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
|
||||
|
||||
Sie könnten tatsächlich einfach schreiben:
|
||||
|
||||
//// tab | Python 3.8+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[Any, Depends(CommonQueryParams)]
|
||||
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -197,7 +197,7 @@ Es wird jedoch empfohlen, den Typ zu deklarieren, da Ihr Editor so weiß, was al
|
||||
|
||||
Aber Sie sehen, dass wir hier etwas Codeduplizierung haben, indem wir `CommonQueryParams` zweimal schreiben:
|
||||
|
||||
//// tab | Python 3.8+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -225,7 +225,7 @@ In diesem speziellen Fall können Sie Folgendes tun:
|
||||
|
||||
Anstatt zu schreiben:
|
||||
|
||||
//// tab | Python 3.8+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8+ nicht annotiert
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
|
||||
|
||||
... schreiben Sie:
|
||||
|
||||
//// tab | Python 3.8+
|
||||
//// tab | Python 3.10+
|
||||
|
||||
```Python
|
||||
commons: Annotated[CommonQueryParams, Depends()]
|
||||
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
|
||||
|
||||
////
|
||||
|
||||
//// tab | Python 3.8 nicht annotiert
|
||||
//// tab | Python 3.10+ nicht annotiert
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -6,15 +6,15 @@ Oder die Abhängigkeit gibt keinen Wert zurück.
|
||||
|
||||
Aber Sie müssen sie trotzdem ausführen/auflösen.
|
||||
|
||||
In diesen Fällen können Sie, anstatt einen Parameter der *Pfadoperation-Funktion* mit `Depends` zu deklarieren, eine `list`e von `dependencies` zum *Pfadoperation-Dekorator* hinzufügen.
|
||||
In diesen Fällen können Sie, anstatt einen Parameter der *Pfadoperation-Funktion* mit `Depends` zu deklarieren, eine `list` von `dependencies` zum *Pfadoperation-Dekorator* hinzufügen.
|
||||
|
||||
## `dependencies` zum *Pfadoperation-Dekorator* hinzufügen { #add-dependencies-to-the-path-operation-decorator }
|
||||
|
||||
Der *Pfadoperation-Dekorator* erhält ein optionales Argument `dependencies`.
|
||||
|
||||
Es sollte eine `list`e von `Depends()` sein:
|
||||
Es sollte eine `list` von `Depends()` sein:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py310.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.
|
||||
|
||||
@@ -44,13 +44,13 @@ Sie können dieselben Abhängigkeits-*Funktionen* verwenden, die Sie normalerwei
|
||||
|
||||
Sie können Anforderungen für einen <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> (wie Header) oder andere Unterabhängigkeiten deklarieren:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
|
||||
|
||||
### Exceptions auslösen { #raise-exceptions }
|
||||
|
||||
Die Abhängigkeiten können Exceptions `raise`n, genau wie normale Abhängigkeiten:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
|
||||
|
||||
### Rückgabewerte { #return-values }
|
||||
|
||||
@@ -58,7 +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:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
|
||||
{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
|
||||
|
||||
## Abhängigkeiten für eine Gruppe von *Pfadoperationen* { #dependencies-for-a-group-of-path-operations }
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Abhängigkeiten mit `yield` { #dependencies-with-yield }
|
||||
|
||||
FastAPI unterstützt Abhängigkeiten, die nach Abschluss einige <abbr title="Manchmal auch genannt „Exit Code“, „Cleanup Code“, „Teardown Code“, „Closing Code“, „Kontext Manager Exit Code“, usw.">zusätzliche Schritte ausführen</abbr>.
|
||||
FastAPI unterstützt Abhängigkeiten, die einige <dfn title="manchmal auch genannt: „Exit Code“, „Cleanup Code“, „Teardown Code“, „Closing Code“, „Kontextmanager Exit Code“, usw.">zusätzliche Schritte nach Abschluss</dfn> ausführen.
|
||||
|
||||
Verwenden Sie dazu `yield` statt `return` und schreiben Sie die zusätzlichen Schritte / den zusätzlichen Code danach.
|
||||
|
||||
@@ -29,15 +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 <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr> erzeugt wird:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *}
|
||||
{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
|
||||
|
||||
Der ge`yield`ete Wert ist das, was in *Pfadoperationen* und andere Abhängigkeiten eingefügt wird:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
|
||||
{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
|
||||
|
||||
Der auf die `yield`-Anweisung folgende Code wird ausgeführt, nachdem die Response erstellt wurde, aber bevor sie gesendet wird:
|
||||
Der auf die `yield`-Anweisung folgende Code wird nach der Response ausgeführt:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
|
||||
{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -51,23 +51,23 @@ Sie können `async`- oder reguläre Funktionen verwenden.
|
||||
|
||||
Wenn Sie einen `try`-Block in einer Abhängigkeit mit `yield` verwenden, empfangen Sie alle Exceptions, die bei Verwendung der Abhängigkeit geworfen wurden.
|
||||
|
||||
Wenn beispielsweise ein Code irgendwann in der Mitte, in einer anderen Abhängigkeit oder in einer *Pfadoperation*, ein „Rollback“ einer Datenbanktransaktion oder einen anderen Fehler verursacht, empfangen Sie die resultierende Exception in Ihrer Abhängigkeit.
|
||||
Wenn beispielsweise ein Code irgendwann in der Mitte, in einer anderen Abhängigkeit oder in einer *Pfadoperation*, ein „Rollback“ einer Datenbanktransaktion macht oder eine andere Exception verursacht, empfangen Sie die Exception in Ihrer Abhängigkeit.
|
||||
|
||||
Sie können also mit `except SomeException` diese bestimmte Exception innerhalb der Abhängigkeit handhaben.
|
||||
|
||||
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.
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
|
||||
{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
|
||||
|
||||
## Unterabhängigkeiten mit `yield` { #sub-dependencies-with-yield }
|
||||
|
||||
Sie können Unterabhängigkeiten und „Bäume“ von Unterabhängigkeiten beliebiger Größe und Form haben, und einige oder alle davon können `yield` verwenden.
|
||||
Sie können Unterabhängigkeiten und „Bäume“ von Unterabhhängigkeiten beliebiger Größe und Form haben, und einige oder alle davon können `yield` verwenden.
|
||||
|
||||
**FastAPI** stellt sicher, dass der „Exit-Code“ in jeder Abhängigkeit mit `yield` in der richtigen Reihenfolge ausgeführt wird.
|
||||
|
||||
Beispielsweise kann `dependency_c` von `dependency_b` und `dependency_b` von `dependency_a` abhängen:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
|
||||
{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
|
||||
|
||||
Und alle können `yield` verwenden.
|
||||
|
||||
@@ -75,7 +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.
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
|
||||
{* ../../docs_src/dependencies/tutorial008_an_py310.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.
|
||||
|
||||
@@ -95,9 +95,11 @@ Dieses funktioniert dank Pythons <a href="https://docs.python.org/3/library/cont
|
||||
|
||||
## Abhängigkeiten mit `yield` und `HTTPException` { #dependencies-with-yield-and-httpexception }
|
||||
|
||||
Sie haben gesehen, dass Ihre Abhängigkeiten `yield` verwenden können und `try`-Blöcke haben können, die Exceptions abfangen.
|
||||
Sie haben gesehen, dass Sie Abhängigkeiten mit `yield` verwenden und `try`-Blöcke haben können, die versuchen, irgendeinen Code auszuführen und dann, nach `finally`, Exit-Code ausführen.
|
||||
|
||||
Auf die gleiche Weise könnten Sie im Exit-Code nach dem `yield` eine `HTTPException` oder ähnliches auslösen.
|
||||
Sie können auch `except` verwenden, um die geworfene Exception abzufangen und damit etwas zu tun.
|
||||
|
||||
Zum Beispiel können Sie eine andere Exception auslösen, wie `HTTPException`.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
@@ -107,25 +109,25 @@ Aber es ist für Sie da, wenn Sie es brauchen. 🤓
|
||||
|
||||
///
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
|
||||
{* ../../docs_src/dependencies/tutorial008b_an_py310.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#install-custom-exception-handlers){.internal-link target=_blank} zu erstellen.
|
||||
Wenn Sie Exceptions abfangen und darauf basierend eine benutzerdefinierte Response erstellen möchten, erstellen Sie einen [benutzerdefinierten Exceptionhandler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
|
||||
|
||||
## Abhängigkeiten mit `yield` und `except` { #dependencies-with-yield-and-except }
|
||||
|
||||
Wenn Sie eine Exception mit `except` in einer Abhängigkeit mit `yield` abfangen und sie nicht erneut auslösen (oder eine neue Exception auslösen), kann FastAPI nicht feststellen, dass es eine Exception gab, genau so wie es bei normalem Python der Fall wäre:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
|
||||
{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
|
||||
|
||||
In diesem Fall sieht der Client eine *HTTP 500 Internal Server Error*-Response, wie es sein sollte, da wir keine `HTTPException` oder Ähnliches auslösen, aber der Server hat **keine Logs** oder einen anderen Hinweis darauf, was der Fehler war. 😱
|
||||
|
||||
### In Abhängigkeiten mit `yield` und `except` immer `raise` verwenden { #always-raise-in-dependencies-with-yield-and-except }
|
||||
|
||||
Wenn Sie eine Exception in einer Abhängigkeit mit `yield` abfangen, sollten Sie – sofern Sie nicht eine andere `HTTPException` oder Ähnliches auslösen – die ursprüngliche Exception erneut auslösen.
|
||||
Wenn Sie eine Exception in einer Abhängigkeit mit `yield` abfangen, sollten Sie – sofern Sie nicht eine andere `HTTPException` oder Ähnliches auslösen – **die ursprüngliche Exception erneut auslösen**.
|
||||
|
||||
Sie können dieselbe Exception mit `raise` erneut auslösen:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
|
||||
{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
|
||||
|
||||
Jetzt erhält der Client dieselbe *HTTP 500 Internal Server Error*-Response, aber der Server enthält unseren benutzerdefinierten `InternalError` in den Logs. 😎
|
||||
|
||||
@@ -178,48 +180,60 @@ Nachdem eine dieser Responses gesendet wurde, kann keine weitere Response gesend
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Obiges Diagramm verwendet `HTTPException`, aber Sie können auch jede andere Exception auslösen, die Sie in einer Abhängigkeit mit `yield` abfangen, oder mit einem [benutzerdefinierten Exceptionhandler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} erstellt haben.
|
||||
|
||||
Wenn Sie eine Exception auslösen, wird sie an die Abhängigkeiten mit `yield` weitergegeben, einschließlich `HTTPException`. In den meisten Fällen sollten Sie dieselbe Exception oder eine neue aus der Abhängigkeit mit `yield` erneut auslösen, um sicherzustellen, dass sie korrekt gehandhabt wird.
|
||||
Wenn Sie in dem Code der *Pfadoperation-Funktion* irgendeine Exception auslösen, wird sie an die Abhängigkeiten mit `yield` weitergegeben, einschließlich `HTTPException`. In den meisten Fällen sollten Sie dieselbe Exception oder eine neue aus der Abhängigkeit mit `yield` erneut auslösen, um sicherzustellen, dass sie korrekt gehandhabt wird.
|
||||
|
||||
///
|
||||
|
||||
## Frühes Beenden und `scope` { #early-exit-and-scope }
|
||||
|
||||
Normalerweise wird der Exit-Code von Abhängigkeiten mit `yield` ausgeführt **nachdem die Response** an den Client gesendet wurde.
|
||||
|
||||
Wenn Sie aber wissen, dass Sie die Abhängigkeit nach der Rückkehr aus der *Pfadoperation-Funktion* nicht mehr benötigen, können Sie `Depends(scope="function")` verwenden, um FastAPI mitzuteilen, dass es die Abhängigkeit nach der Rückkehr aus der *Pfadoperation-Funktion* schließen soll, jedoch **bevor** die **Response gesendet wird**.
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
|
||||
|
||||
`Depends()` erhält einen `scope`-Parameter, der sein kann:
|
||||
|
||||
* `"function"`: startet die Abhängigkeit vor der *Pfadoperation-Funktion*, die den Request bearbeitet, beendet die Abhängigkeit nach dem Ende der *Pfadoperation-Funktion*, aber **bevor** die Response an den Client zurückgesendet wird. Die Abhängigkeitsfunktion wird also **um** die *Pfadoperation-**Funktion*** **herum** ausgeführt.
|
||||
* `"request"`: startet die Abhängigkeit vor der *Pfadoperation-Funktion*, die den Request bearbeitet (ähnlich wie bei `"function"`), beendet sie jedoch **nachdem** die Response an den Client zurückgesendet wurde. Die Abhängigkeitsfunktion wird also **um** den **Request**- und Response-Zyklus **herum** ausgeführt.
|
||||
|
||||
Wenn nicht angegeben und die Abhängigkeit `yield` hat, hat sie standardmäßig einen `scope` von `"request"`.
|
||||
|
||||
### `scope` für Unterabhängigkeiten { #scope-for-sub-dependencies }
|
||||
|
||||
Wenn Sie eine Abhängigkeit mit `scope="request"` (dem Default) deklarieren, muss jede Unterabhängigkeit ebenfalls einen `scope` von `"request"` haben.
|
||||
|
||||
Eine Abhängigkeit mit `scope` von `"function"` kann jedoch Abhängigkeiten mit `scope` von `"function"` und `scope` von `"request"` haben.
|
||||
|
||||
Das liegt daran, dass jede Abhängigkeit in der Lage sein muss, ihren Exit-Code vor den Unterabhängigkeiten auszuführen, da sie diese während ihres Exit-Codes möglicherweise noch verwenden muss.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
participant client as Client
|
||||
participant dep_req as Abhängigkeit scope="request"
|
||||
participant dep_func as Abhängigkeit scope="function"
|
||||
participant operation as Pfadoperation
|
||||
|
||||
client ->> dep_req: Startet den Request
|
||||
Note over dep_req: Führt den Code bis zum yield aus
|
||||
dep_req ->> dep_func: Reicht Abhängigkeit weiter
|
||||
Note over dep_func: Führt den Code bis zum yield aus
|
||||
dep_func ->> operation: Führt Pfadoperation mit Abhängigkeit aus
|
||||
operation ->> dep_func: Kehrt aus Pfadoperation zurück
|
||||
Note over dep_func: Führt Code nach yield aus
|
||||
Note over dep_func: ✅ Abhängigkeit geschlossen
|
||||
dep_func ->> client: Sendet Response an Client
|
||||
Note over client: Response gesendet
|
||||
Note over dep_req: Führt Code nach yield aus
|
||||
Note over dep_req: ✅ Abhängigkeit geschlossen
|
||||
```
|
||||
|
||||
## Abhängigkeiten mit `yield`, `HTTPException`, `except` und Hintergrundtasks { #dependencies-with-yield-httpexception-except-and-background-tasks }
|
||||
|
||||
/// warning | Achtung
|
||||
|
||||
Sie benötigen diese technischen Details höchstwahrscheinlich nicht, Sie können diesen Abschnitt überspringen und weiter unten fortfahren.
|
||||
|
||||
Diese Details sind vor allem dann nützlich, wenn Sie eine Version von FastAPI vor 0.106.0 verwendet haben und Ressourcen aus Abhängigkeiten mit `yield` in Hintergrundtasks verwendet haben.
|
||||
|
||||
///
|
||||
|
||||
### Abhängigkeiten mit `yield` und `except`, technische Details { #dependencies-with-yield-and-except-technical-details }
|
||||
|
||||
Vor FastAPI 0.110.0 war es so, dass wenn Sie eine Abhängigkeit mit `yield` verwendeten und dort eine Exception mit `except` abfingen und die Exception nicht erneut auslösten, diese Exception automatisch an Exceptionhandler oder den internen Serverfehler-Handler weitergereicht/ausgelöst wurde.
|
||||
|
||||
Dies wurde in Version 0.110.0 geändert, um unbehandelte Speichernutzung durch weitergereichte Exceptions ohne Handler (interne Serverfehler) zu beheben und um das Verhalten an regulären Python-Code anzugleichen.
|
||||
|
||||
### Hintergrundtasks und Abhängigkeiten mit `yield`, technische Details { #background-tasks-and-dependencies-with-yield-technical-details }
|
||||
|
||||
Vor FastAPI 0.106.0 war das Auslösen von Exceptions nach `yield` nicht möglich, der Exit-Code in Abhängigkeiten mit `yield` wurde ausgeführt, *nachdem* die Response gesendet wurde, die [Exceptionhandler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank} wären also bereits ausgeführt worden.
|
||||
|
||||
Dies wurde hauptsächlich so konzipiert, damit die gleichen Objekte, die durch Abhängigkeiten ge`yield`et werden, innerhalb von Hintergrundtasks verwendet werden können, da der Exit-Code ausgeführt wird, nachdem die Hintergrundtasks abgeschlossen sind.
|
||||
|
||||
Da dies jedoch bedeuten würde, darauf zu warten, dass die Response durch das Netzwerk reist, während eine Ressource unnötigerweise in einer Abhängigkeit mit yield gehalten wird (z. B. eine Datenbankverbindung), wurde dies in FastAPI 0.106.0 geändert.
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
Darüber hinaus handelt es sich bei einem Hintergrundtask normalerweise um einen unabhängigen Satz von Logik, der separat behandelt werden sollte, mit eigenen Ressourcen (z. B. einer eigenen Datenbankverbindung).
|
||||
|
||||
Auf diese Weise erhalten Sie wahrscheinlich saubereren Code.
|
||||
|
||||
///
|
||||
|
||||
Wenn Sie sich früher auf dieses Verhalten verlassen haben, sollten Sie jetzt die Ressourcen für Hintergrundtasks innerhalb des Hintergrundtasks selbst erstellen und intern nur Daten verwenden, die nicht von den Ressourcen von Abhängigkeiten mit `yield` abhängen.
|
||||
|
||||
Anstatt beispielsweise dieselbe Datenbanksitzung zu verwenden, würden Sie eine neue Datenbanksitzung innerhalb des Hintergrundtasks erstellen und die Objekte mithilfe dieser neuen Sitzung aus der Datenbank abrufen. Und anstatt das Objekt aus der Datenbank als Parameter an die Hintergrundtask-Funktion zu übergeben, würden Sie die ID dieses Objekts übergeben und das Objekt dann innerhalb der Hintergrundtask-Funktion erneut laden.
|
||||
Abhängigkeiten mit `yield` haben sich im Laufe der Zeit weiterentwickelt, um verschiedene Anwendungsfälle abzudecken und einige Probleme zu beheben.
|
||||
|
||||
Wenn Sie sehen möchten, was sich in verschiedenen Versionen von FastAPI geändert hat, lesen Sie mehr dazu im fortgeschrittenen Teil, unter [Fortgeschrittene Abhängigkeiten – Abhängigkeiten mit `yield`, `HTTPException`, `except` und Hintergrundtasks](../../advanced/advanced-dependencies.md#dependencies-with-yield-httpexception-except-and-background-tasks){.internal-link target=_blank}.
|
||||
## Kontextmanager { #context-managers }
|
||||
|
||||
### Was sind „Kontextmanager“ { #what-are-context-managers }
|
||||
@@ -254,7 +268,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:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *}
|
||||
{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
|
||||
|
||||
/// tip | Tipp
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ Bei einigen Anwendungstypen möchten Sie möglicherweise Abhängigkeiten zur ges
|
||||
|
||||
In diesem Fall werden sie auf alle *Pfadoperationen* in der Anwendung angewendet:
|
||||
|
||||
{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[16] *}
|
||||
{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
|
||||
|
||||
|
||||
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 App.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Abhängigkeiten { #dependencies }
|
||||
|
||||
**FastAPI** hat ein sehr mächtiges, aber intuitives **<abbr title="auch bekannt als: Komponenten, Ressourcen, Provider, Services, Injectables">Dependency Injection</abbr>** System.
|
||||
**FastAPI** hat ein sehr mächtiges, aber intuitives **<dfn title="auch bekannt als Komponenten, Ressourcen, Provider, Services, Injectables">Abhängigkeitsinjektion</dfn>** System.
|
||||
|
||||
Es ist so konzipiert, sehr einfach zu verwenden zu sein und es jedem Entwickler sehr leicht zu machen, andere Komponenten mit **FastAPI** zu integrieren.
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user