mirror of
https://github.com/fastapi/fastapi.git
synced 2025-12-24 14:48:35 -05:00
Compare commits
2010 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c81e136d75 | ||
|
|
79846b2d2b | ||
|
|
1ccc5a862b | ||
|
|
8df86309c8 | ||
|
|
925ba5c652 | ||
|
|
1bb998d516 | ||
|
|
89fd635925 | ||
|
|
9f13595247 | ||
|
|
bf9bb08b28 | ||
|
|
75f59c46d5 | ||
|
|
fe975b0031 | ||
|
|
c21e3371b8 | ||
|
|
acd4c11282 | ||
|
|
08ba3a98a3 | ||
|
|
0cc8e9cf31 | ||
|
|
8ca7c5c29d | ||
|
|
cd6150806f | ||
|
|
571b5c6f0c | ||
|
|
c1f41fc5fe | ||
|
|
6e129dbaaf | ||
|
|
da2f365db4 | ||
|
|
dfe58433c0 | ||
|
|
1267736d9f | ||
|
|
7048ecfa7b | ||
|
|
d1f1425392 | ||
|
|
d824a5ca9b | ||
|
|
723d47403b | ||
|
|
d455f3f868 | ||
|
|
4b9e9e40b5 | ||
|
|
fa103cf1fd | ||
|
|
c6be4c6d65 | ||
|
|
0ab88cd1a9 | ||
|
|
9bdb8cc45a | ||
|
|
48afd32ac8 | ||
|
|
48e9d87e7e | ||
|
|
dafce52bc7 | ||
|
|
d82809d90d | ||
|
|
1ae5466140 | ||
|
|
c4128e7f5a | ||
|
|
6bc0d210da | ||
|
|
08f049208e | ||
|
|
221b22200a | ||
|
|
3eac0a4a87 | ||
|
|
fdf66c825e | ||
|
|
6ce6c8954c | ||
|
|
ac4bf3b5eb | ||
|
|
6ab811763f | ||
|
|
d4e85da18b | ||
|
|
d666ccb622 | ||
|
|
38f0cad517 | ||
|
|
bd90bed02a | ||
|
|
546392db98 | ||
|
|
0bc87ec77c | ||
|
|
fbfd53542e | ||
|
|
994ea1ad33 | ||
|
|
69673548bc | ||
|
|
166d348ea6 | ||
|
|
9eaed2eb37 | ||
|
|
f63b3ad53e | ||
|
|
375513f114 | ||
|
|
ef176c6631 | ||
|
|
7b7e86a307 | ||
|
|
25aabe05ce | ||
|
|
392ffaae43 | ||
|
|
202ee0497a | ||
|
|
321e873c95 | ||
|
|
4860631468 | ||
|
|
8e4c96c703 | ||
|
|
39813aa9b0 | ||
|
|
3e3278ed3f | ||
|
|
c8a07078cf | ||
|
|
59f91db1d2 | ||
|
|
f04b61bd16 | ||
|
|
253d58bc5c | ||
|
|
78b8a9b6ec | ||
|
|
c26db94a90 | ||
|
|
d1f3753e5e | ||
|
|
d5b0cc9f58 | ||
|
|
42daed222e | ||
|
|
fd3bfe9f50 | ||
|
|
1fea9c5626 | ||
|
|
d783463ebd | ||
|
|
8a4cfa52af | ||
|
|
25382d2d19 | ||
|
|
b9bb441b23 | ||
|
|
e33f30a607 | ||
|
|
cc9a73c3f8 | ||
|
|
66e03c816b | ||
|
|
639cf3440a | ||
|
|
2f1b856fe6 | ||
|
|
31e148ba8e | ||
|
|
40c2c44ff9 | ||
|
|
c5f72f02cd | ||
|
|
9b83a00c40 | ||
|
|
83012a9cf6 | ||
|
|
8625189351 | ||
|
|
e570371003 | ||
|
|
4d099250f6 | ||
|
|
9ef46a2299 | ||
|
|
30a9d68232 | ||
|
|
03bb7c166c | ||
|
|
c5f343a4fd | ||
|
|
83050bead6 | ||
|
|
bd219c2bbf | ||
|
|
4b95025d44 | ||
|
|
ff64772dd1 | ||
|
|
e8fd74e737 | ||
|
|
87842ac0db | ||
|
|
7674da89d3 | ||
|
|
e9326de161 | ||
|
|
97effae92d | ||
|
|
a8bde44029 | ||
|
|
be54d44b0c | ||
|
|
35d93d59d8 | ||
|
|
7b3727e03e | ||
|
|
a270ab0c3f | ||
|
|
f6f39d8714 | ||
|
|
4f4035262c | ||
|
|
6879082b36 | ||
|
|
52ca6cb95b | ||
|
|
9e283ef66b | ||
|
|
75e7e9e0a2 | ||
|
|
2ca77f9a4d | ||
|
|
3c05189b06 | ||
|
|
a04acf6900 | ||
|
|
d566c6cbca | ||
|
|
6e94ec2bf0 | ||
|
|
e85c109bcd | ||
|
|
445e611a29 | ||
|
|
392766bcfa | ||
|
|
5ed70f285b | ||
|
|
d6fb9429d2 | ||
|
|
9a5147382e | ||
|
|
99deead7fc | ||
|
|
18e6c3ff6a | ||
|
|
3c5536a780 | ||
|
|
79eed9d7d9 | ||
|
|
e37d504e27 | ||
|
|
70688eb7b2 | ||
|
|
16599b7356 | ||
|
|
148bcf5ce4 | ||
|
|
e4c8df062b | ||
|
|
b313f86338 | ||
|
|
9293795e99 | ||
|
|
58757f63af | ||
|
|
88dc4ce3d7 | ||
|
|
c9d3656a6e | ||
|
|
3e4840f21b | ||
|
|
9cb2586499 | ||
|
|
8b62319d6c | ||
|
|
6e3c707c60 | ||
|
|
94fa151881 | ||
|
|
a4f3bc5a69 | ||
|
|
05342cc264 | ||
|
|
8115282ed3 | ||
|
|
9ad2cb29f9 | ||
|
|
23d0efa894 | ||
|
|
e1129af819 | ||
|
|
c59539913d | ||
|
|
7a64587d7f | ||
|
|
62fc0b4923 | ||
|
|
fc7da62005 | ||
|
|
40df42f5c7 | ||
|
|
0b0af37b0e | ||
|
|
73920366e5 | ||
|
|
682067cab2 | ||
|
|
ca30b92dd7 | ||
|
|
72b542d90a | ||
|
|
9012ab8bcd | ||
|
|
9530defba8 | ||
|
|
7c23bbd96f | ||
|
|
11b6c0146d | ||
|
|
4e29835609 | ||
|
|
9858577cd6 | ||
|
|
cd1ee83435 | ||
|
|
fe74890b4b | ||
|
|
97a2ebc219 | ||
|
|
805226c2b0 | ||
|
|
5905c3f740 | ||
|
|
00f3c831f3 | ||
|
|
e84cb6663e | ||
|
|
fb8e9083f4 | ||
|
|
6b83525ff4 | ||
|
|
fba7493042 | ||
|
|
53973f7f94 | ||
|
|
1562592bde | ||
|
|
52a84175c1 | ||
|
|
929289b630 | ||
|
|
69bd7d8501 | ||
|
|
a6af7c27f8 | ||
|
|
aa6a8e5d49 | ||
|
|
c482dd3d42 | ||
|
|
681e5c0199 | ||
|
|
eb39b0f8f8 | ||
|
|
27ce2e2108 | ||
|
|
f56b0d571d | ||
|
|
5c6d7b2ff3 | ||
|
|
78813a543d | ||
|
|
903e3be3b8 | ||
|
|
a17da3d0f4 | ||
|
|
d202598c71 | ||
|
|
2dfdcea69a | ||
|
|
789d649fba | ||
|
|
bea1fdd2eb | ||
|
|
929c700117 | ||
|
|
f4e895bc8a | ||
|
|
adef9f4c02 | ||
|
|
6e1152d31f | ||
|
|
9812116dc7 | ||
|
|
2583a83f9d | ||
|
|
59d654672f | ||
|
|
d0027de64f | ||
|
|
3c20b6e42b | ||
|
|
3178c17776 | ||
|
|
1be95ba02d | ||
|
|
2a3a786dd7 | ||
|
|
a3edc76051 | ||
|
|
d70eef825e | ||
|
|
679aee85ce | ||
|
|
cb35e275e3 | ||
|
|
18d087f9c6 | ||
|
|
d0573f5713 | ||
|
|
efc12c5cdb | ||
|
|
4d5cbc71ac | ||
|
|
10500dbc03 | ||
|
|
63ad0ed4a6 | ||
|
|
dc9fb1305a | ||
|
|
9efab1bd96 | ||
|
|
97f04ab58c | ||
|
|
1ba515a18d | ||
|
|
5f1cc3a5ff | ||
|
|
41db4cba4c | ||
|
|
83bcdc40d8 | ||
|
|
8bdab084f9 | ||
|
|
5c4054ab8a | ||
|
|
7e4e0d22ae | ||
|
|
612b8ff168 | ||
|
|
46bb5d2c4b | ||
|
|
c458ca6f07 | ||
|
|
46974c510e | ||
|
|
89ec1f2d36 | ||
|
|
128c925c35 | ||
|
|
884203676d | ||
|
|
9b4e85f088 | ||
|
|
991db7b05a | ||
|
|
ebd917a530 | ||
|
|
99d8470a8e | ||
|
|
7c5626bef7 | ||
|
|
91e5a5d1cf | ||
|
|
fcc4dd61f1 | ||
|
|
0b53ee505b | ||
|
|
c942a9b8d0 | ||
|
|
c77384fc8f | ||
|
|
0c07e542a7 | ||
|
|
ec30c3001d | ||
|
|
22837ee202 | ||
|
|
0eb05cabbf | ||
|
|
6883f362a5 | ||
|
|
4638b2c64e | ||
|
|
3c01b2469f | ||
|
|
63a5ffcf57 | ||
|
|
da1c67338f | ||
|
|
46a509649d | ||
|
|
1d416c4c53 | ||
|
|
89095eba4f | ||
|
|
5a63f660de | ||
|
|
9c483505e3 | ||
|
|
ad0e923fed | ||
|
|
fc717f84ff | ||
|
|
b1204a9b62 | ||
|
|
16630bf54d | ||
|
|
50ea75ae98 | ||
|
|
a0852e2f53 | ||
|
|
fa74093440 | ||
|
|
bcd9ab95e1 | ||
|
|
d537ee93d7 | ||
|
|
1c93d5523a | ||
|
|
f92f87d379 | ||
|
|
57141ccac4 | ||
|
|
46b903f70b | ||
|
|
fdbd48be5f | ||
|
|
5f67ac6fd6 | ||
|
|
ba5310f731 | ||
|
|
f57ccd8ef3 | ||
|
|
c040e3602a | ||
|
|
86d4073632 | ||
|
|
59208e4ddc | ||
|
|
0781a91d19 | ||
|
|
41735d2de9 | ||
|
|
a0c717d784 | ||
|
|
0ed9ca78bc | ||
|
|
678d35994a | ||
|
|
a7edd0b80d | ||
|
|
f36d2e2b2b | ||
|
|
5f0e095689 | ||
|
|
ccd242348f | ||
|
|
066cfae56e | ||
|
|
51e768e85a | ||
|
|
10fbfd6dc7 | ||
|
|
85e602d7cc | ||
|
|
fbc13d1f5b | ||
|
|
d4e2bdb33a | ||
|
|
8a5befd099 | ||
|
|
9a442c9730 | ||
|
|
4fa4965beb | ||
|
|
5f4680201c | ||
|
|
5cd99a9517 | ||
|
|
b6ea8414a9 | ||
|
|
be3e29fb3c | ||
|
|
cf730518bc | ||
|
|
d62f5c1b28 | ||
|
|
4cf9075809 | ||
|
|
a0c677ef0d | ||
|
|
54aa27ca07 | ||
|
|
ac9f56ea5e | ||
|
|
ed9425ef50 | ||
|
|
9a85535e7f | ||
|
|
c9308cf070 | ||
|
|
058cb6e88e | ||
|
|
876ea7978f | ||
|
|
da0bfd22aa | ||
|
|
d0917ce015 | ||
|
|
6002290659 | ||
|
|
e92a8649f9 | ||
|
|
c28337e61d | ||
|
|
f4aea58528 | ||
|
|
fcab59be88 | ||
|
|
6aa9ef0c96 | ||
|
|
c7fe6fea33 | ||
|
|
c53e5bd4b1 | ||
|
|
db4452d47e | ||
|
|
53127efde5 | ||
|
|
9974c4b6ac | ||
|
|
7ff62468a0 | ||
|
|
38493f8ae1 | ||
|
|
e0945eb1c8 | ||
|
|
a26a3c1cbf | ||
|
|
2889b4a3df | ||
|
|
8b20eece4c | ||
|
|
330e8112ac | ||
|
|
7a2e9c7aaa | ||
|
|
1613749cc3 | ||
|
|
669b3a4cb8 | ||
|
|
5f089435e5 | ||
|
|
f1c61dec0c | ||
|
|
a96effa86e | ||
|
|
29c36f9d3f | ||
|
|
fcf49a04eb | ||
|
|
558d929568 | ||
|
|
f3086a7b15 | ||
|
|
64d512e349 | ||
|
|
88556dafb6 | ||
|
|
6a46532cc4 | ||
|
|
c75de8cba2 | ||
|
|
85443e64ee | ||
|
|
2623a06105 | ||
|
|
d72599b4dc | ||
|
|
16e058697d | ||
|
|
bbfa450991 | ||
|
|
22524a1610 | ||
|
|
959f6bf209 | ||
|
|
80eac96c70 | ||
|
|
bbb8fe1e60 | ||
|
|
bfb1422555 | ||
|
|
0cc40ed664 | ||
|
|
4a1c69e6c2 | ||
|
|
42a4ed7a18 | ||
|
|
146b9d6e04 | ||
|
|
e0d1619362 | ||
|
|
fdfcb9412e | ||
|
|
866a24f879 | ||
|
|
ee4b2bb8ae | ||
|
|
f67b19f0f7 | ||
|
|
9dc1a3026d | ||
|
|
e13df8ee79 | ||
|
|
e04878edfe | ||
|
|
0e3ff851c2 | ||
|
|
e866a2c7e1 | ||
|
|
90fc4299d1 | ||
|
|
a3a37a4213 | ||
|
|
3c6528460c | ||
|
|
5ba0c8c002 | ||
|
|
0ae8db447a | ||
|
|
9c6086eee6 | ||
|
|
ebe69913ae | ||
|
|
81115dba53 | ||
|
|
1d1859675f | ||
|
|
c6aa28bea2 | ||
|
|
20f689ded2 | ||
|
|
1213227667 | ||
|
|
e782ba43ce | ||
|
|
6ddd0c64b0 | ||
|
|
a05e8b4e6f | ||
|
|
e83aa43296 | ||
|
|
95cbb43b06 | ||
|
|
babe2f9b03 | ||
|
|
add7c4800c | ||
|
|
b741ea7619 | ||
|
|
74ce2204ae | ||
|
|
823df88c34 | ||
|
|
3658733b5e | ||
|
|
715c0341a9 | ||
|
|
adcf03f2bc | ||
|
|
1073062c7f | ||
|
|
7291cead65 | ||
|
|
4267bd1f4f | ||
|
|
b2aa3593be | ||
|
|
ed0fcba7cb | ||
|
|
22a155efc1 | ||
|
|
306326a213 | ||
|
|
4fec12b354 | ||
|
|
275306c369 | ||
|
|
4d270463af | ||
|
|
6620273083 | ||
|
|
0b4fe10c8f | ||
|
|
c4007cb9ec | ||
|
|
3ec498af63 | ||
|
|
895789bed0 | ||
|
|
ef5d6181b6 | ||
|
|
3079ba925e | ||
|
|
ddf6daeb07 | ||
|
|
f3efaf69da | ||
|
|
f8460a8b54 | ||
|
|
d0cc996dc7 | ||
|
|
c70fab38e7 | ||
|
|
80d68a6eda | ||
|
|
dacb689290 | ||
|
|
dd2f759bac | ||
|
|
4cff206ebb | ||
|
|
0195bb5706 | ||
|
|
0ae8d09189 | ||
|
|
9df22ab864 | ||
|
|
81967f8f93 | ||
|
|
7dd4a4f435 | ||
|
|
94b7527dfd | ||
|
|
a3a8d68715 | ||
|
|
ee035dfa9a | ||
|
|
5a79564dab | ||
|
|
dc1534736d | ||
|
|
fc559b5fcd | ||
|
|
0d43b6552b | ||
|
|
89839eb834 | ||
|
|
f266dc17d7 | ||
|
|
697ec94a7e | ||
|
|
ae369d879a | ||
|
|
198b7ef2cb | ||
|
|
68e04f6531 | ||
|
|
c00e1ec6bf | ||
|
|
d3ff7c620a | ||
|
|
fae28a9bd7 | ||
|
|
0e7478d39c | ||
|
|
dbb43da9c0 | ||
|
|
56f887de15 | ||
|
|
fbe1a803fc | ||
|
|
52b5b08910 | ||
|
|
e7e6404faf | ||
|
|
30b3905ef3 | ||
|
|
b1d0f1e970 | ||
|
|
7250c194da | ||
|
|
173b891603 | ||
|
|
6ae8f07d24 | ||
|
|
b83709add4 | ||
|
|
a71077c530 | ||
|
|
278adc012a | ||
|
|
356a57daa8 | ||
|
|
b9d7f86743 | ||
|
|
adf4e77dd6 | ||
|
|
0e1a9d1c0f | ||
|
|
d8b6aa630c | ||
|
|
0bb8920ae1 | ||
|
|
95c182a42c | ||
|
|
165d57db24 | ||
|
|
ae5280e501 | ||
|
|
d4b2ef8137 | ||
|
|
fd2080aece | ||
|
|
3c8d8c38a7 | ||
|
|
fa92dbf557 | ||
|
|
cd8854c4c7 | ||
|
|
b63398f4b5 | ||
|
|
728b961d35 | ||
|
|
5e34cb1868 | ||
|
|
bbd34c55d5 | ||
|
|
8a72d363c8 | ||
|
|
ee93ad952c | ||
|
|
d26674616c | ||
|
|
40a19fe261 | ||
|
|
8b4546352f | ||
|
|
b3f2f08251 | ||
|
|
3d3a7dbe7e | ||
|
|
d69b5f39b4 | ||
|
|
70213467a6 | ||
|
|
8d1d1703f4 | ||
|
|
1285ba4b2e | ||
|
|
6bbfd27c19 | ||
|
|
4c0b9b831c | ||
|
|
9e6dcba766 | ||
|
|
e1825589ba | ||
|
|
acc59df815 | ||
|
|
d86b54e79b | ||
|
|
6b77179e3b | ||
|
|
8dab25df71 | ||
|
|
22bed0008c | ||
|
|
de6ccd7754 | ||
|
|
26c68c6e0d | ||
|
|
dc10b81d05 | ||
|
|
1f2070af20 | ||
|
|
a95212565a | ||
|
|
d80b065b5e | ||
|
|
dde140d8e3 | ||
|
|
96c3f44a0e | ||
|
|
0539dd9cd3 | ||
|
|
aaf5a380df | ||
|
|
e3c055ba8f | ||
|
|
afe44f0b25 | ||
|
|
8cd8aa4b67 | ||
|
|
26097421d3 | ||
|
|
3df68694c0 | ||
|
|
f3e9dcd891 | ||
|
|
00bdf533ef | ||
|
|
ae56590c51 | ||
|
|
923e0ac0c1 | ||
|
|
a64387c3fc | ||
|
|
c8124496fc | ||
|
|
75792eb82b | ||
|
|
bb53d0b0ea | ||
|
|
f928f3390c | ||
|
|
d5c84594cb | ||
|
|
0968329ed7 | ||
|
|
880c8b37cf | ||
|
|
92181ef182 | ||
|
|
ca2fae0588 | ||
|
|
af3a6ef78b | ||
|
|
eb3ab337ab | ||
|
|
5215b39d50 | ||
|
|
9359a8d65f | ||
|
|
afaa0391a5 | ||
|
|
438656395a | ||
|
|
39319a7ede | ||
|
|
8c6ad35615 | ||
|
|
f90465f5b4 | ||
|
|
1835b3f76d | ||
|
|
2201f29be3 | ||
|
|
68f25120c5 | ||
|
|
7d6e70791d | ||
|
|
18819f9850 | ||
|
|
ad65e72d90 | ||
|
|
ec072d75fe | ||
|
|
09acce4b2c | ||
|
|
f6808e76dc | ||
|
|
f8f5281ef5 | ||
|
|
b993b4af28 | ||
|
|
982911f08f | ||
|
|
634cf22584 | ||
|
|
12f60cac7a | ||
|
|
e7b1b96a54 | ||
|
|
a6a39f3009 | ||
|
|
1ff8df6e7f | ||
|
|
7953353a35 | ||
|
|
6c16d6a4f9 | ||
|
|
eb80b79555 | ||
|
|
ab8988ff7c | ||
|
|
09381ba042 | ||
|
|
767df02814 | ||
|
|
a21c315574 | ||
|
|
7f0e2f6cfa | ||
|
|
94bbb91ec2 | ||
|
|
2f9c6ab36a | ||
|
|
74638fcf7c | ||
|
|
eb2e183361 | ||
|
|
8a9a117ec7 | ||
|
|
e88089ec21 | ||
|
|
3a3b61dc6e | ||
|
|
ea017c9919 | ||
|
|
38802eefeb | ||
|
|
58848897f4 | ||
|
|
73c6011ec4 | ||
|
|
30e7b6a34c | ||
|
|
a9c2b8336b | ||
|
|
f79e6a48a1 | ||
|
|
fb849ee7ef | ||
|
|
e90d53f6f4 | ||
|
|
8afd291572 | ||
|
|
441b726537 | ||
|
|
46f5091c9f | ||
|
|
d268eb2011 | ||
|
|
e5eb56f0b5 | ||
|
|
f9dcff1490 | ||
|
|
5d0e2f58e7 | ||
|
|
b489b327b8 | ||
|
|
48ca7a6368 | ||
|
|
65e4286bc9 | ||
|
|
b862639ce9 | ||
|
|
8fe80e81e1 | ||
|
|
dc7e13846c | ||
|
|
fc4ad71069 | ||
|
|
7e3e4fa7ea | ||
|
|
e23fa40e6c | ||
|
|
a0d79b3706 | ||
|
|
a79228138b | ||
|
|
623b0f37de | ||
|
|
44d1b21ba2 | ||
|
|
0ba0c4662d | ||
|
|
f1feb1427b | ||
|
|
a1cdf8cd44 | ||
|
|
5c576e42be | ||
|
|
9031d1daee | ||
|
|
c07aced06d | ||
|
|
3b5839260f | ||
|
|
50fb34bf55 | ||
|
|
2f21bef91b | ||
|
|
e35df688d5 | ||
|
|
59d154fa6f | ||
|
|
ee182c6a0a | ||
|
|
9197cbd36c | ||
|
|
f30b6c6001 | ||
|
|
71b10e5890 | ||
|
|
49619c0180 | ||
|
|
84f6a03011 | ||
|
|
ec3b6e975c | ||
|
|
35244ee83b | ||
|
|
0be244ad52 | ||
|
|
169af0217e | ||
|
|
21fd708c6e | ||
|
|
ec2ec48293 | ||
|
|
e3339f6770 | ||
|
|
85dc173d19 | ||
|
|
801e90863a | ||
|
|
86fb017aad | ||
|
|
2226f962ff | ||
|
|
b4a98a7224 | ||
|
|
c5954d3bc0 | ||
|
|
80cb57e4b2 | ||
|
|
fb26c1ee70 | ||
|
|
120cf49089 | ||
|
|
48b7804a79 | ||
|
|
19701d12fb | ||
|
|
606028dc8c | ||
|
|
100799cde2 | ||
|
|
c15fce3248 | ||
|
|
b7bd3c1d55 | ||
|
|
3ccb960478 | ||
|
|
6497cb08f5 | ||
|
|
7c3137301b | ||
|
|
397a2e3484 | ||
|
|
2fcf044a90 | ||
|
|
ff47d50a9b | ||
|
|
43d8ebfb4d | ||
|
|
c43120258f | ||
|
|
a0fd613527 | ||
|
|
1d5bbe5552 | ||
|
|
bea5194ffc | ||
|
|
b768643577 | ||
|
|
8047230181 | ||
|
|
6c6382df4d | ||
|
|
f8c875bb3f | ||
|
|
d8f3e8f20d | ||
|
|
1876ebc779 | ||
|
|
1673b3ec11 | ||
|
|
1711403732 | ||
|
|
acab64b3c3 | ||
|
|
0a8d6871fb | ||
|
|
ca437cdfab | ||
|
|
c5be1b0550 | ||
|
|
9262fa8362 | ||
|
|
31690dda2c | ||
|
|
8b66b9ca3e | ||
|
|
975d859ac4 | ||
|
|
82775f7cd0 | ||
|
|
497e5a2422 | ||
|
|
f31ad41dda | ||
|
|
d75c69e01f | ||
|
|
f204e8010a | ||
|
|
bcabbf8b37 | ||
|
|
29df6b3e83 | ||
|
|
16f1d073db | ||
|
|
199916ac8c | ||
|
|
4bb8ac2114 | ||
|
|
a5eff3b78e | ||
|
|
277a53442b | ||
|
|
9cae3cdb09 | ||
|
|
f673e64eeb | ||
|
|
3d0f130ff3 | ||
|
|
9cbd42b13e | ||
|
|
8c593a9cc9 | ||
|
|
f3b04a6118 | ||
|
|
4fcdb31947 | ||
|
|
1bbbdb4b7f | ||
|
|
15dd12629e | ||
|
|
0f7de452dd | ||
|
|
35445828c8 | ||
|
|
ff2daa0471 | ||
|
|
e9098abe8c | ||
|
|
062107159f | ||
|
|
a38b0a7fac | ||
|
|
643291b9ca | ||
|
|
441f75a06c | ||
|
|
688d2db5e3 | ||
|
|
99a41e7f8d | ||
|
|
d71b12f323 | ||
|
|
cb5a200a7c | ||
|
|
2aaac141dd | ||
|
|
03cbdd4f74 | ||
|
|
a7e659e472 | ||
|
|
350745c545 | ||
|
|
d0e4015034 | ||
|
|
b1e691091d | ||
|
|
9b4e6751bb | ||
|
|
8082b45f24 | ||
|
|
86c459d1e8 | ||
|
|
2a91ee945d | ||
|
|
764703cc56 | ||
|
|
71ea5883cd | ||
|
|
cc51b251dd | ||
|
|
6337186ff4 | ||
|
|
88606940f5 | ||
|
|
98bb5480a5 | ||
|
|
170123a41f | ||
|
|
9262a699f2 | ||
|
|
9a87c6d8d2 | ||
|
|
f396912043 | ||
|
|
0696454445 | ||
|
|
a145d3d277 | ||
|
|
453471d07b | ||
|
|
938b1a3542 | ||
|
|
4ce27b5d4d | ||
|
|
f9134fe5e4 | ||
|
|
d8ca285f8d | ||
|
|
1233a7d93b | ||
|
|
38902407c0 | ||
|
|
4fa0cd4def | ||
|
|
edd38c0230 | ||
|
|
8f90e514f4 | ||
|
|
fa1ffa5677 | ||
|
|
c0d6865c10 | ||
|
|
8a353ab911 | ||
|
|
262183b534 | ||
|
|
faf7ce5af5 | ||
|
|
3d201623dd | ||
|
|
59fbdefd7f | ||
|
|
e5980a71c2 | ||
|
|
0d1be46481 | ||
|
|
4fa4432173 | ||
|
|
c9eda31dd6 | ||
|
|
f2bc805113 | ||
|
|
8fc4872c1b | ||
|
|
b017a33ebd | ||
|
|
424674a082 | ||
|
|
944f06a901 | ||
|
|
3279ef38ed | ||
|
|
d286e6a5be | ||
|
|
b1c5b64c2c | ||
|
|
2ef0b9896e | ||
|
|
d07422a07a | ||
|
|
8724c493d9 | ||
|
|
df50d7c13f | ||
|
|
e0962d0b54 | ||
|
|
b7d5746773 | ||
|
|
3005c8c7b9 | ||
|
|
260d97ec6f | ||
|
|
f4620c42cf | ||
|
|
65ed4b5433 | ||
|
|
12342888d6 | ||
|
|
ee4e27a94f | ||
|
|
86fa3cb24f | ||
|
|
9090c771ee | ||
|
|
8df8b037f2 | ||
|
|
792285a047 | ||
|
|
66f6344820 | ||
|
|
b44e85ca8a | ||
|
|
33d61430cf | ||
|
|
146f57b8f7 | ||
|
|
1920c3dd16 | ||
|
|
07b12c8e41 | ||
|
|
4642d5bb86 | ||
|
|
0fd99ec337 | ||
|
|
7c8383c96b | ||
|
|
2b54432a9c | ||
|
|
acd2287b57 | ||
|
|
1d106bd959 | ||
|
|
77fc14eb69 | ||
|
|
41d75b6d1c | ||
|
|
ddd9da3db4 | ||
|
|
197c1d6dd7 | ||
|
|
d9e7a541fd | ||
|
|
c449ae5c74 | ||
|
|
1d8d81a6d5 | ||
|
|
d81c908132 | ||
|
|
cb4da93643 | ||
|
|
3cbfae16cf | ||
|
|
0def8382b8 | ||
|
|
02fae6a38e | ||
|
|
75af472029 | ||
|
|
e1135eddb5 | ||
|
|
acf8a91c25 | ||
|
|
c4f361c0c4 | ||
|
|
cc57bfcf60 | ||
|
|
26f725d259 | ||
|
|
9e018c322c | ||
|
|
3fefc83d42 | ||
|
|
2c31667407 | ||
|
|
233214795a | ||
|
|
e1d0e3874b | ||
|
|
eddbae948f | ||
|
|
5c842586c2 | ||
|
|
fc96370ce3 | ||
|
|
d820267cde | ||
|
|
bd94d313c9 | ||
|
|
2b6f1585ec | ||
|
|
bab5c201da | ||
|
|
aec2d26bac | ||
|
|
d5d6eebd40 | ||
|
|
7982aa5143 | ||
|
|
fd6ce67392 | ||
|
|
d3eb787090 | ||
|
|
6125dc72cd | ||
|
|
cf8b40e660 | ||
|
|
fab2a765de | ||
|
|
9aa698aa67 | ||
|
|
87e29ec2c5 | ||
|
|
abd148f63a | ||
|
|
9f38a05954 | ||
|
|
c89dc736bd | ||
|
|
19769d0483 | ||
|
|
586d17bfb5 | ||
|
|
786b5858e5 | ||
|
|
8a0d4c79c1 | ||
|
|
440d2d2d1a | ||
|
|
e953059054 | ||
|
|
f5d7df3c6c | ||
|
|
1ce16c2f40 | ||
|
|
03d4d4c38e | ||
|
|
2d2f1dee5d | ||
|
|
59e36481dc | ||
|
|
4fcb00328c | ||
|
|
9d56a3cb59 | ||
|
|
78b07cb809 | ||
|
|
6034f80687 | ||
|
|
b93f8a709a | ||
|
|
618c99d774 | ||
|
|
291180bf2d | ||
|
|
cbe8d552c1 | ||
|
|
af18d5c49f | ||
|
|
a698908ed6 | ||
|
|
dba9ea8120 | ||
|
|
f8d4d04015 | ||
|
|
5a864d8261 | ||
|
|
1bf55200a9 | ||
|
|
59b1f353b3 | ||
|
|
569afb4378 | ||
|
|
0f8349fcb7 | ||
|
|
6215fdd39e | ||
|
|
94ca8c1e29 | ||
|
|
f4963f05bf | ||
|
|
d4608a00cf | ||
|
|
699b5ef841 | ||
|
|
3de0fb82bf | ||
|
|
85518bc58b | ||
|
|
ca5d57ea79 | ||
|
|
347e391271 | ||
|
|
a75d080124 | ||
|
|
f0388915a8 | ||
|
|
9e2f5c67b6 | ||
|
|
93e4a19e35 | ||
|
|
e1c6d7d310 | ||
|
|
d23b295b96 | ||
|
|
26e94116c1 | ||
|
|
24968937e5 | ||
|
|
5c5b889288 | ||
|
|
436261b3ea | ||
|
|
5c62a59e7b | ||
|
|
acbe79da37 | ||
|
|
a85aa125d2 | ||
|
|
9af8cc69d5 | ||
|
|
7fe79441c1 | ||
|
|
b8ae84d460 | ||
|
|
ca2b1dbb64 | ||
|
|
672c55ac62 | ||
|
|
66c27c3e07 | ||
|
|
44f4885c66 | ||
|
|
4da33e3031 | ||
|
|
a1ede32f29 | ||
|
|
0a82b3a900 | ||
|
|
d08a062ee2 | ||
|
|
83f6781037 | ||
|
|
764ecae2d4 | ||
|
|
4e9f75912f | ||
|
|
2b10ca1cc4 | ||
|
|
3efb4f7edf | ||
|
|
9c25f9615c | ||
|
|
e7158bc592 | ||
|
|
6d642ef5fb | ||
|
|
b0cd4d7e7e | ||
|
|
0a87bc88b8 | ||
|
|
062efcbb5d | ||
|
|
aa4a69f790 | ||
|
|
eb79441a7f | ||
|
|
fa5639cb35 | ||
|
|
10e3a02582 | ||
|
|
fb9c4b31b9 | ||
|
|
39dbee9d56 | ||
|
|
dd463d0dc2 | ||
|
|
461e0d4cce | ||
|
|
da69a1c4c0 | ||
|
|
a5d697b9b5 | ||
|
|
8e416875ce | ||
|
|
446d194c46 | ||
|
|
cace5a79f7 | ||
|
|
dabb4898f1 | ||
|
|
f282c0e207 | ||
|
|
146ff28d9c | ||
|
|
58ab733f19 | ||
|
|
0a61a6c865 | ||
|
|
fb1f341231 | ||
|
|
652cf4bb6b | ||
|
|
08410ca568 | ||
|
|
0d5e0ba5d5 | ||
|
|
b2c9574fc6 | ||
|
|
a859497a72 | ||
|
|
3c93e803d5 | ||
|
|
0bd8f901df | ||
|
|
864643ef76 | ||
|
|
5d80e02ae8 | ||
|
|
affe542753 | ||
|
|
8e887d7145 | ||
|
|
46cf92c55a | ||
|
|
921b6f742a | ||
|
|
c1fee263e1 | ||
|
|
42d10ef4bf | ||
|
|
637cf89dbd | ||
|
|
a81e2f20a5 | ||
|
|
53076170c0 | ||
|
|
eb89968b36 | ||
|
|
c54fb7e208 | ||
|
|
077e5baf2c | ||
|
|
9c6e0d02bb | ||
|
|
d198f38b45 | ||
|
|
4ba1e81f16 | ||
|
|
b1508dcacc | ||
|
|
bb20f5e60d | ||
|
|
7e4887ea55 | ||
|
|
ffaecddbf6 | ||
|
|
e43f434448 | ||
|
|
eb453a50b8 | ||
|
|
5a28f95a93 | ||
|
|
4093c35058 | ||
|
|
7efdc11075 | ||
|
|
24cda290e8 | ||
|
|
d06b4d7bb8 | ||
|
|
1a8284725a | ||
|
|
4f168c5ada | ||
|
|
b67532ee5c | ||
|
|
c29aa0bc87 | ||
|
|
5551e7282c | ||
|
|
8e68ddbddf | ||
|
|
46882b9ae1 | ||
|
|
e423c8241a | ||
|
|
3581034eff | ||
|
|
b69781b161 | ||
|
|
12db3926b5 | ||
|
|
afe1f69e79 | ||
|
|
426bd096ad | ||
|
|
0ceacef413 | ||
|
|
fee3126d3a | ||
|
|
8f4e3a4377 | ||
|
|
3b686c3774 | ||
|
|
17f0ec8927 | ||
|
|
a6ef62ce7b | ||
|
|
d9fa2311b3 | ||
|
|
c15f042318 | ||
|
|
a8bde38f7c | ||
|
|
496ccc0f70 | ||
|
|
11d0a08acd | ||
|
|
4d26fa5c54 | ||
|
|
eb1d68c789 | ||
|
|
292b8c8ce9 | ||
|
|
cce8d9e32c | ||
|
|
ac0f594305 | ||
|
|
cc0d0f3899 | ||
|
|
67d5ba1efd | ||
|
|
2210c84efd | ||
|
|
378fa4ef75 | ||
|
|
eb515b1af7 | ||
|
|
19fd336cde | ||
|
|
63744b2e8a | ||
|
|
85f0d2b924 | ||
|
|
507e9baf9e | ||
|
|
c6461ad7dc | ||
|
|
5fbf597cd5 | ||
|
|
bc99d2b7b8 | ||
|
|
0eb27ab4d0 | ||
|
|
68c43eb126 | ||
|
|
00ac07f65c | ||
|
|
d8b0a9dc6e | ||
|
|
8c36572d23 | ||
|
|
e0e3224588 | ||
|
|
4e2595f928 | ||
|
|
6de8748788 | ||
|
|
39ec5b33d9 | ||
|
|
557fe61d92 | ||
|
|
458a7fbf15 | ||
|
|
ae22bca9fe | ||
|
|
9229ba8078 | ||
|
|
96ca425b1f | ||
|
|
c86a4e1dd3 | ||
|
|
24749aef71 | ||
|
|
f6a3bc2902 | ||
|
|
ba8c78d87f | ||
|
|
69784e5141 | ||
|
|
8a02a47124 | ||
|
|
5607c198c4 | ||
|
|
cf5e67590a | ||
|
|
655db2af1f | ||
|
|
8c102814fd | ||
|
|
189ac3e280 | ||
|
|
2680f369d0 | ||
|
|
284eb6615d | ||
|
|
099c478655 | ||
|
|
54c02d402a | ||
|
|
4b968c4e39 | ||
|
|
1db0fc2953 | ||
|
|
d29aa3d436 | ||
|
|
1b6350ad9e | ||
|
|
cb7e79ab8a | ||
|
|
fe086a4903 | ||
|
|
64e7deaebc | ||
|
|
bee35f5ae1 | ||
|
|
3a786a7a3a | ||
|
|
eaeafc32c4 | ||
|
|
c8b4e4d455 | ||
|
|
1760da0efa | ||
|
|
f49ba24b71 | ||
|
|
7b6e198d31 | ||
|
|
6ac35b1c2a | ||
|
|
dc9c570733 | ||
|
|
20d4834546 | ||
|
|
f7d7c6c865 | ||
|
|
c03b9b2d4c | ||
|
|
70f1b8ebd0 | ||
|
|
13bf477579 | ||
|
|
ab5afd0b42 | ||
|
|
b5dcd98605 | ||
|
|
2280a48c67 | ||
|
|
8c5d1f30dc | ||
|
|
98a0fe8628 | ||
|
|
38c52fa12d | ||
|
|
7c2ed25d6f | ||
|
|
dda105c50d | ||
|
|
326837443f | ||
|
|
cb5b4e1b7e | ||
|
|
a23eaaeda8 | ||
|
|
d0ced2c7c9 | ||
|
|
3409c9e32f | ||
|
|
53a86a885d | ||
|
|
4ac310875d | ||
|
|
30e742d566 | ||
|
|
84490a2160 | ||
|
|
4d4452ede5 | ||
|
|
25a48287ed | ||
|
|
9a33a0e24c | ||
|
|
27fd954a45 | ||
|
|
ab33ba27af | ||
|
|
e9ba01dc59 | ||
|
|
e809bdc170 | ||
|
|
717a1ec409 | ||
|
|
eba2c66532 | ||
|
|
3788ca4640 | ||
|
|
97fa743ecb | ||
|
|
e726b7b771 | ||
|
|
6a22b75afd | ||
|
|
4093d9b22a | ||
|
|
18daf8f301 | ||
|
|
962578bec2 | ||
|
|
85cff59109 | ||
|
|
b869c7c872 | ||
|
|
016c3f0d5b | ||
|
|
4eb9c60652 | ||
|
|
8879757a88 | ||
|
|
fadfcfda4a | ||
|
|
b8c4149e89 | ||
|
|
836bb97a2d | ||
|
|
7db359182d | ||
|
|
4eada92883 | ||
|
|
6a74f3a0c1 | ||
|
|
daa0765653 | ||
|
|
27e26b5939 | ||
|
|
6f45f43709 | ||
|
|
6c80e9a8e0 | ||
|
|
3b2e891917 | ||
|
|
9121fccf55 | ||
|
|
fa2c750443 | ||
|
|
29e7b31ee6 | ||
|
|
bb6c6ed5d1 | ||
|
|
1a5273773e | ||
|
|
3f40c37905 | ||
|
|
996dfd05bd | ||
|
|
0a1dd7894c | ||
|
|
dbfd3f7e18 | ||
|
|
a0209a0d2c | ||
|
|
099aab79e6 | ||
|
|
7dc5b94d45 | ||
|
|
684c0077cc | ||
|
|
75d8a6b5c2 | ||
|
|
96fdfc53cc | ||
|
|
49517d3310 | ||
|
|
9355cc4eaa | ||
|
|
1ce59152e7 | ||
|
|
1241f7f0b7 | ||
|
|
fd74c0f6a4 | ||
|
|
e4eac12c34 | ||
|
|
b235653a6c | ||
|
|
4cb4bdb984 | ||
|
|
ba596152d9 | ||
|
|
a1227624c8 | ||
|
|
9ce1ae771c | ||
|
|
b9fed9b485 | ||
|
|
0d97e1f97d | ||
|
|
1ce7258a01 | ||
|
|
bcd06fdfdf | ||
|
|
fc35b7d18d | ||
|
|
8c12ab0d5b | ||
|
|
38194a29bc | ||
|
|
6b65de6033 | ||
|
|
f80230d654 | ||
|
|
f6cc418d79 | ||
|
|
3ce9407093 | ||
|
|
ef1716c39e | ||
|
|
9ab7da6562 | ||
|
|
fcfff5e8e5 | ||
|
|
67ef62a4dd | ||
|
|
7741635b3b | ||
|
|
3d81bc638b | ||
|
|
c1801738b0 | ||
|
|
ba84f167f5 | ||
|
|
0a38c51b9e | ||
|
|
db5b2bdf56 | ||
|
|
5ac84120b3 | ||
|
|
2d296c5d07 | ||
|
|
71c96d9eb9 | ||
|
|
5342a0a00f | ||
|
|
163b086f21 | ||
|
|
0876d3df1d | ||
|
|
50baf5e804 | ||
|
|
3d6da2c32d | ||
|
|
e721d04350 | ||
|
|
8cc6f9baac | ||
|
|
dfd453e001 | ||
|
|
7e9d5aacf8 | ||
|
|
d27a218bc3 | ||
|
|
0c4ded88fe | ||
|
|
0e0931d308 | ||
|
|
dcfa9eb8fe | ||
|
|
6ebf60b175 | ||
|
|
a4d0724a97 | ||
|
|
c235e9b78c | ||
|
|
5fa3e239db | ||
|
|
3d1b107d70 | ||
|
|
18e0828daf | ||
|
|
f16c7729bd | ||
|
|
9f3c8cd139 | ||
|
|
a7a35aee61 | ||
|
|
dc5a966548 | ||
|
|
ea8d7f689e | ||
|
|
0ed6c92341 | ||
|
|
79f52c76cf | ||
|
|
b725e9eb45 | ||
|
|
787e54b096 | ||
|
|
15fd60b29a | ||
|
|
edf6b2d61f | ||
|
|
7eb17fc874 | ||
|
|
7e4bfaf0e9 | ||
|
|
e1d4fc5325 | ||
|
|
faec748ef6 | ||
|
|
afec8c4580 | ||
|
|
8a1f0aa3b6 | ||
|
|
f784644510 | ||
|
|
710a2f745c | ||
|
|
bd230fe473 | ||
|
|
9c5b000956 | ||
|
|
a9f2a25feb | ||
|
|
c00c2d1ecf | ||
|
|
dd7bbae837 | ||
|
|
0a84d48a82 | ||
|
|
e5d0b97dee | ||
|
|
811c3f873f | ||
|
|
662fc81544 | ||
|
|
5e2f2d541d | ||
|
|
8116d8158b | ||
|
|
e6836781d5 | ||
|
|
098088c763 | ||
|
|
4bf9a52043 | ||
|
|
eb6f964ede | ||
|
|
4473a9bcbf | ||
|
|
fdc7c96ece | ||
|
|
a694be81ae | ||
|
|
0abb743e9c | ||
|
|
acda3f06b0 | ||
|
|
3127bc4e05 | ||
|
|
18b24df9c8 | ||
|
|
b27758fe13 | ||
|
|
a0b2006230 | ||
|
|
bd143ffa5a | ||
|
|
77c1988a8b | ||
|
|
26a36f79fa | ||
|
|
97d8d4016b | ||
|
|
246e80512d | ||
|
|
fc6827d68a | ||
|
|
4d91f978d2 | ||
|
|
aabe2c7d66 | ||
|
|
377234ad8e | ||
|
|
38b785813f | ||
|
|
fa7e3c996e | ||
|
|
90120dd6e8 | ||
|
|
36772548b7 | ||
|
|
40bb0c5f36 | ||
|
|
60918d25a1 | ||
|
|
3afce2c4b8 | ||
|
|
9f6f25d54c | ||
|
|
d5b09cd958 | ||
|
|
aece74982d | ||
|
|
2b1e5b9f82 | ||
|
|
43df5d05ed | ||
|
|
eaa49ebd20 | ||
|
|
a6293397bc | ||
|
|
b890bd1dc5 | ||
|
|
3819a11b5f | ||
|
|
4aed0411e9 | ||
|
|
04ac466748 | ||
|
|
d75126a4ce | ||
|
|
c654e8384b | ||
|
|
7c9d0168ff | ||
|
|
e956ba4d4a | ||
|
|
85b32f51ff | ||
|
|
08fabb7b2e | ||
|
|
273b2cd646 | ||
|
|
de1a5125f8 | ||
|
|
da86791224 | ||
|
|
c646eaa6bb | ||
|
|
bf44b428dd | ||
|
|
c2907b189c | ||
|
|
75317d230b | ||
|
|
e662654c49 | ||
|
|
2a67321130 | ||
|
|
8d9d2c0d3f | ||
|
|
dc6a78c357 | ||
|
|
73d1def114 | ||
|
|
3dc74ba29f | ||
|
|
d9d6031db5 | ||
|
|
6135417789 | ||
|
|
6d138f218b | ||
|
|
e10a4375f9 | ||
|
|
3e32eb55f0 | ||
|
|
b3f139c0d9 | ||
|
|
3b4c692534 | ||
|
|
05c859f324 | ||
|
|
48a33b0453 | ||
|
|
70746a7bf0 | ||
|
|
69e3c6e3d3 | ||
|
|
388e5c0c25 | ||
|
|
61db5ebcc2 | ||
|
|
23845979ea | ||
|
|
83f7a36d05 | ||
|
|
462014e296 | ||
|
|
5da5ae5554 | ||
|
|
f3a985cb81 | ||
|
|
22528373bb | ||
|
|
ce0ec06e8a | ||
|
|
10397ddc30 | ||
|
|
6f72a27632 | ||
|
|
2783667f80 | ||
|
|
d8c1d040d4 | ||
|
|
7f037f1bdc | ||
|
|
f31104585f | ||
|
|
5934a75ddd | ||
|
|
650abf091b | ||
|
|
66f18e9282 | ||
|
|
f044f13121 | ||
|
|
0250cfa398 | ||
|
|
f4ce2510f3 | ||
|
|
8f0a604a37 | ||
|
|
0f4c2b6ee0 | ||
|
|
368d314e11 | ||
|
|
4e79cb0be4 | ||
|
|
973595b3cb | ||
|
|
fa779017d2 | ||
|
|
b2e27de2fc | ||
|
|
31a7bfd227 | ||
|
|
47dde41c6c | ||
|
|
413a86998e | ||
|
|
36721d4362 | ||
|
|
c09e950bd2 | ||
|
|
4d208b2b90 | ||
|
|
071c6a17dd | ||
|
|
4ab79c679b | ||
|
|
33be5fc8ba | ||
|
|
a7a353e1f5 | ||
|
|
c153d9b83e | ||
|
|
2875d88ccf | ||
|
|
9e0cca828d | ||
|
|
5dc3ec4a65 | ||
|
|
bda392cba6 | ||
|
|
f22137346a | ||
|
|
f108741a82 | ||
|
|
8433e8efe2 | ||
|
|
e6a1a9e193 | ||
|
|
bbb22813e6 | ||
|
|
f0f8e287ec | ||
|
|
0af6cbe990 | ||
|
|
9e9e068762 | ||
|
|
9fda0149da | ||
|
|
95a713b3e2 | ||
|
|
2da3d62d37 | ||
|
|
7dd2e92d7e | ||
|
|
6d06e13284 | ||
|
|
a2199c545b | ||
|
|
08cbc6c8ff | ||
|
|
f730160037 | ||
|
|
20360c207e | ||
|
|
568a54dff2 | ||
|
|
91cacc9c92 | ||
|
|
b3899333f4 | ||
|
|
6b6a310e54 | ||
|
|
cb2dce03c0 | ||
|
|
7122687f25 | ||
|
|
af6fcf1413 | ||
|
|
cd8b90a5a4 | ||
|
|
c88fb2eef0 | ||
|
|
17781e3596 | ||
|
|
a381642558 | ||
|
|
5828043b69 | ||
|
|
909a81f88a | ||
|
|
faec713e0d | ||
|
|
60addbcdd5 | ||
|
|
a27a1bc53c | ||
|
|
41f291524d | ||
|
|
6b3bc7384e | ||
|
|
561bbfb5d2 | ||
|
|
8ce1c81398 | ||
|
|
cb40e27db2 | ||
|
|
f031973848 | ||
|
|
307d37d85c | ||
|
|
bf290fa5f0 | ||
|
|
26f313d524 | ||
|
|
73021d7261 | ||
|
|
f54fb88ad5 | ||
|
|
b3d2f47bc8 | ||
|
|
52f170b3fe | ||
|
|
9442845ca5 | ||
|
|
fe31b0caae | ||
|
|
d2ca3df033 | ||
|
|
838ea752b2 | ||
|
|
2b49b8c70a | ||
|
|
05b024d61b | ||
|
|
c7742e3c56 | ||
|
|
4f9104ce97 | ||
|
|
07a8f7b5b5 | ||
|
|
f2a28f4b5b | ||
|
|
5a4a61ca67 | ||
|
|
71ac76c3cd | ||
|
|
68dca8f42d | ||
|
|
a38e6f4e2c | ||
|
|
ca26f2274c | ||
|
|
8108cd89bb | ||
|
|
8560151090 | ||
|
|
91805cdf03 | ||
|
|
48cba16578 | ||
|
|
7098e3b150 | ||
|
|
a7cc25eb11 | ||
|
|
d2eb4a71ee | ||
|
|
54eeb3161f | ||
|
|
4fabcfa3ab | ||
|
|
5c29daadcc | ||
|
|
5614b94ccc | ||
|
|
e170c86412 | ||
|
|
180bdf31ac | ||
|
|
1e58a3e44c | ||
|
|
dfe3f614ed | ||
|
|
97c747fe54 | ||
|
|
fdb6c9ccc5 | ||
|
|
4fdcdf341c | ||
|
|
e2a6341c60 | ||
|
|
7046d80a23 | ||
|
|
9f89399f5e | ||
|
|
ed0fe9f369 | ||
|
|
6e9b771abf | ||
|
|
4a93562a3d | ||
|
|
3f478b7733 | ||
|
|
c660d96dce | ||
|
|
6de9f5890d | ||
|
|
a16ecf2f91 | ||
|
|
7a2c5526d4 | ||
|
|
d6b5bc9401 | ||
|
|
e6f8aa8756 | ||
|
|
f0a14a9ab6 | ||
|
|
c3dbf4ef7c | ||
|
|
52dd5924d7 | ||
|
|
a960c42178 | ||
|
|
436b023fe4 | ||
|
|
f1759297c7 | ||
|
|
f1ca8da6e1 | ||
|
|
478f157013 | ||
|
|
5c8b41abf2 | ||
|
|
4236c99b7f | ||
|
|
1a816fd6a0 | ||
|
|
02b7d988ae | ||
|
|
1b70a1cbf6 | ||
|
|
259c55f7cd | ||
|
|
6a05f1774e | ||
|
|
6189aacd0f | ||
|
|
9e6b069c09 | ||
|
|
6ffc8a547f | ||
|
|
51e920e2fc | ||
|
|
c27b9dcf9d | ||
|
|
c7e137c6e0 | ||
|
|
7e4d7fe895 | ||
|
|
2c57ea57bf | ||
|
|
be7d15ce3a | ||
|
|
afc2bb0801 | ||
|
|
313bbe802f | ||
|
|
d550738fa2 | ||
|
|
cc99e23e82 | ||
|
|
dbdcf86a11 | ||
|
|
2434980968 | ||
|
|
ee27f7790f | ||
|
|
d2cc2627ba | ||
|
|
f6a285c13c | ||
|
|
8af0b136b1 | ||
|
|
159a61d2b0 | ||
|
|
94fe5495fa | ||
|
|
8cc3ac1329 | ||
|
|
6b49f67d11 | ||
|
|
9972b76efa | ||
|
|
410da16a14 | ||
|
|
8997f96540 | ||
|
|
b8331b13d7 | ||
|
|
7a3c244c07 | ||
|
|
7a692d2c7b | ||
|
|
b53c443a06 | ||
|
|
7d7289aeb8 | ||
|
|
24b638faf6 | ||
|
|
2561a17225 | ||
|
|
d8cfa8ac87 | ||
|
|
76083559f0 | ||
|
|
df56655361 | ||
|
|
2e67f2fa6d | ||
|
|
ac073b2f5f | ||
|
|
4bcdbc5673 | ||
|
|
97adeca0a4 | ||
|
|
ac99792762 | ||
|
|
d01e0a10d8 | ||
|
|
de0f466ef8 | ||
|
|
77f7447ee8 | ||
|
|
48827eb7fc | ||
|
|
5786d2ef78 | ||
|
|
166088775a | ||
|
|
1052914c20 | ||
|
|
7bdc86b6b4 | ||
|
|
733218f199 | ||
|
|
3fb6d2982f | ||
|
|
b323726d86 | ||
|
|
2db2381b68 | ||
|
|
d31648c82e | ||
|
|
e6c2343691 | ||
|
|
ab0379ee52 | ||
|
|
790fa217f7 | ||
|
|
b892b5e028 | ||
|
|
39eedb31f7 | ||
|
|
8355832c7c | ||
|
|
5821ea8a69 | ||
|
|
3dbdc74366 | ||
|
|
939acef803 | ||
|
|
22a5960d36 | ||
|
|
8c5efe0b4b | ||
|
|
730ded2870 | ||
|
|
1a000d7e5f | ||
|
|
104ee630fc | ||
|
|
ea69c373ac | ||
|
|
9118749128 | ||
|
|
87ad6a46e8 | ||
|
|
75c64b6e4c | ||
|
|
ccd3b97f03 | ||
|
|
074d39fa17 | ||
|
|
f1419322b3 | ||
|
|
b8e6d18385 | ||
|
|
82a1300257 | ||
|
|
13d9de4a49 | ||
|
|
f931dd0717 | ||
|
|
24d2226326 | ||
|
|
0c895f1eaf | ||
|
|
c041c52d91 | ||
|
|
cc9e6b3484 | ||
|
|
dfcc6bc154 | ||
|
|
7e708f7411 | ||
|
|
e09646441d | ||
|
|
1631f981af | ||
|
|
4ce18167e7 | ||
|
|
a676899557 | ||
|
|
b299792ebf | ||
|
|
9fcec3abe9 | ||
|
|
5df00f3ec4 | ||
|
|
20ba6e8b97 | ||
|
|
a42c690496 | ||
|
|
bed0f065fa | ||
|
|
76632fcf24 | ||
|
|
32a010394f | ||
|
|
8d572faa24 | ||
|
|
f495d98fae | ||
|
|
3702cef08d | ||
|
|
9474706ec2 | ||
|
|
e1755f4fa6 | ||
|
|
c75c13c3b0 | ||
|
|
8673e1c127 | ||
|
|
360868fe25 | ||
|
|
b46b3f00bf | ||
|
|
c6e950dc9c | ||
|
|
4e74d40736 | ||
|
|
612d114f3a | ||
|
|
f88ffd1a0b | ||
|
|
cdf0f8a933 | ||
|
|
8650dee4bc | ||
|
|
dca9cc3ec5 | ||
|
|
d6f37b2138 | ||
|
|
5a13f78078 | ||
|
|
d625963cc5 | ||
|
|
142710a0f3 | ||
|
|
47fcacd4d6 | ||
|
|
00104c9259 | ||
|
|
8386e61f17 | ||
|
|
9b7125f66b | ||
|
|
68dc9bd5ac | ||
|
|
7a02d862aa | ||
|
|
479e87e467 | ||
|
|
1ea24e1813 | ||
|
|
492c0924c4 | ||
|
|
048355f01d | ||
|
|
fe889f38e8 | ||
|
|
1dd2bc7675 | ||
|
|
91ffa0ed27 | ||
|
|
6ab0f89858 | ||
|
|
bfc9733660 | ||
|
|
9c00618710 | ||
|
|
beedd199e8 | ||
|
|
ae580deaea | ||
|
|
e1231eeef1 | ||
|
|
8a1ebb38e2 | ||
|
|
e9413f2711 | ||
|
|
7434d2bec7 | ||
|
|
f2c565d8e4 | ||
|
|
cb55d7cdde | ||
|
|
d513680005 | ||
|
|
a5ee4d93d2 | ||
|
|
3a2d4434ce | ||
|
|
d1dfc812f1 | ||
|
|
0b76b675db | ||
|
|
5a776fbff5 | ||
|
|
7667605520 | ||
|
|
642762564d | ||
|
|
78ead585f8 | ||
|
|
48bf243050 | ||
|
|
0e920e6f02 | ||
|
|
afac22dfd2 | ||
|
|
2836e10e2d | ||
|
|
aa62d9212f | ||
|
|
620bffc2b4 | ||
|
|
b56cf6c08f | ||
|
|
cead6ba887 | ||
|
|
23772f3c49 | ||
|
|
45304562a6 | ||
|
|
3d767008df | ||
|
|
5c6811c4ef | ||
|
|
25e1a2602d | ||
|
|
b6272a36af | ||
|
|
db91255ede | ||
|
|
ab52e1c7e4 | ||
|
|
4924d08e7e | ||
|
|
a7c65271ac | ||
|
|
030f1f2ae2 | ||
|
|
74f13e522b | ||
|
|
a4f88f74f2 | ||
|
|
3826129b16 | ||
|
|
636f06cd6b | ||
|
|
c8365bd339 | ||
|
|
df38e53723 | ||
|
|
c606407929 | ||
|
|
f59f85d755 | ||
|
|
42bb15de22 | ||
|
|
e96b002599 | ||
|
|
75b83ce3aa | ||
|
|
ad5aa33864 | ||
|
|
952cd736ac | ||
|
|
026039cae2 | ||
|
|
e2609dff95 | ||
|
|
8486b41349 | ||
|
|
e77ea63577 | ||
|
|
097df92c1c | ||
|
|
be669059fb | ||
|
|
dfdd371c52 | ||
|
|
e1e8627168 | ||
|
|
0916c1c3ef | ||
|
|
11656f7bd5 | ||
|
|
483d092af8 | ||
|
|
60aa63b68a | ||
|
|
eb547bd4fd | ||
|
|
0dfde6e284 | ||
|
|
2d7038e03e | ||
|
|
4f0a3a9e4d | ||
|
|
1701930c86 | ||
|
|
a6897963d5 | ||
|
|
c14803e3fa | ||
|
|
cdba8481c2 | ||
|
|
64ca596a11 | ||
|
|
e1758d107e | ||
|
|
3390182fc9 | ||
|
|
912a43ee3d | ||
|
|
4020304945 | ||
|
|
0a2fc78fea | ||
|
|
b91acfb457 | ||
|
|
b9a0179a03 | ||
|
|
5ed48ccdc8 | ||
|
|
f32d67c8b9 | ||
|
|
0752c7242d | ||
|
|
be855c696b | ||
|
|
da9b5201c4 | ||
|
|
4daa6ef4e4 | ||
|
|
4ad7c55618 | ||
|
|
79e08a2541 | ||
|
|
1c9c80ba93 | ||
|
|
25cb05c876 | ||
|
|
694fbab074 | ||
|
|
2fd28434dd | ||
|
|
d15556b152 | ||
|
|
38d8bab770 | ||
|
|
52f0f8657e | ||
|
|
aedf5c895a | ||
|
|
117f9e4abe | ||
|
|
604fea9fc1 | ||
|
|
994bfd4591 | ||
|
|
02722923b1 | ||
|
|
d63a93429b | ||
|
|
b93e216dc7 | ||
|
|
95a29b6e67 | ||
|
|
272f01a153 | ||
|
|
1a345ae7fc | ||
|
|
c5c138b8eb | ||
|
|
da20e33414 | ||
|
|
7fbe3737bc | ||
|
|
f63cec9c95 | ||
|
|
3063ad83ec | ||
|
|
78680e5bee | ||
|
|
55b9faeb48 | ||
|
|
72645dfeab | ||
|
|
3223de5598 | ||
|
|
1afa4e8e75 | ||
|
|
6fd3736da2 | ||
|
|
7e043e5e6f | ||
|
|
d1585c42b9 | ||
|
|
fc494e3527 | ||
|
|
b344cc9415 | ||
|
|
38b71a9298 | ||
|
|
769ee73240 | ||
|
|
1df2f14c64 | ||
|
|
eab9a0e139 | ||
|
|
b86ac6739a | ||
|
|
9840d9e59d | ||
|
|
0ec52157df | ||
|
|
f1c5330b65 | ||
|
|
306ec8de04 | ||
|
|
6d7c9893d4 | ||
|
|
6264709054 | ||
|
|
76c2077f47 | ||
|
|
9cc4428de3 | ||
|
|
a63b1efc29 | ||
|
|
9863c3fca8 | ||
|
|
6fb97f44cf | ||
|
|
f64c448329 | ||
|
|
df6cbc5ec6 | ||
|
|
0f0af751e4 | ||
|
|
6c9dca55bc | ||
|
|
d71e807401 | ||
|
|
7df9ddfe4e | ||
|
|
4170659359 | ||
|
|
2940a7fdfa | ||
|
|
dadd6650ed | ||
|
|
c5a21354af | ||
|
|
8bafe2a482 | ||
|
|
42f1716b48 | ||
|
|
6ab2841dbb | ||
|
|
0f54657377 | ||
|
|
79e5b36551 | ||
|
|
074868d77e | ||
|
|
3dd16a9458 | ||
|
|
62c23ab5fa | ||
|
|
11c05beece | ||
|
|
7b3ef43127 | ||
|
|
e0080e5f75 | ||
|
|
e1ba54bd12 | ||
|
|
7032dfb4f1 | ||
|
|
14e7f7c1f4 | ||
|
|
9ed6f1e419 | ||
|
|
b268c39758 | ||
|
|
4dd386b807 | ||
|
|
b7251f1654 | ||
|
|
780d3e65ad | ||
|
|
cc8cac200f | ||
|
|
e7be5c8ac5 | ||
|
|
8f52864899 | ||
|
|
47a630721a | ||
|
|
10ae6de111 | ||
|
|
2b47f3e56b | ||
|
|
d60dd1b60e | ||
|
|
2822f7ca64 | ||
|
|
ff6afeaf78 | ||
|
|
74852d406c | ||
|
|
921642dc7b | ||
|
|
5c01d44ee9 | ||
|
|
135704dcc8 | ||
|
|
88793bb6c2 | ||
|
|
70a51b3aff | ||
|
|
340a582be7 | ||
|
|
5f66b5466f | ||
|
|
d2169ee567 | ||
|
|
a5c03ba1b7 | ||
|
|
e4ea6426dc | ||
|
|
8bf7cd1dc6 | ||
|
|
92feb3ade7 | ||
|
|
d0e739d8f2 | ||
|
|
4efa6bd75e | ||
|
|
600f15faa0 | ||
|
|
250fa519f9 | ||
|
|
3c6dafcc8e | ||
|
|
8447000eee | ||
|
|
fe453f80ed | ||
|
|
3ff504f03f | ||
|
|
eea9ab6106 | ||
|
|
e9e07c41bb | ||
|
|
17a5e18f46 | ||
|
|
9148bd8b6f | ||
|
|
39766d0f96 | ||
|
|
2d9bca56b2 | ||
|
|
f158d95ce9 | ||
|
|
7a4164ef60 | ||
|
|
f3730a79af | ||
|
|
42eff23a79 | ||
|
|
25bc33350d | ||
|
|
b84d082005 | ||
|
|
1f01ce9615 | ||
|
|
352c5f5ecc | ||
|
|
e5594e860f | ||
|
|
50926faead | ||
|
|
a303afc0e5 | ||
|
|
12607e85e3 | ||
|
|
38fd363e89 | ||
|
|
7f62cfd231 | ||
|
|
c5168bd036 | ||
|
|
be472c5215 | ||
|
|
adac38ecea | ||
|
|
c8b634226e | ||
|
|
ca4cf7cc70 | ||
|
|
b87072bc12 | ||
|
|
04e2bfafbc | ||
|
|
181a32236a | ||
|
|
1f54a8e0a1 | ||
|
|
d63475bb7d | ||
|
|
5a3c5f1523 | ||
|
|
12bc9285f7 | ||
|
|
31df2ea940 | ||
|
|
50b90dd6a4 | ||
|
|
7dd881334d | ||
|
|
530fc8ff3f | ||
|
|
ef460b4d23 | ||
|
|
b591de2ace | ||
|
|
34c857b7cb | ||
|
|
c78bc0c82d | ||
|
|
194446e51a | ||
|
|
777e2151e6 | ||
|
|
5ce5bdba0b | ||
|
|
e4300769ac | ||
|
|
c6dd627bdd | ||
|
|
6576f724bb | ||
|
|
91a6736d0e | ||
|
|
8fb755703d | ||
|
|
748bedd37c | ||
|
|
bf58788f29 | ||
|
|
5f78ba4a31 | ||
|
|
db9f827263 | ||
|
|
dd9e94cf21 | ||
|
|
e482d74241 | ||
|
|
bd2acbcabb | ||
|
|
f913d469a8 | ||
|
|
66cb266641 | ||
|
|
74954894c5 | ||
|
|
ceedfccde0 | ||
|
|
2ee0eedf23 | ||
|
|
c0f3019764 | ||
|
|
dd6d0cb23c | ||
|
|
fe15620df3 | ||
|
|
6af857f206 | ||
|
|
7ce756f9dd | ||
|
|
c0b1fddb31 | ||
|
|
9aea85a84e | ||
|
|
fddd1c12de | ||
|
|
b13a4baf32 | ||
|
|
5ffa18f10f | ||
|
|
828915baf5 | ||
|
|
a071ddf3cd | ||
|
|
3651b8a30f | ||
|
|
0d73b9ff1c | ||
|
|
43235cf236 | ||
|
|
269a155583 | ||
|
|
12433d51dd | ||
|
|
3699e17212 | ||
|
|
8231fbede4 | ||
|
|
50bc14b835 | ||
|
|
4310c89c83 | ||
|
|
d39dd06a22 | ||
|
|
a0ab47e89e | ||
|
|
5cbcb9a965 | ||
|
|
801ceaec80 | ||
|
|
c7334ae9f8 | ||
|
|
d737599a2c | ||
|
|
d2d72a8e4a | ||
|
|
7895c12fa1 | ||
|
|
5f6a14c413 | ||
|
|
2b4e88fa98 | ||
|
|
11723bca27 | ||
|
|
b49517a64f | ||
|
|
f910e0c96c | ||
|
|
c1ba2a3127 | ||
|
|
28396173c7 | ||
|
|
69974b792e | ||
|
|
352412a3cb | ||
|
|
745ab48d65 | ||
|
|
4a5cda0d77 | ||
|
|
b90bf2da9e | ||
|
|
a552cbdf59 | ||
|
|
2351fb5623 | ||
|
|
807522c616 | ||
|
|
81a529c251 | ||
|
|
7efc15aeef | ||
|
|
d66d8379c0 | ||
|
|
5a00467951 | ||
|
|
434d32b891 | ||
|
|
535247ffc4 | ||
|
|
7e2518350a | ||
|
|
1b2a7546af | ||
|
|
2d9bb64047 | ||
|
|
072c2bc7f9 | ||
|
|
da7826b0eb | ||
|
|
2f478eeca6 | ||
|
|
543ef7753a | ||
|
|
88a887329e | ||
|
|
8cfe254400 | ||
|
|
bfd46e562b | ||
|
|
a0e4d38bea | ||
|
|
b0414b9929 | ||
|
|
3b4413f9f5 | ||
|
|
374cdf29a9 | ||
|
|
8d844bc5cf | ||
|
|
1092261ae1 | ||
|
|
5984233223 | ||
|
|
98bb9f13da | ||
|
|
d375dc6ebe | ||
|
|
ee335bca82 | ||
|
|
601d8eb809 | ||
|
|
b99f350a18 | ||
|
|
c1b0e796c6 | ||
|
|
d9e65147c7 | ||
|
|
6001513c4f | ||
|
|
3fa033d8d5 | ||
|
|
59f7e66ac3 | ||
|
|
08e8dfccbe | ||
|
|
fc70a2f36f | ||
|
|
f5c5dbb739 | ||
|
|
ca939fabf7 | ||
|
|
cc3d795bea | ||
|
|
7fc1bac54b | ||
|
|
27367df90c | ||
|
|
f93861e321 | ||
|
|
30e56ec835 | ||
|
|
48ccef9ad2 | ||
|
|
b79e002635 | ||
|
|
1fa28b7cb6 | ||
|
|
22f7eae3f2 | ||
|
|
ae93773465 | ||
|
|
0f387553d1 | ||
|
|
d53a253c8d | ||
|
|
f8f0a6e462 | ||
|
|
f7eea768f6 | ||
|
|
53d316f706 | ||
|
|
741de7f927 | ||
|
|
16b3669adf | ||
|
|
c5807fdaa4 | ||
|
|
897b7d1b99 | ||
|
|
409264960e | ||
|
|
cfb72eec5a | ||
|
|
778822bd9a | ||
|
|
cfd2c3017f | ||
|
|
caed37a08f | ||
|
|
4c1b54e209 | ||
|
|
e4f0947821 | ||
|
|
22e858f65c | ||
|
|
046d6b7fa0 | ||
|
|
89f36371b9 | ||
|
|
406b3ac805 | ||
|
|
f71ba8885e | ||
|
|
121e87b3e0 | ||
|
|
2d013b8340 | ||
|
|
761e5ff01d | ||
|
|
9812684178 | ||
|
|
f7a87cd6ba | ||
|
|
f67bc3ffe8 | ||
|
|
dff644abe0 | ||
|
|
fc7b4ab880 | ||
|
|
1d0f909ca5 | ||
|
|
a0cdbe449b | ||
|
|
44bd64d797 | ||
|
|
bfa78db458 | ||
|
|
4e77737a3f | ||
|
|
d03c197c80 | ||
|
|
06e42a4e5d | ||
|
|
bd1e85a8d3 | ||
|
|
506d5dce39 | ||
|
|
a7b4c73663 | ||
|
|
d4f3ca1c1b | ||
|
|
471d703611 | ||
|
|
a46bbc54cd | ||
|
|
a4405bbed2 | ||
|
|
e9b189e9f2 | ||
|
|
483bce3ae1 | ||
|
|
7372f6ba11 | ||
|
|
8d92557e53 | ||
|
|
c56342bf79 | ||
|
|
07e094fd50 | ||
|
|
1cc30de32f | ||
|
|
3397d4d69a | ||
|
|
766157bfb4 | ||
|
|
d96223460b | ||
|
|
fd99dfc95b | ||
|
|
10fb7ace04 | ||
|
|
a1a19b103c | ||
|
|
5c111caf40 | ||
|
|
651ee5e4d2 | ||
|
|
c398ac87d9 | ||
|
|
0a77c613b0 | ||
|
|
70bc469373 | ||
|
|
b76334f544 | ||
|
|
14b467db06 | ||
|
|
3a0c22ce7d | ||
|
|
3b7e4e0544 | ||
|
|
d4d5b21b2e | ||
|
|
6e1cd45a46 | ||
|
|
b86d130eb6 | ||
|
|
90afc72e64 | ||
|
|
042c697b6b | ||
|
|
02441ff031 | ||
|
|
210af1fd3d | ||
|
|
06eaa32bf0 | ||
|
|
4f88a5fddb | ||
|
|
eb6be1d725 | ||
|
|
1d99681fd4 | ||
|
|
618be44023 | ||
|
|
544afaff97 | ||
|
|
e6b3b994be | ||
|
|
67f148ff83 | ||
|
|
6c34600599 | ||
|
|
016a4b7491 | ||
|
|
be21b74ad5 | ||
|
|
0f152b4e97 | ||
|
|
0d165d1efa | ||
|
|
9d54215a3a | ||
|
|
8ab916baed | ||
|
|
c83c50b27d | ||
|
|
c2ad214a84 | ||
|
|
459f0e11e5 | ||
|
|
56e43ba204 | ||
|
|
10485cad5a | ||
|
|
53a7798e58 | ||
|
|
372ed58677 | ||
|
|
3f8bfd62b7 | ||
|
|
02a6fcad98 | ||
|
|
651ced68bf | ||
|
|
670b64360d | ||
|
|
1f53fef70a | ||
|
|
d1f067dc5b | ||
|
|
15241b53a8 | ||
|
|
38fd8a674b | ||
|
|
bd37d8d04f | ||
|
|
bc99ad0ad1 | ||
|
|
aea04ee32e | ||
|
|
869c7389e2 | ||
|
|
2738df3801 | ||
|
|
433d7862ea | ||
|
|
7625e1e386 | ||
|
|
53e773a2e1 | ||
|
|
c13b54ad0e | ||
|
|
71c2abb41d | ||
|
|
6205935323 | ||
|
|
5fd5b6e72d | ||
|
|
faf88cea0b | ||
|
|
025b38df40 | ||
|
|
ac60cba75f | ||
|
|
94ee932351 | ||
|
|
cf760d6802 | ||
|
|
c65fdc4bed | ||
|
|
0ac9b3ee5c | ||
|
|
f2bd2c44e2 | ||
|
|
f0beab1778 | ||
|
|
95f2dc065e | ||
|
|
4e8080f290 | ||
|
|
fbbed6fe81 | ||
|
|
2d5a5d0d9e |
144
.github/DISCUSSION_TEMPLATE/questions.yml
vendored
Normal file
144
.github/DISCUSSION_TEMPLATE/questions.yml
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
labels: [question]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for your interest in FastAPI! 🚀
|
||||
|
||||
Please follow these instructions, fill every question, and do every step. 🙏
|
||||
|
||||
I'm asking this because answering questions and solving problems in GitHub is what consumes most of the time.
|
||||
|
||||
I end up not being able to add new features, fix bugs, review pull requests, etc. as fast as I wish because I have to spend too much time handling questions.
|
||||
|
||||
All that, on top of all the incredible help provided by a bunch of community members, the [FastAPI Experts](https://fastapi.tiangolo.com/fastapi-people/#experts), that give a lot of their time to come here and help others.
|
||||
|
||||
That's a lot of work they are doing, but if more FastAPI users came to help others like them just a little bit more, it would be much less effort for them (and you and me 😅).
|
||||
|
||||
By asking questions in a structured way (following this) it will be much easier to help you.
|
||||
|
||||
And there's a high chance that you will find the solution along the way and you won't even have to submit it and wait for an answer. 😎
|
||||
|
||||
As there are too many questions, I'll have to discard and close the incomplete ones. That will allow me (and others) to focus on helping people like you that follow the whole process and help us help you. 🤓
|
||||
- type: checkboxes
|
||||
id: checks
|
||||
attributes:
|
||||
label: First Check
|
||||
description: Please confirm and check all the following options.
|
||||
options:
|
||||
- label: I added a very descriptive title here.
|
||||
required: true
|
||||
- label: I used the GitHub search to find a similar question and didn't find it.
|
||||
required: true
|
||||
- label: I searched the FastAPI documentation, with the integrated search.
|
||||
required: true
|
||||
- label: I already searched in Google "How to X in FastAPI" and didn't find any information.
|
||||
required: true
|
||||
- label: I already read and followed all the tutorial in the docs and didn't find an answer.
|
||||
required: true
|
||||
- label: I already checked if it is not related to FastAPI but to [Pydantic](https://github.com/pydantic/pydantic).
|
||||
required: true
|
||||
- label: I already checked if it is not related to FastAPI but to [Swagger UI](https://github.com/swagger-api/swagger-ui).
|
||||
required: true
|
||||
- label: I already checked if it is not related to FastAPI but to [ReDoc](https://github.com/Redocly/redoc).
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: help
|
||||
attributes:
|
||||
label: Commit to Help
|
||||
description: |
|
||||
After submitting this, I commit to one of:
|
||||
|
||||
* Read open questions until I find 2 where I can help someone and add a comment to help there.
|
||||
* I already hit the "watch" button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
|
||||
* Review one Pull Request by downloading the code and following [all the review process](https://fastapi.tiangolo.com/help-fastapi/#review-pull-requests).
|
||||
|
||||
options:
|
||||
- label: I commit to help with one of those options 👆
|
||||
required: true
|
||||
- type: textarea
|
||||
id: example
|
||||
attributes:
|
||||
label: Example Code
|
||||
description: |
|
||||
Please add a self-contained, [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example) with your use case.
|
||||
|
||||
If I (or someone) can copy it, run it, and see it right away, there's a much higher chance I (or someone) will be able to help you.
|
||||
|
||||
placeholder: |
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
render: python
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
What is the problem, question, or error?
|
||||
|
||||
Write a short description telling me what you are doing, what you expect to happen, and what is currently happening.
|
||||
placeholder: |
|
||||
* Open the browser and call the endpoint `/`.
|
||||
* It returns a JSON with `{"Hello": "World"}`.
|
||||
* But I expected it to return `{"Hello": "Sara"}`.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: What operating system are you on?
|
||||
multiple: true
|
||||
options:
|
||||
- Linux
|
||||
- Windows
|
||||
- macOS
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: os-details
|
||||
attributes:
|
||||
label: Operating System Details
|
||||
description: You can add more details about your operating system here, in particular if you chose "Other".
|
||||
- type: input
|
||||
id: fastapi-version
|
||||
attributes:
|
||||
label: FastAPI Version
|
||||
description: |
|
||||
What FastAPI version are you using?
|
||||
|
||||
You can find the FastAPI version with:
|
||||
|
||||
```bash
|
||||
python -c "import fastapi; print(fastapi.__version__)"
|
||||
```
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: python-version
|
||||
attributes:
|
||||
label: Python Version
|
||||
description: |
|
||||
What Python version are you using?
|
||||
|
||||
You can find the Python version with:
|
||||
|
||||
```bash
|
||||
python --version
|
||||
```
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
label: Additional Context
|
||||
description: Add any additional context information or screenshots you think are useful.
|
||||
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
github: [tiangolo]
|
||||
62
.github/ISSUE_TEMPLATE/bug_report.md
vendored
62
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,62 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: "[BUG]"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Describe the bug
|
||||
|
||||
Write here a clear and concise description of what the bug is.
|
||||
|
||||
### To Reproduce
|
||||
|
||||
Steps to reproduce the behavior with a minimum self-contained file.
|
||||
|
||||
Replace each part with your own scenario:
|
||||
|
||||
1. Create a file with:
|
||||
|
||||
```Python
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
```
|
||||
|
||||
3. Open the browser and call the endpoint `/`.
|
||||
4. It returns a JSON with `{"Hello": "World"}`.
|
||||
5. But I expected it to return `{"Hello": "Sara"}`.
|
||||
|
||||
### Expected behavior
|
||||
|
||||
Add a clear and concise description of what you expected to happen.
|
||||
|
||||
### Screenshots
|
||||
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
### Environment
|
||||
|
||||
- OS: [e.g. Linux / Windows / macOS]
|
||||
- FastAPI Version [e.g. 0.3.0], get it with:
|
||||
|
||||
```bash
|
||||
python -c "import fastapi; print(fastapi.__version__)"
|
||||
```
|
||||
|
||||
- Python version, get it with:
|
||||
|
||||
```bash
|
||||
python --version
|
||||
```
|
||||
|
||||
### Additional context
|
||||
|
||||
Add any other context about the problem here.
|
||||
16
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
16
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Security Contact
|
||||
about: Please report security vulnerabilities to security@tiangolo.com
|
||||
- name: Question or Problem
|
||||
about: Ask a question or ask about a problem in GitHub Discussions.
|
||||
url: https://github.com/tiangolo/fastapi/discussions/categories/questions
|
||||
- name: Feature Request
|
||||
about: To suggest an idea or ask about a feature, please start with a question saying what you would like to achieve. There might be a way to do it already.
|
||||
url: https://github.com/tiangolo/fastapi/discussions/categories/questions
|
||||
- name: Show and tell
|
||||
about: Show what you built with FastAPI or to be used with FastAPI.
|
||||
url: https://github.com/tiangolo/fastapi/discussions/categories/show-and-tell
|
||||
- name: Translations
|
||||
about: Coordinate translations in GitHub Discussions.
|
||||
url: https://github.com/tiangolo/fastapi/discussions/categories/translations
|
||||
26
.github/ISSUE_TEMPLATE/feature_request.md
vendored
26
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,26 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: "[FEATURE]"
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Is your feature request related to a problem
|
||||
|
||||
Is your feature request related to a problem?
|
||||
|
||||
Add a clear and concise description of what the problem is. Ex. I want to be able to [...] but I can't because [...]
|
||||
|
||||
### The solution you would like
|
||||
|
||||
Add a clear and concise description of what you want to happen.
|
||||
|
||||
### Describe alternatives you've considered
|
||||
|
||||
Add a clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
### Additional context
|
||||
|
||||
Add any other context or screenshots about the feature request here.
|
||||
22
.github/ISSUE_TEMPLATE/privileged.yml
vendored
Normal file
22
.github/ISSUE_TEMPLATE/privileged.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Privileged
|
||||
description: You are @tiangolo or he asked you directly to create an issue here. If not, check the other options. 👇
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for your interest in FastAPI! 🚀
|
||||
|
||||
If you are not @tiangolo or he didn't ask you directly to create an issue here, please start the conversation in a [Question in GitHub Discussions](https://github.com/tiangolo/fastapi/discussions/categories/questions) instead.
|
||||
- type: checkboxes
|
||||
id: privileged
|
||||
attributes:
|
||||
label: Privileged issue
|
||||
description: Confirm that you are allowed to create an issue here.
|
||||
options:
|
||||
- label: I'm @tiangolo or he asked me directly to create an issue here.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: content
|
||||
attributes:
|
||||
label: Issue Content
|
||||
description: Add the content of the issue here.
|
||||
24
.github/ISSUE_TEMPLATE/question.md
vendored
24
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -1,24 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Ask a question
|
||||
title: "[QUESTION]"
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### First check
|
||||
|
||||
* [ ] I used the GitHub search to find a similar issue and didn't find it.
|
||||
* [ ] I searched the FastAPI documentation, with the integrated search.
|
||||
* [ ] I already searched in Google "How to X in FastAPI" and didn't find any information.
|
||||
|
||||
### Description
|
||||
|
||||
How can I [...]?
|
||||
|
||||
Is it possible to [...]?
|
||||
|
||||
### Additional context
|
||||
|
||||
Add any other context or screenshots about the feature request here.
|
||||
7
.github/actions/comment-docs-preview-in-pr/Dockerfile
vendored
Normal file
7
.github/actions/comment-docs-preview-in-pr/Dockerfile
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM python:3.7
|
||||
|
||||
RUN pip install httpx "pydantic==1.5.1" pygithub
|
||||
|
||||
COPY ./app /app
|
||||
|
||||
CMD ["python", "/app/main.py"]
|
||||
13
.github/actions/comment-docs-preview-in-pr/action.yml
vendored
Normal file
13
.github/actions/comment-docs-preview-in-pr/action.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
name: Comment Docs Preview in PR
|
||||
description: Comment with the docs URL preview in the PR
|
||||
author: Sebastián Ramírez <tiangolo@gmail.com>
|
||||
inputs:
|
||||
token:
|
||||
description: Token for the repo. Can be passed in using {{ secrets.GITHUB_TOKEN }}
|
||||
required: true
|
||||
deploy_url:
|
||||
description: The deployment URL to comment in the PR
|
||||
required: true
|
||||
runs:
|
||||
using: docker
|
||||
image: Dockerfile
|
||||
68
.github/actions/comment-docs-preview-in-pr/app/main.py
vendored
Normal file
68
.github/actions/comment-docs-preview-in-pr/app/main.py
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
import logging
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Union
|
||||
|
||||
import httpx
|
||||
from github import Github
|
||||
from github.PullRequest import PullRequest
|
||||
from pydantic import BaseModel, BaseSettings, SecretStr, ValidationError
|
||||
|
||||
github_api = "https://api.github.com"
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
github_repository: str
|
||||
github_event_path: Path
|
||||
github_event_name: Union[str, None] = None
|
||||
input_token: SecretStr
|
||||
input_deploy_url: str
|
||||
|
||||
|
||||
class PartialGithubEventHeadCommit(BaseModel):
|
||||
id: str
|
||||
|
||||
|
||||
class PartialGithubEventWorkflowRun(BaseModel):
|
||||
head_commit: PartialGithubEventHeadCommit
|
||||
|
||||
|
||||
class PartialGithubEvent(BaseModel):
|
||||
workflow_run: PartialGithubEventWorkflowRun
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
settings = Settings()
|
||||
logging.info(f"Using config: {settings.json()}")
|
||||
g = Github(settings.input_token.get_secret_value())
|
||||
repo = g.get_repo(settings.github_repository)
|
||||
try:
|
||||
event = PartialGithubEvent.parse_file(settings.github_event_path)
|
||||
except ValidationError as e:
|
||||
logging.error(f"Error parsing event file: {e.errors()}")
|
||||
sys.exit(0)
|
||||
use_pr: Union[PullRequest, None] = None
|
||||
for pr in repo.get_pulls():
|
||||
if pr.head.sha == event.workflow_run.head_commit.id:
|
||||
use_pr = pr
|
||||
break
|
||||
if not use_pr:
|
||||
logging.error(f"No PR found for hash: {event.workflow_run.head_commit.id}")
|
||||
sys.exit(0)
|
||||
github_headers = {
|
||||
"Authorization": f"token {settings.input_token.get_secret_value()}"
|
||||
}
|
||||
url = f"{github_api}/repos/{settings.github_repository}/issues/{use_pr.number}/comments"
|
||||
logging.info(f"Using comments URL: {url}")
|
||||
response = httpx.post(
|
||||
url,
|
||||
headers=github_headers,
|
||||
json={
|
||||
"body": f"📝 Docs preview for commit {use_pr.head.sha} at: {settings.input_deploy_url}"
|
||||
},
|
||||
)
|
||||
if not (200 <= response.status_code <= 300):
|
||||
logging.error(f"Error posting comment: {response.text}")
|
||||
sys.exit(1)
|
||||
logging.info("Finished")
|
||||
7
.github/actions/notify-translations/Dockerfile
vendored
Normal file
7
.github/actions/notify-translations/Dockerfile
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM python:3.7
|
||||
|
||||
RUN pip install httpx PyGithub "pydantic==1.5.1" "pyyaml>=5.3.1,<6.0.0"
|
||||
|
||||
COPY ./app /app
|
||||
|
||||
CMD ["python", "/app/main.py"]
|
||||
10
.github/actions/notify-translations/action.yml
vendored
Normal file
10
.github/actions/notify-translations/action.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
name: "Notify Translations"
|
||||
description: "Notify in the issue for a translation when there's a new PR available"
|
||||
author: "Sebastián Ramírez <tiangolo@gmail.com>"
|
||||
inputs:
|
||||
token:
|
||||
description: 'Token, to read the GitHub API. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
|
||||
required: true
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'Dockerfile'
|
||||
417
.github/actions/notify-translations/app/main.py
vendored
Normal file
417
.github/actions/notify-translations/app/main.py
vendored
Normal file
@@ -0,0 +1,417 @@
|
||||
import logging
|
||||
import random
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Union, cast
|
||||
|
||||
import httpx
|
||||
from github import Github
|
||||
from pydantic import BaseModel, BaseSettings, SecretStr
|
||||
|
||||
awaiting_label = "awaiting review"
|
||||
lang_all_label = "lang-all"
|
||||
approved_label = "approved-2"
|
||||
translations_path = Path(__file__).parent / "translations.yml"
|
||||
|
||||
github_graphql_url = "https://api.github.com/graphql"
|
||||
questions_translations_category_id = "DIC_kwDOCZduT84CT5P9"
|
||||
|
||||
all_discussions_query = """
|
||||
query Q($category_id: ID) {
|
||||
repository(name: "fastapi", owner: "tiangolo") {
|
||||
discussions(categoryId: $category_id, first: 100) {
|
||||
nodes {
|
||||
title
|
||||
id
|
||||
number
|
||||
labels(first: 10) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
translation_discussion_query = """
|
||||
query Q($after: String, $discussion_number: Int!) {
|
||||
repository(name: "fastapi", owner: "tiangolo") {
|
||||
discussion(number: $discussion_number) {
|
||||
comments(first: 100, after: $after) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
id
|
||||
url
|
||||
body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
add_comment_mutation = """
|
||||
mutation Q($discussion_id: ID!, $body: String!) {
|
||||
addDiscussionComment(input: {discussionId: $discussion_id, body: $body}) {
|
||||
comment {
|
||||
id
|
||||
url
|
||||
body
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
update_comment_mutation = """
|
||||
mutation Q($comment_id: ID!, $body: String!) {
|
||||
updateDiscussionComment(input: {commentId: $comment_id, body: $body}) {
|
||||
comment {
|
||||
id
|
||||
url
|
||||
body
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class Comment(BaseModel):
|
||||
id: str
|
||||
url: str
|
||||
body: str
|
||||
|
||||
|
||||
class UpdateDiscussionComment(BaseModel):
|
||||
comment: Comment
|
||||
|
||||
|
||||
class UpdateCommentData(BaseModel):
|
||||
updateDiscussionComment: UpdateDiscussionComment
|
||||
|
||||
|
||||
class UpdateCommentResponse(BaseModel):
|
||||
data: UpdateCommentData
|
||||
|
||||
|
||||
class AddDiscussionComment(BaseModel):
|
||||
comment: Comment
|
||||
|
||||
|
||||
class AddCommentData(BaseModel):
|
||||
addDiscussionComment: AddDiscussionComment
|
||||
|
||||
|
||||
class AddCommentResponse(BaseModel):
|
||||
data: AddCommentData
|
||||
|
||||
|
||||
class CommentsEdge(BaseModel):
|
||||
node: Comment
|
||||
cursor: str
|
||||
|
||||
|
||||
class Comments(BaseModel):
|
||||
edges: List[CommentsEdge]
|
||||
|
||||
|
||||
class CommentsDiscussion(BaseModel):
|
||||
comments: Comments
|
||||
|
||||
|
||||
class CommentsRepository(BaseModel):
|
||||
discussion: CommentsDiscussion
|
||||
|
||||
|
||||
class CommentsData(BaseModel):
|
||||
repository: CommentsRepository
|
||||
|
||||
|
||||
class CommentsResponse(BaseModel):
|
||||
data: CommentsData
|
||||
|
||||
|
||||
class AllDiscussionsLabelNode(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
|
||||
|
||||
class AllDiscussionsLabelsEdge(BaseModel):
|
||||
node: AllDiscussionsLabelNode
|
||||
|
||||
|
||||
class AllDiscussionsDiscussionLabels(BaseModel):
|
||||
edges: List[AllDiscussionsLabelsEdge]
|
||||
|
||||
|
||||
class AllDiscussionsDiscussionNode(BaseModel):
|
||||
title: str
|
||||
id: str
|
||||
number: int
|
||||
labels: AllDiscussionsDiscussionLabels
|
||||
|
||||
|
||||
class AllDiscussionsDiscussions(BaseModel):
|
||||
nodes: List[AllDiscussionsDiscussionNode]
|
||||
|
||||
|
||||
class AllDiscussionsRepository(BaseModel):
|
||||
discussions: AllDiscussionsDiscussions
|
||||
|
||||
|
||||
class AllDiscussionsData(BaseModel):
|
||||
repository: AllDiscussionsRepository
|
||||
|
||||
|
||||
class AllDiscussionsResponse(BaseModel):
|
||||
data: AllDiscussionsData
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
github_repository: str
|
||||
input_token: SecretStr
|
||||
github_event_path: Path
|
||||
github_event_name: Union[str, None] = None
|
||||
httpx_timeout: int = 30
|
||||
input_debug: Union[bool, None] = False
|
||||
|
||||
|
||||
class PartialGitHubEventIssue(BaseModel):
|
||||
number: int
|
||||
|
||||
|
||||
class PartialGitHubEvent(BaseModel):
|
||||
pull_request: PartialGitHubEventIssue
|
||||
|
||||
|
||||
def get_graphql_response(
|
||||
*,
|
||||
settings: Settings,
|
||||
query: str,
|
||||
after: Union[str, None] = None,
|
||||
category_id: Union[str, None] = None,
|
||||
discussion_number: Union[int, None] = None,
|
||||
discussion_id: Union[str, None] = None,
|
||||
comment_id: Union[str, None] = None,
|
||||
body: Union[str, None] = None,
|
||||
) -> Dict[str, Any]:
|
||||
headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"}
|
||||
# some fields are only used by one query, but GraphQL allows unused variables, so
|
||||
# keep them here for simplicity
|
||||
variables = {
|
||||
"after": after,
|
||||
"category_id": category_id,
|
||||
"discussion_number": discussion_number,
|
||||
"discussion_id": discussion_id,
|
||||
"comment_id": comment_id,
|
||||
"body": body,
|
||||
}
|
||||
response = httpx.post(
|
||||
github_graphql_url,
|
||||
headers=headers,
|
||||
timeout=settings.httpx_timeout,
|
||||
json={"query": query, "variables": variables, "operationName": "Q"},
|
||||
)
|
||||
if response.status_code != 200:
|
||||
logging.error(
|
||||
f"Response was not 200, after: {after}, category_id: {category_id}"
|
||||
)
|
||||
logging.error(response.text)
|
||||
raise RuntimeError(response.text)
|
||||
data = response.json()
|
||||
if "errors" in data:
|
||||
logging.error(f"Errors in response, after: {after}, category_id: {category_id}")
|
||||
logging.error(response.text)
|
||||
raise RuntimeError(response.text)
|
||||
return cast(Dict[str, Any], data)
|
||||
|
||||
|
||||
def get_graphql_translation_discussions(*, settings: Settings):
|
||||
data = get_graphql_response(
|
||||
settings=settings,
|
||||
query=all_discussions_query,
|
||||
category_id=questions_translations_category_id,
|
||||
)
|
||||
graphql_response = AllDiscussionsResponse.parse_obj(data)
|
||||
return graphql_response.data.repository.discussions.nodes
|
||||
|
||||
|
||||
def get_graphql_translation_discussion_comments_edges(
|
||||
*, settings: Settings, discussion_number: int, after: Union[str, None] = None
|
||||
):
|
||||
data = get_graphql_response(
|
||||
settings=settings,
|
||||
query=translation_discussion_query,
|
||||
discussion_number=discussion_number,
|
||||
after=after,
|
||||
)
|
||||
graphql_response = CommentsResponse.parse_obj(data)
|
||||
return graphql_response.data.repository.discussion.comments.edges
|
||||
|
||||
|
||||
def get_graphql_translation_discussion_comments(
|
||||
*, settings: Settings, discussion_number: int
|
||||
):
|
||||
comment_nodes: List[Comment] = []
|
||||
discussion_edges = get_graphql_translation_discussion_comments_edges(
|
||||
settings=settings, discussion_number=discussion_number
|
||||
)
|
||||
|
||||
while discussion_edges:
|
||||
for discussion_edge in discussion_edges:
|
||||
comment_nodes.append(discussion_edge.node)
|
||||
last_edge = discussion_edges[-1]
|
||||
discussion_edges = get_graphql_translation_discussion_comments_edges(
|
||||
settings=settings,
|
||||
discussion_number=discussion_number,
|
||||
after=last_edge.cursor,
|
||||
)
|
||||
return comment_nodes
|
||||
|
||||
|
||||
def create_comment(*, settings: Settings, discussion_id: str, body: str):
|
||||
data = get_graphql_response(
|
||||
settings=settings,
|
||||
query=add_comment_mutation,
|
||||
discussion_id=discussion_id,
|
||||
body=body,
|
||||
)
|
||||
response = AddCommentResponse.parse_obj(data)
|
||||
return response.data.addDiscussionComment.comment
|
||||
|
||||
|
||||
def update_comment(*, settings: Settings, comment_id: str, body: str):
|
||||
data = get_graphql_response(
|
||||
settings=settings,
|
||||
query=update_comment_mutation,
|
||||
comment_id=comment_id,
|
||||
body=body,
|
||||
)
|
||||
response = UpdateCommentResponse.parse_obj(data)
|
||||
return response.data.updateDiscussionComment.comment
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
settings = Settings()
|
||||
if settings.input_debug:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
else:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.debug(f"Using config: {settings.json()}")
|
||||
g = Github(settings.input_token.get_secret_value())
|
||||
repo = g.get_repo(settings.github_repository)
|
||||
if not settings.github_event_path.is_file():
|
||||
raise RuntimeError(
|
||||
f"No github event file available at: {settings.github_event_path}"
|
||||
)
|
||||
contents = settings.github_event_path.read_text()
|
||||
github_event = PartialGitHubEvent.parse_raw(contents)
|
||||
|
||||
# Avoid race conditions with multiple labels
|
||||
sleep_time = random.random() * 10 # random number between 0 and 10 seconds
|
||||
logging.info(
|
||||
f"Sleeping for {sleep_time} seconds to avoid "
|
||||
"race conditions and multiple comments"
|
||||
)
|
||||
time.sleep(sleep_time)
|
||||
|
||||
# Get PR
|
||||
logging.debug(f"Processing PR: #{github_event.pull_request.number}")
|
||||
pr = repo.get_pull(github_event.pull_request.number)
|
||||
label_strs = {label.name for label in pr.get_labels()}
|
||||
langs = []
|
||||
for label in label_strs:
|
||||
if label.startswith("lang-") and not label == lang_all_label:
|
||||
langs.append(label[5:])
|
||||
logging.info(f"PR #{pr.number} has labels: {label_strs}")
|
||||
if not langs or lang_all_label not in label_strs:
|
||||
logging.info(f"PR #{pr.number} doesn't seem to be a translation PR, skipping")
|
||||
sys.exit(0)
|
||||
|
||||
# Generate translation map, lang ID to discussion
|
||||
discussions = get_graphql_translation_discussions(settings=settings)
|
||||
lang_to_discussion_map: Dict[str, AllDiscussionsDiscussionNode] = {}
|
||||
for discussion in discussions:
|
||||
for edge in discussion.labels.edges:
|
||||
label = edge.node.name
|
||||
if label.startswith("lang-") and not label == lang_all_label:
|
||||
lang = label[5:]
|
||||
lang_to_discussion_map[lang] = discussion
|
||||
logging.debug(f"Using translations map: {lang_to_discussion_map}")
|
||||
|
||||
# Messages to create or check
|
||||
new_translation_message = f"Good news everyone! 😉 There's a new translation PR to be reviewed: #{pr.number} by @{pr.user.login}. 🎉 This requires 2 approvals from native speakers to be merged. 🤓"
|
||||
done_translation_message = f"~There's a new translation PR to be reviewed: #{pr.number} by @{pr.user.login}~ Good job! This is done. 🍰☕"
|
||||
|
||||
# Normally only one language, but still
|
||||
for lang in langs:
|
||||
if lang not in lang_to_discussion_map:
|
||||
log_message = f"Could not find discussion for language: {lang}"
|
||||
logging.error(log_message)
|
||||
raise RuntimeError(log_message)
|
||||
discussion = lang_to_discussion_map[lang]
|
||||
logging.info(
|
||||
f"Found a translation discussion for language: {lang} in discussion: #{discussion.number}"
|
||||
)
|
||||
|
||||
already_notified_comment: Union[Comment, None] = None
|
||||
already_done_comment: Union[Comment, None] = None
|
||||
|
||||
logging.info(
|
||||
f"Checking current comments in discussion: #{discussion.number} to see if already notified about this PR: #{pr.number}"
|
||||
)
|
||||
comments = get_graphql_translation_discussion_comments(
|
||||
settings=settings, discussion_number=discussion.number
|
||||
)
|
||||
for comment in comments:
|
||||
if new_translation_message in comment.body:
|
||||
already_notified_comment = comment
|
||||
elif done_translation_message in comment.body:
|
||||
already_done_comment = comment
|
||||
logging.info(
|
||||
f"Already notified comment: {already_notified_comment}, already done comment: {already_done_comment}"
|
||||
)
|
||||
|
||||
if pr.state == "open" and awaiting_label in label_strs:
|
||||
logging.info(
|
||||
f"This PR seems to be a language translation and awaiting reviews: #{pr.number}"
|
||||
)
|
||||
if already_notified_comment:
|
||||
logging.info(
|
||||
f"This PR #{pr.number} was already notified in comment: {already_notified_comment.url}"
|
||||
)
|
||||
else:
|
||||
logging.info(
|
||||
f"Writing notification comment about PR #{pr.number} in Discussion: #{discussion.number}"
|
||||
)
|
||||
comment = create_comment(
|
||||
settings=settings,
|
||||
discussion_id=discussion.id,
|
||||
body=new_translation_message,
|
||||
)
|
||||
logging.info(f"Notified in comment: {comment.url}")
|
||||
elif pr.state == "closed" or approved_label in label_strs:
|
||||
logging.info(f"Already approved or closed PR #{pr.number}")
|
||||
if already_done_comment:
|
||||
logging.info(
|
||||
f"This PR #{pr.number} was already marked as done in comment: {already_done_comment.url}"
|
||||
)
|
||||
elif already_notified_comment:
|
||||
updated_comment = update_comment(
|
||||
settings=settings,
|
||||
comment_id=already_notified_comment.id,
|
||||
body=done_translation_message,
|
||||
)
|
||||
logging.info(f"Marked as done in comment: {updated_comment.url}")
|
||||
else:
|
||||
logging.info(
|
||||
f"There doesn't seem to be anything to be done about PR #{pr.number}"
|
||||
)
|
||||
logging.info("Finished")
|
||||
7
.github/actions/people/Dockerfile
vendored
Normal file
7
.github/actions/people/Dockerfile
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM python:3.7
|
||||
|
||||
RUN pip install httpx PyGithub "pydantic==1.5.1" "pyyaml>=5.3.1,<6.0.0"
|
||||
|
||||
COPY ./app /app
|
||||
|
||||
CMD ["python", "/app/main.py"]
|
||||
13
.github/actions/people/action.yml
vendored
Normal file
13
.github/actions/people/action.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
name: "Generate FastAPI People"
|
||||
description: "Generate the data for the FastAPI People page"
|
||||
author: "Sebastián Ramírez <tiangolo@gmail.com>"
|
||||
inputs:
|
||||
token:
|
||||
description: 'User token, to read the GitHub API. Can be passed in using {{ secrets.ACTION_TOKEN }}'
|
||||
required: true
|
||||
standard_token:
|
||||
description: 'Default GitHub Action token, used for the PR. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
|
||||
required: true
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'Dockerfile'
|
||||
726
.github/actions/people/app/main.py
vendored
Normal file
726
.github/actions/people/app/main.py
vendored
Normal file
@@ -0,0 +1,726 @@
|
||||
import logging
|
||||
import subprocess
|
||||
import sys
|
||||
from collections import Counter, defaultdict
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any, Container, DefaultDict, Dict, List, Set, Union
|
||||
|
||||
import httpx
|
||||
import yaml
|
||||
from github import Github
|
||||
from pydantic import BaseModel, BaseSettings, SecretStr
|
||||
|
||||
github_graphql_url = "https://api.github.com/graphql"
|
||||
questions_category_id = "MDE4OkRpc2N1c3Npb25DYXRlZ29yeTMyMDAxNDM0"
|
||||
|
||||
discussions_query = """
|
||||
query Q($after: String, $category_id: ID) {
|
||||
repository(name: "fastapi", owner: "tiangolo") {
|
||||
discussions(first: 100, after: $after, categoryId: $category_id) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
number
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
title
|
||||
createdAt
|
||||
comments(first: 100) {
|
||||
nodes {
|
||||
createdAt
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
isAnswer
|
||||
replies(first: 10) {
|
||||
nodes {
|
||||
createdAt
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
issues_query = """
|
||||
query Q($after: String) {
|
||||
repository(name: "fastapi", owner: "tiangolo") {
|
||||
issues(first: 100, after: $after) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
number
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
title
|
||||
createdAt
|
||||
state
|
||||
comments(first: 100) {
|
||||
nodes {
|
||||
createdAt
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
prs_query = """
|
||||
query Q($after: String) {
|
||||
repository(name: "fastapi", owner: "tiangolo") {
|
||||
pullRequests(first: 100, after: $after) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
number
|
||||
labels(first: 100) {
|
||||
nodes {
|
||||
name
|
||||
}
|
||||
}
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
title
|
||||
createdAt
|
||||
state
|
||||
comments(first: 100) {
|
||||
nodes {
|
||||
createdAt
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
reviews(first:100) {
|
||||
nodes {
|
||||
author {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
state
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
sponsors_query = """
|
||||
query Q($after: String) {
|
||||
user(login: "tiangolo") {
|
||||
sponsorshipsAsMaintainer(first: 100, after: $after) {
|
||||
edges {
|
||||
cursor
|
||||
node {
|
||||
sponsorEntity {
|
||||
... on Organization {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
... on User {
|
||||
login
|
||||
avatarUrl
|
||||
url
|
||||
}
|
||||
}
|
||||
tier {
|
||||
name
|
||||
monthlyPriceInDollars
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
class Author(BaseModel):
|
||||
login: str
|
||||
avatarUrl: str
|
||||
url: str
|
||||
|
||||
|
||||
# Issues and Discussions
|
||||
|
||||
|
||||
class CommentsNode(BaseModel):
|
||||
createdAt: datetime
|
||||
author: Union[Author, None] = None
|
||||
|
||||
|
||||
class Replies(BaseModel):
|
||||
nodes: List[CommentsNode]
|
||||
|
||||
|
||||
class DiscussionsCommentsNode(CommentsNode):
|
||||
replies: Replies
|
||||
|
||||
|
||||
class Comments(BaseModel):
|
||||
nodes: List[CommentsNode]
|
||||
|
||||
|
||||
class DiscussionsComments(BaseModel):
|
||||
nodes: List[DiscussionsCommentsNode]
|
||||
|
||||
|
||||
class IssuesNode(BaseModel):
|
||||
number: int
|
||||
author: Union[Author, None] = None
|
||||
title: str
|
||||
createdAt: datetime
|
||||
state: str
|
||||
comments: Comments
|
||||
|
||||
|
||||
class DiscussionsNode(BaseModel):
|
||||
number: int
|
||||
author: Union[Author, None] = None
|
||||
title: str
|
||||
createdAt: datetime
|
||||
comments: DiscussionsComments
|
||||
|
||||
|
||||
class IssuesEdge(BaseModel):
|
||||
cursor: str
|
||||
node: IssuesNode
|
||||
|
||||
|
||||
class DiscussionsEdge(BaseModel):
|
||||
cursor: str
|
||||
node: DiscussionsNode
|
||||
|
||||
|
||||
class Issues(BaseModel):
|
||||
edges: List[IssuesEdge]
|
||||
|
||||
|
||||
class Discussions(BaseModel):
|
||||
edges: List[DiscussionsEdge]
|
||||
|
||||
|
||||
class IssuesRepository(BaseModel):
|
||||
issues: Issues
|
||||
|
||||
|
||||
class DiscussionsRepository(BaseModel):
|
||||
discussions: Discussions
|
||||
|
||||
|
||||
class IssuesResponseData(BaseModel):
|
||||
repository: IssuesRepository
|
||||
|
||||
|
||||
class DiscussionsResponseData(BaseModel):
|
||||
repository: DiscussionsRepository
|
||||
|
||||
|
||||
class IssuesResponse(BaseModel):
|
||||
data: IssuesResponseData
|
||||
|
||||
|
||||
class DiscussionsResponse(BaseModel):
|
||||
data: DiscussionsResponseData
|
||||
|
||||
|
||||
# PRs
|
||||
|
||||
|
||||
class LabelNode(BaseModel):
|
||||
name: str
|
||||
|
||||
|
||||
class Labels(BaseModel):
|
||||
nodes: List[LabelNode]
|
||||
|
||||
|
||||
class ReviewNode(BaseModel):
|
||||
author: Union[Author, None] = None
|
||||
state: str
|
||||
|
||||
|
||||
class Reviews(BaseModel):
|
||||
nodes: List[ReviewNode]
|
||||
|
||||
|
||||
class PullRequestNode(BaseModel):
|
||||
number: int
|
||||
labels: Labels
|
||||
author: Union[Author, None] = None
|
||||
title: str
|
||||
createdAt: datetime
|
||||
state: str
|
||||
comments: Comments
|
||||
reviews: Reviews
|
||||
|
||||
|
||||
class PullRequestEdge(BaseModel):
|
||||
cursor: str
|
||||
node: PullRequestNode
|
||||
|
||||
|
||||
class PullRequests(BaseModel):
|
||||
edges: List[PullRequestEdge]
|
||||
|
||||
|
||||
class PRsRepository(BaseModel):
|
||||
pullRequests: PullRequests
|
||||
|
||||
|
||||
class PRsResponseData(BaseModel):
|
||||
repository: PRsRepository
|
||||
|
||||
|
||||
class PRsResponse(BaseModel):
|
||||
data: PRsResponseData
|
||||
|
||||
|
||||
# Sponsors
|
||||
|
||||
|
||||
class SponsorEntity(BaseModel):
|
||||
login: str
|
||||
avatarUrl: str
|
||||
url: str
|
||||
|
||||
|
||||
class Tier(BaseModel):
|
||||
name: str
|
||||
monthlyPriceInDollars: float
|
||||
|
||||
|
||||
class SponsorshipAsMaintainerNode(BaseModel):
|
||||
sponsorEntity: SponsorEntity
|
||||
tier: Tier
|
||||
|
||||
|
||||
class SponsorshipAsMaintainerEdge(BaseModel):
|
||||
cursor: str
|
||||
node: SponsorshipAsMaintainerNode
|
||||
|
||||
|
||||
class SponsorshipAsMaintainer(BaseModel):
|
||||
edges: List[SponsorshipAsMaintainerEdge]
|
||||
|
||||
|
||||
class SponsorsUser(BaseModel):
|
||||
sponsorshipsAsMaintainer: SponsorshipAsMaintainer
|
||||
|
||||
|
||||
class SponsorsResponseData(BaseModel):
|
||||
user: SponsorsUser
|
||||
|
||||
|
||||
class SponsorsResponse(BaseModel):
|
||||
data: SponsorsResponseData
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
input_token: SecretStr
|
||||
input_standard_token: SecretStr
|
||||
github_repository: str
|
||||
httpx_timeout: int = 30
|
||||
|
||||
|
||||
def get_graphql_response(
|
||||
*,
|
||||
settings: Settings,
|
||||
query: str,
|
||||
after: Union[str, None] = None,
|
||||
category_id: Union[str, None] = None,
|
||||
) -> Dict[str, Any]:
|
||||
headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"}
|
||||
# category_id is only used by one query, but GraphQL allows unused variables, so
|
||||
# keep it here for simplicity
|
||||
variables = {"after": after, "category_id": category_id}
|
||||
response = httpx.post(
|
||||
github_graphql_url,
|
||||
headers=headers,
|
||||
timeout=settings.httpx_timeout,
|
||||
json={"query": query, "variables": variables, "operationName": "Q"},
|
||||
)
|
||||
if response.status_code != 200:
|
||||
logging.error(
|
||||
f"Response was not 200, after: {after}, category_id: {category_id}"
|
||||
)
|
||||
logging.error(response.text)
|
||||
raise RuntimeError(response.text)
|
||||
data = response.json()
|
||||
if "errors" in data:
|
||||
logging.error(f"Errors in response, after: {after}, category_id: {category_id}")
|
||||
logging.error(response.text)
|
||||
raise RuntimeError(response.text)
|
||||
return data
|
||||
|
||||
|
||||
def get_graphql_issue_edges(*, settings: Settings, after: Union[str, None] = None):
|
||||
data = get_graphql_response(settings=settings, query=issues_query, after=after)
|
||||
graphql_response = IssuesResponse.parse_obj(data)
|
||||
return graphql_response.data.repository.issues.edges
|
||||
|
||||
|
||||
def get_graphql_question_discussion_edges(
|
||||
*,
|
||||
settings: Settings,
|
||||
after: Union[str, None] = None,
|
||||
):
|
||||
data = get_graphql_response(
|
||||
settings=settings,
|
||||
query=discussions_query,
|
||||
after=after,
|
||||
category_id=questions_category_id,
|
||||
)
|
||||
graphql_response = DiscussionsResponse.parse_obj(data)
|
||||
return graphql_response.data.repository.discussions.edges
|
||||
|
||||
|
||||
def get_graphql_pr_edges(*, settings: Settings, after: Union[str, None] = None):
|
||||
data = get_graphql_response(settings=settings, query=prs_query, after=after)
|
||||
graphql_response = PRsResponse.parse_obj(data)
|
||||
return graphql_response.data.repository.pullRequests.edges
|
||||
|
||||
|
||||
def get_graphql_sponsor_edges(*, settings: Settings, after: Union[str, None] = None):
|
||||
data = get_graphql_response(settings=settings, query=sponsors_query, after=after)
|
||||
graphql_response = SponsorsResponse.parse_obj(data)
|
||||
return graphql_response.data.user.sponsorshipsAsMaintainer.edges
|
||||
|
||||
|
||||
def get_issues_experts(settings: Settings):
|
||||
issue_nodes: List[IssuesNode] = []
|
||||
issue_edges = get_graphql_issue_edges(settings=settings)
|
||||
|
||||
while issue_edges:
|
||||
for edge in issue_edges:
|
||||
issue_nodes.append(edge.node)
|
||||
last_edge = issue_edges[-1]
|
||||
issue_edges = get_graphql_issue_edges(settings=settings, after=last_edge.cursor)
|
||||
|
||||
commentors = Counter()
|
||||
last_month_commentors = Counter()
|
||||
authors: Dict[str, Author] = {}
|
||||
|
||||
now = datetime.now(tz=timezone.utc)
|
||||
one_month_ago = now - timedelta(days=30)
|
||||
|
||||
for issue in issue_nodes:
|
||||
issue_author_name = None
|
||||
if issue.author:
|
||||
authors[issue.author.login] = issue.author
|
||||
issue_author_name = issue.author.login
|
||||
issue_commentors = set()
|
||||
for comment in issue.comments.nodes:
|
||||
if comment.author:
|
||||
authors[comment.author.login] = comment.author
|
||||
if comment.author.login != issue_author_name:
|
||||
issue_commentors.add(comment.author.login)
|
||||
for author_name in issue_commentors:
|
||||
commentors[author_name] += 1
|
||||
if issue.createdAt > one_month_ago:
|
||||
last_month_commentors[author_name] += 1
|
||||
|
||||
return commentors, last_month_commentors, authors
|
||||
|
||||
|
||||
def get_discussions_experts(settings: Settings):
|
||||
discussion_nodes: List[DiscussionsNode] = []
|
||||
discussion_edges = get_graphql_question_discussion_edges(settings=settings)
|
||||
|
||||
while discussion_edges:
|
||||
for discussion_edge in discussion_edges:
|
||||
discussion_nodes.append(discussion_edge.node)
|
||||
last_edge = discussion_edges[-1]
|
||||
discussion_edges = get_graphql_question_discussion_edges(
|
||||
settings=settings, after=last_edge.cursor
|
||||
)
|
||||
|
||||
commentors = Counter()
|
||||
last_month_commentors = Counter()
|
||||
authors: Dict[str, Author] = {}
|
||||
|
||||
now = datetime.now(tz=timezone.utc)
|
||||
one_month_ago = now - timedelta(days=30)
|
||||
|
||||
for discussion in discussion_nodes:
|
||||
discussion_author_name = None
|
||||
if discussion.author:
|
||||
authors[discussion.author.login] = discussion.author
|
||||
discussion_author_name = discussion.author.login
|
||||
discussion_commentors = set()
|
||||
for comment in discussion.comments.nodes:
|
||||
if comment.author:
|
||||
authors[comment.author.login] = comment.author
|
||||
if comment.author.login != discussion_author_name:
|
||||
discussion_commentors.add(comment.author.login)
|
||||
for reply in comment.replies.nodes:
|
||||
if reply.author:
|
||||
authors[reply.author.login] = reply.author
|
||||
if reply.author.login != discussion_author_name:
|
||||
discussion_commentors.add(reply.author.login)
|
||||
for author_name in discussion_commentors:
|
||||
commentors[author_name] += 1
|
||||
if discussion.createdAt > one_month_ago:
|
||||
last_month_commentors[author_name] += 1
|
||||
return commentors, last_month_commentors, authors
|
||||
|
||||
|
||||
def get_experts(settings: Settings):
|
||||
# Migrated to only use GitHub Discussions
|
||||
# (
|
||||
# issues_commentors,
|
||||
# issues_last_month_commentors,
|
||||
# issues_authors,
|
||||
# ) = get_issues_experts(settings=settings)
|
||||
(
|
||||
discussions_commentors,
|
||||
discussions_last_month_commentors,
|
||||
discussions_authors,
|
||||
) = get_discussions_experts(settings=settings)
|
||||
# commentors = issues_commentors + discussions_commentors
|
||||
commentors = discussions_commentors
|
||||
# last_month_commentors = (
|
||||
# issues_last_month_commentors + discussions_last_month_commentors
|
||||
# )
|
||||
last_month_commentors = discussions_last_month_commentors
|
||||
# authors = {**issues_authors, **discussions_authors}
|
||||
authors = {**discussions_authors}
|
||||
return commentors, last_month_commentors, authors
|
||||
|
||||
|
||||
def get_contributors(settings: Settings):
|
||||
pr_nodes: List[PullRequestNode] = []
|
||||
pr_edges = get_graphql_pr_edges(settings=settings)
|
||||
|
||||
while pr_edges:
|
||||
for edge in pr_edges:
|
||||
pr_nodes.append(edge.node)
|
||||
last_edge = pr_edges[-1]
|
||||
pr_edges = get_graphql_pr_edges(settings=settings, after=last_edge.cursor)
|
||||
|
||||
contributors = Counter()
|
||||
commentors = Counter()
|
||||
reviewers = Counter()
|
||||
authors: Dict[str, Author] = {}
|
||||
|
||||
for pr in pr_nodes:
|
||||
author_name = None
|
||||
if pr.author:
|
||||
authors[pr.author.login] = pr.author
|
||||
author_name = pr.author.login
|
||||
pr_commentors: Set[str] = set()
|
||||
pr_reviewers: Set[str] = set()
|
||||
for comment in pr.comments.nodes:
|
||||
if comment.author:
|
||||
authors[comment.author.login] = comment.author
|
||||
if comment.author.login == author_name:
|
||||
continue
|
||||
pr_commentors.add(comment.author.login)
|
||||
for author_name in pr_commentors:
|
||||
commentors[author_name] += 1
|
||||
for review in pr.reviews.nodes:
|
||||
if review.author:
|
||||
authors[review.author.login] = review.author
|
||||
pr_reviewers.add(review.author.login)
|
||||
for reviewer in pr_reviewers:
|
||||
reviewers[reviewer] += 1
|
||||
if pr.state == "MERGED" and pr.author:
|
||||
contributors[pr.author.login] += 1
|
||||
return contributors, commentors, reviewers, authors
|
||||
|
||||
|
||||
def get_individual_sponsors(settings: Settings):
|
||||
nodes: List[SponsorshipAsMaintainerNode] = []
|
||||
edges = get_graphql_sponsor_edges(settings=settings)
|
||||
|
||||
while edges:
|
||||
for edge in edges:
|
||||
nodes.append(edge.node)
|
||||
last_edge = edges[-1]
|
||||
edges = get_graphql_sponsor_edges(settings=settings, after=last_edge.cursor)
|
||||
|
||||
tiers: DefaultDict[float, Dict[str, SponsorEntity]] = defaultdict(dict)
|
||||
for node in nodes:
|
||||
tiers[node.tier.monthlyPriceInDollars][
|
||||
node.sponsorEntity.login
|
||||
] = node.sponsorEntity
|
||||
return tiers
|
||||
|
||||
|
||||
def get_top_users(
|
||||
*,
|
||||
counter: Counter,
|
||||
min_count: int,
|
||||
authors: Dict[str, Author],
|
||||
skip_users: Container[str],
|
||||
):
|
||||
users = []
|
||||
for commentor, count in counter.most_common(50):
|
||||
if commentor in skip_users:
|
||||
continue
|
||||
if count >= min_count:
|
||||
author = authors[commentor]
|
||||
users.append(
|
||||
{
|
||||
"login": commentor,
|
||||
"count": count,
|
||||
"avatarUrl": author.avatarUrl,
|
||||
"url": author.url,
|
||||
}
|
||||
)
|
||||
return users
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
settings = Settings()
|
||||
logging.info(f"Using config: {settings.json()}")
|
||||
g = Github(settings.input_standard_token.get_secret_value())
|
||||
repo = g.get_repo(settings.github_repository)
|
||||
question_commentors, question_last_month_commentors, question_authors = get_experts(
|
||||
settings=settings
|
||||
)
|
||||
contributors, pr_commentors, reviewers, pr_authors = get_contributors(
|
||||
settings=settings
|
||||
)
|
||||
authors = {**question_authors, **pr_authors}
|
||||
maintainers_logins = {"tiangolo"}
|
||||
bot_names = {"codecov", "github-actions", "pre-commit-ci", "dependabot"}
|
||||
maintainers = []
|
||||
for login in maintainers_logins:
|
||||
user = authors[login]
|
||||
maintainers.append(
|
||||
{
|
||||
"login": login,
|
||||
"answers": question_commentors[login],
|
||||
"prs": contributors[login],
|
||||
"avatarUrl": user.avatarUrl,
|
||||
"url": user.url,
|
||||
}
|
||||
)
|
||||
|
||||
min_count_expert = 10
|
||||
min_count_last_month = 3
|
||||
min_count_contributor = 4
|
||||
min_count_reviewer = 4
|
||||
skip_users = maintainers_logins | bot_names
|
||||
experts = get_top_users(
|
||||
counter=question_commentors,
|
||||
min_count=min_count_expert,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
last_month_active = get_top_users(
|
||||
counter=question_last_month_commentors,
|
||||
min_count=min_count_last_month,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
top_contributors = get_top_users(
|
||||
counter=contributors,
|
||||
min_count=min_count_contributor,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
top_reviewers = get_top_users(
|
||||
counter=reviewers,
|
||||
min_count=min_count_reviewer,
|
||||
authors=authors,
|
||||
skip_users=skip_users,
|
||||
)
|
||||
|
||||
tiers = get_individual_sponsors(settings=settings)
|
||||
keys = list(tiers.keys())
|
||||
keys.sort(reverse=True)
|
||||
sponsors = []
|
||||
for key in keys:
|
||||
sponsor_group = []
|
||||
for login, sponsor in tiers[key].items():
|
||||
sponsor_group.append(
|
||||
{"login": login, "avatarUrl": sponsor.avatarUrl, "url": sponsor.url}
|
||||
)
|
||||
sponsors.append(sponsor_group)
|
||||
|
||||
people = {
|
||||
"maintainers": maintainers,
|
||||
"experts": experts,
|
||||
"last_month_active": last_month_active,
|
||||
"top_contributors": top_contributors,
|
||||
"top_reviewers": top_reviewers,
|
||||
}
|
||||
github_sponsors = {
|
||||
"sponsors": sponsors,
|
||||
}
|
||||
people_path = Path("./docs/en/data/people.yml")
|
||||
github_sponsors_path = Path("./docs/en/data/github_sponsors.yml")
|
||||
people_old_content = people_path.read_text(encoding="utf-8")
|
||||
github_sponsors_old_content = github_sponsors_path.read_text(encoding="utf-8")
|
||||
new_people_content = yaml.dump(
|
||||
people, sort_keys=False, width=200, allow_unicode=True
|
||||
)
|
||||
new_github_sponsors_content = yaml.dump(
|
||||
github_sponsors, sort_keys=False, width=200, allow_unicode=True
|
||||
)
|
||||
if (
|
||||
people_old_content == new_people_content
|
||||
and github_sponsors_old_content == new_github_sponsors_content
|
||||
):
|
||||
logging.info("The FastAPI People data hasn't changed, finishing.")
|
||||
sys.exit(0)
|
||||
people_path.write_text(new_people_content, encoding="utf-8")
|
||||
github_sponsors_path.write_text(new_github_sponsors_content, encoding="utf-8")
|
||||
logging.info("Setting up GitHub Actions git user")
|
||||
subprocess.run(["git", "config", "user.name", "github-actions"], check=True)
|
||||
subprocess.run(
|
||||
["git", "config", "user.email", "github-actions@github.com"], check=True
|
||||
)
|
||||
branch_name = "fastapi-people"
|
||||
logging.info(f"Creating a new branch {branch_name}")
|
||||
subprocess.run(["git", "checkout", "-b", branch_name], check=True)
|
||||
logging.info("Adding updated file")
|
||||
subprocess.run(
|
||||
["git", "add", str(people_path), str(github_sponsors_path)], check=True
|
||||
)
|
||||
logging.info("Committing updated file")
|
||||
message = "👥 Update FastAPI People"
|
||||
result = subprocess.run(["git", "commit", "-m", message], check=True)
|
||||
logging.info("Pushing branch")
|
||||
subprocess.run(["git", "push", "origin", branch_name], check=True)
|
||||
logging.info("Creating PR")
|
||||
pr = repo.create_pull(title=message, body=message, base="master", head=branch_name)
|
||||
logging.info(f"Created PR: {pr.number}")
|
||||
logging.info("Finished")
|
||||
7
.github/actions/watch-previews/Dockerfile
vendored
Normal file
7
.github/actions/watch-previews/Dockerfile
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM python:3.7
|
||||
|
||||
RUN pip install httpx PyGithub "pydantic==1.5.1"
|
||||
|
||||
COPY ./app /app
|
||||
|
||||
CMD ["python", "/app/main.py"]
|
||||
10
.github/actions/watch-previews/action.yml
vendored
Normal file
10
.github/actions/watch-previews/action.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
name: "Watch docs previews in PRs"
|
||||
description: "Check PRs and trigger new docs deploys"
|
||||
author: "Sebastián Ramírez <tiangolo@gmail.com>"
|
||||
inputs:
|
||||
token:
|
||||
description: 'Token for the repo. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
|
||||
required: true
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'Dockerfile'
|
||||
101
.github/actions/watch-previews/app/main.py
vendored
Normal file
101
.github/actions/watch-previews/app/main.py
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import List, Union
|
||||
|
||||
import httpx
|
||||
from github import Github
|
||||
from github.NamedUser import NamedUser
|
||||
from pydantic import BaseModel, BaseSettings, SecretStr
|
||||
|
||||
github_api = "https://api.github.com"
|
||||
netlify_api = "https://api.netlify.com"
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
input_token: SecretStr
|
||||
github_repository: str
|
||||
github_event_path: Path
|
||||
github_event_name: Union[str, None] = None
|
||||
|
||||
|
||||
class Artifact(BaseModel):
|
||||
id: int
|
||||
node_id: str
|
||||
name: str
|
||||
size_in_bytes: int
|
||||
url: str
|
||||
archive_download_url: str
|
||||
expired: bool
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class ArtifactResponse(BaseModel):
|
||||
total_count: int
|
||||
artifacts: List[Artifact]
|
||||
|
||||
|
||||
def get_message(commit: str) -> str:
|
||||
return f"Docs preview for commit {commit} at"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
settings = Settings()
|
||||
logging.info(f"Using config: {settings.json()}")
|
||||
g = Github(settings.input_token.get_secret_value())
|
||||
repo = g.get_repo(settings.github_repository)
|
||||
owner: NamedUser = repo.owner
|
||||
headers = {"Authorization": f"token {settings.input_token.get_secret_value()}"}
|
||||
prs = list(repo.get_pulls(state="open"))
|
||||
response = httpx.get(
|
||||
f"{github_api}/repos/{settings.github_repository}/actions/artifacts",
|
||||
headers=headers,
|
||||
)
|
||||
data = response.json()
|
||||
artifacts_response = ArtifactResponse.parse_obj(data)
|
||||
for pr in prs:
|
||||
logging.info("-----")
|
||||
logging.info(f"Processing PR #{pr.number}: {pr.title}")
|
||||
pr_comments = list(pr.get_issue_comments())
|
||||
pr_commits = list(pr.get_commits())
|
||||
last_commit = pr_commits[0]
|
||||
for pr_commit in pr_commits:
|
||||
if pr_commit.commit.author.date > last_commit.commit.author.date:
|
||||
last_commit = pr_commit
|
||||
commit = last_commit.commit.sha
|
||||
logging.info(f"Last commit: {commit}")
|
||||
message = get_message(commit)
|
||||
notified = False
|
||||
for pr_comment in pr_comments:
|
||||
if message in pr_comment.body:
|
||||
notified = True
|
||||
logging.info(f"Docs preview was notified: {notified}")
|
||||
if not notified:
|
||||
artifact_name = f"docs-zip-{commit}"
|
||||
use_artifact: Union[Artifact, None] = None
|
||||
for artifact in artifacts_response.artifacts:
|
||||
if artifact.name == artifact_name:
|
||||
use_artifact = artifact
|
||||
break
|
||||
if not use_artifact:
|
||||
logging.info("Artifact not available")
|
||||
else:
|
||||
logging.info(f"Existing artifact: {use_artifact.name}")
|
||||
response = httpx.post(
|
||||
"https://api.github.com/repos/tiangolo/fastapi/actions/workflows/preview-docs.yml/dispatches",
|
||||
headers=headers,
|
||||
json={
|
||||
"ref": "master",
|
||||
"inputs": {
|
||||
"pr": f"{pr.number}",
|
||||
"name": artifact_name,
|
||||
"commit": commit,
|
||||
},
|
||||
},
|
||||
)
|
||||
logging.info(
|
||||
f"Trigger sent, response status: {response.status_code} - content: {response.content}"
|
||||
)
|
||||
logging.info("Finished")
|
||||
16
.github/dependabot.yml
vendored
Normal file
16
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
version: 2
|
||||
updates:
|
||||
# GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
commit-message:
|
||||
prefix: ⬆
|
||||
# Python
|
||||
- package-ecosystem: "pip"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
commit-message:
|
||||
prefix: ⬆
|
||||
49
.github/workflows/build-docs.yml
vendored
Normal file
49
.github/workflows/build-docs.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: Build Docs
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
jobs:
|
||||
build-docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- uses: actions/cache@v3
|
||||
id: cache
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-docs-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-v03
|
||||
- name: Install docs extras
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install .[doc]
|
||||
- name: Install Material for MkDocs Insiders
|
||||
if: ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false ) && steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git
|
||||
- name: Build Docs
|
||||
run: python ./scripts/docs.py build-all
|
||||
- name: Zip docs
|
||||
run: bash ./scripts/zip-docs.sh
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: docs-zip
|
||||
path: ./site/docs.zip
|
||||
- name: Deploy to Netlify
|
||||
uses: nwtgck/actions-netlify@v2.0.0
|
||||
with:
|
||||
publish-dir: './site'
|
||||
production-branch: master
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
enable-commit-comment: false
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
||||
29
.github/workflows/deploy-docs.yml
vendored
29
.github/workflows/deploy-docs.yml
vendored
@@ -1,29 +0,0 @@
|
||||
name: Build and Deploy to Netlify
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: "3.7"
|
||||
- name: Install Flit
|
||||
run: python3.7 -m pip install flit
|
||||
- name: Install docs extras
|
||||
run: python3.7 -m flit install --extras doc
|
||||
- name: Build MkDocs
|
||||
run: python3.7 -m mkdocs build
|
||||
- name: Deploy to Netlify
|
||||
uses: nwtgck/actions-netlify@v1.0.3
|
||||
with:
|
||||
publish-dir: './site'
|
||||
production-branch: master
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
||||
30
.github/workflows/issue-manager.yml
vendored
Normal file
30
.github/workflows/issue-manager.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: Issue Manager
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
issue_comment:
|
||||
types:
|
||||
- created
|
||||
issues:
|
||||
types:
|
||||
- labeled
|
||||
pull_request_target:
|
||||
types:
|
||||
- labeled
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
issue-manager:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: tiangolo/issue-manager@0.4.0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
config: >
|
||||
{
|
||||
"answered": {
|
||||
"delay": 864000,
|
||||
"message": "Assuming the original need was handled, this will be automatically closed now. But feel free to add more comments or create new issues or PRs."
|
||||
}
|
||||
}
|
||||
13
.github/workflows/label-approved.yml
vendored
Normal file
13
.github/workflows/label-approved.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
name: Label Approved
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 12 * * *"
|
||||
|
||||
jobs:
|
||||
label-approved:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: docker://tiangolo/label-approved:0.0.2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
40
.github/workflows/latest-changes.yml
vendored
Normal file
40
.github/workflows/latest-changes.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
name: Latest Changes
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- master
|
||||
types:
|
||||
- closed
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
number:
|
||||
description: PR number
|
||||
required: true
|
||||
debug_enabled:
|
||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
||||
required: false
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
latest-changes:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
# To allow latest-changes to commit to master
|
||||
token: ${{ secrets.ACTIONS_TOKEN }}
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
token: ${{ secrets.ACTIONS_TOKEN }}
|
||||
standard_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: docker://tiangolo/latest-changes:0.0.3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
latest_changes_file: docs/en/docs/release-notes.md
|
||||
latest_changes_header: '## Latest Changes\n\n'
|
||||
debug_logs: true
|
||||
19
.github/workflows/main.yml
vendored
19
.github/workflows/main.yml
vendored
@@ -1,19 +0,0 @@
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
jobs:
|
||||
issue-manager:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: tiangolo/issue-manager@master
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
config: >
|
||||
{
|
||||
"answered": {
|
||||
"users": ["tiangolo", "dmontagu"],
|
||||
"delay": 864000,
|
||||
"message": "Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues."
|
||||
}
|
||||
}
|
||||
22
.github/workflows/notify-translations.yml
vendored
Normal file
22
.github/workflows/notify-translations.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Notify Translations
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- labeled
|
||||
- closed
|
||||
|
||||
jobs:
|
||||
notify-translations:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
- uses: ./.github/actions/notify-translations
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
32
.github/workflows/people.yml
vendored
Normal file
32
.github/workflows/people.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: FastAPI People
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 14 1 * *"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug_enabled:
|
||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
||||
required: false
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
fastapi-people:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# Ref: https://github.com/actions/runner/issues/2033
|
||||
- name: Fix git safe.directory in container
|
||||
run: mkdir -p /home/runner/work/_temp/_github_home && printf "[safe]\n\tdirectory = /github/workspace" > /home/runner/work/_temp/_github_home/.gitconfig
|
||||
# Allow debugging with tmate
|
||||
- name: Setup tmate session
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }}
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
token: ${{ secrets.ACTIONS_TOKEN }}
|
||||
standard_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: ./.github/actions/people
|
||||
with:
|
||||
token: ${{ secrets.ACTIONS_TOKEN }}
|
||||
standard_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
46
.github/workflows/preview-docs.yml
vendored
Normal file
46
.github/workflows/preview-docs.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Preview Docs
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Build Docs
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
preview-docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Clean site
|
||||
run: |
|
||||
rm -rf ./site
|
||||
mkdir ./site
|
||||
- name: Download Artifact Docs
|
||||
uses: dawidd6/action-download-artifact@v2.26.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
workflow: build-docs.yml
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
name: docs-zip
|
||||
path: ./site/
|
||||
- name: Unzip docs
|
||||
run: |
|
||||
cd ./site
|
||||
unzip docs.zip
|
||||
rm -f docs.zip
|
||||
- name: Deploy to Netlify
|
||||
id: netlify
|
||||
uses: nwtgck/actions-netlify@v2.0.0
|
||||
with:
|
||||
publish-dir: './site'
|
||||
production-deploy: false
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
enable-commit-comment: false
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
||||
- name: Comment Deploy
|
||||
uses: ./.github/actions/comment-docs-preview-in-pr
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
deploy_url: "${{ steps.netlify.outputs.deploy-url }}"
|
||||
46
.github/workflows/publish.yml
vendored
Normal file
46
.github/workflows/publish.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Publish
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.7"
|
||||
cache: "pip"
|
||||
cache-dependency-path: pyproject.toml
|
||||
- uses: actions/cache@v3
|
||||
id: cache
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish
|
||||
- name: Install build dependencies
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install build
|
||||
- name: Build distribution
|
||||
run: python -m build
|
||||
- name: Publish
|
||||
uses: pypa/gh-action-pypi-publish@v1.6.4
|
||||
with:
|
||||
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: echo "$GITHUB_CONTEXT"
|
||||
# - name: Notify
|
||||
# env:
|
||||
# GITTER_TOKEN: ${{ secrets.GITTER_TOKEN }}
|
||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# TAG: ${{ github.event.release.name }}
|
||||
# run: bash scripts/notify.sh
|
||||
35
.github/workflows/smokeshow.yml
vendored
Normal file
35
.github/workflows/smokeshow.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Smokeshow
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Test]
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
statuses: write
|
||||
|
||||
jobs:
|
||||
smokeshow:
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
- run: pip install smokeshow
|
||||
|
||||
- uses: dawidd6/action-download-artifact@v2.26.0
|
||||
with:
|
||||
workflow: test.yml
|
||||
commit: ${{ github.event.workflow_run.head_sha }}
|
||||
|
||||
- run: smokeshow upload coverage-html
|
||||
env:
|
||||
SMOKESHOW_GITHUB_STATUS_DESCRIPTION: Coverage {coverage-percentage}
|
||||
SMOKESHOW_GITHUB_COVERAGE_THRESHOLD: 100
|
||||
SMOKESHOW_GITHUB_CONTEXT: coverage
|
||||
SMOKESHOW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SMOKESHOW_GITHUB_PR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
SMOKESHOW_AUTH_KEY: ${{ secrets.SMOKESHOW_AUTH_KEY }}
|
||||
93
.github/workflows/test.yml
vendored
Normal file
93
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: "pip"
|
||||
cache-dependency-path: pyproject.toml
|
||||
- uses: actions/cache@v3
|
||||
id: cache
|
||||
with:
|
||||
path: ${{ env.pythonLocation }}
|
||||
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test-v03
|
||||
- name: Install Dependencies
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: pip install -e .[all,dev,doc,test]
|
||||
- name: Lint
|
||||
run: bash scripts/lint.sh
|
||||
- run: mkdir coverage
|
||||
- name: Test
|
||||
run: 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@v3
|
||||
with:
|
||||
name: coverage
|
||||
path: coverage
|
||||
coverage-combine:
|
||||
needs: [test]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.8'
|
||||
cache: "pip"
|
||||
cache-dependency-path: pyproject.toml
|
||||
|
||||
- name: Get coverage files
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: coverage
|
||||
path: coverage
|
||||
|
||||
- run: pip install coverage[toml]
|
||||
|
||||
- run: ls -la coverage
|
||||
- run: coverage combine coverage
|
||||
- run: coverage report
|
||||
- run: coverage html --show-contexts --title "Coverage for ${{ github.sha }}"
|
||||
|
||||
- name: Store coverage HTML
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: coverage-html
|
||||
path: htmlcov
|
||||
|
||||
# https://github.com/marketplace/actions/alls-green#why
|
||||
check: # This job does nothing and is only used for the branch protection
|
||||
|
||||
if: always()
|
||||
|
||||
needs:
|
||||
- coverage-combine
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Decide whether the needed jobs succeeded or failed
|
||||
uses: re-actors/alls-green@release/v1
|
||||
with:
|
||||
jobs: ${{ toJSON(needs) }}
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -14,3 +14,12 @@ test.db
|
||||
log.txt
|
||||
Pipfile.lock
|
||||
env3.*
|
||||
env
|
||||
docs_build
|
||||
venv
|
||||
docs.zip
|
||||
archive.zip
|
||||
|
||||
# vim temporary files
|
||||
*~
|
||||
.*.sw?
|
||||
|
||||
46
.pre-commit-config.yaml
Normal file
46
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
# 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
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-toml
|
||||
- id: check-yaml
|
||||
args:
|
||||
- --unsafe
|
||||
- id: end-of-file-fixer
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.3.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args:
|
||||
- --py3-plus
|
||||
- --keep-runtime-typing
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.0.254
|
||||
hooks:
|
||||
- id: ruff
|
||||
args:
|
||||
- --fix
|
||||
- repo: https://github.com/pycqa/isort
|
||||
rev: 5.12.0
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort (python)
|
||||
- id: isort
|
||||
name: isort (cython)
|
||||
types: [cython]
|
||||
- id: isort
|
||||
name: isort (pyi)
|
||||
types: [pyi]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.1.0
|
||||
hooks:
|
||||
- id: black
|
||||
ci:
|
||||
autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
|
||||
autoupdate_commit_msg: ⬆ [pre-commit.ci] pre-commit autoupdate
|
||||
32
.travis.yml
32
.travis.yml
@@ -1,32 +0,0 @@
|
||||
dist: xenial
|
||||
|
||||
language: python
|
||||
|
||||
cache: pip
|
||||
|
||||
python:
|
||||
- "3.6"
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
- "nightly"
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- python: "nightly"
|
||||
|
||||
install:
|
||||
- pip install flit
|
||||
- flit install --symlink
|
||||
|
||||
script:
|
||||
- bash scripts/test.sh
|
||||
|
||||
after_script:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
deploy:
|
||||
provider: script
|
||||
script: bash scripts/deploy.sh
|
||||
on:
|
||||
tags: true
|
||||
python: "3.6"
|
||||
180
README.md
180
README.md
@@ -5,17 +5,17 @@
|
||||
<em>FastAPI framework, high performance, easy to learn, fast to code, ready for production</em>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://travis-ci.com/tiangolo/fastapi" target="_blank">
|
||||
<img src="https://travis-ci.com/tiangolo/fastapi.svg?branch=master" alt="Build Status">
|
||||
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest+event%3Apush+branch%3Amaster" target="_blank">
|
||||
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg?event=push&branch=master" alt="Test">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
|
||||
<img src="https://codecov.io/gh/tiangolo/fastapi/branch/master/graph/badge.svg" alt="Coverage">
|
||||
<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/tiangolo/fastapi" target="_blank">
|
||||
<img src="https://coverage-badge.samuelcolvin.workers.dev/tiangolo/fastapi.svg" alt="Coverage">
|
||||
</a>
|
||||
<a href="https://pypi.org/project/fastapi" target="_blank">
|
||||
<img src="https://badge.fury.io/py/fastapi.svg" alt="Package version">
|
||||
<img src="https://img.shields.io/pypi/v/fastapi?color=%2334D058&label=pypi%20package" alt="Package version">
|
||||
</a>
|
||||
<a href="https://gitter.im/tiangolo/fastapi?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" target="_blank">
|
||||
<img src="https://badges.gitter.im/tiangolo/fastapi.svg" alt="Join the chat at https://gitter.im/tiangolo/fastapi">
|
||||
<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>
|
||||
|
||||
@@ -27,59 +27,96 @@
|
||||
|
||||
---
|
||||
|
||||
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
|
||||
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints.
|
||||
|
||||
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% *.
|
||||
* **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.
|
||||
* **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="http://json-schema.org/" class="external-link" target="_blank">JSON Schema</a>.
|
||||
* **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>
|
||||
|
||||
## Sponsors
|
||||
|
||||
<!-- sponsors -->
|
||||
|
||||
<a href="https://cryptapi.io/" target="_blank" title="CryptAPI: Your easy to use, secure and privacy oriented payment gateway."><img src="https://fastapi.tiangolo.com/img/sponsors/cryptapi.svg"></a>
|
||||
<a href="https://www.deta.sh/?ref=fastapi" target="_blank" title="The launchpad for all your (team's) ideas"><img src="https://fastapi.tiangolo.com/img/sponsors/deta.svg"></a>
|
||||
<a href="https://www.investsuite.com/jobs" target="_blank" title="Wealthtech jobs with FastAPI"><img src="https://fastapi.tiangolo.com/img/sponsors/investsuite.svg"></a>
|
||||
<a href="https://training.talkpython.fm/fastapi-courses" target="_blank" title="FastAPI video courses on demand from people you trust"><img src="https://fastapi.tiangolo.com/img/sponsors/talkpython.png"></a>
|
||||
<a href="https://testdriven.io/courses/tdd-fastapi/" target="_blank" title="Learn to build high-quality web apps with best practices"><img src="https://fastapi.tiangolo.com/img/sponsors/testdriven.svg"></a>
|
||||
<a href="https://github.com/deepset-ai/haystack/" target="_blank" title="Build powerful search from composable, open source building blocks"><img src="https://fastapi.tiangolo.com/img/sponsors/haystack-fastapi.svg"></a>
|
||||
<a href="https://careers.powens.com/" target="_blank" title="Powens is hiring!"><img src="https://fastapi.tiangolo.com/img/sponsors/powens.png"></a>
|
||||
<a href="https://www.svix.com/" target="_blank" title="Svix - Webhooks as a service"><img src="https://fastapi.tiangolo.com/img/sponsors/svix.svg"></a>
|
||||
<a href="https://databento.com/" target="_blank" title="Pay as you go for market data"><img src="https://fastapi.tiangolo.com/img/sponsors/databento.svg"></a>
|
||||
|
||||
<!-- /sponsors -->
|
||||
|
||||
<a href="https://fastapi.tiangolo.com/fastapi-people/#sponsors" class="external-link" target="_blank">Other sponsors</a>
|
||||
|
||||
## Opinions
|
||||
|
||||
"*[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products.*"
|
||||
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"*I’m over the moon excited about **FastAPI**. It’s so fun!*"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"*Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that.*"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="http://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"*If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]*"
|
||||
|
||||
"*We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]*"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"*We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]*"
|
||||
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
|
||||
|
||||
<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** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
|
||||
|
||||
<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>
|
||||
|
||||
---
|
||||
|
||||
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
|
||||
|
||||
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
|
||||
|
||||
<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**, 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>
|
||||
|
||||
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
|
||||
|
||||
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
|
||||
|
||||
## Requirements
|
||||
|
||||
Python 3.6+
|
||||
Python 3.7+
|
||||
|
||||
FastAPI stands on the shoulders of giants:
|
||||
|
||||
@@ -88,16 +125,28 @@ FastAPI stands on the shoulders of giants:
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install fastapi
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install fastapi
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
You will also need an ASGI server, for production such as <a href="http://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
|
||||
</div>
|
||||
|
||||
```bash
|
||||
pip install uvicorn
|
||||
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://github.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Example
|
||||
|
||||
### Create it
|
||||
@@ -105,6 +154,8 @@ pip install uvicorn
|
||||
* Create a file `main.py` with:
|
||||
|
||||
```Python
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
@@ -116,7 +167,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: str = None):
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -125,7 +176,9 @@ def read_item(item_id: int, q: str = None):
|
||||
|
||||
If your code uses `async` / `await`, use `async def`:
|
||||
|
||||
```Python hl_lines="7 12"
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
app = FastAPI()
|
||||
@@ -137,7 +190,7 @@ async def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
async def read_item(item_id: int, q: str = None):
|
||||
async def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
@@ -151,10 +204,20 @@ If you don't know, check the _"In a hurry?"_ section about <a href="https://fast
|
||||
|
||||
Run the server with:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --reload
|
||||
<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>About the command <code>uvicorn main:app --reload</code>...</summary>
|
||||
|
||||
@@ -205,7 +268,9 @@ 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="2 7 8 9 10 23 24 25"
|
||||
```Python hl_lines="4 9-12 25-27"
|
||||
from typing import Union
|
||||
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
@@ -215,7 +280,7 @@ app = FastAPI()
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: bool = None
|
||||
is_offer: Union[bool, None] = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
@@ -224,7 +289,7 @@ def read_root():
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: str = None):
|
||||
def read_item(item_id: int, q: Union[str, None] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
|
||||
|
||||
@@ -261,13 +326,13 @@ And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" targe
|
||||
|
||||
### Recap
|
||||
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
|
||||
You do that with standard modern Python types.
|
||||
|
||||
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
|
||||
|
||||
Just standard **Python 3.6+**.
|
||||
Just standard **Python 3.7+**.
|
||||
|
||||
For example, for an `int`:
|
||||
|
||||
@@ -318,7 +383,7 @@ Coming back to the previous code example, **FastAPI** will:
|
||||
* As the `q` parameter is declared with `= None`, it is optional.
|
||||
* Without the `None` it would be required (as is the body in the case with `PUT`).
|
||||
* For `PUT` requests to `/items/{item_id}`, Read the body as JSON:
|
||||
* Check that it has a required attribute `name` that should be a `str`.
|
||||
* Check that it has a required attribute `name` that should be a `str`.
|
||||
* Check that it has a required attribute `price` that has to be a `float`.
|
||||
* Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
|
||||
* All this would also work for deeply nested JSON objects.
|
||||
@@ -363,10 +428,10 @@ For a more complete example including more features, see the <a href="https://fa
|
||||
* A very powerful and easy to use **<abbr title="also known as components, resources, providers, services, injectables">Dependency Injection</abbr>** 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.
|
||||
* Many extra features (thanks to Starlette) as:
|
||||
* **WebSockets**
|
||||
* **GraphQL**
|
||||
* extremely easy tests based on `requests` and `pytest`
|
||||
* extremely easy tests based on HTTPX and `pytest`
|
||||
* **CORS**
|
||||
* **Cookie Sessions**
|
||||
* ...and more.
|
||||
@@ -386,20 +451,19 @@ Used by Pydantic:
|
||||
|
||||
Used by Starlette:
|
||||
|
||||
* <a href="http://docs.python-requests.org" target="_blank"><code>requests</code></a> - Required if you want to use the `TestClient`.
|
||||
* <a href="https://github.com/Tinche/aiofiles" target="_blank"><code>aiofiles</code></a> - Required if you want to use `FileResponse` or `StaticFiles`.
|
||||
* <a href="http://jinja.pocoo.org" target="_blank"><code>jinja2</code></a> - Required if you want to use the default template configuration.
|
||||
* <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://andrew-d.github.io/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://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
|
||||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
|
||||
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - Required for `GraphQLApp` support.
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
|
||||
|
||||
Used by FastAPI / Starlette:
|
||||
|
||||
* <a href="http://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
|
||||
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
|
||||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
|
||||
|
||||
You can install all of these with `pip install fastapi[all]`.
|
||||
You can install all of these with `pip install "fastapi[all]"`.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
31
SECURITY.md
Normal file
31
SECURITY.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Security Policy
|
||||
|
||||
Security is very important for FastAPI and its community. 🔒
|
||||
|
||||
Learn more about it below. 👇
|
||||
|
||||
## Versions
|
||||
|
||||
The latest version of FastAPI is supported.
|
||||
|
||||
You are encouraged to [write tests](https://fastapi.tiangolo.com/tutorial/testing/) for your application and update your FastAPI version frequently after ensuring that your tests are passing. This way you will benefit from the latest features, bug fixes, and **security fixes**.
|
||||
|
||||
You can learn more about [FastAPI versions and how to pin and upgrade them](https://fastapi.tiangolo.com/deployment/versions/) for your project in the docs.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you think you found a vulnerability, and even if you are not sure about it, please report it right away by sending an email to: security@tiangolo.com. Please try to be as explicit as possible, describing all the steps and example code to reproduce the security issue.
|
||||
|
||||
I (the author, [@tiangolo](https://twitter.com/tiangolo)) will review it thoroughly and get back to you.
|
||||
|
||||
## Public Discussions
|
||||
|
||||
Please restrain from publicly discussing a potential security vulnerability. 🙊
|
||||
|
||||
It's better to discuss privately and try to find a solution first, to limit the potential impact as much as possible.
|
||||
|
||||
---
|
||||
|
||||
Thanks for your help!
|
||||
|
||||
The FastAPI community and I thank you for that. 🙇
|
||||
@@ -1,30 +0,0 @@
|
||||
By default, **FastAPI** will return the responses using Starlette's `JSONResponse`, putting the content you return from your *path operation* inside of that `JSONResponse`.
|
||||
|
||||
It will use the default status code or the one you set in your *path operation*.
|
||||
|
||||
## Additional status codes
|
||||
|
||||
If you want to return additional status codes apart from the main one, you can do that by returning a `Response` directly, like a `JSONResponse`, and set the additional status code directly.
|
||||
|
||||
For example, let's say that you want to have a *path operation* that allows to update items, and returns HTTP status codes of 200 "OK" when successful.
|
||||
|
||||
But you also want it to accept new items. And when the items didn't exist before, it creates them, and returns an HTTP status code of 201 "Created".
|
||||
|
||||
To achieve that, import `JSONResponse`, and return your content there directly, setting the `status_code` that you want:
|
||||
|
||||
```Python hl_lines="2 20"
|
||||
{!./src/additional_status_codes/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! warning
|
||||
When you return a `Response` directly, like in the example above, it will be returned directly.
|
||||
|
||||
It won't be serialized with a model, etc.
|
||||
|
||||
Make sure it has the data you want it to have, and that the values are valid JSON (if you are using `JSONResponse`).
|
||||
|
||||
## OpenAPI and API docs
|
||||
|
||||
If you return additional status codes and responses directly, they won't be included in the OpenAPI schema (the API docs), because FastAPI doesn't have a way to know before hand what you are going to return.
|
||||
|
||||
But you can document that in your code, using: [Additional Responses](additional-responses.md){.internal-link target=_blank}.
|
||||
@@ -1,102 +0,0 @@
|
||||
!!! warning
|
||||
This is a rather advanced topic.
|
||||
|
||||
If you are starting with **FastAPI**, you might not need this.
|
||||
|
||||
By default, **FastAPI** will return the responses using Starlette's `JSONResponse`.
|
||||
|
||||
You can override it by returning a `Response` directly as seen in [Return a Response directly](response-directly.md){.internal-link target=_blank}.
|
||||
|
||||
But if you return a `Response` directly, the data won't be automatically converted, and the documentation won't be automatically generated (for example, including the specific "media type", in the HTTP header `Content-Type`).
|
||||
|
||||
But you can also declare the `Response` that you want to be used, in the *path operation decorator*.
|
||||
|
||||
The contents that you return from your *path operation function* will be put inside of that `Response`.
|
||||
|
||||
And if that `Response` has a JSON media type (`application/json`), like is the case with the `JSONResponse` and `UJSONResponse`, the data you return will be automatically converted (and filtered) with any Pydantic `response_model` that you declared in the *path operation decorator*.
|
||||
|
||||
!!! note
|
||||
If you use a response class with no media type, FastAPI will expect your response to have no content, so it will not document the response format in its generated OpenAPI docs.
|
||||
|
||||
## Use `UJSONResponse`
|
||||
|
||||
For example, if you are squeezing performance, you can install and use `ujson` and set the response to be Starlette's `UJSONResponse`.
|
||||
|
||||
Import the `Response` class (sub-class) you want to use and declare it in the *path operation decorator*.
|
||||
|
||||
```Python hl_lines="2 7"
|
||||
{!./src/custom_response/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
Notice that you import it directly from `starlette.responses`, not from `fastapi`.
|
||||
|
||||
!!! info
|
||||
The parameter `response_class` will also be used to define the "media type" of the response.
|
||||
|
||||
In this case, the HTTP header `Content-Type` will be set to `application/json`.
|
||||
|
||||
And it will be documented as such in OpenAPI.
|
||||
|
||||
## HTML Response
|
||||
|
||||
To return a response with HTML directly from **FastAPI**, use `HTMLResponse`.
|
||||
|
||||
* Import `HTMLResponse`.
|
||||
* Pass `HTMLResponse` as the parameter `content_type` of your *path operation*.
|
||||
|
||||
```Python hl_lines="2 7"
|
||||
{!./src/custom_response/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
Notice that you import it directly from `starlette.responses`, not from `fastapi`.
|
||||
|
||||
!!! info
|
||||
The parameter `response_class` will also be used to define the "media type" of the response.
|
||||
|
||||
In this case, the HTTP header `Content-Type` will be set to `text/html`.
|
||||
|
||||
And it will be documented as such in OpenAPI.
|
||||
|
||||
### Return a Starlette `Response`
|
||||
|
||||
As seen in [Return a Response directly](response-directly.md){.internal-link target=_blank}, you can also override the response directly in your *path operation*, by returning it.
|
||||
|
||||
The same example from above, returning an `HTMLResponse`, could look like:
|
||||
|
||||
```Python hl_lines="2 7 19"
|
||||
{!./src/custom_response/tutorial003.py!}
|
||||
```
|
||||
|
||||
!!! warning
|
||||
A `Response` returned directly by your *path operation function* won't be documented in OpenAPI (for example, the `Content-Type` won't be documented) and won't be visible in the automatic interactive docs.
|
||||
|
||||
!!! info
|
||||
Of course, the actual `Content-Type` header, status code, etc, will come from the `Response` object your returned.
|
||||
|
||||
### Document in OpenAPI and override `Response`
|
||||
|
||||
If you want to override the response from inside of the function but at the same time document the "media type" in OpenAPI, you can use the `response_class` parameter AND return a `Response` object.
|
||||
|
||||
The `response_class` will then be used only to document the OpenAPI *path operation*, but your `Response` will be used as is.
|
||||
|
||||
#### Return an `HTMLResponse` directly
|
||||
|
||||
For example, it could be something like:
|
||||
|
||||
```Python hl_lines="7 23 21"
|
||||
{!./src/custom_response/tutorial004.py!}
|
||||
```
|
||||
|
||||
In this example, the function `generate_html_response()` already generates a Starlette `Response` instead of the HTML in a `str`.
|
||||
|
||||
By returning the result of calling `generate_html_response()`, you are already returning a `Response` that will override the default **FastAPI** behavior.
|
||||
|
||||
But as you passed the `HTMLResponse` in the `response_class`, **FastAPI** will know how to document it in OpenAPI and the interactive docs as HTML with `text/html`:
|
||||
|
||||
<img src="/img/tutorial/custom-response/image01.png">
|
||||
|
||||
## Additional documentation
|
||||
|
||||
You can also declare the media type and many other details in OpenAPI using `responses`: [Additional Responses in OpenAPI](additional-responses.md){.internal-link target=_blank}.
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
You can define event handlers (functions) that need to be executed before the application starts up, or when the application is shutting down.
|
||||
|
||||
These functions can be declared with `async def` or normal `def`.
|
||||
|
||||
## `startup` event
|
||||
|
||||
To add a function that should be run before the application starts, declare it with the event `"startup"`:
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!./src/events/tutorial001.py!}
|
||||
```
|
||||
|
||||
In this case, the `startup` event handler function will initialize the items "database" (just a `dict`) with some values.
|
||||
|
||||
You can add more than one event handler function.
|
||||
|
||||
And your application won't start receiving requests until all the `startup` event handlers have completed.
|
||||
|
||||
## `shutdown` event
|
||||
|
||||
To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!./src/events/tutorial002.py!}
|
||||
```
|
||||
|
||||
Here, the `shutdown` event handler function will write a text line `"Application shutdown"` to a file `log.txt`.
|
||||
|
||||
!!! info
|
||||
In the `open()` function, the `mode="a"` means "append", so, the line will be added after whatever is on that file, without overwriting the previous contents.
|
||||
|
||||
!!! tip
|
||||
Notice that in this case we are using a standard Python `open()` function that interacts with a file.
|
||||
|
||||
So, it involves I/O (input/output), that requires "waiting" for things to be written to disk.
|
||||
|
||||
But `open()` doesn't use `async` and `await`.
|
||||
|
||||
So, we declare the event handler function with standard `def` instead of `async def`.
|
||||
|
||||
!!! info
|
||||
You can read more about these event handlers in <a href="https://www.starlette.io/events/" class="external-link" target="_blank">Starlette's Events' docs</a>.
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
**FastAPI** has optional support for GraphQL (provided by Starlette directly), using the `graphene` library.
|
||||
|
||||
You can combine normal FastAPI *path operations* with GraphQL on the same application.
|
||||
|
||||
## Import and use `graphene`
|
||||
|
||||
GraphQL is implemented with Graphene, you can check <a href="https://docs.graphene-python.org/en/latest/quickstart/" class="external-link" target="_blank">Graphene's docs</a> for more details.
|
||||
|
||||
Import `graphene` and define your GraphQL data:
|
||||
|
||||
```Python hl_lines="1 6 7 8 9 10"
|
||||
{!./src/graphql/tutorial001.py!}
|
||||
```
|
||||
|
||||
## Add Starlette's `GraphQLApp`
|
||||
|
||||
Then import and add Starlette's `GraphQLApp`:
|
||||
|
||||
```Python hl_lines="3 14"
|
||||
{!./src/graphql/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
Here we are using `.add_route`, that is the way to add a route in Starlette (inherited by FastAPI) without declaring the specific operation (as would be with `.get()`, `.post()`, etc).
|
||||
|
||||
## Check it
|
||||
|
||||
Run it with Uvicorn and open your browser at <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
|
||||
|
||||
You will see GraphiQL web user interface:
|
||||
|
||||
<img src="/img/tutorial/graphql/image01.png">
|
||||
|
||||
## More details
|
||||
|
||||
For more details, including:
|
||||
|
||||
* Accessing request information
|
||||
* Adding background tasks
|
||||
* Using normal or async functions
|
||||
|
||||
check the official <a href="https://www.starlette.io/graphql/" class="external-link" target="_blank">Starlette GraphQL docs</a>.
|
||||
@@ -1,50 +0,0 @@
|
||||
## OpenAPI operationId
|
||||
|
||||
!!! warning
|
||||
If you are not an "expert" in OpenAPI, you probably don't need this.
|
||||
|
||||
You can set the OpenAPI `operationId` to be used in your *path operation* with the parameter `operation_id`.
|
||||
|
||||
You would have to make sure that it is unique for each operation.
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!./src/path_operation_advanced_configuration/tutorial001.py!}
|
||||
```
|
||||
|
||||
### Using the *path operation function* name as the operationId
|
||||
|
||||
If you want to use your APIs' function names as `operationId`s, you can iterate over all of them and override each *path operation's* `operation_id` using their `APIRoute.name`.
|
||||
|
||||
You should do it after adding all your *path operations*.
|
||||
|
||||
```Python hl_lines="2 12 13 14 15 16 17 18 19 20 21 24"
|
||||
{!./src/path_operation_advanced_configuration/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
If you manually call `app.openapi()`, you should update the `operationId`s before that.
|
||||
|
||||
!!! warning
|
||||
If you do this, you have to make sure each one of your *path operation functions* has a unique name.
|
||||
|
||||
Even if they are in different modules (Python files).
|
||||
|
||||
## Exclude from OpenAPI
|
||||
|
||||
To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`;
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!./src/path_operation_advanced_configuration/tutorial003.py!}
|
||||
```
|
||||
|
||||
## Advanced description from docstring
|
||||
|
||||
You can limit the lines used from the docstring of a *path operation function* for OpenAPI.
|
||||
|
||||
Adding an `\f` (an escaped "form feed" character) causes **FastAPI** to truncate the output used for OpenAPI at this point.
|
||||
|
||||
It won't show up in the documentation, but other tools (such as Sphinx) will be able to use the rest.
|
||||
|
||||
```Python hl_lines="19 20 21 22 23 24 25 26 27 28 29"
|
||||
{!./src/path_operation_advanced_configuration/tutorial004.py!}
|
||||
```
|
||||
@@ -1,92 +0,0 @@
|
||||
There are at least two situations where you could need to create your **FastAPI** application using some specific paths.
|
||||
|
||||
But then you need to set them up to be served with a path prefix.
|
||||
|
||||
It could happen if you have a:
|
||||
|
||||
* **Proxy** server.
|
||||
* You are "**mounting**" a FastAPI application inside another FastAPI application (or inside another ASGI application, like Starlette).
|
||||
|
||||
## Proxy
|
||||
|
||||
Having a proxy in this case means that you could declare a path at `/app`, but then, you could need to add a layer on top (the Proxy) that would put your **FastAPI** application under a path like `/api/v1`.
|
||||
|
||||
In this case, the original path `/app` will actually be served at `/api/v1/app`.
|
||||
|
||||
Even though your application "thinks" it is serving at `/app`.
|
||||
|
||||
And the Proxy could be re-writing the path "on the fly" to keep your application convinced that it is serving at `/app`.
|
||||
|
||||
Up to here, everything would work as normally.
|
||||
|
||||
But then, when you open the integrated docs, they would expect to get the OpenAPI schema at `/openapi.json`, instead of `/api/v1/openapi.json`.
|
||||
|
||||
So, the frontend (that runs in the browser) would try to reach `/openapi.json` and wouldn't be able to get the OpenAPI schema.
|
||||
|
||||
So, it's needed that the frontend looks for the OpenAPI schema at `/api/v1/openapi.json`.
|
||||
|
||||
And it's also needed that the returned JSON OpenAPI schema has the defined path at `/api/v1/app` (behind the proxy) instead of `/app`.
|
||||
|
||||
---
|
||||
|
||||
For these cases, you can declare an `openapi_prefix` parameter in your `FastAPI` application.
|
||||
|
||||
See the section below, about "mounting", for an example.
|
||||
|
||||
## Mounting a **FastAPI** application
|
||||
|
||||
"Mounting" means adding a complete "independent" application in a specific path, that then takes care of handling all the sub-paths.
|
||||
|
||||
You could want to do this if you have several "independent" applications that you want to separate, having their own independent OpenAPI schema and user interfaces.
|
||||
|
||||
### Top-level application
|
||||
|
||||
First, create the main, top-level, **FastAPI** application, and its *path operations*:
|
||||
|
||||
```Python hl_lines="3 6 7 8"
|
||||
{!./src/sub_applications/tutorial001.py!}
|
||||
```
|
||||
|
||||
### Sub-application
|
||||
|
||||
Then, create your sub-application, and its *path operations*.
|
||||
|
||||
This sub-application is just another standard FastAPI application, but this is the one that will be "mounted".
|
||||
|
||||
When creating the sub-application, use the parameter `openapi_prefix`. In this case, with a prefix of `/subapi`:
|
||||
|
||||
```Python hl_lines="11 14 15 16"
|
||||
{!./src/sub_applications/tutorial001.py!}
|
||||
```
|
||||
|
||||
### Mount the sub-application
|
||||
|
||||
In your top-level application, `app`, mount the sub-application, `subapi`.
|
||||
|
||||
Here you need to make sure you use the same path that you used for the `openapi_prefix`, in this case, `/subapi`:
|
||||
|
||||
```Python hl_lines="11 19"
|
||||
{!./src/sub_applications/tutorial001.py!}
|
||||
```
|
||||
|
||||
## Check the automatic API docs
|
||||
|
||||
Now, run `uvicorn`, if your file is at `main.py`, it would be:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
And open the docs at <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
You will see the automatic API docs for the main app, including only its own paths:
|
||||
|
||||
<img src="/img/tutorial/sub-applications/image01.png">
|
||||
|
||||
And then, open the docs for the sub-application, at <a href="http://127.0.0.1:8000/subapi/docs" class="external-link" target="_blank">http://127.0.0.1:8000/subapi/docs</a>.
|
||||
|
||||
You will see the automatic API docs for the sub-application, including only its own sub-paths, with their correct prefix:
|
||||
|
||||
<img src="/img/tutorial/sub-applications/image02.png">
|
||||
|
||||
If you try interacting with any of the two user interfaces, they will work, because the browser will be able to talk to the correct path (or sub-path).
|
||||
@@ -1,9 +0,0 @@
|
||||
## Testing WebSockets
|
||||
|
||||
You can use the same `TestClient` to test WebSockets.
|
||||
|
||||
For this, you use the `TestClient` in a `with` statement, connecting to the WebSocket:
|
||||
|
||||
```Python hl_lines="27 28 29 30 31"
|
||||
{!./src/app_testing/tutorial002.py!}
|
||||
```
|
||||
@@ -1,109 +0,0 @@
|
||||
|
||||
You can use <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSockets</a> with **FastAPI**.
|
||||
|
||||
## WebSockets client
|
||||
|
||||
### In production
|
||||
|
||||
In your production system, you probably have a frontend created with a modern framework like React, Vue.js or Angular.
|
||||
|
||||
And to communicate using WebSockets with your backend you would probably use your frontend's utilities.
|
||||
|
||||
Or you might have a native mobile application that communicates with your WebSocket backend directly, in native code.
|
||||
|
||||
Or you might have any other way to communicate with the WebSocket endpoint.
|
||||
|
||||
---
|
||||
|
||||
But for this example, we'll use a very simple HTML document with some JavaScript, all inside a long string.
|
||||
|
||||
This, of course, is not optimal and you wouldn't use it for production.
|
||||
|
||||
In production you would have one of the options above.
|
||||
|
||||
But it's the simplest way to focus on the server-side of WebSockets and have a working example:
|
||||
|
||||
```Python hl_lines="2 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 42 43 44"
|
||||
{!./src/websockets/tutorial001.py!}
|
||||
```
|
||||
|
||||
## Create a `websocket`
|
||||
|
||||
In your **FastAPI** application, create a `websocket`:
|
||||
|
||||
```Python hl_lines="3 47 48"
|
||||
{!./src/websockets/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
In this example we are importing `WebSocket` from `starlette.websockets` to use it in the type declaration in the WebSocket route function.
|
||||
|
||||
## Await for messages and send messages
|
||||
|
||||
In your WebSocket route you can `await` for messages and send messages.
|
||||
|
||||
```Python hl_lines="49 50 51 52 53"
|
||||
{!./src/websockets/tutorial001.py!}
|
||||
```
|
||||
|
||||
You can receive and send binary, text, and JSON data.
|
||||
|
||||
## Using `Depends` and others
|
||||
|
||||
In WebSocket endpoints you can import from `fastapi` and use:
|
||||
|
||||
* `Depends`
|
||||
* `Security`
|
||||
* `Cookie`
|
||||
* `Header`
|
||||
* `Path`
|
||||
* `Query`
|
||||
|
||||
They work the same way as for other FastAPI endpoints/*path operations*:
|
||||
|
||||
```Python hl_lines="55 56 57 58 59 60 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78"
|
||||
{!./src/websockets/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
In a WebSocket it doesn't really make sense to raise an `HTTPException`. So it's better to close the WebSocket connection directly.
|
||||
|
||||
You can use a closing code from the <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">valid codes defined in the specification</a>.
|
||||
|
||||
In the future, there will be a `WebSocketException` that you will be able to `raise` from anywhere, and add exception handlers for it. It depends on the <a href="https://github.com/encode/starlette/pull/527" class="external-link" target="_blank">PR #527</a> in Starlette.
|
||||
|
||||
## More info
|
||||
|
||||
To learn more about the options, check Starlette's documentation for:
|
||||
|
||||
* <a href="https://www.starlette.io/applications/" class="external-link" target="_blank">Applications (`websocket_route`)</a>.
|
||||
* <a href="https://www.starlette.io/websockets/" class="external-link" target="_blank">The `WebSocket` class</a>.
|
||||
* <a href="https://www.starlette.io/endpoints/#websocketendpoint" class="external-link" target="_blank">Class-based WebSocket handling</a>.
|
||||
|
||||
## Test it
|
||||
|
||||
If your file is named `main.py`, run your application with:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
Open your browser at <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
|
||||
|
||||
You will see a simple page like:
|
||||
|
||||
<img src="/img/tutorial/websockets/image01.png">
|
||||
|
||||
You can type messages in the input box, and send them:
|
||||
|
||||
<img src="/img/tutorial/websockets/image02.png">
|
||||
|
||||
And your **FastAPI** application with WebSockets will respond back:
|
||||
|
||||
<img src="/img/tutorial/websockets/image03.png">
|
||||
|
||||
You can send (and receive) many messages:
|
||||
|
||||
<img src="/img/tutorial/websockets/image04.png">
|
||||
|
||||
And all of them will use the same WebSocket connection.
|
||||
466
docs/az/docs/index.md
Normal file
466
docs/az/docs/index.md
Normal file
@@ -0,0 +1,466 @@
|
||||
|
||||
{!../../../docs/missing-translation.md!}
|
||||
|
||||
|
||||
<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, high performance, easy to learn, fast to code, ready for production</em>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest" target="_blank">
|
||||
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg" alt="Test">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/codecov/c/github/tiangolo/fastapi?color=%2334D058" 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>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
**Documentation**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
|
||||
|
||||
**Source Code**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a>
|
||||
|
||||
---
|
||||
|
||||
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
|
||||
|
||||
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.
|
||||
* **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>
|
||||
|
||||
## Sponsors
|
||||
|
||||
<!-- 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">Other sponsors</a>
|
||||
|
||||
## Opinions
|
||||
|
||||
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
|
||||
|
||||
<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** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
|
||||
|
||||
<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>
|
||||
|
||||
---
|
||||
|
||||
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
|
||||
|
||||
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
## **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>
|
||||
|
||||
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
|
||||
|
||||
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
|
||||
|
||||
## Requirements
|
||||
|
||||
Python 3.7+
|
||||
|
||||
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://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> for the data parts.
|
||||
|
||||
## Installation
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install fastapi
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Example
|
||||
|
||||
### Create it
|
||||
|
||||
* Create a file `main.py` with:
|
||||
|
||||
```Python
|
||||
from typing import Optional
|
||||
|
||||
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: Optional[str] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Or use <code>async def</code>...</summary>
|
||||
|
||||
If your code uses `async` / `await`, use `async def`:
|
||||
|
||||
```Python hl_lines="9 14"
|
||||
from typing import Optional
|
||||
|
||||
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: Optional[str] = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
|
||||
|
||||
</details>
|
||||
|
||||
### Run it
|
||||
|
||||
Run the server with:
|
||||
|
||||
<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>About the command <code>uvicorn main:app --reload</code>...</summary>
|
||||
|
||||
The command `uvicorn main:app` refers to:
|
||||
|
||||
* `main`: the file `main.py` (the Python "module").
|
||||
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
|
||||
* `--reload`: make the server restart after code changes. Only do this for development.
|
||||
|
||||
</details>
|
||||
|
||||
### Check it
|
||||
|
||||
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
|
||||
|
||||
You will see the JSON response as:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
You already created an API that:
|
||||
|
||||
* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
|
||||
* Both _paths_ take `GET` <em>operations</em> (also known as HTTP _methods_).
|
||||
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
|
||||
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
|
||||
|
||||
### Interactive API docs
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
|
||||
|
||||

|
||||
|
||||
### Alternative API docs
|
||||
|
||||
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
You will see the alternative automatic documentation (provided by <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
|
||||
|
||||

|
||||
|
||||
## Example upgrade
|
||||
|
||||
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 Optional
|
||||
|
||||
from fastapi import FastAPI
|
||||
from pydantic import BaseModel
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
class Item(BaseModel):
|
||||
name: str
|
||||
price: float
|
||||
is_offer: Optional[bool] = None
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def read_root():
|
||||
return {"Hello": "World"}
|
||||
|
||||
|
||||
@app.get("/items/{item_id}")
|
||||
def read_item(item_id: int, q: Optional[str] = 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}
|
||||
```
|
||||
|
||||
The server should reload automatically (because you added `--reload` to the `uvicorn` command above).
|
||||
|
||||
### Interactive API docs upgrade
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
* The interactive API documentation will be automatically updated, including the new body:
|
||||
|
||||

|
||||
|
||||
* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
|
||||
|
||||

|
||||
|
||||
* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen:
|
||||
|
||||

|
||||
|
||||
### Alternative API docs upgrade
|
||||
|
||||
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
* The alternative documentation will also reflect the new query parameter and body:
|
||||
|
||||

|
||||
|
||||
### Recap
|
||||
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
|
||||
You do that with standard modern Python types.
|
||||
|
||||
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
|
||||
|
||||
Just standard **Python 3.6+**.
|
||||
|
||||
For example, for an `int`:
|
||||
|
||||
```Python
|
||||
item_id: int
|
||||
```
|
||||
|
||||
or for a more complex `Item` model:
|
||||
|
||||
```Python
|
||||
item: Item
|
||||
```
|
||||
|
||||
...and with that single declaration you get:
|
||||
|
||||
* Editor support, including:
|
||||
* Completion.
|
||||
* Type checks.
|
||||
* 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:
|
||||
* JSON.
|
||||
* Path parameters.
|
||||
* Query parameters.
|
||||
* Cookies.
|
||||
* 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):
|
||||
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
|
||||
* `datetime` objects.
|
||||
* `UUID` objects.
|
||||
* Database models.
|
||||
* ...and many more.
|
||||
* Automatic interactive API documentation, including 2 alternative user interfaces:
|
||||
* Swagger UI.
|
||||
* ReDoc.
|
||||
|
||||
---
|
||||
|
||||
Coming back to the previous code example, **FastAPI** will:
|
||||
|
||||
* Validate that there is an `item_id` in the path for `GET` and `PUT` requests.
|
||||
* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests.
|
||||
* If it is not, the client will see a useful, clear error.
|
||||
* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests.
|
||||
* As the `q` parameter is declared with `= None`, it is optional.
|
||||
* Without the `None` it would be required (as is the body in the case with `PUT`).
|
||||
* For `PUT` requests to `/items/{item_id}`, Read the body as JSON:
|
||||
* Check that it has a required attribute `name` that should be a `str`.
|
||||
* Check that it has a required attribute `price` that has to be a `float`.
|
||||
* Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
|
||||
* All this would also work for deeply nested JSON objects.
|
||||
* Convert from and to JSON automatically.
|
||||
* Document everything with OpenAPI, that can be used by:
|
||||
* Interactive documentation systems.
|
||||
* Automatic client code generation systems, for many languages.
|
||||
* Provide 2 interactive documentation web interfaces directly.
|
||||
|
||||
---
|
||||
|
||||
We just scratched the surface, but you already get the idea of how it all works.
|
||||
|
||||
Try changing the line with:
|
||||
|
||||
```Python
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
...from:
|
||||
|
||||
```Python
|
||||
... "item_name": item.name ...
|
||||
```
|
||||
|
||||
...to:
|
||||
|
||||
```Python
|
||||
... "item_price": item.price ...
|
||||
```
|
||||
|
||||
...and see how your editor will auto-complete the attributes and know their types:
|
||||
|
||||

|
||||
|
||||
For a more complete example including more features, see the <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
|
||||
|
||||
**Spoiler alert**: the tutorial - user guide includes:
|
||||
|
||||
* 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.
|
||||
* 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).
|
||||
* Many extra features (thanks to Starlette) as:
|
||||
* **WebSockets**
|
||||
* **GraphQL**
|
||||
* extremely easy tests based on `requests` and `pytest`
|
||||
* **CORS**
|
||||
* **Cookie Sessions**
|
||||
* ...and more.
|
||||
|
||||
## Performance
|
||||
|
||||
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
|
||||
|
||||
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
|
||||
|
||||
## Optional Dependencies
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
|
||||
|
||||
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://andrew-d.github.io/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://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
|
||||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
|
||||
* <a href="https://graphene-python.org/" target="_blank"><code>graphene</code></a> - Required for `GraphQLApp` support.
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
|
||||
|
||||
Used by FastAPI / Starlette:
|
||||
|
||||
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
|
||||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
|
||||
|
||||
You can install all of these with `pip install fastapi[all]`.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the terms of the MIT license.
|
||||
154
docs/az/mkdocs.yml
Normal file
154
docs/az/mkdocs.yml
Normal file
@@ -0,0 +1,154 @@
|
||||
site_name: FastAPI
|
||||
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
|
||||
site_url: https://fastapi.tiangolo.com/az/
|
||||
theme:
|
||||
name: material
|
||||
custom_dir: overrides
|
||||
palette:
|
||||
- media: '(prefers-color-scheme: light)'
|
||||
scheme: default
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb
|
||||
name: Switch to light mode
|
||||
- media: '(prefers-color-scheme: dark)'
|
||||
scheme: slate
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb-outline
|
||||
name: Switch to dark mode
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
favicon: https://fastapi.tiangolo.com/img/favicon.png
|
||||
language: en
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
data: data
|
||||
nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- he: /he/
|
||||
- hy: /hy/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
- sq: /sq/
|
||||
- sv: /sv/
|
||||
- ta: /ta/
|
||||
- tr: /tr/
|
||||
- uk: /uk/
|
||||
- zh: /zh/
|
||||
markdown_extensions:
|
||||
- toc:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
- extra
|
||||
- pymdownx.superfences:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- attr_list
|
||||
- md_in_html
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: G-YNEVN69SC3
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
link: https://dev.to/tiangolo
|
||||
- icon: fontawesome/brands/medium
|
||||
link: https://medium.com/@tiangolo
|
||||
- icon: fontawesome/solid/globe
|
||||
link: https://tiangolo.com
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
name: 😉
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /he/
|
||||
name: he
|
||||
- link: /hy/
|
||||
name: hy
|
||||
- link: /id/
|
||||
name: id
|
||||
- link: /it/
|
||||
name: it - italiano
|
||||
- link: /ja/
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
name: pt - português
|
||||
- link: /ru/
|
||||
name: ru - русский язык
|
||||
- link: /sq/
|
||||
name: sq - shqip
|
||||
- link: /sv/
|
||||
name: sv - svenska
|
||||
- link: /ta/
|
||||
name: ta - தமிழ்
|
||||
- link: /tr/
|
||||
name: tr - Türkçe
|
||||
- link: /uk/
|
||||
name: uk - українська мова
|
||||
- link: /zh/
|
||||
name: zh - 汉语
|
||||
extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
@@ -1,175 +0,0 @@
|
||||
First, you might want to see the basic ways to [help FastAPI and get help](help-fastapi.md){.internal-link target=_blank}.
|
||||
|
||||
## Developing
|
||||
|
||||
If you already cloned the repository and you know that you need to deep dive in the code, here are some guidelines to set up your environment.
|
||||
|
||||
### Virtual environment with `venv`
|
||||
|
||||
You can create a virtual environment in a directory using Python's `venv` module:
|
||||
|
||||
```console
|
||||
$ python -m venv env
|
||||
```
|
||||
|
||||
That will create a directory `./env/` with the Python binaries and then you will be able to install packages for that isolated environment.
|
||||
|
||||
### Activate the environment
|
||||
|
||||
Activate the new environment with:
|
||||
|
||||
```console
|
||||
$ source ./env/bin/activate
|
||||
```
|
||||
|
||||
Or in Windows' PowerShell:
|
||||
|
||||
```console
|
||||
$ .\env\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
Or if you use Bash for Windows (e.g. <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
|
||||
|
||||
```console
|
||||
$ source ./env/Scripts/activate
|
||||
```
|
||||
|
||||
To check it worked, use:
|
||||
|
||||
```console
|
||||
$ which pip
|
||||
|
||||
some/directory/fastapi/env/bin/pip
|
||||
```
|
||||
|
||||
If it shows the `pip` binary at `env/bin/pip` then it worked. 🎉
|
||||
|
||||
Or in Windows PowerShell:
|
||||
|
||||
```console
|
||||
$ Get-Command pip
|
||||
|
||||
some/directory/fastapi/env/bin/pip
|
||||
```
|
||||
!!! tip
|
||||
Every time you install a new package with `pip` under that environment, activate the environment again.
|
||||
|
||||
This makes sure that if you use a terminal program installed by that package (like `flit`), you use the one from your local environment and not any other that could be installed globally.
|
||||
|
||||
### Flit
|
||||
|
||||
**FastAPI** uses <a href="https://flit.readthedocs.io/en/latest/index.html" class="external-link" target="_blank">Flit</a> to build, package and publish the project.
|
||||
|
||||
After activating the environment as described above, install `flit`:
|
||||
|
||||
```console
|
||||
$ pip install flit
|
||||
```
|
||||
|
||||
Now re-activate the environment to make sure you are using the `flit` you just installed (and not a global one).
|
||||
|
||||
And now use `flit` to install the development dependencies:
|
||||
|
||||
```console
|
||||
$ flit install --deps develop --symlink
|
||||
```
|
||||
|
||||
It will install all the dependencies and your local FastAPI in your local environment.
|
||||
|
||||
#### Using your local FastAPI
|
||||
|
||||
If you create a Python file that imports and uses FastAPI, and run it with the Python from your local environment, it will use your local FastAPI source code.
|
||||
|
||||
And if you update that local FastAPI source code, as it is installed with `--symlink`, when you run that Python file again, it will use the fresh version of FastAPI you just edited.
|
||||
|
||||
That way, you don't have to "install" your local version to be able to test every change.
|
||||
|
||||
### Format
|
||||
|
||||
There is a script that you can run that will format and clean all your code:
|
||||
|
||||
```console
|
||||
$ bash scripts/format.sh
|
||||
```
|
||||
|
||||
It will also auto-sort all your imports.
|
||||
|
||||
For it to sort them correctly, you need to have FastAPI installed locally in your environment, with the command in the section above:
|
||||
|
||||
```console
|
||||
$ flit install --symlink
|
||||
```
|
||||
|
||||
### Format imports
|
||||
|
||||
There is another script that formats all the imports and makes sure you don't have unused imports:
|
||||
|
||||
```console
|
||||
$ bash scripts/format-imports.sh
|
||||
```
|
||||
|
||||
As it runs one command after the other and modifies and reverts many files, it takes a bit longer to run, so it might be easier to use `scripts/format.sh` frequently and `scripts/format-imports.sh` only before committing.
|
||||
|
||||
## Docs
|
||||
|
||||
The documentation uses <a href="https://www.mkdocs.org/" class="external-link" target="_blank">MkDocs</a>.
|
||||
|
||||
All the documentation is in Markdown format in the directory `./docs`.
|
||||
|
||||
Many of the tutorials have blocks of code.
|
||||
|
||||
In most of the cases, these blocks of code are actual complete applications that can be run as is.
|
||||
|
||||
In fact, those blocks of code are not written inside the Markdown, they are Python files in the `./docs/src/` directory.
|
||||
|
||||
And those Python files are included/injected in the documentation when generating the site.
|
||||
|
||||
### Docs for tests
|
||||
|
||||
Most of the tests actually run against the example source files in the documentation.
|
||||
|
||||
This helps making sure that:
|
||||
|
||||
* The documentation is up to date.
|
||||
* The documentation examples can be run as is.
|
||||
* Most of the features are covered by the documentation, ensured by test coverage.
|
||||
|
||||
During local development, there is a script that builds the site and checks for any changes, live-reloading:
|
||||
|
||||
```console
|
||||
$ bash scripts/docs-live.sh
|
||||
```
|
||||
|
||||
It will serve the documentation on `http://0.0.0.0:8008`.
|
||||
|
||||
That way, you can edit the documentation/source files and see the changes live.
|
||||
|
||||
### Apps and docs at the same time
|
||||
|
||||
If you run the examples with, e.g.:
|
||||
|
||||
```console
|
||||
$ uvicorn tutorial001:app --reload
|
||||
```
|
||||
|
||||
as Uvicorn by default will use the port `8000`, the documentation on port `8008` won't clash.
|
||||
|
||||
## Tests
|
||||
|
||||
There is a script that you can run locally to test all the code and generate coverage reports in HTML:
|
||||
|
||||
```console
|
||||
$ bash scripts/test-cov-html.sh
|
||||
```
|
||||
|
||||
This command generates a directory `./htmlcov/`, if you open the file `./htmlcov/index.html` in your browser, you can explore interactively the regions of code that are covered by the tests, and notice if there is any region missing.
|
||||
|
||||
### Tests in your editor
|
||||
|
||||
If you want to use the integrated tests in your editor add `./docs/src` to your `PYTHONPATH` variable.
|
||||
|
||||
For example, in VS Code you can create a file `.env` with:
|
||||
|
||||
```env
|
||||
PYTHONPATH=./docs/src
|
||||
```
|
||||
@@ -1,13 +0,0 @@
|
||||
a.external-link::after {
|
||||
/* \00A0 is a non-breaking space
|
||||
to make the mark be on the same line as the link
|
||||
*/
|
||||
content: "\00A0[↪]";
|
||||
}
|
||||
|
||||
a.internal-link::after {
|
||||
/* \00A0 is a non-breaking space
|
||||
to make the mark be on the same line as the link
|
||||
*/
|
||||
content: "\00A0↪";
|
||||
}
|
||||
203
docs/de/docs/features.md
Normal file
203
docs/de/docs/features.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# Merkmale
|
||||
|
||||
## FastAPI Merkmale
|
||||
|
||||
**FastAPI** ermöglicht Ihnen folgendes:
|
||||
|
||||
### Basiert auf offenen Standards
|
||||
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification" class="external-link" target="_blank"><strong>OpenAPI</strong></a> für API-Erstellung, zusammen mit Deklarationen von <abbr title="auch genannt: Endpunkte, Routen">Pfad</abbr> <abbr title="gemeint sind: HTTP-Methoden, wie POST, GET, PUT, DELETE">Operationen</abbr>, Parameter, Nachrichtenrumpf-Anfragen (englisch: body request), Sicherheit, etc.
|
||||
* Automatische Dokumentation der Datenentitäten mit dem <a href="https://json-schema.org/" class="external-link" target="_blank"><strong>JSON Schema</strong></a> (OpenAPI basiert selber auf dem JSON Schema).
|
||||
* Entworfen auf Grundlage dieser Standards nach einer sorgfältigen Studie, statt einer nachträglichen Schicht über diesen Standards.
|
||||
* Dies ermöglicht automatische **Quellcode-Generierung auf Benutzerebene** in vielen Sprachen.
|
||||
|
||||
### Automatische Dokumentation
|
||||
|
||||
Mit einer interaktiven API-Dokumentation und explorativen webbasierten Benutzerschnittstellen. Da FastAPI auf OpenAPI basiert, gibt es hierzu mehrere Optionen, wobei zwei standardmäßig vorhanden sind.
|
||||
|
||||
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank"><strong>Swagger UI</strong></a>, bietet interaktive Exploration: testen und rufen Sie ihre API direkt vom Webbrowser auf.
|
||||
|
||||

|
||||
|
||||
* Alternative API-Dokumentation mit <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank"><strong>ReDoc</strong></a>.
|
||||
|
||||

|
||||
|
||||
### Nur modernes Python
|
||||
|
||||
Alles basiert auf **Python 3.6 Typ**-Deklarationen (dank Pydantic). Es muss keine neue Syntax gelernt werden, nur standardisiertes modernes Python.
|
||||
|
||||
|
||||
|
||||
Wenn Sie eine kurze, zweiminütige, Auffrischung in der Benutzung von Python Typ-Deklarationen benötigen (auch wenn Sie FastAPI nicht nutzen), schauen Sie sich diese kurze Einführung an (Englisch): Python Types{.internal-link target=_blank}.
|
||||
|
||||
Sie schreiben Standard-Python mit Typ-Deklarationen:
|
||||
|
||||
```Python
|
||||
from typing import List, Dict
|
||||
from datetime import date
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
# Deklariere eine Variable als str
|
||||
# und bekomme Editor-Unterstütung innerhalb der Funktion
|
||||
def main(user_id: str):
|
||||
return user_id
|
||||
|
||||
|
||||
# Ein Pydantic model
|
||||
class User(BaseModel):
|
||||
id: int
|
||||
name: str
|
||||
joined: date
|
||||
```
|
||||
|
||||
Dies kann nun wiefolgt benutzt werden:
|
||||
|
||||
```Python
|
||||
my_user: User = User(id=3, name="John Doe", joined="2018-07-19")
|
||||
|
||||
second_user_data = {
|
||||
"id": 4,
|
||||
"name": "Mary",
|
||||
"joined": "2018-11-30",
|
||||
}
|
||||
|
||||
my_second_user: User = User(**second_user_data)
|
||||
```
|
||||
|
||||
!!! info
|
||||
`**second_user_data` bedeutet:
|
||||
|
||||
Übergebe die Schlüssel und die zugehörigen Werte des `second_user_data` Datenwörterbuches direkt als Schlüssel-Wert Argumente, äquivalent zu: `User(id=4, name="Mary", joined="2018-11-30")`
|
||||
|
||||
### Editor Unterstützung
|
||||
|
||||
FastAPI wurde so entworfen, dass es einfach und intuitiv zu benutzen ist; alle Entscheidungen wurden auf mehreren Editoren getestet (sogar vor der eigentlichen Implementierung), um so eine best mögliche Entwicklererfahrung zu gewährleisten.
|
||||
|
||||
In der letzen Python Entwickler Umfrage stellte sich heraus, dass <a href="https://www.jetbrains.com/research/python-developers-survey-2017/#tools-and-features" class="external-link" target="_blank">die meist genutzte Funktion die "Autovervollständigung" ist</a>.
|
||||
|
||||
Die gesamte Struktur von **FastAPI** soll dem gerecht werden. Autovervollständigung funktioniert überall.
|
||||
|
||||
Sie müssen selten in die Dokumentation schauen.
|
||||
|
||||
So kann ihr Editor Sie unterstützen:
|
||||
|
||||
* in <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>:
|
||||
|
||||

|
||||
|
||||
* in <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>:
|
||||
|
||||

|
||||
|
||||
Sie bekommen Autovervollständigung an Stellen, an denen Sie dies vorher nicht für möglich gehalten hätten. Zum Beispiel der `price` Schlüssel aus einem JSON Datensatz (dieser könnte auch verschachtelt sein) aus einer Anfrage.
|
||||
|
||||
Hierdurch werden Sie nie wieder einen falschen Schlüsselnamen benutzen und sparen sich lästiges Suchen in der Dokumentation, um beispielsweise herauszufinden ob Sie `username` oder `user_name` als Schlüssel verwenden.
|
||||
|
||||
### Kompakt
|
||||
|
||||
FastAPI nutzt für alles sensible **Standard-Einstellungen**, welche optional überall konfiguriert werden können. Alle Parameter können ganz genau an Ihre Bedürfnisse angepasst werden, sodass sie genau die API definieren können, die sie brauchen.
|
||||
|
||||
Aber standardmäßig, **"funktioniert einfach"** alles.
|
||||
|
||||
### Validierung
|
||||
|
||||
* Validierung für die meisten (oder alle?) Python **Datentypen**, hierzu gehören:
|
||||
* JSON Objekte (`dict`).
|
||||
* JSON Listen (`list`), die den Typ ihrer Elemente definieren.
|
||||
* Zeichenketten (`str`), mit definierter minimaler und maximaler Länge.
|
||||
* Zahlen (`int`, `float`) mit minimaler und maximaler Größe, usw.
|
||||
|
||||
* Validierung für ungewöhnliche Typen, wie:
|
||||
* URL.
|
||||
* Email.
|
||||
* UUID.
|
||||
* ... und andere.
|
||||
|
||||
Die gesamte Validierung übernimmt das etablierte und robuste **Pydantic**.
|
||||
|
||||
### Sicherheit und Authentifizierung
|
||||
|
||||
Integrierte Sicherheit und Authentifizierung. Ohne Kompromisse bei Datenbanken oder Datenmodellen.
|
||||
|
||||
Unterstützt werden alle von OpenAPI definierten Sicherheitsschemata, hierzu gehören:
|
||||
|
||||
* HTTP Basis Authentifizierung.
|
||||
* **OAuth2** (auch mit **JWT Zugriffstokens**). Schauen Sie sich hierzu dieses Tutorial an: [OAuth2 mit JWT](tutorial/security/oauth2-jwt.md){.internal-link target=_blank}.
|
||||
* API Schlüssel in:
|
||||
* Kopfzeile (HTTP Header).
|
||||
* Anfrageparametern.
|
||||
* Cookies, etc.
|
||||
|
||||
Zusätzlich gibt es alle Sicherheitsfunktionen von Starlette (auch **session cookies**).
|
||||
|
||||
Alles wurde als wiederverwendbare Werkzeuge und Komponenten geschaffen, die einfach in ihre Systeme, Datenablagen, relationale und nicht-relationale Datenbanken, ..., integriert werden können.
|
||||
|
||||
### Einbringen von Abhängigkeiten (meist: Dependency Injection)
|
||||
|
||||
FastAPI enthält ein extrem einfaches, aber extrem mächtiges <abbr title='oft verwendet im Zusammenhang von: Komponenten, Resourcen, Diensten, Dienstanbieter'><strong>Dependency Injection</strong></abbr> System.
|
||||
|
||||
* Selbst Abhängigkeiten können Abhängigkeiten haben, woraus eine Hierachie oder ein **"Graph" von Abhängigkeiten** entsteht.
|
||||
* **Automatische Umsetzung** durch FastAPI.
|
||||
* Alle abhängigen Komponenten könnten Daten von Anfragen, **Erweiterungen der Pfadoperations-**Einschränkungen und der automatisierten Dokumentation benötigen.
|
||||
* **Automatische Validierung** selbst für *Pfadoperationen*-Parameter, die in den Abhängigkeiten definiert wurden.
|
||||
* Unterstützt komplexe Benutzerauthentifizierungssysteme, **Datenbankverbindungen**, usw.
|
||||
* **Keine Kompromisse** bei Datenbanken, Eingabemasken, usw. Sondern einfache Integration von allen.
|
||||
|
||||
### Unbegrenzte Erweiterungen
|
||||
|
||||
Oder mit anderen Worten, sie werden nicht benötigt. Importieren und nutzen Sie Quellcode nach Bedarf.
|
||||
|
||||
Jede Integration wurde so entworfen, dass sie einfach zu nutzen ist (mit Abhängigkeiten), sodass Sie eine Erweiterung für Ihre Anwendung mit nur zwei Zeilen an Quellcode implementieren können. Hierbei nutzen Sie die selbe Struktur und Syntax, wie bei Pfadoperationen.
|
||||
|
||||
### Getestet
|
||||
|
||||
* 100% <abbr title="Die Anzahl an Code, die automatisch getestet wird">Testabdeckung</abbr>.
|
||||
* 100% <abbr title="Python Typ Annotationen, mit dennen Ihr Editor und andere exteren Werkezuge Sie besser unterstützen können">Typen annotiert</abbr>.
|
||||
* Verwendet in Produktionsanwendungen.
|
||||
|
||||
## Starlette's Merkmale
|
||||
|
||||
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://www.starlette.io/" class="external-link" target="_blank"><strong>Starlette</strong></a>. Das bedeutet, auch ihr eigener Starlette Quellcode funktioniert.
|
||||
|
||||
`FastAPI` ist eigentlich eine Unterklasse von `Starlette`. Wenn Sie also bereits Starlette kennen oder benutzen, können Sie das meiste Ihres Wissens direkt anwenden.
|
||||
|
||||
Mit **FastAPI** bekommen Sie viele von **Starlette**'s Funktionen (da FastAPI nur Starlette auf Steroiden ist):
|
||||
|
||||
* Stark beeindruckende Performanz. Es ist <a href="https://github.com/encode/starlette#performance" class="external-link" target="_blank">eines der schnellsten Python Frameworks, auf Augenhöhe mit **NodeJS** und **Go**</a>.
|
||||
* **WebSocket**-Unterstützung.
|
||||
* Hintergrundaufgaben im selben Prozess.
|
||||
* Ereignisse für das Starten und Herunterfahren.
|
||||
* Testclient basierend auf HTTPX.
|
||||
* **CORS**, GZip, statische Dateien, Antwortfluss.
|
||||
* **Sitzungs und Cookie** Unterstützung.
|
||||
* 100% Testabdeckung.
|
||||
* 100% Typen annotiert.
|
||||
|
||||
## Pydantic's Merkmale
|
||||
|
||||
**FastAPI** ist vollkommen kompatibel (und basiert auf) <a href="https://pydantic-docs.helpmanual.io" class="external-link" target="_blank"><strong>Pydantic</strong></a>. Das bedeutet, auch jeder zusätzliche Pydantic Quellcode funktioniert.
|
||||
|
||||
Verfügbar sind ebenso externe auf Pydantic basierende Bibliotheken, wie <abbr title="Object-Relational Mapper (Abbildung von Objekten auf relationale Strukturen)">ORM</abbr>s, <abbr title="Object-Document Mapper (Abbildung von Objekten auf nicht-relationale Strukturen)">ODM</abbr>s für Datenbanken.
|
||||
|
||||
Daher können Sie in vielen Fällen das Objekt einer Anfrage **direkt zur Datenbank** schicken, weil alles automatisch validiert wird.
|
||||
|
||||
Das selbe gilt auch für die andere Richtung: Sie können jedes Objekt aus der Datenbank **direkt zum Klienten** schicken.
|
||||
|
||||
Mit **FastAPI** bekommen Sie alle Funktionen von **Pydantic** (da FastAPI für die gesamte Datenverarbeitung Pydantic nutzt):
|
||||
|
||||
* **Kein Kopfzerbrechen**:
|
||||
* Sie müssen keine neue Schemadefinitionssprache lernen.
|
||||
* Wenn Sie mit Python's Typisierung arbeiten können, können Sie auch mit Pydantic arbeiten.
|
||||
* Gutes Zusammenspiel mit Ihrer/Ihrem **<abbr title="Integrierten Entwicklungsumgebung, ähnlich zu (Quellcode-)Editor">IDE</abbr>/<abbr title="Ein Programm, was Fehler im Quellcode sucht">linter</abbr>/Gehirn**:
|
||||
* Weil Datenstrukturen von Pydantic einfach nur Instanzen ihrer definierten Klassen sind, sollten Autovervollständigung, Linting, mypy und ihre Intuition einwandfrei funktionieren.
|
||||
* **Schnell**:
|
||||
* In <a href="https://pydantic-docs.helpmanual.io/benchmarks/" class="external-link" target="_blank">Vergleichen</a> ist Pydantic schneller als jede andere getestete Bibliothek.
|
||||
* Validierung von **komplexen Strukturen**:
|
||||
* Benutzung von hierachischen Pydantic Schemata, Python `typing`’s `List` und `Dict`, etc.
|
||||
* Validierungen erlauben eine klare und einfache Datenschemadefinition, überprüft und dokumentiert als JSON Schema.
|
||||
* Sie können stark **verschachtelte JSON** Objekte haben und diese sind trotzdem validiert und annotiert.
|
||||
* **Erweiterbar**:
|
||||
* Pydantic erlaubt die Definition von eigenen Datentypen oder sie können die Validierung mit einer `validator` dekorierten Methode erweitern.
|
||||
* 100% Testabdeckung.
|
||||
464
docs/de/docs/index.md
Normal file
464
docs/de/docs/index.md
Normal file
@@ -0,0 +1,464 @@
|
||||
|
||||
{!../../../docs/missing-translation.md!}
|
||||
|
||||
|
||||
<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, high performance, easy to learn, fast to code, ready for production</em>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/tiangolo/fastapi/actions?query=workflow%3ATest" target="_blank">
|
||||
<img src="https://github.com/tiangolo/fastapi/workflows/Test/badge.svg" alt="Test">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/tiangolo/fastapi" target="_blank">
|
||||
<img src="https://img.shields.io/codecov/c/github/tiangolo/fastapi?color=%2334D058" 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>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
**Documentation**: <a href="https://fastapi.tiangolo.com" target="_blank">https://fastapi.tiangolo.com</a>
|
||||
|
||||
**Source Code**: <a href="https://github.com/tiangolo/fastapi" target="_blank">https://github.com/tiangolo/fastapi</a>
|
||||
|
||||
---
|
||||
|
||||
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.6+ based on standard Python type hints.
|
||||
|
||||
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.
|
||||
* **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>
|
||||
|
||||
## Sponsors
|
||||
|
||||
<!-- 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">Other sponsors</a>
|
||||
|
||||
## Opinions
|
||||
|
||||
"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Kabir Khan - <strong>Microsoft</strong> <a href="https://github.com/tiangolo/fastapi/pull/26" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
|
||||
|
||||
<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** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
|
||||
|
||||
<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>
|
||||
|
||||
---
|
||||
|
||||
"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Brian Okken - <strong><a href="https://pythonbytes.fm/episodes/show/123/time-to-right-the-py-wrongs?time_in_sec=855" target="_blank">Python Bytes</a> podcast host</strong> <a href="https://twitter.com/brianokken/status/1112220079972728832" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Timothy Crosley - <strong><a href="https://www.hug.rest/" target="_blank">Hug</a> creator</strong> <a href="https://news.ycombinator.com/item?id=19455465" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
|
||||
|
||||
"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
|
||||
|
||||
<div style="text-align: right; margin-right: 10%;">Ines Montani - Matthew Honnibal - <strong><a href="https://explosion.ai" target="_blank">Explosion AI</a> founders - <a href="https://spacy.io" target="_blank">spaCy</a> creators</strong> <a href="https://twitter.com/_inesmontani/status/1144173225322143744" target="_blank"><small>(ref)</small></a> - <a href="https://twitter.com/honnibal/status/1144031421859655680" target="_blank"><small>(ref)</small></a></div>
|
||||
|
||||
---
|
||||
|
||||
## **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>
|
||||
|
||||
If you are building a <abbr title="Command Line Interface">CLI</abbr> app to be used in the terminal instead of a web API, check out <a href="https://typer.tiangolo.com/" class="external-link" target="_blank">**Typer**</a>.
|
||||
|
||||
**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
|
||||
|
||||
## Requirements
|
||||
|
||||
Python 3.7+
|
||||
|
||||
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://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> for the data parts.
|
||||
|
||||
## Installation
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install fastapi
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
You will also need an ASGI server, for production such as <a href="https://www.uvicorn.org" class="external-link" target="_blank">Uvicorn</a> or <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>.
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install "uvicorn[standard]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## Example
|
||||
|
||||
### Create it
|
||||
|
||||
* Create a file `main.py` with:
|
||||
|
||||
```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>Or use <code>async def</code>...</summary>
|
||||
|
||||
If your code uses `async` / `await`, use `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}
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
If you don't know, check the _"In a hurry?"_ section about <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank">`async` and `await` in the docs</a>.
|
||||
|
||||
</details>
|
||||
|
||||
### Run it
|
||||
|
||||
Run the server with:
|
||||
|
||||
<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>About the command <code>uvicorn main:app --reload</code>...</summary>
|
||||
|
||||
The command `uvicorn main:app` refers to:
|
||||
|
||||
* `main`: the file `main.py` (the Python "module").
|
||||
* `app`: the object created inside of `main.py` with the line `app = FastAPI()`.
|
||||
* `--reload`: make the server restart after code changes. Only do this for development.
|
||||
|
||||
</details>
|
||||
|
||||
### Check it
|
||||
|
||||
Open your browser at <a href="http://127.0.0.1:8000/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1:8000/items/5?q=somequery</a>.
|
||||
|
||||
You will see the JSON response as:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
You already created an API that:
|
||||
|
||||
* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
|
||||
* Both _paths_ take `GET` <em>operations</em> (also known as HTTP _methods_).
|
||||
* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
|
||||
* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
|
||||
|
||||
### Interactive API docs
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
|
||||
|
||||

|
||||
|
||||
### Alternative API docs
|
||||
|
||||
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
You will see the alternative automatic documentation (provided by <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
|
||||
|
||||

|
||||
|
||||
## Example upgrade
|
||||
|
||||
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
|
||||
|
||||
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}
|
||||
```
|
||||
|
||||
The server should reload automatically (because you added `--reload` to the `uvicorn` command above).
|
||||
|
||||
### Interactive API docs upgrade
|
||||
|
||||
Now go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
* The interactive API documentation will be automatically updated, including the new body:
|
||||
|
||||

|
||||
|
||||
* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
|
||||
|
||||

|
||||
|
||||
* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen:
|
||||
|
||||

|
||||
|
||||
### Alternative API docs upgrade
|
||||
|
||||
And now, go to <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a>.
|
||||
|
||||
* The alternative documentation will also reflect the new query parameter and body:
|
||||
|
||||

|
||||
|
||||
### Recap
|
||||
|
||||
In summary, you declare **once** the types of parameters, body, etc. as function parameters.
|
||||
|
||||
You do that with standard modern Python types.
|
||||
|
||||
You don't have to learn a new syntax, the methods or classes of a specific library, etc.
|
||||
|
||||
Just standard **Python 3.6+**.
|
||||
|
||||
For example, for an `int`:
|
||||
|
||||
```Python
|
||||
item_id: int
|
||||
```
|
||||
|
||||
or for a more complex `Item` model:
|
||||
|
||||
```Python
|
||||
item: Item
|
||||
```
|
||||
|
||||
...and with that single declaration you get:
|
||||
|
||||
* Editor support, including:
|
||||
* Completion.
|
||||
* Type checks.
|
||||
* 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:
|
||||
* JSON.
|
||||
* Path parameters.
|
||||
* Query parameters.
|
||||
* Cookies.
|
||||
* 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):
|
||||
* Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
|
||||
* `datetime` objects.
|
||||
* `UUID` objects.
|
||||
* Database models.
|
||||
* ...and many more.
|
||||
* Automatic interactive API documentation, including 2 alternative user interfaces:
|
||||
* Swagger UI.
|
||||
* ReDoc.
|
||||
|
||||
---
|
||||
|
||||
Coming back to the previous code example, **FastAPI** will:
|
||||
|
||||
* Validate that there is an `item_id` in the path for `GET` and `PUT` requests.
|
||||
* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests.
|
||||
* If it is not, the client will see a useful, clear error.
|
||||
* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests.
|
||||
* As the `q` parameter is declared with `= None`, it is optional.
|
||||
* Without the `None` it would be required (as is the body in the case with `PUT`).
|
||||
* For `PUT` requests to `/items/{item_id}`, Read the body as JSON:
|
||||
* Check that it has a required attribute `name` that should be a `str`.
|
||||
* Check that it has a required attribute `price` that has to be a `float`.
|
||||
* Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
|
||||
* All this would also work for deeply nested JSON objects.
|
||||
* Convert from and to JSON automatically.
|
||||
* Document everything with OpenAPI, that can be used by:
|
||||
* Interactive documentation systems.
|
||||
* Automatic client code generation systems, for many languages.
|
||||
* Provide 2 interactive documentation web interfaces directly.
|
||||
|
||||
---
|
||||
|
||||
We just scratched the surface, but you already get the idea of how it all works.
|
||||
|
||||
Try changing the line with:
|
||||
|
||||
```Python
|
||||
return {"item_name": item.name, "item_id": item_id}
|
||||
```
|
||||
|
||||
...from:
|
||||
|
||||
```Python
|
||||
... "item_name": item.name ...
|
||||
```
|
||||
|
||||
...to:
|
||||
|
||||
```Python
|
||||
... "item_price": item.price ...
|
||||
```
|
||||
|
||||
...and see how your editor will auto-complete the attributes and know their types:
|
||||
|
||||

|
||||
|
||||
For a more complete example including more features, see the <a href="https://fastapi.tiangolo.com/tutorial/">Tutorial - User Guide</a>.
|
||||
|
||||
**Spoiler alert**: the tutorial - user guide includes:
|
||||
|
||||
* 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.
|
||||
* 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).
|
||||
* Many extra features (thanks to Starlette) as:
|
||||
* **WebSockets**
|
||||
* extremely easy tests based on `requests` and `pytest`
|
||||
* **CORS**
|
||||
* **Cookie Sessions**
|
||||
* ...and more.
|
||||
|
||||
## Performance
|
||||
|
||||
Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as <a href="https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7" class="external-link" target="_blank">one of the fastest Python frameworks available</a>, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
|
||||
|
||||
To understand more about it, see the section <a href="https://fastapi.tiangolo.com/benchmarks/" class="internal-link" target="_blank">Benchmarks</a>.
|
||||
|
||||
## Optional Dependencies
|
||||
|
||||
Used by Pydantic:
|
||||
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - for faster JSON <abbr title="converting the string that comes from an HTTP request into Python data">"parsing"</abbr>.
|
||||
* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
|
||||
|
||||
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://andrew-d.github.io/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://pythonhosted.org/itsdangerous/" target="_blank"><code>itsdangerous</code></a> - Required for `SessionMiddleware` support.
|
||||
* <a href="https://pyyaml.org/wiki/PyYAMLDocumentation" target="_blank"><code>pyyaml</code></a> - Required for Starlette's `SchemaGenerator` support (you probably don't need it with FastAPI).
|
||||
* <a href="https://github.com/esnme/ultrajson" target="_blank"><code>ujson</code></a> - Required if you want to use `UJSONResponse`.
|
||||
|
||||
Used by FastAPI / Starlette:
|
||||
|
||||
* <a href="https://www.uvicorn.org" target="_blank"><code>uvicorn</code></a> - for the server that loads and serves your application.
|
||||
* <a href="https://github.com/ijl/orjson" target="_blank"><code>orjson</code></a> - Required if you want to use `ORJSONResponse`.
|
||||
|
||||
You can install all of these with `pip install fastapi[all]`.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the terms of the MIT license.
|
||||
155
docs/de/mkdocs.yml
Normal file
155
docs/de/mkdocs.yml
Normal file
@@ -0,0 +1,155 @@
|
||||
site_name: FastAPI
|
||||
site_description: FastAPI framework, high performance, easy to learn, fast to code, ready for production
|
||||
site_url: https://fastapi.tiangolo.com/de/
|
||||
theme:
|
||||
name: material
|
||||
custom_dir: overrides
|
||||
palette:
|
||||
- media: '(prefers-color-scheme: light)'
|
||||
scheme: default
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb
|
||||
name: Switch to light mode
|
||||
- media: '(prefers-color-scheme: dark)'
|
||||
scheme: slate
|
||||
primary: teal
|
||||
accent: amber
|
||||
toggle:
|
||||
icon: material/lightbulb-outline
|
||||
name: Switch to dark mode
|
||||
features:
|
||||
- search.suggest
|
||||
- search.highlight
|
||||
- content.tabs.link
|
||||
icon:
|
||||
repo: fontawesome/brands/github-alt
|
||||
logo: https://fastapi.tiangolo.com/img/icon-white.svg
|
||||
favicon: https://fastapi.tiangolo.com/img/favicon.png
|
||||
language: de
|
||||
repo_name: tiangolo/fastapi
|
||||
repo_url: https://github.com/tiangolo/fastapi
|
||||
edit_uri: ''
|
||||
plugins:
|
||||
- search
|
||||
- markdownextradata:
|
||||
data: data
|
||||
nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- az: /az/
|
||||
- de: /de/
|
||||
- em: /em/
|
||||
- es: /es/
|
||||
- fa: /fa/
|
||||
- fr: /fr/
|
||||
- he: /he/
|
||||
- hy: /hy/
|
||||
- id: /id/
|
||||
- it: /it/
|
||||
- ja: /ja/
|
||||
- ko: /ko/
|
||||
- nl: /nl/
|
||||
- pl: /pl/
|
||||
- pt: /pt/
|
||||
- ru: /ru/
|
||||
- sq: /sq/
|
||||
- sv: /sv/
|
||||
- ta: /ta/
|
||||
- tr: /tr/
|
||||
- uk: /uk/
|
||||
- zh: /zh/
|
||||
- features.md
|
||||
markdown_extensions:
|
||||
- toc:
|
||||
permalink: true
|
||||
- markdown.extensions.codehilite:
|
||||
guess_lang: false
|
||||
- mdx_include:
|
||||
base_path: docs
|
||||
- admonition
|
||||
- codehilite
|
||||
- extra
|
||||
- pymdownx.superfences:
|
||||
custom_fences:
|
||||
- name: mermaid
|
||||
class: mermaid
|
||||
format: !!python/name:pymdownx.superfences.fence_code_format ''
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- attr_list
|
||||
- md_in_html
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
property: G-YNEVN69SC3
|
||||
social:
|
||||
- icon: fontawesome/brands/github-alt
|
||||
link: https://github.com/tiangolo/fastapi
|
||||
- icon: fontawesome/brands/discord
|
||||
link: https://discord.gg/VQjSZaeJmf
|
||||
- icon: fontawesome/brands/twitter
|
||||
link: https://twitter.com/fastapi
|
||||
- icon: fontawesome/brands/linkedin
|
||||
link: https://www.linkedin.com/in/tiangolo
|
||||
- icon: fontawesome/brands/dev
|
||||
link: https://dev.to/tiangolo
|
||||
- icon: fontawesome/brands/medium
|
||||
link: https://medium.com/@tiangolo
|
||||
- icon: fontawesome/solid/globe
|
||||
link: https://tiangolo.com
|
||||
alternate:
|
||||
- link: /
|
||||
name: en - English
|
||||
- link: /az/
|
||||
name: az
|
||||
- link: /de/
|
||||
name: de
|
||||
- link: /em/
|
||||
name: 😉
|
||||
- link: /es/
|
||||
name: es - español
|
||||
- link: /fa/
|
||||
name: fa
|
||||
- link: /fr/
|
||||
name: fr - français
|
||||
- link: /he/
|
||||
name: he
|
||||
- link: /hy/
|
||||
name: hy
|
||||
- link: /id/
|
||||
name: id
|
||||
- link: /it/
|
||||
name: it - italiano
|
||||
- link: /ja/
|
||||
name: ja - 日本語
|
||||
- link: /ko/
|
||||
name: ko - 한국어
|
||||
- link: /nl/
|
||||
name: nl
|
||||
- link: /pl/
|
||||
name: pl
|
||||
- link: /pt/
|
||||
name: pt - português
|
||||
- link: /ru/
|
||||
name: ru - русский язык
|
||||
- link: /sq/
|
||||
name: sq - shqip
|
||||
- link: /sv/
|
||||
name: sv - svenska
|
||||
- link: /ta/
|
||||
name: ta - தமிழ்
|
||||
- link: /tr/
|
||||
name: tr - Türkçe
|
||||
- link: /uk/
|
||||
name: uk - українська мова
|
||||
- link: /zh/
|
||||
name: zh - 汉语
|
||||
extra_css:
|
||||
- https://fastapi.tiangolo.com/css/termynal.css
|
||||
- https://fastapi.tiangolo.com/css/custom.css
|
||||
extra_javascript:
|
||||
- https://fastapi.tiangolo.com/js/termynal.js
|
||||
- https://fastapi.tiangolo.com/js/custom.js
|
||||
@@ -1,262 +0,0 @@
|
||||
You can use <a href="https://www.docker.com/" class="external-link" target="_blank">**Docker**</a> for deployment. It has several advantages like security, replicability, development simplicity, etc.
|
||||
|
||||
In this section you'll see instructions and links to guides to know how to:
|
||||
|
||||
* Make your **FastAPI** application a Docker image/container with maximum performance. In about **5 min**.
|
||||
* (Optionally) understand what you, as a developer, need to know about HTTPS.
|
||||
* Set up a Docker Swarm mode cluster with automatic HTTPS, even on a simple $5 USD/month server. In about **20 min**.
|
||||
* Generate and deploy a full **FastAPI** application, using your Docker Swarm cluster, with HTTPS, etc. In about **10 min**.
|
||||
|
||||
---
|
||||
|
||||
You can also easily use **FastAPI** in a standard server directly too (without Docker).
|
||||
|
||||
## Docker
|
||||
|
||||
If you are using Docker, you can use the official Docker image:
|
||||
|
||||
### <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>
|
||||
|
||||
This image has an "auto-tuning" mechanism included, so that you can just add your code and get very high performance automatically. And without making sacrifices.
|
||||
|
||||
But you can still change and update all the configurations with environment variables or configuration files.
|
||||
|
||||
!!! tip
|
||||
To see all the configurations and options, go to the Docker image page: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>.
|
||||
|
||||
### Create a `Dockerfile`
|
||||
|
||||
* Go to your project directory.
|
||||
* Create a `Dockerfile` with:
|
||||
|
||||
```Dockerfile
|
||||
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
|
||||
|
||||
COPY ./app /app
|
||||
```
|
||||
|
||||
#### Bigger Applications
|
||||
|
||||
If you followed the section about creating [Bigger Applications with Multiple Files](tutorial/bigger-applications.md){.internal-link target=_blank}, your `Dockerfile` might instead look like:
|
||||
|
||||
```Dockerfile
|
||||
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
|
||||
|
||||
COPY ./app /app/app
|
||||
```
|
||||
|
||||
#### Raspberry Pi and other architectures
|
||||
|
||||
If you are running Docker in a Raspberry Pi (that has an ARM processor) or any other architecture, you can create a `Dockerfile` from scratch, based on a Python base image (that is multi-architecture) and use Uvicorn alone.
|
||||
|
||||
In this case, your `Dockerfile` could look like:
|
||||
|
||||
```Dockerfile
|
||||
FROM python:3.7
|
||||
|
||||
RUN pip install fastapi uvicorn
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
COPY ./app /app
|
||||
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
|
||||
```
|
||||
|
||||
### Create the **FastAPI** Code
|
||||
|
||||
* Create an `app` directory and enter in it.
|
||||
* Create a `main.py` file with:
|
||||
|
||||
```Python
|
||||
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: str = None):
|
||||
return {"item_id": item_id, "q": q}
|
||||
```
|
||||
|
||||
* You should now have a directory structure like:
|
||||
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ └── main.py
|
||||
└── Dockerfile
|
||||
```
|
||||
|
||||
### Build the Docker image
|
||||
|
||||
* Go to the project directory (in where your `Dockerfile` is, containing your `app` directory).
|
||||
* Build your FastAPI image:
|
||||
|
||||
```bash
|
||||
docker build -t myimage .
|
||||
```
|
||||
|
||||
### Start the Docker container
|
||||
|
||||
* Run a container based on your image:
|
||||
|
||||
```bash
|
||||
docker run -d --name mycontainer -p 80:80 myimage
|
||||
```
|
||||
|
||||
Now you have an optimized FastAPI server in a Docker container. Auto-tuned for your current server (and number of CPU cores).
|
||||
|
||||
### Check it
|
||||
|
||||
You should be able to check it in your Docker container's URL, for example: <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> or <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (or equivalent, using your Docker host).
|
||||
|
||||
You will see something like:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
### Interactive API docs
|
||||
|
||||
Now you can go to <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> or <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (or equivalent, using your Docker host).
|
||||
|
||||
You will see the automatic interactive API documentation (provided by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>):
|
||||
|
||||

|
||||
|
||||
### Alternative API docs
|
||||
|
||||
And you can also go to <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> or <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (or equivalent, using your Docker host).
|
||||
|
||||
You will see the alternative automatic documentation (provided by <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>):
|
||||
|
||||

|
||||
|
||||
## HTTPS
|
||||
|
||||
### About HTTPS
|
||||
|
||||
It is easy to assume that HTTPS is something that is just "enabled" or not.
|
||||
|
||||
But it is way more complex than that.
|
||||
|
||||
!!! tip
|
||||
If you are in a hurry or don't care, continue with the next section for step by step instructions to set everything up.
|
||||
|
||||
To learn the basics of HTTPS, from a consumer perspective, check <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>.
|
||||
|
||||
Now, from a developer's perspective, here are several things to have in mind while thinking about HTTPS:
|
||||
|
||||
* For HTTPS, the server needs to have "certificates" generated by a third party.
|
||||
* Those certificates are actually acquired from the third-party, not "generated".
|
||||
* Certificates have a lifetime.
|
||||
* They expire.
|
||||
* And then they need to be renewed, acquired again from the third party.
|
||||
* The encryption of the connection happens at the TCP level.
|
||||
* That's one layer below HTTP.
|
||||
* So, the certificate and encryption handling is done before HTTP.
|
||||
* TCP doesn't know about "domains". Only about IP addresses.
|
||||
* The information about the specific domain requested goes in the HTTP data.
|
||||
* The HTTPS certificates "certify" a certain domain, but the protocol and encryption happen at the TCP level, before knowing which domain is being dealt with.
|
||||
* By default, that would mean that you can only have one HTTPS certificate per IP address.
|
||||
* No matter how big your server is or how small each application you have on it might be.
|
||||
* There is a solution to this, however.
|
||||
* There's an extension to the TLS protocol (the one handling the encryption at the TCP level, before HTTP) called <a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication">SNI</abbr></a>.
|
||||
* This SNI extension allows one single server (with a single IP address) to have several HTTPS certificates and serve multiple HTTPS domains/applications.
|
||||
* For this to work, a single component (program) running on the server, listening on the public IP address, must have all the HTTPS certificates in the server.
|
||||
* After obtaining a secure connection, the communication protocol is still HTTP.
|
||||
* The contents are encrypted, even though they are being sent with the HTTP protocol.
|
||||
|
||||
It is a common practice to have one program/HTTP server running on the server (the machine, host, etc.) and managing all the HTTPS parts : sending the decrypted HTTP requests to the actual HTTP application running in the same server (the **FastAPI** application, in this case), take the HTTP response from the application, encrypt it using the appropriate certificate and sending it back to the client using HTTPS. This server is often called a <a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">TLS Termination Proxy</a>.
|
||||
|
||||
### Let's Encrypt
|
||||
|
||||
Before Let's Encrypt, these HTTPS certificates were sold by trusted third-parties.
|
||||
|
||||
The process to acquire one of these certificates used to be cumbersome, require quite some paperwork and the certificates were quite expensive.
|
||||
|
||||
But then <a href="https://letsencrypt.org/" class="external-link" target="_blank">Let's Encrypt</a> was created.
|
||||
|
||||
It is a project from the Linux Foundation. It provides HTTPS certificates for free. In an automated way. These certificates use all the standard cryptographic security, and are short lived (about 3 months), so the security is actually better because of their reduced lifespan.
|
||||
|
||||
The domains are securely verified and the certificates are generated automatically. This also allows automating the renewal of these certificates.
|
||||
|
||||
The idea is to automate the acquisition and renewal of these certificates, so that you can have secure HTTPS, for free, forever.
|
||||
|
||||
### Traefik
|
||||
|
||||
<a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a> is a high performance reverse proxy / load balancer. It can do the "TLS Termination Proxy" job (apart from other features).
|
||||
|
||||
It has integration with Let's Encrypt. So, it can handle all the HTTPS parts, including certificate acquisition and renewal.
|
||||
|
||||
It also has integrations with Docker. So, you can declare your domains in each application configurations and have it read those configurations, generate the HTTPS certificates and serve HTTPS to your application automatically, without requiring any change in its configuration.
|
||||
|
||||
---
|
||||
|
||||
With this information and tools, continue with the next section to combine everything.
|
||||
|
||||
## Docker Swarm mode cluster with Traefik and HTTPS
|
||||
|
||||
You can have a Docker Swarm mode cluster set up in minutes (about 20 min) with a main Traefik handling HTTPS (including certificate acquisition and renewal).
|
||||
|
||||
By using Docker Swarm mode, you can start with a "cluster" of a single machine (it can even be a $5 USD / month server) and then you can grow as much as you need adding more servers.
|
||||
|
||||
To set up a Docker Swarm Mode cluster with Traefik and HTTPS handling, follow this guide:
|
||||
|
||||
### <a href="https://medium.com/@tiangolo/docker-swarm-mode-and-traefik-for-a-https-cluster-20328dba6232" class="external-link" target="_blank">Docker Swarm Mode and Traefik for an HTTPS cluster</a>
|
||||
|
||||
### Deploy a FastAPI application
|
||||
|
||||
The easiest way to set everything up, would be using the [**FastAPI** Project Generators](project-generation.md){.internal-link target=_blank}.
|
||||
|
||||
It is designed to be integrated with this Docker Swarm cluster with Traefik and HTTPS described above.
|
||||
|
||||
You can generate a project in about 2 min.
|
||||
|
||||
The generated project has instructions to deploy it, doing it takes another 2 min.
|
||||
|
||||
## Alternatively, deploy **FastAPI** without Docker
|
||||
|
||||
You can deploy **FastAPI** directly without Docker too.
|
||||
|
||||
You just need to install an ASGI compatible server like:
|
||||
|
||||
* <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>, a lightning-fast ASGI server, built on uvloop and httptools.
|
||||
|
||||
```bash
|
||||
pip install uvicorn
|
||||
```
|
||||
|
||||
* <a href="https://gitlab.com/pgjones/hypercorn" class="external-link" target="_blank">Hypercorn</a>, an ASGI server also compatible with HTTP/2.
|
||||
|
||||
```bash
|
||||
pip install hypercorn
|
||||
```
|
||||
|
||||
...or any other ASGI server.
|
||||
|
||||
And run your application the same way you have done in the tutorials, but without the `--reload` option, e.g.:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --host 0.0.0.0 --port 80
|
||||
```
|
||||
|
||||
or with Hypercorn:
|
||||
|
||||
```bash
|
||||
hypercorn main:app --bind 0.0.0.0:80
|
||||
```
|
||||
|
||||
You might want to set up some tooling to make sure it is restarted automatically if it stops.
|
||||
|
||||
You might also want to install <a href="https://gunicorn.org/" class="external-link" target="_blank">Gunicorn</a> and <a href="https://www.uvicorn.org/#running-with-gunicorn" class="external-link" target="_blank">use it as a manager for Uvicorn</a>, or use Hypercorn with multiple workers.
|
||||
|
||||
Making sure to fine-tune the number of workers, etc.
|
||||
|
||||
But if you are doing all that, you might just use the Docker image that does it automatically.
|
||||
240
docs/em/docs/advanced/additional-responses.md
Normal file
240
docs/em/docs/advanced/additional-responses.md
Normal file
@@ -0,0 +1,240 @@
|
||||
# 🌖 📨 🗄
|
||||
|
||||
!!! warning
|
||||
👉 👍 🏧 ❔.
|
||||
|
||||
🚥 👆 ▶️ ⏮️ **FastAPI**, 👆 💪 🚫 💪 👉.
|
||||
|
||||
👆 💪 📣 🌖 📨, ⏮️ 🌖 👔 📟, 🔉 🆎, 📛, ♒️.
|
||||
|
||||
👈 🌖 📨 🔜 🔌 🗄 🔗, 👫 🔜 😑 🛠️ 🩺.
|
||||
|
||||
✋️ 👈 🌖 📨 👆 ✔️ ⚒ 💭 👆 📨 `Response` 💖 `JSONResponse` 🔗, ⏮️ 👆 👔 📟 & 🎚.
|
||||
|
||||
## 🌖 📨 ⏮️ `model`
|
||||
|
||||
👆 💪 🚶♀️ 👆 *➡ 🛠️ 👨🎨* 🔢 `responses`.
|
||||
|
||||
⚫️ 📨 `dict`, 🔑 👔 📟 🔠 📨, 💖 `200`, & 💲 🎏 `dict`Ⓜ ⏮️ ℹ 🔠 👫.
|
||||
|
||||
🔠 👈 📨 `dict`Ⓜ 💪 ✔️ 🔑 `model`, ⚗ Pydantic 🏷, 💖 `response_model`.
|
||||
|
||||
**FastAPI** 🔜 ✊ 👈 🏷, 🏗 🚮 🎻 🔗 & 🔌 ⚫️ ☑ 🥉 🗄.
|
||||
|
||||
🖼, 📣 ➕1️⃣ 📨 ⏮️ 👔 📟 `404` & Pydantic 🏷 `Message`, 👆 💪 ✍:
|
||||
|
||||
```Python hl_lines="18 22"
|
||||
{!../../../docs_src/additional_responses/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
✔️ 🤯 👈 👆 ✔️ 📨 `JSONResponse` 🔗.
|
||||
|
||||
!!! info
|
||||
`model` 🔑 🚫 🍕 🗄.
|
||||
|
||||
**FastAPI** 🔜 ✊ Pydantic 🏷 ⚪️➡️ 📤, 🏗 `JSON Schema`, & 🚮 ⚫️ ☑ 🥉.
|
||||
|
||||
☑ 🥉:
|
||||
|
||||
* 🔑 `content`, 👈 ✔️ 💲 ➕1️⃣ 🎻 🎚 (`dict`) 👈 🔌:
|
||||
* 🔑 ⏮️ 📻 🆎, ✅ `application/json`, 👈 🔌 💲 ➕1️⃣ 🎻 🎚, 👈 🔌:
|
||||
* 🔑 `schema`, 👈 ✔️ 💲 🎻 🔗 ⚪️➡️ 🏷, 📥 ☑ 🥉.
|
||||
* **FastAPI** 🚮 🔗 📥 🌐 🎻 🔗 ➕1️⃣ 🥉 👆 🗄 ↩️ ✅ ⚫️ 🔗. 👉 🌌, 🎏 🈸 & 👩💻 💪 ⚙️ 👈 🎻 🔗 🔗, 🚚 👻 📟 ⚡ 🧰, ♒️.
|
||||
|
||||
🏗 📨 🗄 👉 *➡ 🛠️* 🔜:
|
||||
|
||||
```JSON hl_lines="3-12"
|
||||
{
|
||||
"responses": {
|
||||
"404": {
|
||||
"description": "Additional Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Message"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Item"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"422": {
|
||||
"description": "Validation Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/HTTPValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
🔗 🔗 ➕1️⃣ 🥉 🔘 🗄 🔗:
|
||||
|
||||
```JSON hl_lines="4-16"
|
||||
{
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Message": {
|
||||
"title": "Message",
|
||||
"required": [
|
||||
"message"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"title": "Message",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Item": {
|
||||
"title": "Item",
|
||||
"required": [
|
||||
"id",
|
||||
"value"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"title": "Id",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"title": "Value",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ValidationError": {
|
||||
"title": "ValidationError",
|
||||
"required": [
|
||||
"loc",
|
||||
"msg",
|
||||
"type"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"loc": {
|
||||
"title": "Location",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"msg": {
|
||||
"title": "Message",
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"title": "Error Type",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"HTTPValidationError": {
|
||||
"title": "HTTPValidationError",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"title": "Detail",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ValidationError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🌖 🔉 🆎 👑 📨
|
||||
|
||||
👆 💪 ⚙️ 👉 🎏 `responses` 🔢 🚮 🎏 🔉 🆎 🎏 👑 📨.
|
||||
|
||||
🖼, 👆 💪 🚮 🌖 📻 🆎 `image/png`, 📣 👈 👆 *➡ 🛠️* 💪 📨 🎻 🎚 (⏮️ 📻 🆎 `application/json`) ⚖️ 🇩🇴 🖼:
|
||||
|
||||
```Python hl_lines="19-24 28"
|
||||
{!../../../docs_src/additional_responses/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
👀 👈 👆 ✔️ 📨 🖼 ⚙️ `FileResponse` 🔗.
|
||||
|
||||
!!! info
|
||||
🚥 👆 ✔ 🎏 📻 🆎 🎯 👆 `responses` 🔢, FastAPI 🔜 🤔 📨 ✔️ 🎏 📻 🆎 👑 📨 🎓 (🔢 `application/json`).
|
||||
|
||||
✋️ 🚥 👆 ✔️ ✔ 🛃 📨 🎓 ⏮️ `None` 🚮 📻 🆎, FastAPI 🔜 ⚙️ `application/json` 🙆 🌖 📨 👈 ✔️ 👨💼 🏷.
|
||||
|
||||
## 🌀 ℹ
|
||||
|
||||
👆 💪 🌀 📨 ℹ ⚪️➡️ 💗 🥉, 🔌 `response_model`, `status_code`, & `responses` 🔢.
|
||||
|
||||
👆 💪 📣 `response_model`, ⚙️ 🔢 👔 📟 `200` (⚖️ 🛃 1️⃣ 🚥 👆 💪), & ⤴️ 📣 🌖 ℹ 👈 🎏 📨 `responses`, 🔗 🗄 🔗.
|
||||
|
||||
**FastAPI** 🔜 🚧 🌖 ℹ ⚪️➡️ `responses`, & 🌀 ⚫️ ⏮️ 🎻 🔗 ⚪️➡️ 👆 🏷.
|
||||
|
||||
🖼, 👆 💪 📣 📨 ⏮️ 👔 📟 `404` 👈 ⚙️ Pydantic 🏷 & ✔️ 🛃 `description`.
|
||||
|
||||
& 📨 ⏮️ 👔 📟 `200` 👈 ⚙️ 👆 `response_model`, ✋️ 🔌 🛃 `example`:
|
||||
|
||||
```Python hl_lines="20-31"
|
||||
{!../../../docs_src/additional_responses/tutorial003.py!}
|
||||
```
|
||||
|
||||
⚫️ 🔜 🌐 🌀 & 🔌 👆 🗄, & 🎦 🛠️ 🩺:
|
||||
|
||||
<img src="/img/tutorial/additional-responses/image01.png">
|
||||
|
||||
## 🌀 🔢 📨 & 🛃 🕐
|
||||
|
||||
👆 💪 💚 ✔️ 🔁 📨 👈 ✔ 📚 *➡ 🛠️*, ✋️ 👆 💚 🌀 👫 ⏮️ 🛃 📨 💚 🔠 *➡ 🛠️*.
|
||||
|
||||
📚 💼, 👆 💪 ⚙️ 🐍 ⚒ "🏗" `dict` ⏮️ `**dict_to_unpack`:
|
||||
|
||||
```Python
|
||||
old_dict = {
|
||||
"old key": "old value",
|
||||
"second old key": "second old value",
|
||||
}
|
||||
new_dict = {**old_dict, "new key": "new value"}
|
||||
```
|
||||
|
||||
📥, `new_dict` 🔜 🔌 🌐 🔑-💲 👫 ⚪️➡️ `old_dict` ➕ 🆕 🔑-💲 👫:
|
||||
|
||||
```Python
|
||||
{
|
||||
"old key": "old value",
|
||||
"second old key": "second old value",
|
||||
"new key": "new value",
|
||||
}
|
||||
```
|
||||
|
||||
👆 💪 ⚙️ 👈 ⚒ 🏤-⚙️ 🔢 📨 👆 *➡ 🛠️* & 🌀 👫 ⏮️ 🌖 🛃 🕐.
|
||||
|
||||
🖼:
|
||||
|
||||
```Python hl_lines="13-17 26"
|
||||
{!../../../docs_src/additional_responses/tutorial004.py!}
|
||||
```
|
||||
|
||||
## 🌖 ℹ 🔃 🗄 📨
|
||||
|
||||
👀 ⚫️❔ ⚫️❔ 👆 💪 🔌 📨, 👆 💪 ✅ 👉 📄 🗄 🔧:
|
||||
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responsesObject" class="external-link" target="_blank">🗄 📨 🎚</a>, ⚫️ 🔌 `Response Object`.
|
||||
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responseObject" class="external-link" target="_blank">🗄 📨 🎚</a>, 👆 💪 🔌 🕳 ⚪️➡️ 👉 🔗 🔠 📨 🔘 👆 `responses` 🔢. ✅ `description`, `headers`, `content` (🔘 👉 👈 👆 📣 🎏 🔉 🆎 & 🎻 🔗), & `links`.
|
||||
37
docs/em/docs/advanced/additional-status-codes.md
Normal file
37
docs/em/docs/advanced/additional-status-codes.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# 🌖 👔 📟
|
||||
|
||||
🔢, **FastAPI** 🔜 📨 📨 ⚙️ `JSONResponse`, 🚮 🎚 👆 📨 ⚪️➡️ 👆 *➡ 🛠️* 🔘 👈 `JSONResponse`.
|
||||
|
||||
⚫️ 🔜 ⚙️ 🔢 👔 📟 ⚖️ 1️⃣ 👆 ⚒ 👆 *➡ 🛠️*.
|
||||
|
||||
## 🌖 👔 📟
|
||||
|
||||
🚥 👆 💚 📨 🌖 👔 📟 ↖️ ⚪️➡️ 👑 1️⃣, 👆 💪 👈 🛬 `Response` 🔗, 💖 `JSONResponse`, & ⚒ 🌖 👔 📟 🔗.
|
||||
|
||||
🖼, ➡️ 💬 👈 👆 💚 ✔️ *➡ 🛠️* 👈 ✔ ℹ 🏬, & 📨 🇺🇸🔍 👔 📟 2️⃣0️⃣0️⃣ "👌" 🕐❔ 🏆.
|
||||
|
||||
✋️ 👆 💚 ⚫️ 🚫 🆕 🏬. & 🕐❔ 🏬 🚫 🔀 ⏭, ⚫️ ✍ 👫, & 📨 🇺🇸🔍 👔 📟 2️⃣0️⃣1️⃣ "✍".
|
||||
|
||||
🏆 👈, 🗄 `JSONResponse`, & 📨 👆 🎚 📤 🔗, ⚒ `status_code` 👈 👆 💚:
|
||||
|
||||
```Python hl_lines="4 25"
|
||||
{!../../../docs_src/additional_status_codes/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! warning
|
||||
🕐❔ 👆 📨 `Response` 🔗, 💖 🖼 🔛, ⚫️ 🔜 📨 🔗.
|
||||
|
||||
⚫️ 🏆 🚫 🎻 ⏮️ 🏷, ♒️.
|
||||
|
||||
⚒ 💭 ⚫️ ✔️ 📊 👆 💚 ⚫️ ✔️, & 👈 💲 ☑ 🎻 (🚥 👆 ⚙️ `JSONResponse`).
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
👆 💪 ⚙️ `from starlette.responses import JSONResponse`.
|
||||
|
||||
**FastAPI** 🚚 🎏 `starlette.responses` `fastapi.responses` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃. 🎏 ⏮️ `status`.
|
||||
|
||||
## 🗄 & 🛠️ 🩺
|
||||
|
||||
🚥 👆 📨 🌖 👔 📟 & 📨 🔗, 👫 🏆 🚫 🔌 🗄 🔗 (🛠️ 🩺), ↩️ FastAPI 🚫 ✔️ 🌌 💭 ⏪ ⚫️❔ 👆 🚶 📨.
|
||||
|
||||
✋️ 👆 💪 📄 👈 👆 📟, ⚙️: [🌖 📨](additional-responses.md){.internal-link target=_blank}.
|
||||
70
docs/em/docs/advanced/advanced-dependencies.md
Normal file
70
docs/em/docs/advanced/advanced-dependencies.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# 🏧 🔗
|
||||
|
||||
## 🔗 🔗
|
||||
|
||||
🌐 🔗 👥 ✔️ 👀 🔧 🔢 ⚖️ 🎓.
|
||||
|
||||
✋️ 📤 💪 💼 🌐❔ 👆 💚 💪 ⚒ 🔢 🔛 🔗, 🍵 ✔️ 📣 📚 🎏 🔢 ⚖️ 🎓.
|
||||
|
||||
➡️ 🌈 👈 👥 💚 ✔️ 🔗 👈 ✅ 🚥 🔢 🔢 `q` 🔌 🔧 🎚.
|
||||
|
||||
✋️ 👥 💚 💪 🔗 👈 🔧 🎚.
|
||||
|
||||
## "🇧🇲" 👐
|
||||
|
||||
🐍 📤 🌌 ⚒ 👐 🎓 "🇧🇲".
|
||||
|
||||
🚫 🎓 ⚫️ (❔ ⏪ 🇧🇲), ✋️ 👐 👈 🎓.
|
||||
|
||||
👈, 👥 📣 👩🔬 `__call__`:
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!../../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
👉 💼, 👉 `__call__` ⚫️❔ **FastAPI** 🔜 ⚙️ ✅ 🌖 🔢 & 🎧-🔗, & 👉 ⚫️❔ 🔜 🤙 🚶♀️ 💲 🔢 👆 *➡ 🛠️ 🔢* ⏪.
|
||||
|
||||
## 🔗 👐
|
||||
|
||||
& 🔜, 👥 💪 ⚙️ `__init__` 📣 🔢 👐 👈 👥 💪 ⚙️ "🔗" 🔗:
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!../../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
👉 💼, **FastAPI** 🏆 🚫 ⏱ 👆 ⚖️ 💅 🔃 `__init__`, 👥 🔜 ⚙️ ⚫️ 🔗 👆 📟.
|
||||
|
||||
## ✍ 👐
|
||||
|
||||
👥 💪 ✍ 👐 👉 🎓 ⏮️:
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!../../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
& 👈 🌌 👥 💪 "🔗" 👆 🔗, 👈 🔜 ✔️ `"bar"` 🔘 ⚫️, 🔢 `checker.fixed_content`.
|
||||
|
||||
## ⚙️ 👐 🔗
|
||||
|
||||
⤴️, 👥 💪 ⚙️ 👉 `checker` `Depends(checker)`, ↩️ `Depends(FixedContentQueryChecker)`, ↩️ 🔗 👐, `checker`, 🚫 🎓 ⚫️.
|
||||
|
||||
& 🕐❔ ❎ 🔗, **FastAPI** 🔜 🤙 👉 `checker` 💖:
|
||||
|
||||
```Python
|
||||
checker(q="somequery")
|
||||
```
|
||||
|
||||
...& 🚶♀️ ⚫️❔ 👈 📨 💲 🔗 👆 *➡ 🛠️ 🔢* 🔢 `fixed_content_included`:
|
||||
|
||||
```Python hl_lines="20"
|
||||
{!../../../docs_src/dependencies/tutorial011.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
🌐 👉 💪 😑 🎭. & ⚫️ 💪 🚫 📶 🆑 ❔ ⚫️ ⚠.
|
||||
|
||||
👫 🖼 😫 🙅, ✋️ 🎦 ❔ ⚫️ 🌐 👷.
|
||||
|
||||
📃 🔃 💂♂, 📤 🚙 🔢 👈 🛠️ 👉 🎏 🌌.
|
||||
|
||||
🚥 👆 🤔 🌐 👉, 👆 ⏪ 💭 ❔ 👈 🚙 🧰 💂♂ 👷 🔘.
|
||||
162
docs/em/docs/advanced/async-sql-databases.md
Normal file
162
docs/em/docs/advanced/async-sql-databases.md
Normal file
@@ -0,0 +1,162 @@
|
||||
# 🔁 🗄 (🔗) 💽
|
||||
|
||||
👆 💪 ⚙️ <a href="https://github.com/encode/databases" class="external-link" target="_blank">`encode/databases`</a> ⏮️ **FastAPI** 🔗 💽 ⚙️ `async` & `await`.
|
||||
|
||||
⚫️ 🔗 ⏮️:
|
||||
|
||||
* ✳
|
||||
* ✳
|
||||
* 🗄
|
||||
|
||||
👉 🖼, 👥 🔜 ⚙️ **🗄**, ↩️ ⚫️ ⚙️ 👁 📁 & 🐍 ✔️ 🛠️ 🐕🦺. , 👆 💪 📁 👉 🖼 & 🏃 ⚫️.
|
||||
|
||||
⏪, 👆 🏭 🈸, 👆 💪 💚 ⚙️ 💽 💽 💖 **✳**.
|
||||
|
||||
!!! tip
|
||||
👆 💪 🛠️ 💭 ⚪️➡️ 📄 🔃 🇸🇲 🐜 ([🗄 (🔗) 💽](../tutorial/sql-databases.md){.internal-link target=_blank}), 💖 ⚙️ 🚙 🔢 🎭 🛠️ 💽, 🔬 👆 **FastAPI** 📟.
|
||||
|
||||
👉 📄 🚫 ✔ 📚 💭, 🌓 😑 <a href="https://www.starlette.io/database/" class="external-link" target="_blank">💃</a>.
|
||||
|
||||
## 🗄 & ⚒ 🆙 `SQLAlchemy`
|
||||
|
||||
* 🗄 `SQLAlchemy`.
|
||||
* ✍ `metadata` 🎚.
|
||||
* ✍ 🏓 `notes` ⚙️ `metadata` 🎚.
|
||||
|
||||
```Python hl_lines="4 14 16-22"
|
||||
{!../../../docs_src/async_sql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👀 👈 🌐 👉 📟 😁 🇸🇲 🐚.
|
||||
|
||||
`databases` 🚫 🔨 🕳 📥.
|
||||
|
||||
## 🗄 & ⚒ 🆙 `databases`
|
||||
|
||||
* 🗄 `databases`.
|
||||
* ✍ `DATABASE_URL`.
|
||||
* ✍ `database` 🎚.
|
||||
|
||||
```Python hl_lines="3 9 12"
|
||||
{!../../../docs_src/async_sql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
🚥 👆 🔗 🎏 💽 (✅ ✳), 👆 🔜 💪 🔀 `DATABASE_URL`.
|
||||
|
||||
## ✍ 🏓
|
||||
|
||||
👉 💼, 👥 🏗 🏓 🎏 🐍 📁, ✋️ 🏭, 👆 🔜 🎲 💚 ✍ 👫 ⏮️ ⚗, 🛠️ ⏮️ 🛠️, ♒️.
|
||||
|
||||
📥, 👉 📄 🔜 🏃 🔗, ▶️️ ⏭ ▶️ 👆 **FastAPI** 🈸.
|
||||
|
||||
* ✍ `engine`.
|
||||
* ✍ 🌐 🏓 ⚪️➡️ `metadata` 🎚.
|
||||
|
||||
```Python hl_lines="25-28"
|
||||
{!../../../docs_src/async_sql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
## ✍ 🏷
|
||||
|
||||
✍ Pydantic 🏷:
|
||||
|
||||
* 🗒 ✍ (`NoteIn`).
|
||||
* 🗒 📨 (`Note`).
|
||||
|
||||
```Python hl_lines="31-33 36-39"
|
||||
{!../../../docs_src/async_sql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
🏗 👫 Pydantic 🏷, 🔢 💽 🔜 ✔, 🎻 (🗜), & ✍ (📄).
|
||||
|
||||
, 👆 🔜 💪 👀 ⚫️ 🌐 🎓 🛠️ 🩺.
|
||||
|
||||
## 🔗 & 🔌
|
||||
|
||||
* ✍ 👆 `FastAPI` 🈸.
|
||||
* ✍ 🎉 🐕🦺 🔗 & 🔌 ⚪️➡️ 💽.
|
||||
|
||||
```Python hl_lines="42 45-47 50-52"
|
||||
{!../../../docs_src/async_sql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
## ✍ 🗒
|
||||
|
||||
✍ *➡ 🛠️ 🔢* ✍ 🗒:
|
||||
|
||||
```Python hl_lines="55-58"
|
||||
{!../../../docs_src/async_sql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! Note
|
||||
👀 👈 👥 🔗 ⏮️ 💽 ⚙️ `await`, *➡ 🛠️ 🔢* 📣 ⏮️ `async`.
|
||||
|
||||
### 👀 `response_model=List[Note]`
|
||||
|
||||
⚫️ ⚙️ `typing.List`.
|
||||
|
||||
👈 📄 (& ✔, 🎻, ⛽) 🔢 💽, `list` `Note`Ⓜ.
|
||||
|
||||
## ✍ 🗒
|
||||
|
||||
✍ *➡ 🛠️ 🔢* ✍ 🗒:
|
||||
|
||||
```Python hl_lines="61-65"
|
||||
{!../../../docs_src/async_sql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! Note
|
||||
👀 👈 👥 🔗 ⏮️ 💽 ⚙️ `await`, *➡ 🛠️ 🔢* 📣 ⏮️ `async`.
|
||||
|
||||
### 🔃 `{**note.dict(), "id": last_record_id}`
|
||||
|
||||
`note` Pydantic `Note` 🎚.
|
||||
|
||||
`note.dict()` 📨 `dict` ⏮️ 🚮 💽, 🕳 💖:
|
||||
|
||||
```Python
|
||||
{
|
||||
"text": "Some note",
|
||||
"completed": False,
|
||||
}
|
||||
```
|
||||
|
||||
✋️ ⚫️ 🚫 ✔️ `id` 🏑.
|
||||
|
||||
👥 ✍ 🆕 `dict`, 👈 🔌 🔑-💲 👫 ⚪️➡️ `note.dict()` ⏮️:
|
||||
|
||||
```Python
|
||||
{**note.dict()}
|
||||
```
|
||||
|
||||
`**note.dict()` "unpacks" the key value pairs directly, so, `{**note.dict()}` would be, more or less, a copy of `note.dict()`.
|
||||
|
||||
& ⤴️, 👥 ↔ 👈 📁 `dict`, ❎ ➕1️⃣ 🔑-💲 👫: `"id": last_record_id`:
|
||||
|
||||
```Python
|
||||
{**note.dict(), "id": last_record_id}
|
||||
```
|
||||
|
||||
, 🏁 🏁 📨 🔜 🕳 💖:
|
||||
|
||||
```Python
|
||||
{
|
||||
"id": 1,
|
||||
"text": "Some note",
|
||||
"completed": False,
|
||||
}
|
||||
```
|
||||
|
||||
## ✅ ⚫️
|
||||
|
||||
👆 💪 📁 👉 📟, & 👀 🩺 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
📤 👆 💪 👀 🌐 👆 🛠️ 📄 & 🔗 ⏮️ ⚫️:
|
||||
|
||||
<img src="/img/tutorial/async-sql-databases/image01.png">
|
||||
|
||||
## 🌅 ℹ
|
||||
|
||||
👆 💪 ✍ 🌅 🔃 <a href="https://github.com/encode/databases" class="external-link" target="_blank">`encode/databases` 🚮 📂 📃</a>.
|
||||
92
docs/em/docs/advanced/async-tests.md
Normal file
92
docs/em/docs/advanced/async-tests.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# 🔁 💯
|
||||
|
||||
👆 ✔️ ⏪ 👀 ❔ 💯 👆 **FastAPI** 🈸 ⚙️ 🚚 `TestClient`. 🆙 🔜, 👆 ✔️ 🕴 👀 ❔ ✍ 🔁 💯, 🍵 ⚙️ `async` 🔢.
|
||||
|
||||
➖ 💪 ⚙️ 🔁 🔢 👆 💯 💪 ⚠, 🖼, 🕐❔ 👆 🔬 👆 💽 🔁. 🌈 👆 💚 💯 📨 📨 👆 FastAPI 🈸 & ⤴️ ✔ 👈 👆 👩💻 ⏪ ✍ ☑ 💽 💽, ⏪ ⚙️ 🔁 💽 🗃.
|
||||
|
||||
➡️ 👀 ❔ 👥 💪 ⚒ 👈 👷.
|
||||
|
||||
## pytest.mark.anyio
|
||||
|
||||
🚥 👥 💚 🤙 🔁 🔢 👆 💯, 👆 💯 🔢 ✔️ 🔁. AnyIO 🚚 👌 📁 👉, 👈 ✔ 👥 ✔ 👈 💯 🔢 🤙 🔁.
|
||||
|
||||
## 🇸🇲
|
||||
|
||||
🚥 👆 **FastAPI** 🈸 ⚙️ 😐 `def` 🔢 ↩️ `async def`, ⚫️ `async` 🈸 🔘.
|
||||
|
||||
`TestClient` 🔨 🎱 🔘 🤙 🔁 FastAPI 🈸 👆 😐 `def` 💯 🔢, ⚙️ 🐩 ✳. ✋️ 👈 🎱 🚫 👷 🚫🔜 🕐❔ 👥 ⚙️ ⚫️ 🔘 🔁 🔢. 🏃 👆 💯 🔁, 👥 💪 🙅♂ 📏 ⚙️ `TestClient` 🔘 👆 💯 🔢.
|
||||
|
||||
`TestClient` ⚓️ 🔛 <a href="https://www.python-httpx.org" class="external-link" target="_blank">🇸🇲</a>, & ↩️, 👥 💪 ⚙️ ⚫️ 🔗 💯 🛠️.
|
||||
|
||||
## 🖼
|
||||
|
||||
🙅 🖼, ➡️ 🤔 📁 📊 🎏 1️⃣ 🔬 [🦏 🈸](../tutorial/bigger-applications.md){.internal-link target=_blank} & [🔬](../tutorial/testing.md){.internal-link target=_blank}:
|
||||
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
│ └── test_main.py
|
||||
```
|
||||
|
||||
📁 `main.py` 🔜 ✔️:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/async_tests/main.py!}
|
||||
```
|
||||
|
||||
📁 `test_main.py` 🔜 ✔️ 💯 `main.py`, ⚫️ 💪 👀 💖 👉 🔜:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/async_tests/test_main.py!}
|
||||
```
|
||||
|
||||
## 🏃 ⚫️
|
||||
|
||||
👆 💪 🏃 👆 💯 🐌 📨:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pytest
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## ℹ
|
||||
|
||||
📑 `@pytest.mark.anyio` 💬 ✳ 👈 👉 💯 🔢 🔜 🤙 🔁:
|
||||
|
||||
```Python hl_lines="7"
|
||||
{!../../../docs_src/async_tests/test_main.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
🗒 👈 💯 🔢 🔜 `async def` ↩️ `def` ⏭ 🕐❔ ⚙️ `TestClient`.
|
||||
|
||||
⤴️ 👥 💪 ✍ `AsyncClient` ⏮️ 📱, & 📨 🔁 📨 ⚫️, ⚙️ `await`.
|
||||
|
||||
```Python hl_lines="9-10"
|
||||
{!../../../docs_src/async_tests/test_main.py!}
|
||||
```
|
||||
|
||||
👉 🌓:
|
||||
|
||||
```Python
|
||||
response = client.get('/')
|
||||
```
|
||||
|
||||
...👈 👥 ⚙️ ⚒ 👆 📨 ⏮️ `TestClient`.
|
||||
|
||||
!!! tip
|
||||
🗒 👈 👥 ⚙️ 🔁/⌛ ⏮️ 🆕 `AsyncClient` - 📨 🔁.
|
||||
|
||||
## 🎏 🔁 🔢 🤙
|
||||
|
||||
🔬 🔢 🔜 🔁, 👆 💪 🔜 🤙 (& `await`) 🎏 `async` 🔢 ↖️ ⚪️➡️ 📨 📨 👆 FastAPI 🈸 👆 💯, ⚫️❔ 👆 🔜 🤙 👫 🙆 🙆 👆 📟.
|
||||
|
||||
!!! tip
|
||||
🚥 👆 ⚔ `RuntimeError: Task attached to a different loop` 🕐❔ 🛠️ 🔁 🔢 🤙 👆 💯 (✅ 🕐❔ ⚙️ <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">✳ MotorClient</a>) 💭 🔗 🎚 👈 💪 🎉 ➰ 🕴 🏞 🔁 🔢, ✅ `'@app.on_event("startup")` ⏲.
|
||||
346
docs/em/docs/advanced/behind-a-proxy.md
Normal file
346
docs/em/docs/advanced/behind-a-proxy.md
Normal file
@@ -0,0 +1,346 @@
|
||||
# ⛅ 🗳
|
||||
|
||||
⚠, 👆 5️⃣📆 💪 ⚙️ **🗳** 💽 💖 Traefik ⚖️ 👌 ⏮️ 📳 👈 🚮 ➕ ➡ 🔡 👈 🚫 👀 👆 🈸.
|
||||
|
||||
👫 💼 👆 💪 ⚙️ `root_path` 🔗 👆 🈸.
|
||||
|
||||
`root_path` 🛠️ 🚚 🔫 🔧 (👈 FastAPI 🏗 🔛, 🔘 💃).
|
||||
|
||||
`root_path` ⚙️ 🍵 👫 🎯 💼.
|
||||
|
||||
& ⚫️ ⚙️ 🔘 🕐❔ 🗜 🎧-🈸.
|
||||
|
||||
## 🗳 ⏮️ 🎞 ➡ 🔡
|
||||
|
||||
✔️ 🗳 ⏮️ 🎞 ➡ 🔡, 👉 💼, ⛓ 👈 👆 💪 📣 ➡ `/app` 👆 📟, ✋️ ⤴️, 👆 🚮 🧽 🔛 🔝 (🗳) 👈 🔜 🚮 👆 **FastAPI** 🈸 🔽 ➡ 💖 `/api/v1`.
|
||||
|
||||
👉 💼, ⏮️ ➡ `/app` 🔜 🤙 🍦 `/api/v1/app`.
|
||||
|
||||
✋️ 🌐 👆 📟 ✍ 🤔 📤 `/app`.
|
||||
|
||||
& 🗳 🔜 **"❎"** **➡ 🔡** 🔛 ✈ ⏭ 📶 📨 Uvicorn, 🚧 👆 🈸 🤔 👈 ⚫️ 🍦 `/app`, 👈 👆 🚫 ✔️ ℹ 🌐 👆 📟 🔌 🔡 `/api/v1`.
|
||||
|
||||
🆙 📥, 🌐 🔜 👷 🛎.
|
||||
|
||||
✋️ ⤴️, 🕐❔ 👆 📂 🛠️ 🩺 🎚 (🕸), ⚫️ 🔜 ⌛ 🤚 🗄 🔗 `/openapi.json`, ↩️ `/api/v1/openapi.json`.
|
||||
|
||||
, 🕸 (👈 🏃 🖥) 🔜 🔄 🏆 `/openapi.json` & 🚫🔜 💪 🤚 🗄 🔗.
|
||||
|
||||
↩️ 👥 ✔️ 🗳 ⏮️ ➡ 🔡 `/api/v1` 👆 📱, 🕸 💪 ☕ 🗄 🔗 `/api/v1/openapi.json`.
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
browser("Browser")
|
||||
proxy["Proxy on http://0.0.0.0:9999/api/v1/app"]
|
||||
server["Server on http://127.0.0.1:8000/app"]
|
||||
|
||||
browser --> proxy
|
||||
proxy --> server
|
||||
```
|
||||
|
||||
!!! tip
|
||||
📢 `0.0.0.0` 🛎 ⚙️ ⛓ 👈 📋 👂 🔛 🌐 📢 💪 👈 🎰/💽.
|
||||
|
||||
🩺 🎚 🔜 💪 🗄 🔗 📣 👈 👉 🛠️ `server` 🔎 `/api/v1` (⛅ 🗳). 🖼:
|
||||
|
||||
```JSON hl_lines="4-8"
|
||||
{
|
||||
"openapi": "3.0.2",
|
||||
// More stuff here
|
||||
"servers": [
|
||||
{
|
||||
"url": "/api/v1"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
// More stuff here
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
👉 🖼, "🗳" 💪 🕳 💖 **Traefik**. & 💽 🔜 🕳 💖 **Uvicorn**, 🏃♂ 👆 FastAPI 🈸.
|
||||
|
||||
### 🚚 `root_path`
|
||||
|
||||
🏆 👉, 👆 💪 ⚙️ 📋 ⏸ 🎛 `--root-path` 💖:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --root-path /api/v1
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
🚥 👆 ⚙️ Hypercorn, ⚫️ ✔️ 🎛 `--root-path`.
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
🔫 🔧 🔬 `root_path` 👉 ⚙️ 💼.
|
||||
|
||||
& `--root-path` 📋 ⏸ 🎛 🚚 👈 `root_path`.
|
||||
|
||||
### ✅ ⏮️ `root_path`
|
||||
|
||||
👆 💪 🤚 ⏮️ `root_path` ⚙️ 👆 🈸 🔠 📨, ⚫️ 🍕 `scope` 📖 (👈 🍕 🔫 🔌).
|
||||
|
||||
📥 👥 ✅ ⚫️ 📧 🎦 🎯.
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!../../../docs_src/behind_a_proxy/tutorial001.py!}
|
||||
```
|
||||
|
||||
⤴️, 🚥 👆 ▶️ Uvicorn ⏮️:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --root-path /api/v1
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
📨 🔜 🕳 💖:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"message": "Hello World",
|
||||
"root_path": "/api/v1"
|
||||
}
|
||||
```
|
||||
|
||||
### ⚒ `root_path` FastAPI 📱
|
||||
|
||||
👐, 🚥 👆 🚫 ✔️ 🌌 🚚 📋 ⏸ 🎛 💖 `--root-path` ⚖️ 🌓, 👆 💪 ⚒ `root_path` 🔢 🕐❔ 🏗 👆 FastAPI 📱:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/behind_a_proxy/tutorial002.py!}
|
||||
```
|
||||
|
||||
🚶♀️ `root_path` `FastAPI` 🔜 🌓 🚶♀️ `--root-path` 📋 ⏸ 🎛 Uvicorn ⚖️ Hypercorn.
|
||||
|
||||
### 🔃 `root_path`
|
||||
|
||||
✔️ 🤯 👈 💽 (Uvicorn) 🏆 🚫 ⚙️ 👈 `root_path` 🕳 🙆 🌘 🚶♀️ ⚫️ 📱.
|
||||
|
||||
✋️ 🚥 👆 🚶 ⏮️ 👆 🖥 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000/app</a> 👆 🔜 👀 😐 📨:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"message": "Hello World",
|
||||
"root_path": "/api/v1"
|
||||
}
|
||||
```
|
||||
|
||||
, ⚫️ 🏆 🚫 ⌛ 🔐 `http://127.0.0.1:8000/api/v1/app`.
|
||||
|
||||
Uvicorn 🔜 ⌛ 🗳 🔐 Uvicorn `http://127.0.0.1:8000/app`, & ⤴️ ⚫️ 🔜 🗳 🎯 🚮 ➕ `/api/v1` 🔡 🔛 🔝.
|
||||
|
||||
## 🔃 🗳 ⏮️ 🎞 ➡ 🔡
|
||||
|
||||
✔️ 🤯 👈 🗳 ⏮️ 🎞 ➡ 🔡 🕴 1️⃣ 🌌 🔗 ⚫️.
|
||||
|
||||
🎲 📚 💼 🔢 🔜 👈 🗳 🚫 ✔️ 🏚 ➡ 🔡.
|
||||
|
||||
💼 💖 👈 (🍵 🎞 ➡ 🔡), 🗳 🔜 👂 🔛 🕳 💖 `https://myawesomeapp.com`, & ⤴️ 🚥 🖥 🚶 `https://myawesomeapp.com/api/v1/app` & 👆 💽 (✅ Uvicorn) 👂 🔛 `http://127.0.0.1:8000` 🗳 (🍵 🎞 ➡ 🔡) 🔜 🔐 Uvicorn 🎏 ➡: `http://127.0.0.1:8000/api/v1/app`.
|
||||
|
||||
## 🔬 🌐 ⏮️ Traefik
|
||||
|
||||
👆 💪 💪 🏃 🥼 🌐 ⏮️ 🎞 ➡ 🔡 ⚙️ <a href="https://docs.traefik.io/" class="external-link" target="_blank">Traefik</a>.
|
||||
|
||||
<a href="https://github.com/containous/traefik/releases" class="external-link" target="_blank">⏬ Traefik</a>, ⚫️ 👁 💱, 👆 💪 ⚗ 🗜 📁 & 🏃 ⚫️ 🔗 ⚪️➡️ 📶.
|
||||
|
||||
⤴️ ✍ 📁 `traefik.toml` ⏮️:
|
||||
|
||||
```TOML hl_lines="3"
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":9999"
|
||||
|
||||
[providers]
|
||||
[providers.file]
|
||||
filename = "routes.toml"
|
||||
```
|
||||
|
||||
👉 💬 Traefik 👂 🔛 ⛴ 9️⃣9️⃣9️⃣9️⃣ & ⚙️ ➕1️⃣ 📁 `routes.toml`.
|
||||
|
||||
!!! tip
|
||||
👥 ⚙️ ⛴ 9️⃣9️⃣9️⃣9️⃣ ↩️ 🐩 🇺🇸🔍 ⛴ 8️⃣0️⃣ 👈 👆 🚫 ✔️ 🏃 ⚫️ ⏮️ 📡 (`sudo`) 😌.
|
||||
|
||||
🔜 ✍ 👈 🎏 📁 `routes.toml`:
|
||||
|
||||
```TOML hl_lines="5 12 20"
|
||||
[http]
|
||||
[http.middlewares]
|
||||
|
||||
[http.middlewares.api-stripprefix.stripPrefix]
|
||||
prefixes = ["/api/v1"]
|
||||
|
||||
[http.routers]
|
||||
|
||||
[http.routers.app-http]
|
||||
entryPoints = ["http"]
|
||||
service = "app"
|
||||
rule = "PathPrefix(`/api/v1`)"
|
||||
middlewares = ["api-stripprefix"]
|
||||
|
||||
[http.services]
|
||||
|
||||
[http.services.app]
|
||||
[http.services.app.loadBalancer]
|
||||
[[http.services.app.loadBalancer.servers]]
|
||||
url = "http://127.0.0.1:8000"
|
||||
```
|
||||
|
||||
👉 📁 🔗 Traefik ⚙️ ➡ 🔡 `/api/v1`.
|
||||
|
||||
& ⤴️ ⚫️ 🔜 ❎ 🚮 📨 👆 Uvicorn 🏃♂ 🔛 `http://127.0.0.1:8000`.
|
||||
|
||||
🔜 ▶️ Traefik:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ ./traefik --configFile=traefik.toml
|
||||
|
||||
INFO[0000] Configuration loaded from file: /home/user/awesomeapi/traefik.toml
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
& 🔜 ▶️ 👆 📱 ⏮️ Uvicorn, ⚙️ `--root-path` 🎛:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --root-path /api/v1
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### ✅ 📨
|
||||
|
||||
🔜, 🚥 👆 🚶 📛 ⏮️ ⛴ Uvicorn: <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>, 👆 🔜 👀 😐 📨:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"message": "Hello World",
|
||||
"root_path": "/api/v1"
|
||||
}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👀 👈 ✋️ 👆 🔐 ⚫️ `http://127.0.0.1:8000/app` ⚫️ 🎦 `root_path` `/api/v1`, ✊ ⚪️➡️ 🎛 `--root-path`.
|
||||
|
||||
& 🔜 📂 📛 ⏮️ ⛴ Traefik, ✅ ➡ 🔡: <a href="http://127.0.0.1:9999/api/v1/app" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/app</a>.
|
||||
|
||||
👥 🤚 🎏 📨:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"message": "Hello World",
|
||||
"root_path": "/api/v1"
|
||||
}
|
||||
```
|
||||
|
||||
✋️ 👉 🕰 📛 ⏮️ 🔡 ➡ 🚚 🗳: `/api/v1`.
|
||||
|
||||
↗️, 💭 📥 👈 👱 🔜 🔐 📱 🔘 🗳, ⏬ ⏮️ ➡ 🔡 `/app/v1` "☑" 1️⃣.
|
||||
|
||||
& ⏬ 🍵 ➡ 🔡 (`http://127.0.0.1:8000/app`), 🚚 Uvicorn 🔗, 🔜 🎯 _🗳_ (Traefik) 🔐 ⚫️.
|
||||
|
||||
👈 🎦 ❔ 🗳 (Traefik) ⚙️ ➡ 🔡 & ❔ 💽 (Uvicorn) ⚙️ `root_path` ⚪️➡️ 🎛 `--root-path`.
|
||||
|
||||
### ✅ 🩺 🎚
|
||||
|
||||
✋️ 📥 🎊 🍕. 👶
|
||||
|
||||
"🛂" 🌌 🔐 📱 🔜 🔘 🗳 ⏮️ ➡ 🔡 👈 👥 🔬. , 👥 🔜 ⌛, 🚥 👆 🔄 🩺 🎚 🍦 Uvicorn 🔗, 🍵 ➡ 🔡 📛, ⚫️ 🏆 🚫 👷, ↩️ ⚫️ ⌛ 🔐 🔘 🗳.
|
||||
|
||||
👆 💪 ✅ ⚫️ <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>:
|
||||
|
||||
<img src="/img/tutorial/behind-a-proxy/image01.png">
|
||||
|
||||
✋️ 🚥 👥 🔐 🩺 🎚 "🛂" 📛 ⚙️ 🗳 ⏮️ ⛴ `9999`, `/api/v1/docs`, ⚫️ 👷 ☑ ❗ 👶
|
||||
|
||||
👆 💪 ✅ ⚫️ <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a>:
|
||||
|
||||
<img src="/img/tutorial/behind-a-proxy/image02.png">
|
||||
|
||||
▶️️ 👥 💚 ⚫️. 👶 👶
|
||||
|
||||
👉 ↩️ FastAPI ⚙️ 👉 `root_path` ✍ 🔢 `server` 🗄 ⏮️ 📛 🚚 `root_path`.
|
||||
|
||||
## 🌖 💽
|
||||
|
||||
!!! warning
|
||||
👉 🌅 🏧 ⚙️ 💼. 💭 🆓 🚶 ⚫️.
|
||||
|
||||
🔢, **FastAPI** 🔜 ✍ `server` 🗄 🔗 ⏮️ 📛 `root_path`.
|
||||
|
||||
✋️ 👆 💪 🚚 🎏 🎛 `servers`, 🖼 🚥 👆 💚 *🎏* 🩺 🎚 🔗 ⏮️ 🏗 & 🏭 🌐.
|
||||
|
||||
🚥 👆 🚶♀️ 🛃 📇 `servers` & 📤 `root_path` (↩️ 👆 🛠️ 👨❤👨 ⛅ 🗳), **FastAPI** 🔜 📩 "💽" ⏮️ 👉 `root_path` ▶️ 📇.
|
||||
|
||||
🖼:
|
||||
|
||||
```Python hl_lines="4-7"
|
||||
{!../../../docs_src/behind_a_proxy/tutorial003.py!}
|
||||
```
|
||||
|
||||
🔜 🏗 🗄 🔗 💖:
|
||||
|
||||
```JSON hl_lines="5-7"
|
||||
{
|
||||
"openapi": "3.0.2",
|
||||
// More stuff here
|
||||
"servers": [
|
||||
{
|
||||
"url": "/api/v1"
|
||||
},
|
||||
{
|
||||
"url": "https://stag.example.com",
|
||||
"description": "Staging environment"
|
||||
},
|
||||
{
|
||||
"url": "https://prod.example.com",
|
||||
"description": "Production environment"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
// More stuff here
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👀 🚘-🏗 💽 ⏮️ `url` 💲 `/api/v1`, ✊ ⚪️➡️ `root_path`.
|
||||
|
||||
🩺 🎚 <a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a> ⚫️ 🔜 👀 💖:
|
||||
|
||||
<img src="/img/tutorial/behind-a-proxy/image03.png">
|
||||
|
||||
!!! tip
|
||||
🩺 🎚 🔜 🔗 ⏮️ 💽 👈 👆 🖊.
|
||||
|
||||
### ❎ 🏧 💽 ⚪️➡️ `root_path`
|
||||
|
||||
🚥 👆 🚫 💚 **FastAPI** 🔌 🏧 💽 ⚙️ `root_path`, 👆 💪 ⚙️ 🔢 `root_path_in_servers=False`:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/behind_a_proxy/tutorial004.py!}
|
||||
```
|
||||
|
||||
& ⤴️ ⚫️ 🏆 🚫 🔌 ⚫️ 🗄 🔗.
|
||||
|
||||
## 🗜 🎧-🈸
|
||||
|
||||
🚥 👆 💪 🗻 🎧-🈸 (🔬 [🎧 🈸 - 🗻](./sub-applications.md){.internal-link target=_blank}) ⏪ ⚙️ 🗳 ⏮️ `root_path`, 👆 💪 ⚫️ 🛎, 👆 🔜 ⌛.
|
||||
|
||||
FastAPI 🔜 🔘 ⚙️ `root_path` 🎆, ⚫️ 🔜 👷. 👶
|
||||
58
docs/em/docs/advanced/conditional-openapi.md
Normal file
58
docs/em/docs/advanced/conditional-openapi.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# 🎲 🗄
|
||||
|
||||
🚥 👆 💪, 👆 💪 ⚙️ ⚒ & 🌐 🔢 🔗 🗄 ✔ ⚓️ 🔛 🌐, & ❎ ⚫️ 🍕.
|
||||
|
||||
## 🔃 💂♂, 🔗, & 🩺
|
||||
|
||||
🕵♂ 👆 🧾 👩💻 🔢 🏭 *🚫🔜 🚫* 🌌 🛡 👆 🛠️.
|
||||
|
||||
👈 🚫 🚮 🙆 ➕ 💂♂ 👆 🛠️, *➡ 🛠️* 🔜 💪 🌐❔ 👫.
|
||||
|
||||
🚥 📤 💂♂ ⚠ 👆 📟, ⚫️ 🔜 🔀.
|
||||
|
||||
🕵♂ 🧾 ⚒ ⚫️ 🌅 ⚠ 🤔 ❔ 🔗 ⏮️ 👆 🛠️, & 💪 ⚒ ⚫️ 🌅 ⚠ 👆 ℹ ⚫️ 🏭. ⚫️ 💪 🤔 🎯 📨 <a href="https://en.wikipedia.org/wiki/Security_through_obscurity" class="external-link" target="_blank">💂♂ 🔘 🌌</a>.
|
||||
|
||||
🚥 👆 💚 🔐 👆 🛠️, 📤 📚 👍 👜 👆 💪, 🖼:
|
||||
|
||||
* ⚒ 💭 👆 ✔️ 👍 🔬 Pydantic 🏷 👆 📨 💪 & 📨.
|
||||
* 🔗 🙆 ✔ ✔ & 🔑 ⚙️ 🔗.
|
||||
* 🙅 🏪 🔢 🔐, 🕴 🔐#️⃣.
|
||||
* 🛠️ & ⚙️ 👍-💭 🔐 🧰, 💖 🇸🇲 & 🥙 🤝, ♒️.
|
||||
* 🚮 🌅 🧽 ✔ 🎛 ⏮️ Oauth2️⃣ ↔ 🌐❔ 💪.
|
||||
* ...♒️.
|
||||
|
||||
👐, 👆 5️⃣📆 ✔️ 📶 🎯 ⚙️ 💼 🌐❔ 👆 🤙 💪 ❎ 🛠️ 🩺 🌐 (✅ 🏭) ⚖️ ⚓️ 🔛 📳 ⚪️➡️ 🌐 🔢.
|
||||
|
||||
## 🎲 🗄 ⚪️➡️ ⚒ & 🇨🇻 {
|
||||
|
||||
👆 💪 💪 ⚙️ 🎏 Pydantic ⚒ 🔗 👆 🏗 🗄 & 🩺 ⚜.
|
||||
|
||||
🖼:
|
||||
|
||||
```Python hl_lines="6 11"
|
||||
{!../../../docs_src/conditional_openapi/tutorial001.py!}
|
||||
```
|
||||
|
||||
📥 👥 📣 ⚒ `openapi_url` ⏮️ 🎏 🔢 `"/openapi.json"`.
|
||||
|
||||
& ⤴️ 👥 ⚙️ ⚫️ 🕐❔ 🏗 `FastAPI` 📱.
|
||||
|
||||
⤴️ 👆 💪 ❎ 🗄 (✅ 🎚 🩺) ⚒ 🌐 🔢 `OPENAPI_URL` 🛁 🎻, 💖:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ OPENAPI_URL= uvicorn main:app
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
⤴️ 🚥 👆 🚶 📛 `/openapi.json`, `/docs`, ⚖️ `/redoc` 👆 🔜 🤚 `404 Not Found` ❌ 💖:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"detail": "Not Found"
|
||||
}
|
||||
```
|
||||
109
docs/em/docs/advanced/custom-request-and-route.md
Normal file
109
docs/em/docs/advanced/custom-request-and-route.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# 🛃 📨 & APIRoute 🎓
|
||||
|
||||
💼, 👆 5️⃣📆 💚 🔐 ⚛ ⚙️ `Request` & `APIRoute` 🎓.
|
||||
|
||||
🎯, 👉 5️⃣📆 👍 🎛 ⚛ 🛠️.
|
||||
|
||||
🖼, 🚥 👆 💚 ✍ ⚖️ 🔬 📨 💪 ⏭ ⚫️ 🛠️ 👆 🈸.
|
||||
|
||||
!!! danger
|
||||
👉 "🏧" ⚒.
|
||||
|
||||
🚥 👆 ▶️ ⏮️ **FastAPI** 👆 💪 💚 🚶 👉 📄.
|
||||
|
||||
## ⚙️ 💼
|
||||
|
||||
⚙️ 💼 🔌:
|
||||
|
||||
* 🏭 🚫-🎻 📨 💪 🎻 (✅ <a href="https://msgpack.org/index.html" class="external-link" target="_blank">`msgpack`</a>).
|
||||
* 🗜 🗜-🗜 📨 💪.
|
||||
* 🔁 🚨 🌐 📨 💪.
|
||||
|
||||
## 🚚 🛃 📨 💪 🔢
|
||||
|
||||
➡️ 👀 ❔ ⚒ ⚙️ 🛃 `Request` 🏿 🗜 🗜 📨.
|
||||
|
||||
& `APIRoute` 🏿 ⚙️ 👈 🛃 📨 🎓.
|
||||
|
||||
### ✍ 🛃 `GzipRequest` 🎓
|
||||
|
||||
!!! tip
|
||||
👉 🧸 🖼 🎦 ❔ ⚫️ 👷, 🚥 👆 💪 🗜 🐕🦺, 👆 💪 ⚙️ 🚚 [`GzipMiddleware`](./middleware.md#gzipmiddleware){.internal-link target=_blank}.
|
||||
|
||||
🥇, 👥 ✍ `GzipRequest` 🎓, ❔ 🔜 📁 `Request.body()` 👩🔬 🗜 💪 🔍 ☑ 🎚.
|
||||
|
||||
🚥 📤 🙅♂ `gzip` 🎚, ⚫️ 🔜 🚫 🔄 🗜 💪.
|
||||
|
||||
👈 🌌, 🎏 🛣 🎓 💪 🍵 🗜 🗜 ⚖️ 🗜 📨.
|
||||
|
||||
```Python hl_lines="8-15"
|
||||
{!../../../docs_src/custom_request_and_route/tutorial001.py!}
|
||||
```
|
||||
|
||||
### ✍ 🛃 `GzipRoute` 🎓
|
||||
|
||||
⏭, 👥 ✍ 🛃 🏿 `fastapi.routing.APIRoute` 👈 🔜 ⚒ ⚙️ `GzipRequest`.
|
||||
|
||||
👉 🕰, ⚫️ 🔜 📁 👩🔬 `APIRoute.get_route_handler()`.
|
||||
|
||||
👉 👩🔬 📨 🔢. & 👈 🔢 ⚫️❔ 🔜 📨 📨 & 📨 📨.
|
||||
|
||||
📥 👥 ⚙️ ⚫️ ✍ `GzipRequest` ⚪️➡️ ⏮️ 📨.
|
||||
|
||||
```Python hl_lines="18-26"
|
||||
{!../../../docs_src/custom_request_and_route/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
`Request` ✔️ `request.scope` 🔢, 👈 🐍 `dict` ⚗ 🗃 🔗 📨.
|
||||
|
||||
`Request` ✔️ `request.receive`, 👈 🔢 "📨" 💪 📨.
|
||||
|
||||
`scope` `dict` & `receive` 🔢 👯♂️ 🍕 🔫 🔧.
|
||||
|
||||
& 👈 2️⃣ 👜, `scope` & `receive`, ⚫️❔ 💪 ✍ 🆕 `Request` 👐.
|
||||
|
||||
💡 🌅 🔃 `Request` ✅ <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">💃 🩺 🔃 📨</a>.
|
||||
|
||||
🕴 👜 🔢 📨 `GzipRequest.get_route_handler` 🔨 🎏 🗜 `Request` `GzipRequest`.
|
||||
|
||||
🔨 👉, 👆 `GzipRequest` 🔜 ✊ 💅 🗜 📊 (🚥 💪) ⏭ 🚶♀️ ⚫️ 👆 *➡ 🛠️*.
|
||||
|
||||
⏮️ 👈, 🌐 🏭 ⚛ 🎏.
|
||||
|
||||
✋️ ↩️ 👆 🔀 `GzipRequest.body`, 📨 💪 🔜 🔁 🗜 🕐❔ ⚫️ 📐 **FastAPI** 🕐❔ 💪.
|
||||
|
||||
## 🔐 📨 💪 ⚠ 🐕🦺
|
||||
|
||||
!!! tip
|
||||
❎ 👉 🎏 ⚠, ⚫️ 🎲 📚 ⏩ ⚙️ `body` 🛃 🐕🦺 `RequestValidationError` ([🚚 ❌](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank}).
|
||||
|
||||
✋️ 👉 🖼 ☑ & ⚫️ 🎦 ❔ 🔗 ⏮️ 🔗 🦲.
|
||||
|
||||
👥 💪 ⚙️ 👉 🎏 🎯 🔐 📨 💪 ⚠ 🐕🦺.
|
||||
|
||||
🌐 👥 💪 🍵 📨 🔘 `try`/`except` 🍫:
|
||||
|
||||
```Python hl_lines="13 15"
|
||||
{!../../../docs_src/custom_request_and_route/tutorial002.py!}
|
||||
```
|
||||
|
||||
🚥 ⚠ 📉, `Request` 👐 🔜 ↔, 👥 💪 ✍ & ⚒ ⚙️ 📨 💪 🕐❔ 🚚 ❌:
|
||||
|
||||
```Python hl_lines="16-18"
|
||||
{!../../../docs_src/custom_request_and_route/tutorial002.py!}
|
||||
```
|
||||
|
||||
## 🛃 `APIRoute` 🎓 📻
|
||||
|
||||
👆 💪 ⚒ `route_class` 🔢 `APIRouter`:
|
||||
|
||||
```Python hl_lines="26"
|
||||
{!../../../docs_src/custom_request_and_route/tutorial003.py!}
|
||||
```
|
||||
|
||||
👉 🖼, *➡ 🛠️* 🔽 `router` 🔜 ⚙️ 🛃 `TimedRoute` 🎓, & 🔜 ✔️ ➕ `X-Response-Time` 🎚 📨 ⏮️ 🕰 ⚫️ ✊ 🏗 📨:
|
||||
|
||||
```Python hl_lines="13-20"
|
||||
{!../../../docs_src/custom_request_and_route/tutorial003.py!}
|
||||
```
|
||||
300
docs/em/docs/advanced/custom-response.md
Normal file
300
docs/em/docs/advanced/custom-response.md
Normal file
@@ -0,0 +1,300 @@
|
||||
# 🛃 📨 - 🕸, 🎏, 📁, 🎏
|
||||
|
||||
🔢, **FastAPI** 🔜 📨 📨 ⚙️ `JSONResponse`.
|
||||
|
||||
👆 💪 🔐 ⚫️ 🛬 `Response` 🔗 👀 [📨 📨 🔗](response-directly.md){.internal-link target=_blank}.
|
||||
|
||||
✋️ 🚥 👆 📨 `Response` 🔗, 📊 🏆 🚫 🔁 🗜, & 🧾 🏆 🚫 🔁 🏗 (🖼, 🔌 🎯 "📻 🆎", 🇺🇸🔍 🎚 `Content-Type` 🍕 🏗 🗄).
|
||||
|
||||
✋️ 👆 💪 📣 `Response` 👈 👆 💚 ⚙️, *➡ 🛠️ 👨🎨*.
|
||||
|
||||
🎚 👈 👆 📨 ⚪️➡️ 👆 *➡ 🛠️ 🔢* 🔜 🚮 🔘 👈 `Response`.
|
||||
|
||||
& 🚥 👈 `Response` ✔️ 🎻 📻 🆎 (`application/json`), 💖 💼 ⏮️ `JSONResponse` & `UJSONResponse`, 💽 👆 📨 🔜 🔁 🗜 (& ⛽) ⏮️ 🙆 Pydantic `response_model` 👈 👆 📣 *➡ 🛠️ 👨🎨*.
|
||||
|
||||
!!! note
|
||||
🚥 👆 ⚙️ 📨 🎓 ⏮️ 🙅♂ 📻 🆎, FastAPI 🔜 ⌛ 👆 📨 ✔️ 🙅♂ 🎚, ⚫️ 🔜 🚫 📄 📨 📁 🚮 🏗 🗄 🩺.
|
||||
|
||||
## ⚙️ `ORJSONResponse`
|
||||
|
||||
🖼, 🚥 👆 ✊ 🎭, 👆 💪 ❎ & ⚙️ <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a> & ⚒ 📨 `ORJSONResponse`.
|
||||
|
||||
🗄 `Response` 🎓 (🎧-🎓) 👆 💚 ⚙️ & 📣 ⚫️ *➡ 🛠️ 👨🎨*.
|
||||
|
||||
⭕ 📨, 📨 `Response` 🔗 🌅 ⏩ 🌘 🛬 📖.
|
||||
|
||||
👉 ↩️ 🔢, FastAPI 🔜 ✔ 🔠 🏬 🔘 & ⚒ 💭 ⚫️ 🎻 ⏮️ 🎻, ⚙️ 🎏 [🎻 🔗 🔢](../tutorial/encoder.md){.internal-link target=_blank} 🔬 🔰. 👉 ⚫️❔ ✔ 👆 📨 **❌ 🎚**, 🖼 💽 🏷.
|
||||
|
||||
✋️ 🚥 👆 🎯 👈 🎚 👈 👆 🛬 **🎻 ⏮️ 🎻**, 👆 💪 🚶♀️ ⚫️ 🔗 📨 🎓 & ❎ ➕ 🌥 👈 FastAPI 🔜 ✔️ 🚶♀️ 👆 📨 🎚 🔘 `jsonable_encoder` ⏭ 🚶♀️ ⚫️ 📨 🎓.
|
||||
|
||||
```Python hl_lines="2 7"
|
||||
{!../../../docs_src/custom_response/tutorial001b.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
🔢 `response_class` 🔜 ⚙️ 🔬 "📻 🆎" 📨.
|
||||
|
||||
👉 💼, 🇺🇸🔍 🎚 `Content-Type` 🔜 ⚒ `application/json`.
|
||||
|
||||
& ⚫️ 🔜 📄 ✅ 🗄.
|
||||
|
||||
!!! tip
|
||||
`ORJSONResponse` ⏳ 🕴 💪 FastAPI, 🚫 💃.
|
||||
|
||||
## 🕸 📨
|
||||
|
||||
📨 📨 ⏮️ 🕸 🔗 ⚪️➡️ **FastAPI**, ⚙️ `HTMLResponse`.
|
||||
|
||||
* 🗄 `HTMLResponse`.
|
||||
* 🚶♀️ `HTMLResponse` 🔢 `response_class` 👆 *➡ 🛠️ 👨🎨*.
|
||||
|
||||
```Python hl_lines="2 7"
|
||||
{!../../../docs_src/custom_response/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
🔢 `response_class` 🔜 ⚙️ 🔬 "📻 🆎" 📨.
|
||||
|
||||
👉 💼, 🇺🇸🔍 🎚 `Content-Type` 🔜 ⚒ `text/html`.
|
||||
|
||||
& ⚫️ 🔜 📄 ✅ 🗄.
|
||||
|
||||
### 📨 `Response`
|
||||
|
||||
👀 [📨 📨 🔗](response-directly.md){.internal-link target=_blank}, 👆 💪 🔐 📨 🔗 👆 *➡ 🛠️*, 🛬 ⚫️.
|
||||
|
||||
🎏 🖼 ⚪️➡️ 🔛, 🛬 `HTMLResponse`, 💪 👀 💖:
|
||||
|
||||
```Python hl_lines="2 7 19"
|
||||
{!../../../docs_src/custom_response/tutorial003.py!}
|
||||
```
|
||||
|
||||
!!! warning
|
||||
`Response` 📨 🔗 👆 *➡ 🛠️ 🔢* 🏆 🚫 📄 🗄 (🖼, `Content-Type` 🏆 🚫 📄) & 🏆 🚫 ⭐ 🏧 🎓 🩺.
|
||||
|
||||
!!! info
|
||||
↗️, ☑ `Content-Type` 🎚, 👔 📟, ♒️, 🔜 👟 ⚪️➡️ `Response` 🎚 👆 📨.
|
||||
|
||||
### 📄 🗄 & 🔐 `Response`
|
||||
|
||||
🚥 👆 💚 🔐 📨 ⚪️➡️ 🔘 🔢 ✋️ 🎏 🕰 📄 "📻 🆎" 🗄, 👆 💪 ⚙️ `response_class` 🔢 & 📨 `Response` 🎚.
|
||||
|
||||
`response_class` 🔜 ⤴️ ⚙️ 🕴 📄 🗄 *➡ 🛠️*, ✋️ 👆 `Response` 🔜 ⚙️.
|
||||
|
||||
#### 📨 `HTMLResponse` 🔗
|
||||
|
||||
🖼, ⚫️ 💪 🕳 💖:
|
||||
|
||||
```Python hl_lines="7 21 23"
|
||||
{!../../../docs_src/custom_response/tutorial004.py!}
|
||||
```
|
||||
|
||||
👉 🖼, 🔢 `generate_html_response()` ⏪ 🏗 & 📨 `Response` ↩️ 🛬 🕸 `str`.
|
||||
|
||||
🛬 🏁 🤙 `generate_html_response()`, 👆 ⏪ 🛬 `Response` 👈 🔜 🔐 🔢 **FastAPI** 🎭.
|
||||
|
||||
✋️ 👆 🚶♀️ `HTMLResponse` `response_class` 💁♂️, **FastAPI** 🔜 💭 ❔ 📄 ⚫️ 🗄 & 🎓 🩺 🕸 ⏮️ `text/html`:
|
||||
|
||||
<img src="/img/tutorial/custom-response/image01.png">
|
||||
|
||||
## 💪 📨
|
||||
|
||||
📥 💪 📨.
|
||||
|
||||
✔️ 🤯 👈 👆 💪 ⚙️ `Response` 📨 🕳 🙆, ⚖️ ✍ 🛃 🎧-🎓.
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
👆 💪 ⚙️ `from starlette.responses import HTMLResponse`.
|
||||
|
||||
**FastAPI** 🚚 🎏 `starlette.responses` `fastapi.responses` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃.
|
||||
|
||||
### `Response`
|
||||
|
||||
👑 `Response` 🎓, 🌐 🎏 📨 😖 ⚪️➡️ ⚫️.
|
||||
|
||||
👆 💪 📨 ⚫️ 🔗.
|
||||
|
||||
⚫️ 🚫 📄 🔢:
|
||||
|
||||
* `content` - `str` ⚖️ `bytes`.
|
||||
* `status_code` - `int` 🇺🇸🔍 👔 📟.
|
||||
* `headers` - `dict` 🎻.
|
||||
* `media_type` - `str` 🤝 📻 🆎. 🤶 Ⓜ. `"text/html"`.
|
||||
|
||||
FastAPI (🤙 💃) 🔜 🔁 🔌 🎚-📐 🎚. ⚫️ 🔜 🔌 🎚-🆎 🎚, ⚓️ 🔛 = & 🔁 = ✍ 🆎.
|
||||
|
||||
```Python hl_lines="1 18"
|
||||
{!../../../docs_src/response_directly/tutorial002.py!}
|
||||
```
|
||||
|
||||
### `HTMLResponse`
|
||||
|
||||
✊ ✍ ⚖️ 🔢 & 📨 🕸 📨, 👆 ✍ 🔛.
|
||||
|
||||
### `PlainTextResponse`
|
||||
|
||||
✊ ✍ ⚖️ 🔢 & 📨 ✅ ✍ 📨.
|
||||
|
||||
```Python hl_lines="2 7 9"
|
||||
{!../../../docs_src/custom_response/tutorial005.py!}
|
||||
```
|
||||
|
||||
### `JSONResponse`
|
||||
|
||||
✊ 💽 & 📨 `application/json` 🗜 📨.
|
||||
|
||||
👉 🔢 📨 ⚙️ **FastAPI**, 👆 ✍ 🔛.
|
||||
|
||||
### `ORJSONResponse`
|
||||
|
||||
⏩ 🎛 🎻 📨 ⚙️ <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>, 👆 ✍ 🔛.
|
||||
|
||||
### `UJSONResponse`
|
||||
|
||||
🎛 🎻 📨 ⚙️ <a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>.
|
||||
|
||||
!!! warning
|
||||
`ujson` 🌘 💛 🌘 🐍 🏗-🛠️ ❔ ⚫️ 🍵 📐-💼.
|
||||
|
||||
```Python hl_lines="2 7"
|
||||
{!../../../docs_src/custom_response/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
⚫️ 💪 👈 `ORJSONResponse` 💪 ⏩ 🎛.
|
||||
|
||||
### `RedirectResponse`
|
||||
|
||||
📨 🇺🇸🔍 ❎. ⚙️ 3️⃣0️⃣7️⃣ 👔 📟 (🍕 ❎) 🔢.
|
||||
|
||||
👆 💪 📨 `RedirectResponse` 🔗:
|
||||
|
||||
```Python hl_lines="2 9"
|
||||
{!../../../docs_src/custom_response/tutorial006.py!}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
⚖️ 👆 💪 ⚙️ ⚫️ `response_class` 🔢:
|
||||
|
||||
|
||||
```Python hl_lines="2 7 9"
|
||||
{!../../../docs_src/custom_response/tutorial006b.py!}
|
||||
```
|
||||
|
||||
🚥 👆 👈, ⤴️ 👆 💪 📨 📛 🔗 ⚪️➡️ 👆 *➡ 🛠️* 🔢.
|
||||
|
||||
👉 💼, `status_code` ⚙️ 🔜 🔢 1️⃣ `RedirectResponse`, ❔ `307`.
|
||||
|
||||
---
|
||||
|
||||
👆 💪 ⚙️ `status_code` 🔢 🌀 ⏮️ `response_class` 🔢:
|
||||
|
||||
```Python hl_lines="2 7 9"
|
||||
{!../../../docs_src/custom_response/tutorial006c.py!}
|
||||
```
|
||||
|
||||
### `StreamingResponse`
|
||||
|
||||
✊ 🔁 🚂 ⚖️ 😐 🚂/🎻 & 🎏 📨 💪.
|
||||
|
||||
```Python hl_lines="2 14"
|
||||
{!../../../docs_src/custom_response/tutorial007.py!}
|
||||
```
|
||||
|
||||
#### ⚙️ `StreamingResponse` ⏮️ 📁-💖 🎚
|
||||
|
||||
🚥 👆 ✔️ 📁-💖 🎚 (✅ 🎚 📨 `open()`), 👆 💪 ✍ 🚂 🔢 🔁 🤭 👈 📁-💖 🎚.
|
||||
|
||||
👈 🌌, 👆 🚫 ✔️ ✍ ⚫️ 🌐 🥇 💾, & 👆 💪 🚶♀️ 👈 🚂 🔢 `StreamingResponse`, & 📨 ⚫️.
|
||||
|
||||
👉 🔌 📚 🗃 🔗 ⏮️ ☁ 💾, 📹 🏭, & 🎏.
|
||||
|
||||
```{ .python .annotate hl_lines="2 10-12 14" }
|
||||
{!../../../docs_src/custom_response/tutorial008.py!}
|
||||
```
|
||||
|
||||
1️⃣. 👉 🚂 🔢. ⚫️ "🚂 🔢" ↩️ ⚫️ 🔌 `yield` 📄 🔘.
|
||||
2️⃣. ⚙️ `with` 🍫, 👥 ⚒ 💭 👈 📁-💖 🎚 📪 ⏮️ 🚂 🔢 🔨. , ⏮️ ⚫️ 🏁 📨 📨.
|
||||
3️⃣. 👉 `yield from` 💬 🔢 🔁 🤭 👈 👜 🌟 `file_like`. & ⤴️, 🔠 🍕 🔁, 🌾 👈 🍕 👟 ⚪️➡️ 👉 🚂 🔢.
|
||||
|
||||
, ⚫️ 🚂 🔢 👈 📨 "🏭" 👷 🕳 🙆 🔘.
|
||||
|
||||
🔨 ⚫️ 👉 🌌, 👥 💪 🚮 ⚫️ `with` 🍫, & 👈 🌌, 🚚 👈 ⚫️ 📪 ⏮️ 🏁.
|
||||
|
||||
!!! tip
|
||||
👀 👈 📥 👥 ⚙️ 🐩 `open()` 👈 🚫 🐕🦺 `async` & `await`, 👥 📣 ➡ 🛠️ ⏮️ 😐 `def`.
|
||||
|
||||
### `FileResponse`
|
||||
|
||||
🔁 🎏 📁 📨.
|
||||
|
||||
✊ 🎏 ⚒ ❌ 🔗 🌘 🎏 📨 🆎:
|
||||
|
||||
* `path` - 📁 📁 🎏.
|
||||
* `headers` - 🙆 🛃 🎚 🔌, 📖.
|
||||
* `media_type` - 🎻 🤝 📻 🆎. 🚥 🔢, 📁 ⚖️ ➡ 🔜 ⚙️ 🔑 📻 🆎.
|
||||
* `filename` - 🚥 ⚒, 👉 🔜 🔌 📨 `Content-Disposition`.
|
||||
|
||||
📁 📨 🔜 🔌 ☑ `Content-Length`, `Last-Modified` & `ETag` 🎚.
|
||||
|
||||
```Python hl_lines="2 10"
|
||||
{!../../../docs_src/custom_response/tutorial009.py!}
|
||||
```
|
||||
|
||||
👆 💪 ⚙️ `response_class` 🔢:
|
||||
|
||||
```Python hl_lines="2 8 10"
|
||||
{!../../../docs_src/custom_response/tutorial009b.py!}
|
||||
```
|
||||
|
||||
👉 💼, 👆 💪 📨 📁 ➡ 🔗 ⚪️➡️ 👆 *➡ 🛠️* 🔢.
|
||||
|
||||
## 🛃 📨 🎓
|
||||
|
||||
👆 💪 ✍ 👆 👍 🛃 📨 🎓, 😖 ⚪️➡️ `Response` & ⚙️ ⚫️.
|
||||
|
||||
🖼, ➡️ 💬 👈 👆 💚 ⚙️ <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>, ✋️ ⏮️ 🛃 ⚒ 🚫 ⚙️ 🔌 `ORJSONResponse` 🎓.
|
||||
|
||||
➡️ 💬 👆 💚 ⚫️ 📨 🔂 & 📁 🎻, 👆 💚 ⚙️ Orjson 🎛 `orjson.OPT_INDENT_2`.
|
||||
|
||||
👆 💪 ✍ `CustomORJSONResponse`. 👑 👜 👆 ✔️ ✍ `Response.render(content)` 👩🔬 👈 📨 🎚 `bytes`:
|
||||
|
||||
```Python hl_lines="9-14 17"
|
||||
{!../../../docs_src/custom_response/tutorial009c.py!}
|
||||
```
|
||||
|
||||
🔜 ↩️ 🛬:
|
||||
|
||||
```json
|
||||
{"message": "Hello World"}
|
||||
```
|
||||
|
||||
...👉 📨 🔜 📨:
|
||||
|
||||
```json
|
||||
{
|
||||
"message": "Hello World"
|
||||
}
|
||||
```
|
||||
|
||||
↗️, 👆 🔜 🎲 🔎 🌅 👍 🌌 ✊ 📈 👉 🌘 ❕ 🎻. 👶
|
||||
|
||||
## 🔢 📨 🎓
|
||||
|
||||
🕐❔ 🏗 **FastAPI** 🎓 👐 ⚖️ `APIRouter` 👆 💪 ✔ ❔ 📨 🎓 ⚙️ 🔢.
|
||||
|
||||
🔢 👈 🔬 👉 `default_response_class`.
|
||||
|
||||
🖼 🔛, **FastAPI** 🔜 ⚙️ `ORJSONResponse` 🔢, 🌐 *➡ 🛠️*, ↩️ `JSONResponse`.
|
||||
|
||||
```Python hl_lines="2 4"
|
||||
{!../../../docs_src/custom_response/tutorial010.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👆 💪 🔐 `response_class` *➡ 🛠️* ⏭.
|
||||
|
||||
## 🌖 🧾
|
||||
|
||||
👆 💪 📣 📻 🆎 & 📚 🎏 ℹ 🗄 ⚙️ `responses`: [🌖 📨 🗄](additional-responses.md){.internal-link target=_blank}.
|
||||
98
docs/em/docs/advanced/dataclasses.md
Normal file
98
docs/em/docs/advanced/dataclasses.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# ⚙️ 🎻
|
||||
|
||||
FastAPI 🏗 🔛 🔝 **Pydantic**, & 👤 ✔️ 🌏 👆 ❔ ⚙️ Pydantic 🏷 📣 📨 & 📨.
|
||||
|
||||
✋️ FastAPI 🐕🦺 ⚙️ <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a> 🎏 🌌:
|
||||
|
||||
```Python hl_lines="1 7-12 19-20"
|
||||
{!../../../docs_src/dataclasses/tutorial001.py!}
|
||||
```
|
||||
|
||||
👉 🐕🦺 👏 **Pydantic**, ⚫️ ✔️ <a href="https://pydantic-docs.helpmanual.io/usage/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">🔗 🐕🦺 `dataclasses`</a>.
|
||||
|
||||
, ⏮️ 📟 🔛 👈 🚫 ⚙️ Pydantic 🎯, FastAPI ⚙️ Pydantic 🗜 📚 🐩 🎻 Pydantic 👍 🍛 🎻.
|
||||
|
||||
& ↗️, ⚫️ 🐕🦺 🎏:
|
||||
|
||||
* 💽 🔬
|
||||
* 💽 🛠️
|
||||
* 💽 🧾, ♒️.
|
||||
|
||||
👉 👷 🎏 🌌 ⏮️ Pydantic 🏷. & ⚫️ 🤙 🏆 🎏 🌌 🔘, ⚙️ Pydantic.
|
||||
|
||||
!!! info
|
||||
✔️ 🤯 👈 🎻 💪 🚫 🌐 Pydantic 🏷 💪.
|
||||
|
||||
, 👆 5️⃣📆 💪 ⚙️ Pydantic 🏷.
|
||||
|
||||
✋️ 🚥 👆 ✔️ 📚 🎻 🤥 🤭, 👉 👌 🎱 ⚙️ 👫 🏋️ 🕸 🛠️ ⚙️ FastAPI. 👶
|
||||
|
||||
## 🎻 `response_model`
|
||||
|
||||
👆 💪 ⚙️ `dataclasses` `response_model` 🔢:
|
||||
|
||||
```Python hl_lines="1 7-13 19"
|
||||
{!../../../docs_src/dataclasses/tutorial002.py!}
|
||||
```
|
||||
|
||||
🎻 🔜 🔁 🗜 Pydantic 🎻.
|
||||
|
||||
👉 🌌, 🚮 🔗 🔜 🎦 🆙 🛠️ 🩺 👩💻 🔢:
|
||||
|
||||
<img src="/img/tutorial/dataclasses/image01.png">
|
||||
|
||||
## 🎻 🔁 📊 📊
|
||||
|
||||
👆 💪 🌀 `dataclasses` ⏮️ 🎏 🆎 ✍ ⚒ 🐦 📊 📊.
|
||||
|
||||
💼, 👆 💪 ✔️ ⚙️ Pydantic ⏬ `dataclasses`. 🖼, 🚥 👆 ✔️ ❌ ⏮️ 🔁 🏗 🛠️ 🧾.
|
||||
|
||||
👈 💼, 👆 💪 🎯 💱 🐩 `dataclasses` ⏮️ `pydantic.dataclasses`, ❔ 💧-♻:
|
||||
|
||||
```{ .python .annotate hl_lines="1 5 8-11 14-17 23-25 28" }
|
||||
{!../../../docs_src/dataclasses/tutorial003.py!}
|
||||
```
|
||||
|
||||
1️⃣. 👥 🗄 `field` ⚪️➡️ 🐩 `dataclasses`.
|
||||
|
||||
2️⃣. `pydantic.dataclasses` 💧-♻ `dataclasses`.
|
||||
|
||||
3️⃣. `Author` 🎻 🔌 📇 `Item` 🎻.
|
||||
|
||||
4️⃣. `Author` 🎻 ⚙️ `response_model` 🔢.
|
||||
|
||||
5️⃣. 👆 💪 ⚙️ 🎏 🐩 🆎 ✍ ⏮️ 🎻 📨 💪.
|
||||
|
||||
👉 💼, ⚫️ 📇 `Item` 🎻.
|
||||
|
||||
6️⃣. 📥 👥 🛬 📖 👈 🔌 `items` ❔ 📇 🎻.
|
||||
|
||||
FastAPI 🎯 <abbr title="converting the data to a format that can be transmitted">✍</abbr> 💽 🎻.
|
||||
|
||||
7️⃣. 📥 `response_model` ⚙️ 🆎 ✍ 📇 `Author` 🎻.
|
||||
|
||||
🔄, 👆 💪 🌀 `dataclasses` ⏮️ 🐩 🆎 ✍.
|
||||
|
||||
8️⃣. 👀 👈 👉 *➡ 🛠️ 🔢* ⚙️ 🥔 `def` ↩️ `async def`.
|
||||
|
||||
🕧, FastAPI 👆 💪 🌀 `def` & `async def` 💪.
|
||||
|
||||
🚥 👆 💪 ↗️ 🔃 🕐❔ ⚙️ ❔, ✅ 👅 📄 _"🏃 ❓" _ 🩺 🔃 <a href="https://fastapi.tiangolo.com/async/#in-a-hurry" target="_blank" class="internal-link">`async` & `await`</a>.
|
||||
|
||||
9️⃣. 👉 *➡ 🛠️ 🔢* 🚫 🛬 🎻 (👐 ⚫️ 💪), ✋️ 📇 📖 ⏮️ 🔗 💽.
|
||||
|
||||
FastAPI 🔜 ⚙️ `response_model` 🔢 (👈 🔌 🎻) 🗜 📨.
|
||||
|
||||
👆 💪 🌀 `dataclasses` ⏮️ 🎏 🆎 ✍ 📚 🎏 🌀 📨 🏗 📊 📊.
|
||||
|
||||
✅-📟 ✍ 💁♂ 🔛 👀 🌅 🎯 ℹ.
|
||||
|
||||
## 💡 🌅
|
||||
|
||||
👆 💪 🌀 `dataclasses` ⏮️ 🎏 Pydantic 🏷, 😖 ⚪️➡️ 👫, 🔌 👫 👆 👍 🏷, ♒️.
|
||||
|
||||
💡 🌅, ✅ <a href="https://pydantic-docs.helpmanual.io/usage/dataclasses/" class="external-link" target="_blank">Pydantic 🩺 🔃 🎻</a>.
|
||||
|
||||
## ⏬
|
||||
|
||||
👉 💪 ↩️ FastAPI ⏬ `0.67.0`. 👶
|
||||
160
docs/em/docs/advanced/events.md
Normal file
160
docs/em/docs/advanced/events.md
Normal file
@@ -0,0 +1,160 @@
|
||||
# 🔆 🎉
|
||||
|
||||
👆 💪 🔬 ⚛ (📟) 👈 🔜 🛠️ ⏭ 🈸 **▶️ 🆙**. 👉 ⛓ 👈 👉 📟 🔜 🛠️ **🕐**, **⏭** 🈸 **▶️ 📨 📨**.
|
||||
|
||||
🎏 🌌, 👆 💪 🔬 ⚛ (📟) 👈 🔜 🛠️ 🕐❔ 🈸 **🤫 🔽**. 👉 💼, 👉 📟 🔜 🛠️ **🕐**, **⏮️** ✔️ 🍵 🎲 **📚 📨**.
|
||||
|
||||
↩️ 👉 📟 🛠️ ⏭ 🈸 **▶️** ✊ 📨, & ▶️️ ⏮️ ⚫️ **🏁** 🚚 📨, ⚫️ 📔 🎂 🈸 **🔆** (🔤 "🔆" 🔜 ⚠ 🥈 👶).
|
||||
|
||||
👉 💪 📶 ⚠ ⚒ 🆙 **ℹ** 👈 👆 💪 ⚙️ 🎂 📱, & 👈 **💰** 👪 📨, &/⚖️ 👈 👆 💪 **🧹 🆙** ⏮️. 🖼, 💽 🔗 🎱, ⚖️ 🚚 🔗 🎰 🏫 🏷.
|
||||
|
||||
## ⚙️ 💼
|
||||
|
||||
➡️ ▶️ ⏮️ 🖼 **⚙️ 💼** & ⤴️ 👀 ❔ ❎ ⚫️ ⏮️ 👉.
|
||||
|
||||
➡️ 🌈 👈 👆 ✔️ **🎰 🏫 🏷** 👈 👆 💚 ⚙️ 🍵 📨. 👶
|
||||
|
||||
🎏 🏷 🔗 👪 📨,, ⚫️ 🚫 1️⃣ 🏷 📍 📨, ⚖️ 1️⃣ 📍 👩💻 ⚖️ 🕳 🎏.
|
||||
|
||||
➡️ 🌈 👈 🚚 🏷 💪 **✊ 🕰**, ↩️ ⚫️ ✔️ ✍ 📚 **💽 ⚪️➡️ 💾**. 👆 🚫 💚 ⚫️ 🔠 📨.
|
||||
|
||||
👆 💪 📐 ⚫️ 🔝 🎚 🕹/📁, ✋️ 👈 🔜 ⛓ 👈 ⚫️ 🔜 **📐 🏷** 🚥 👆 🏃♂ 🙅 🏧 💯, ⤴️ 👈 💯 🔜 **🐌** ↩️ ⚫️ 🔜 ✔️ ⌛ 🏷 📐 ⏭ 💆♂ 💪 🏃 🔬 🍕 📟.
|
||||
|
||||
👈 ⚫️❔ 👥 🔜 ❎, ➡️ 📐 🏷 ⏭ 📨 🍵, ✋️ 🕴 ▶️️ ⏭ 🈸 ▶️ 📨 📨, 🚫 ⏪ 📟 ➖ 📐.
|
||||
|
||||
## 🔆
|
||||
|
||||
👆 💪 🔬 👉 *🕴* & *🤫* ⚛ ⚙️ `lifespan` 🔢 `FastAPI` 📱, & "🔑 👨💼" (👤 🔜 🎦 👆 ⚫️❔ 👈 🥈).
|
||||
|
||||
➡️ ▶️ ⏮️ 🖼 & ⤴️ 👀 ⚫️ ℹ.
|
||||
|
||||
👥 ✍ 🔁 🔢 `lifespan()` ⏮️ `yield` 💖 👉:
|
||||
|
||||
```Python hl_lines="16 19"
|
||||
{!../../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
|
||||
📥 👥 ⚖ 😥 *🕴* 🛠️ 🚚 🏷 🚮 (❌) 🏷 🔢 📖 ⏮️ 🎰 🏫 🏷 ⏭ `yield`. 👉 📟 🔜 🛠️ **⏭** 🈸 **▶️ ✊ 📨**, ⏮️ *🕴*.
|
||||
|
||||
& ⤴️, ▶️️ ⏮️ `yield`, 👥 🚚 🏷. 👉 📟 🔜 🛠️ **⏮️** 🈸 **🏁 🚚 📨**, ▶️️ ⏭ *🤫*. 👉 💪, 🖼, 🚀 ℹ 💖 💾 ⚖️ 💻.
|
||||
|
||||
!!! tip
|
||||
`shutdown` 🔜 🔨 🕐❔ 👆 **⛔️** 🈸.
|
||||
|
||||
🎲 👆 💪 ▶️ 🆕 ⏬, ⚖️ 👆 🤚 🎡 🏃 ⚫️. 🤷
|
||||
|
||||
### 🔆 🔢
|
||||
|
||||
🥇 👜 👀, 👈 👥 ⚖ 🔁 🔢 ⏮️ `yield`. 👉 📶 🎏 🔗 ⏮️ `yield`.
|
||||
|
||||
```Python hl_lines="14-19"
|
||||
{!../../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
|
||||
🥇 🍕 🔢, ⏭ `yield`, 🔜 🛠️ **⏭** 🈸 ▶️.
|
||||
|
||||
& 🍕 ⏮️ `yield` 🔜 🛠️ **⏮️** 🈸 ✔️ 🏁.
|
||||
|
||||
### 🔁 🔑 👨💼
|
||||
|
||||
🚥 👆 ✅, 🔢 🎀 ⏮️ `@asynccontextmanager`.
|
||||
|
||||
👈 🗜 🔢 🔘 🕳 🤙 "**🔁 🔑 👨💼**".
|
||||
|
||||
```Python hl_lines="1 13"
|
||||
{!../../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
|
||||
**🔑 👨💼** 🐍 🕳 👈 👆 💪 ⚙️ `with` 📄, 🖼, `open()` 💪 ⚙️ 🔑 👨💼:
|
||||
|
||||
```Python
|
||||
with open("file.txt") as file:
|
||||
file.read()
|
||||
```
|
||||
|
||||
⏮️ ⏬ 🐍, 📤 **🔁 🔑 👨💼**. 👆 🔜 ⚙️ ⚫️ ⏮️ `async with`:
|
||||
|
||||
```Python
|
||||
async with lifespan(app):
|
||||
await do_stuff()
|
||||
```
|
||||
|
||||
🕐❔ 👆 ✍ 🔑 👨💼 ⚖️ 🔁 🔑 👨💼 💖 🔛, ⚫️❔ ⚫️ 🔨 👈, ⏭ 🛬 `with` 🍫, ⚫️ 🔜 🛠️ 📟 ⏭ `yield`, & ⏮️ ❎ `with` 🍫, ⚫️ 🔜 🛠️ 📟 ⏮️ `yield`.
|
||||
|
||||
👆 📟 🖼 🔛, 👥 🚫 ⚙️ ⚫️ 🔗, ✋️ 👥 🚶♀️ ⚫️ FastAPI ⚫️ ⚙️ ⚫️.
|
||||
|
||||
`lifespan` 🔢 `FastAPI` 📱 ✊ **🔁 🔑 👨💼**, 👥 💪 🚶♀️ 👆 🆕 `lifespan` 🔁 🔑 👨💼 ⚫️.
|
||||
|
||||
```Python hl_lines="22"
|
||||
{!../../../docs_src/events/tutorial003.py!}
|
||||
```
|
||||
|
||||
## 🎛 🎉 (😢)
|
||||
|
||||
!!! warning
|
||||
👍 🌌 🍵 *🕴* & *🤫* ⚙️ `lifespan` 🔢 `FastAPI` 📱 🔬 🔛.
|
||||
|
||||
👆 💪 🎲 🚶 👉 🍕.
|
||||
|
||||
📤 🎛 🌌 🔬 👉 ⚛ 🛠️ ⏮️ *🕴* & ⏮️ *🤫*.
|
||||
|
||||
👆 💪 🔬 🎉 🐕🦺 (🔢) 👈 💪 🛠️ ⏭ 🈸 ▶️ 🆙, ⚖️ 🕐❔ 🈸 🤫 🔽.
|
||||
|
||||
👫 🔢 💪 📣 ⏮️ `async def` ⚖️ 😐 `def`.
|
||||
|
||||
### `startup` 🎉
|
||||
|
||||
🚮 🔢 👈 🔜 🏃 ⏭ 🈸 ▶️, 📣 ⚫️ ⏮️ 🎉 `"startup"`:
|
||||
|
||||
```Python hl_lines="8"
|
||||
{!../../../docs_src/events/tutorial001.py!}
|
||||
```
|
||||
|
||||
👉 💼, `startup` 🎉 🐕🦺 🔢 🔜 🔢 🏬 "💽" ( `dict`) ⏮️ 💲.
|
||||
|
||||
👆 💪 🚮 🌅 🌘 1️⃣ 🎉 🐕🦺 🔢.
|
||||
|
||||
& 👆 🈸 🏆 🚫 ▶️ 📨 📨 ⏭ 🌐 `startup` 🎉 🐕🦺 ✔️ 🏁.
|
||||
|
||||
### `shutdown` 🎉
|
||||
|
||||
🚮 🔢 👈 🔜 🏃 🕐❔ 🈸 🤫 🔽, 📣 ⚫️ ⏮️ 🎉 `"shutdown"`:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/events/tutorial002.py!}
|
||||
```
|
||||
|
||||
📥, `shutdown` 🎉 🐕🦺 🔢 🔜 ✍ ✍ ⏸ `"Application shutdown"` 📁 `log.txt`.
|
||||
|
||||
!!! info
|
||||
`open()` 🔢, `mode="a"` ⛓ "🎻",, ⏸ 🔜 🚮 ⏮️ ⚫️❔ 🔛 👈 📁, 🍵 📁 ⏮️ 🎚.
|
||||
|
||||
!!! tip
|
||||
👀 👈 👉 💼 👥 ⚙️ 🐩 🐍 `open()` 🔢 👈 🔗 ⏮️ 📁.
|
||||
|
||||
, ⚫️ 🔌 👤/🅾 (🔢/🔢), 👈 🚚 "⌛" 👜 ✍ 💾.
|
||||
|
||||
✋️ `open()` 🚫 ⚙️ `async` & `await`.
|
||||
|
||||
, 👥 📣 🎉 🐕🦺 🔢 ⏮️ 🐩 `def` ↩️ `async def`.
|
||||
|
||||
!!! info
|
||||
👆 💪 ✍ 🌅 🔃 👫 🎉 🐕🦺 <a href="https://www.starlette.io/events/" class="external-link" target="_blank">💃 🎉' 🩺</a>.
|
||||
|
||||
### `startup` & `shutdown` 👯♂️
|
||||
|
||||
📤 ↕ 🤞 👈 ⚛ 👆 *🕴* & *🤫* 🔗, 👆 💪 💚 ▶️ 🕳 & ⤴️ 🏁 ⚫️, 📎 ℹ & ⤴️ 🚀 ⚫️, ♒️.
|
||||
|
||||
🔨 👈 👽 🔢 👈 🚫 💰 ⚛ ⚖️ 🔢 👯♂️ 🌅 ⚠ 👆 🔜 💪 🏪 💲 🌐 🔢 ⚖️ 🎏 🎱.
|
||||
|
||||
↩️ 👈, ⚫️ 🔜 👍 ↩️ ⚙️ `lifespan` 🔬 🔛.
|
||||
|
||||
## 📡 ℹ
|
||||
|
||||
📡 ℹ 😟 🤓. 👶
|
||||
|
||||
🔘, 🔫 📡 🔧, 👉 🍕 <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">🔆 🛠️</a>, & ⚫️ 🔬 🎉 🤙 `startup` & `shutdown`.
|
||||
|
||||
## 🎧 🈸
|
||||
|
||||
👶 ✔️ 🤯 👈 👫 🔆 🎉 (🕴 & 🤫) 🔜 🕴 🛠️ 👑 🈸, 🚫 [🎧 🈸 - 🗻](./sub-applications.md){.internal-link target=_blank}.
|
||||
314
docs/em/docs/advanced/extending-openapi.md
Normal file
314
docs/em/docs/advanced/extending-openapi.md
Normal file
@@ -0,0 +1,314 @@
|
||||
# ↔ 🗄
|
||||
|
||||
!!! warning
|
||||
👉 👍 🏧 ⚒. 👆 🎲 💪 🚶 ⚫️.
|
||||
|
||||
🚥 👆 📄 🔰 - 👩💻 🦮, 👆 💪 🎲 🚶 👉 📄.
|
||||
|
||||
🚥 👆 ⏪ 💭 👈 👆 💪 🔀 🏗 🗄 🔗, 😣 👂.
|
||||
|
||||
📤 💼 🌐❔ 👆 💪 💪 🔀 🏗 🗄 🔗.
|
||||
|
||||
👉 📄 👆 🔜 👀 ❔.
|
||||
|
||||
## 😐 🛠️
|
||||
|
||||
😐 (🔢) 🛠️, ⏩.
|
||||
|
||||
`FastAPI` 🈸 (👐) ✔️ `.openapi()` 👩🔬 👈 📈 📨 🗄 🔗.
|
||||
|
||||
🍕 🈸 🎚 🏗, *➡ 🛠️* `/openapi.json` (⚖️ ⚫️❔ 👆 ⚒ 👆 `openapi_url`) ®.
|
||||
|
||||
⚫️ 📨 🎻 📨 ⏮️ 🏁 🈸 `.openapi()` 👩🔬.
|
||||
|
||||
🔢, ⚫️❔ 👩🔬 `.openapi()` 🔨 ✅ 🏠 `.openapi_schema` 👀 🚥 ⚫️ ✔️ 🎚 & 📨 👫.
|
||||
|
||||
🚥 ⚫️ 🚫, ⚫️ 🏗 👫 ⚙️ 🚙 🔢 `fastapi.openapi.utils.get_openapi`.
|
||||
|
||||
& 👈 🔢 `get_openapi()` 📨 🔢:
|
||||
|
||||
* `title`: 🗄 📛, 🎦 🩺.
|
||||
* `version`: ⏬ 👆 🛠️, ✅ `2.5.0`.
|
||||
* `openapi_version`: ⏬ 🗄 🔧 ⚙️. 🔢, ⏪: `3.0.2`.
|
||||
* `description`: 📛 👆 🛠️.
|
||||
* `routes`: 📇 🛣, 👫 🔠 ® *➡ 🛠️*. 👫 ✊ ⚪️➡️ `app.routes`.
|
||||
|
||||
## 🔑 🔢
|
||||
|
||||
⚙️ ℹ 🔛, 👆 💪 ⚙️ 🎏 🚙 🔢 🏗 🗄 🔗 & 🔐 🔠 🍕 👈 👆 💪.
|
||||
|
||||
🖼, ➡️ 🚮 <a href="https://github.com/Rebilly/ReDoc/blob/master/docs/redoc-vendor-extensions.md#x-logo" class="external-link" target="_blank">📄 🗄 ↔ 🔌 🛃 🔱</a>.
|
||||
|
||||
### 😐 **FastAPI**
|
||||
|
||||
🥇, ✍ 🌐 👆 **FastAPI** 🈸 🛎:
|
||||
|
||||
```Python hl_lines="1 4 7-9"
|
||||
{!../../../docs_src/extending_openapi/tutorial001.py!}
|
||||
```
|
||||
|
||||
### 🏗 🗄 🔗
|
||||
|
||||
⤴️, ⚙️ 🎏 🚙 🔢 🏗 🗄 🔗, 🔘 `custom_openapi()` 🔢:
|
||||
|
||||
```Python hl_lines="2 15-20"
|
||||
{!../../../docs_src/extending_openapi/tutorial001.py!}
|
||||
```
|
||||
|
||||
### 🔀 🗄 🔗
|
||||
|
||||
🔜 👆 💪 🚮 📄 ↔, ❎ 🛃 `x-logo` `info` "🎚" 🗄 🔗:
|
||||
|
||||
```Python hl_lines="21-23"
|
||||
{!../../../docs_src/extending_openapi/tutorial001.py!}
|
||||
```
|
||||
|
||||
### 💾 🗄 🔗
|
||||
|
||||
👆 💪 ⚙️ 🏠 `.openapi_schema` "💾", 🏪 👆 🏗 🔗.
|
||||
|
||||
👈 🌌, 👆 🈸 🏆 🚫 ✔️ 🏗 🔗 🔠 🕰 👩💻 📂 👆 🛠️ 🩺.
|
||||
|
||||
⚫️ 🔜 🏗 🕴 🕐, & ⤴️ 🎏 💾 🔗 🔜 ⚙️ ⏭ 📨.
|
||||
|
||||
```Python hl_lines="13-14 24-25"
|
||||
{!../../../docs_src/extending_openapi/tutorial001.py!}
|
||||
```
|
||||
|
||||
### 🔐 👩🔬
|
||||
|
||||
🔜 👆 💪 ❎ `.openapi()` 👩🔬 ⏮️ 👆 🆕 🔢.
|
||||
|
||||
```Python hl_lines="28"
|
||||
{!../../../docs_src/extending_openapi/tutorial001.py!}
|
||||
```
|
||||
|
||||
### ✅ ⚫️
|
||||
|
||||
🕐 👆 🚶 <a href="http://127.0.0.1:8000/redoc" class="external-link" target="_blank">http://127.0.0.1:8000/redoc</a> 👆 🔜 👀 👈 👆 ⚙️ 👆 🛃 🔱 (👉 🖼, **FastAPI**'Ⓜ 🔱):
|
||||
|
||||
<img src="/img/tutorial/extending-openapi/image01.png">
|
||||
|
||||
## 👤-🕸 🕸 & 🎚 🩺
|
||||
|
||||
🛠️ 🩺 ⚙️ **🦁 🎚** & **📄**, & 🔠 👈 💪 🕸 & 🎚 📁.
|
||||
|
||||
🔢, 👈 📁 🍦 ⚪️➡️ <abbr title="Content Delivery Network: A service, normally composed of several servers, that provides static files, like JavaScript and CSS. It's commonly used to serve those files from the server closer to the client, improving performance.">💲</abbr>.
|
||||
|
||||
✋️ ⚫️ 💪 🛃 ⚫️, 👆 💪 ⚒ 🎯 💲, ⚖️ 🍦 📁 👆.
|
||||
|
||||
👈 ⚠, 🖼, 🚥 👆 💪 👆 📱 🚧 👷 ⏪ 📱, 🍵 📂 🕸 🔐, ⚖️ 🇧🇿 🕸.
|
||||
|
||||
📥 👆 🔜 👀 ❔ 🍦 👈 📁 👆, 🎏 FastAPI 📱, & 🔗 🩺 ⚙️ 👫.
|
||||
|
||||
### 🏗 📁 📊
|
||||
|
||||
➡️ 💬 👆 🏗 📁 📊 👀 💖 👉:
|
||||
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
```
|
||||
|
||||
🔜 ✍ 📁 🏪 📚 🎻 📁.
|
||||
|
||||
👆 🆕 📁 📊 💪 👀 💖 👉:
|
||||
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
└── static/
|
||||
```
|
||||
|
||||
### ⏬ 📁
|
||||
|
||||
⏬ 🎻 📁 💪 🩺 & 🚮 👫 🔛 👈 `static/` 📁.
|
||||
|
||||
👆 💪 🎲 ▶️️-🖊 🔠 🔗 & 🖊 🎛 🎏 `Save link as...`.
|
||||
|
||||
**🦁 🎚** ⚙️ 📁:
|
||||
|
||||
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui-bundle.js" class="external-link" target="_blank">`swagger-ui-bundle.js`</a>
|
||||
* <a href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui.css" class="external-link" target="_blank">`swagger-ui.css`</a>
|
||||
|
||||
& **📄** ⚙️ 📁:
|
||||
|
||||
* <a href="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js" class="external-link" target="_blank">`redoc.standalone.js`</a>
|
||||
|
||||
⏮️ 👈, 👆 📁 📊 💪 👀 💖:
|
||||
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py
|
||||
└── static
|
||||
├── redoc.standalone.js
|
||||
├── swagger-ui-bundle.js
|
||||
└── swagger-ui.css
|
||||
```
|
||||
|
||||
### 🍦 🎻 📁
|
||||
|
||||
* 🗄 `StaticFiles`.
|
||||
* "🗻" `StaticFiles()` 👐 🎯 ➡.
|
||||
|
||||
```Python hl_lines="7 11"
|
||||
{!../../../docs_src/extending_openapi/tutorial002.py!}
|
||||
```
|
||||
|
||||
### 💯 🎻 📁
|
||||
|
||||
▶️ 👆 🈸 & 🚶 <a href="http://127.0.0.1:8000/static/redoc.standalone.js" class="external-link" target="_blank">http://127.0.0.1:8000/static/redoc.standalone.js</a>.
|
||||
|
||||
👆 🔜 👀 📶 📏 🕸 📁 **📄**.
|
||||
|
||||
⚫️ 💪 ▶️ ⏮️ 🕳 💖:
|
||||
|
||||
```JavaScript
|
||||
/*!
|
||||
* ReDoc - OpenAPI/Swagger-generated API Reference Documentation
|
||||
* -------------------------------------------------------------
|
||||
* Version: "2.0.0-rc.18"
|
||||
* Repo: https://github.com/Redocly/redoc
|
||||
*/
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof m
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
👈 ✔ 👈 👆 💆♂ 💪 🍦 🎻 📁 ⚪️➡️ 👆 📱, & 👈 👆 🥉 🎻 📁 🩺 ☑ 🥉.
|
||||
|
||||
🔜 👥 💪 🔗 📱 ⚙️ 📚 🎻 📁 🩺.
|
||||
|
||||
### ❎ 🏧 🩺
|
||||
|
||||
🥇 🔁 ❎ 🏧 🩺, 📚 ⚙️ 💲 🔢.
|
||||
|
||||
❎ 👫, ⚒ 👫 📛 `None` 🕐❔ 🏗 👆 `FastAPI` 📱:
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/extending_openapi/tutorial002.py!}
|
||||
```
|
||||
|
||||
### 🔌 🛃 🩺
|
||||
|
||||
🔜 👆 💪 ✍ *➡ 🛠️* 🛃 🩺.
|
||||
|
||||
👆 💪 🏤-⚙️ FastAPI 🔗 🔢 ✍ 🕸 📃 🩺, & 🚶♀️ 👫 💪 ❌:
|
||||
|
||||
* `openapi_url`: 📛 🌐❔ 🕸 📃 🩺 💪 🤚 🗄 🔗 👆 🛠️. 👆 💪 ⚙️ 📥 🔢 `app.openapi_url`.
|
||||
* `title`: 📛 👆 🛠️.
|
||||
* `oauth2_redirect_url`: 👆 💪 ⚙️ `app.swagger_ui_oauth2_redirect_url` 📥 ⚙️ 🔢.
|
||||
* `swagger_js_url`: 📛 🌐❔ 🕸 👆 🦁 🎚 🩺 💪 🤚 **🕸** 📁. 👉 1️⃣ 👈 👆 👍 📱 🔜 🍦.
|
||||
* `swagger_css_url`: 📛 🌐❔ 🕸 👆 🦁 🎚 🩺 💪 🤚 **🎚** 📁. 👉 1️⃣ 👈 👆 👍 📱 🔜 🍦.
|
||||
|
||||
& ➡ 📄...
|
||||
|
||||
```Python hl_lines="2-6 14-22 25-27 30-36"
|
||||
{!../../../docs_src/extending_openapi/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
*➡ 🛠️* `swagger_ui_redirect` 👩🎓 🕐❔ 👆 ⚙️ Oauth2️⃣.
|
||||
|
||||
🚥 👆 🛠️ 👆 🛠️ ⏮️ Oauth2️⃣ 🐕🦺, 👆 🔜 💪 🔓 & 👟 🔙 🛠️ 🩺 ⏮️ 📎 🎓. & 🔗 ⏮️ ⚫️ ⚙️ 🎰 Oauth2️⃣ 🤝.
|
||||
|
||||
🦁 🎚 🔜 🍵 ⚫️ ⛅ 🎑 👆, ✋️ ⚫️ 💪 👉 "❎" 👩🎓.
|
||||
|
||||
### ✍ *➡ 🛠️* 💯 ⚫️
|
||||
|
||||
🔜, 💪 💯 👈 🌐 👷, ✍ *➡ 🛠️*:
|
||||
|
||||
```Python hl_lines="39-41"
|
||||
{!../../../docs_src/extending_openapi/tutorial002.py!}
|
||||
```
|
||||
|
||||
### 💯 ⚫️
|
||||
|
||||
🔜, 👆 🔜 💪 🔌 👆 📻, 🚶 👆 🩺 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>, & 🔃 📃.
|
||||
|
||||
& 🍵 🕸, 👆 🔜 💪 👀 🩺 👆 🛠️ & 🔗 ⏮️ ⚫️.
|
||||
|
||||
## 🛠️ 🦁 🎚
|
||||
|
||||
👆 💪 🔗 ➕ <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration" class="external-link" target="_blank">🦁 🎚 🔢</a>.
|
||||
|
||||
🔗 👫, 🚶♀️ `swagger_ui_parameters` ❌ 🕐❔ 🏗 `FastAPI()` 📱 🎚 ⚖️ `get_swagger_ui_html()` 🔢.
|
||||
|
||||
`swagger_ui_parameters` 📨 📖 ⏮️ 📳 🚶♀️ 🦁 🎚 🔗.
|
||||
|
||||
FastAPI 🗜 📳 **🎻** ⚒ 👫 🔗 ⏮️ 🕸, 👈 ⚫️❔ 🦁 🎚 💪.
|
||||
|
||||
### ❎ ❕ 🎦
|
||||
|
||||
🖼, 👆 💪 ❎ ❕ 🎦 🦁 🎚.
|
||||
|
||||
🍵 🔀 ⚒, ❕ 🎦 🛠️ 🔢:
|
||||
|
||||
<img src="/img/tutorial/extending-openapi/image02.png">
|
||||
|
||||
✋️ 👆 💪 ❎ ⚫️ ⚒ `syntaxHighlight` `False`:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/extending_openapi/tutorial003.py!}
|
||||
```
|
||||
|
||||
...& ⤴️ 🦁 🎚 🏆 🚫 🎦 ❕ 🎦 🚫🔜:
|
||||
|
||||
<img src="/img/tutorial/extending-openapi/image03.png">
|
||||
|
||||
### 🔀 🎢
|
||||
|
||||
🎏 🌌 👆 💪 ⚒ ❕ 🎦 🎢 ⏮️ 🔑 `"syntaxHighlight.theme"` (👀 👈 ⚫️ ✔️ ❣ 🖕):
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/extending_openapi/tutorial004.py!}
|
||||
```
|
||||
|
||||
👈 📳 🔜 🔀 ❕ 🎦 🎨 🎢:
|
||||
|
||||
<img src="/img/tutorial/extending-openapi/image04.png">
|
||||
|
||||
### 🔀 🔢 🦁 🎚 🔢
|
||||
|
||||
FastAPI 🔌 🔢 📳 🔢 ☑ 🌅 ⚙️ 💼.
|
||||
|
||||
⚫️ 🔌 👫 🔢 📳:
|
||||
|
||||
```Python
|
||||
{!../../../fastapi/openapi/docs.py[ln:7-13]!}
|
||||
```
|
||||
|
||||
👆 💪 🔐 🙆 👫 ⚒ 🎏 💲 ❌ `swagger_ui_parameters`.
|
||||
|
||||
🖼, ❎ `deepLinking` 👆 💪 🚶♀️ 👉 ⚒ `swagger_ui_parameters`:
|
||||
|
||||
```Python hl_lines="3"
|
||||
{!../../../docs_src/extending_openapi/tutorial005.py!}
|
||||
```
|
||||
|
||||
### 🎏 🦁 🎚 🔢
|
||||
|
||||
👀 🌐 🎏 💪 📳 👆 💪 ⚙️, ✍ 🛂 <a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration" class="external-link" target="_blank">🩺 🦁 🎚 🔢</a>.
|
||||
|
||||
### 🕸-🕴 ⚒
|
||||
|
||||
🦁 🎚 ✔ 🎏 📳 **🕸-🕴** 🎚 (🖼, 🕸 🔢).
|
||||
|
||||
FastAPI 🔌 👫 🕸-🕴 `presets` ⚒:
|
||||
|
||||
```JavaScript
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIBundle.SwaggerUIStandalonePreset
|
||||
]
|
||||
```
|
||||
|
||||
👫 **🕸** 🎚, 🚫 🎻, 👆 💪 🚫 🚶♀️ 👫 ⚪️➡️ 🐍 📟 🔗.
|
||||
|
||||
🚥 👆 💪 ⚙️ 🕸-🕴 📳 💖 📚, 👆 💪 ⚙️ 1️⃣ 👩🔬 🔛. 🔐 🌐 🦁 🎚 *➡ 🛠️* & ❎ ✍ 🙆 🕸 👆 💪.
|
||||
267
docs/em/docs/advanced/generate-clients.md
Normal file
267
docs/em/docs/advanced/generate-clients.md
Normal file
@@ -0,0 +1,267 @@
|
||||
# 🏗 👩💻
|
||||
|
||||
**FastAPI** ⚓️ 🔛 🗄 🔧, 👆 🤚 🏧 🔗 ⏮️ 📚 🧰, 🔌 🏧 🛠️ 🩺 (🚚 🦁 🎚).
|
||||
|
||||
1️⃣ 🎯 📈 👈 🚫 🎯 ⭐ 👈 👆 💪 **🏗 👩💻** (🕣 🤙 <abbr title="Software Development Kits">**📱**</abbr> ) 👆 🛠️, 📚 🎏 **🛠️ 🇪🇸**.
|
||||
|
||||
## 🗄 👩💻 🚂
|
||||
|
||||
📤 📚 🧰 🏗 👩💻 ⚪️➡️ **🗄**.
|
||||
|
||||
⚠ 🧰 <a href="https://openapi-generator.tech/" class="external-link" target="_blank">🗄 🚂</a>.
|
||||
|
||||
🚥 👆 🏗 **🕸**, 📶 😌 🎛 <a href="https://github.com/ferdikoomen/openapi-typescript-codegen" class="external-link" target="_blank">🗄-📕-🇦🇪</a>.
|
||||
|
||||
## 🏗 📕 🕸 👩💻
|
||||
|
||||
➡️ ▶️ ⏮️ 🙅 FastAPI 🈸:
|
||||
|
||||
=== "🐍 3️⃣.6️⃣ & 🔛"
|
||||
|
||||
```Python hl_lines="9-11 14-15 18 19 23"
|
||||
{!> ../../../docs_src/generate_clients/tutorial001.py!}
|
||||
```
|
||||
|
||||
=== "🐍 3️⃣.9️⃣ & 🔛"
|
||||
|
||||
```Python hl_lines="7-9 12-13 16-17 21"
|
||||
{!> ../../../docs_src/generate_clients/tutorial001_py39.py!}
|
||||
```
|
||||
|
||||
👀 👈 *➡ 🛠️* 🔬 🏷 👫 ⚙️ 📨 🚀 & 📨 🚀, ⚙️ 🏷 `Item` & `ResponseMessage`.
|
||||
|
||||
### 🛠️ 🩺
|
||||
|
||||
🚥 👆 🚶 🛠️ 🩺, 👆 🔜 👀 👈 ⚫️ ✔️ **🔗** 📊 📨 📨 & 📨 📨:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image01.png">
|
||||
|
||||
👆 💪 👀 👈 🔗 ↩️ 👫 📣 ⏮️ 🏷 📱.
|
||||
|
||||
👈 ℹ 💪 📱 **🗄 🔗**, & ⤴️ 🎦 🛠️ 🩺 (🦁 🎚).
|
||||
|
||||
& 👈 🎏 ℹ ⚪️➡️ 🏷 👈 🔌 🗄 ⚫️❔ 💪 ⚙️ **🏗 👩💻 📟**.
|
||||
|
||||
### 🏗 📕 👩💻
|
||||
|
||||
🔜 👈 👥 ✔️ 📱 ⏮️ 🏷, 👥 💪 🏗 👩💻 📟 🕸.
|
||||
|
||||
#### ❎ `openapi-typescript-codegen`
|
||||
|
||||
👆 💪 ❎ `openapi-typescript-codegen` 👆 🕸 📟 ⏮️:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ npm install openapi-typescript-codegen --save-dev
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
#### 🏗 👩💻 📟
|
||||
|
||||
🏗 👩💻 📟 👆 💪 ⚙️ 📋 ⏸ 🈸 `openapi` 👈 🔜 🔜 ❎.
|
||||
|
||||
↩️ ⚫️ ❎ 🇧🇿 🏗, 👆 🎲 🚫🔜 💪 🤙 👈 📋 🔗, ✋️ 👆 🔜 🚮 ⚫️ 🔛 👆 `package.json` 📁.
|
||||
|
||||
⚫️ 💪 👀 💖 👉:
|
||||
|
||||
```JSON hl_lines="7"
|
||||
{
|
||||
"name": "frontend-app",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"generate-client": "openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios"
|
||||
},
|
||||
"author": "",
|
||||
"license": "",
|
||||
"devDependencies": {
|
||||
"openapi-typescript-codegen": "^0.20.1",
|
||||
"typescript": "^4.6.2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
⏮️ ✔️ 👈 ☕ `generate-client` ✍ 📤, 👆 💪 🏃 ⚫️ ⏮️:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ npm run generate-client
|
||||
|
||||
frontend-app@1.0.0 generate-client /home/user/code/frontend-app
|
||||
> openapi --input http://localhost:8000/openapi.json --output ./src/client --client axios
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
👈 📋 🔜 🏗 📟 `./src/client` & 🔜 ⚙️ `axios` (🕸 🇺🇸🔍 🗃) 🔘.
|
||||
|
||||
### 🔄 👅 👩💻 📟
|
||||
|
||||
🔜 👆 💪 🗄 & ⚙️ 👩💻 📟, ⚫️ 💪 👀 💖 👉, 👀 👈 👆 🤚 ✍ 👩🔬:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image02.png">
|
||||
|
||||
👆 🔜 🤚 ✍ 🚀 📨:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image03.png">
|
||||
|
||||
!!! tip
|
||||
👀 ✍ `name` & `price`, 👈 🔬 FastAPI 🈸, `Item` 🏷.
|
||||
|
||||
👆 🔜 ✔️ ⏸ ❌ 📊 👈 👆 📨:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image04.png">
|
||||
|
||||
📨 🎚 🔜 ✔️ ✍:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image05.png">
|
||||
|
||||
## FastAPI 📱 ⏮️ 🔖
|
||||
|
||||
📚 💼 👆 FastAPI 📱 🔜 🦏, & 👆 🔜 🎲 ⚙️ 🔖 🎏 🎏 👪 *➡ 🛠️*.
|
||||
|
||||
🖼, 👆 💪 ✔️ 📄 **🏬** & ➕1️⃣ 📄 **👩💻**, & 👫 💪 👽 🔖:
|
||||
|
||||
|
||||
=== "🐍 3️⃣.6️⃣ & 🔛"
|
||||
|
||||
```Python hl_lines="23 28 36"
|
||||
{!> ../../../docs_src/generate_clients/tutorial002.py!}
|
||||
```
|
||||
|
||||
=== "🐍 3️⃣.9️⃣ & 🔛"
|
||||
|
||||
```Python hl_lines="21 26 34"
|
||||
{!> ../../../docs_src/generate_clients/tutorial002_py39.py!}
|
||||
```
|
||||
|
||||
### 🏗 📕 👩💻 ⏮️ 🔖
|
||||
|
||||
🚥 👆 🏗 👩💻 FastAPI 📱 ⚙️ 🔖, ⚫️ 🔜 🛎 🎏 👩💻 📟 ⚓️ 🔛 🔖.
|
||||
|
||||
👉 🌌 👆 🔜 💪 ✔️ 👜 ✔ & 👪 ☑ 👩💻 📟:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image06.png">
|
||||
|
||||
👉 💼 👆 ✔️:
|
||||
|
||||
* `ItemsService`
|
||||
* `UsersService`
|
||||
|
||||
### 👩💻 👩🔬 📛
|
||||
|
||||
▶️️ 🔜 🏗 👩🔬 📛 💖 `createItemItemsPost` 🚫 👀 📶 🧹:
|
||||
|
||||
```TypeScript
|
||||
ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
|
||||
```
|
||||
|
||||
...👈 ↩️ 👩💻 🚂 ⚙️ 🗄 🔗 **🛠️ 🆔** 🔠 *➡ 🛠️*.
|
||||
|
||||
🗄 🚚 👈 🔠 🛠️ 🆔 😍 🤭 🌐 *➡ 🛠️*, FastAPI ⚙️ **🔢 📛**, **➡**, & **🇺🇸🔍 👩🔬/🛠️** 🏗 👈 🛠️ 🆔, ↩️ 👈 🌌 ⚫️ 💪 ⚒ 💭 👈 🛠️ 🆔 😍.
|
||||
|
||||
✋️ 👤 🔜 🎦 👆 ❔ 📉 👈 ⏭. 👶
|
||||
|
||||
## 🛃 🛠️ 🆔 & 👍 👩🔬 📛
|
||||
|
||||
👆 💪 **🔀** 🌌 👫 🛠️ 🆔 **🏗** ⚒ 👫 🙅 & ✔️ **🙅 👩🔬 📛** 👩💻.
|
||||
|
||||
👉 💼 👆 🔜 ✔️ 🚚 👈 🔠 🛠️ 🆔 **😍** 🎏 🌌.
|
||||
|
||||
🖼, 👆 💪 ⚒ 💭 👈 🔠 *➡ 🛠️* ✔️ 🔖, & ⤴️ 🏗 🛠️ 🆔 ⚓️ 🔛 **🔖** & *➡ 🛠️* **📛** (🔢 📛).
|
||||
|
||||
### 🛃 🏗 😍 🆔 🔢
|
||||
|
||||
FastAPI ⚙️ **😍 🆔** 🔠 *➡ 🛠️*, ⚫️ ⚙️ **🛠️ 🆔** & 📛 🙆 💪 🛃 🏷, 📨 ⚖️ 📨.
|
||||
|
||||
👆 💪 🛃 👈 🔢. ⚫️ ✊ `APIRoute` & 🔢 🎻.
|
||||
|
||||
🖼, 📥 ⚫️ ⚙️ 🥇 🔖 (👆 🔜 🎲 ✔️ 🕴 1️⃣ 🔖) & *➡ 🛠️* 📛 (🔢 📛).
|
||||
|
||||
👆 💪 ⤴️ 🚶♀️ 👈 🛃 🔢 **FastAPI** `generate_unique_id_function` 🔢:
|
||||
|
||||
=== "🐍 3️⃣.6️⃣ & 🔛"
|
||||
|
||||
```Python hl_lines="8-9 12"
|
||||
{!> ../../../docs_src/generate_clients/tutorial003.py!}
|
||||
```
|
||||
|
||||
=== "🐍 3️⃣.9️⃣ & 🔛"
|
||||
|
||||
```Python hl_lines="6-7 10"
|
||||
{!> ../../../docs_src/generate_clients/tutorial003_py39.py!}
|
||||
```
|
||||
|
||||
### 🏗 📕 👩💻 ⏮️ 🛃 🛠️ 🆔
|
||||
|
||||
🔜 🚥 👆 🏗 👩💻 🔄, 👆 🔜 👀 👈 ⚫️ ✔️ 📉 👩🔬 📛:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image07.png">
|
||||
|
||||
👆 👀, 👩🔬 📛 🔜 ✔️ 🔖 & ⤴️ 🔢 📛, 🔜 👫 🚫 🔌 ℹ ⚪️➡️ 📛 ➡ & 🇺🇸🔍 🛠️.
|
||||
|
||||
### 🗜 🗄 🔧 👩💻 🚂
|
||||
|
||||
🏗 📟 ✔️ **❎ ℹ**.
|
||||
|
||||
👥 ⏪ 💭 👈 👉 👩🔬 🔗 **🏬** ↩️ 👈 🔤 `ItemsService` (✊ ⚪️➡️ 🔖), ✋️ 👥 ✔️ 📛 🔡 👩🔬 📛 💁♂️. 👶
|
||||
|
||||
👥 🔜 🎲 💚 🚧 ⚫️ 🗄 🏢, 👈 🔜 🚚 👈 🛠️ 🆔 **😍**.
|
||||
|
||||
✋️ 🏗 👩💻 👥 💪 **🔀** 🗄 🛠️ 🆔 ▶️️ ⏭ 🏭 👩💻, ⚒ 👈 👩🔬 📛 👌 & **🧹**.
|
||||
|
||||
👥 💪 ⏬ 🗄 🎻 📁 `openapi.json` & ⤴️ 👥 💪 **❎ 👈 🔡 🔖** ⏮️ ✍ 💖 👉:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/generate_clients/tutorial004.py!}
|
||||
```
|
||||
|
||||
⏮️ 👈, 🛠️ 🆔 🔜 📁 ⚪️➡️ 👜 💖 `items-get_items` `get_items`, 👈 🌌 👩💻 🚂 💪 🏗 🙅 👩🔬 📛.
|
||||
|
||||
### 🏗 📕 👩💻 ⏮️ 🗜 🗄
|
||||
|
||||
🔜 🔚 🏁 📁 `openapi.json`, 👆 🔜 🔀 `package.json` ⚙️ 👈 🇧🇿 📁, 🖼:
|
||||
|
||||
```JSON hl_lines="7"
|
||||
{
|
||||
"name": "frontend-app",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"generate-client": "openapi --input ./openapi.json --output ./src/client --client axios"
|
||||
},
|
||||
"author": "",
|
||||
"license": "",
|
||||
"devDependencies": {
|
||||
"openapi-typescript-codegen": "^0.20.1",
|
||||
"typescript": "^4.6.2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
⏮️ 🏭 🆕 👩💻, 👆 🔜 🔜 ✔️ **🧹 👩🔬 📛**, ⏮️ 🌐 **✍**, **⏸ ❌**, ♒️:
|
||||
|
||||
<img src="/img/tutorial/generate-clients/image08.png">
|
||||
|
||||
## 💰
|
||||
|
||||
🕐❔ ⚙️ 🔁 🏗 👩💻 👆 🔜 **✍** :
|
||||
|
||||
* 👩🔬.
|
||||
* 📨 🚀 💪, 🔢 🔢, ♒️.
|
||||
* 📨 🚀.
|
||||
|
||||
👆 🔜 ✔️ **⏸ ❌** 🌐.
|
||||
|
||||
& 🕐❔ 👆 ℹ 👩💻 📟, & **♻** 🕸, ⚫️ 🔜 ✔️ 🙆 🆕 *➡ 🛠️* 💪 👩🔬, 🗝 🕐 ❎, & 🙆 🎏 🔀 🔜 🎨 🔛 🏗 📟. 👶
|
||||
|
||||
👉 ⛓ 👈 🚥 🕳 🔀 ⚫️ 🔜 **🎨** 🔛 👩💻 📟 🔁. & 🚥 👆 **🏗** 👩💻 ⚫️ 🔜 ❌ 👅 🚥 👆 ✔️ 🙆 **🔖** 📊 ⚙️.
|
||||
|
||||
, 👆 🔜 **🔍 📚 ❌** 📶 ⏪ 🛠️ 🛵 ↩️ ✔️ ⌛ ❌ 🎦 🆙 👆 🏁 👩💻 🏭 & ⤴️ 🔄 ℹ 🌐❔ ⚠. 👶
|
||||
56
docs/em/docs/advanced/graphql.md
Normal file
56
docs/em/docs/advanced/graphql.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# 🕹
|
||||
|
||||
**FastAPI** ⚓️ 🔛 **🔫** 🐩, ⚫️ 📶 ⏩ 🛠️ 🙆 **🕹** 🗃 🔗 ⏮️ 🔫.
|
||||
|
||||
👆 💪 🌀 😐 FastAPI *➡ 🛠️* ⏮️ 🕹 🔛 🎏 🈸.
|
||||
|
||||
!!! tip
|
||||
**🕹** ❎ 📶 🎯 ⚙️ 💼.
|
||||
|
||||
⚫️ ✔️ **📈** & **⚠** 🕐❔ 🔬 ⚠ **🕸 🔗**.
|
||||
|
||||
⚒ 💭 👆 🔬 🚥 **💰** 👆 ⚙️ 💼 ⚖ **👐**. 👶
|
||||
|
||||
## 🕹 🗃
|
||||
|
||||
📥 **🕹** 🗃 👈 ✔️ **🔫** 🐕🦺. 👆 💪 ⚙️ 👫 ⏮️ **FastAPI**:
|
||||
|
||||
* <a href="https://strawberry.rocks/" class="external-link" target="_blank">🍓</a> 👶
|
||||
* ⏮️ <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">🩺 FastAPI</a>
|
||||
* <a href="https://ariadnegraphql.org/" class="external-link" target="_blank">👸</a>
|
||||
* ⏮️ <a href="https://ariadnegraphql.org/docs/starlette-integration" class="external-link" target="_blank">🩺 💃</a> (👈 ✔ FastAPI)
|
||||
* <a href="https://tartiflette.io/" class="external-link" target="_blank">🍟</a>
|
||||
* ⏮️ <a href="https://tartiflette.github.io/tartiflette-asgi/" class="external-link" target="_blank">🍟 🔫</a> 🚚 🔫 🛠️
|
||||
* <a href="https://graphene-python.org/" class="external-link" target="_blank">⚗</a>
|
||||
* ⏮️ <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">💃-Graphene3️⃣</a>
|
||||
|
||||
## 🕹 ⏮️ 🍓
|
||||
|
||||
🚥 👆 💪 ⚖️ 💚 👷 ⏮️ **🕹**, <a href="https://strawberry.rocks/" class="external-link" target="_blank">**🍓**</a> **👍** 🗃 ⚫️ ✔️ 🔧 🔐 **FastAPI** 🔧, ⚫️ 🌐 ⚓️ 🔛 **🆎 ✍**.
|
||||
|
||||
⚓️ 🔛 👆 ⚙️ 💼, 👆 5️⃣📆 💖 ⚙️ 🎏 🗃, ✋️ 🚥 👆 💭 👤, 👤 🔜 🎲 🤔 👆 🔄 **🍓**.
|
||||
|
||||
📥 🤪 🎮 ❔ 👆 💪 🛠️ 🍓 ⏮️ FastAPI:
|
||||
|
||||
```Python hl_lines="3 22 25-26"
|
||||
{!../../../docs_src/graphql/tutorial001.py!}
|
||||
```
|
||||
|
||||
👆 💪 💡 🌅 🔃 🍓 <a href="https://strawberry.rocks/" class="external-link" target="_blank">🍓 🧾</a>.
|
||||
|
||||
& 🩺 🔃 <a href="https://strawberry.rocks/docs/integrations/fastapi" class="external-link" target="_blank">🍓 ⏮️ FastAPI</a>.
|
||||
|
||||
## 🗝 `GraphQLApp` ⚪️➡️ 💃
|
||||
|
||||
⏮️ ⏬ 💃 🔌 `GraphQLApp` 🎓 🛠️ ⏮️ <a href="https://graphene-python.org/" class="external-link" target="_blank">⚗</a>.
|
||||
|
||||
⚫️ 😢 ⚪️➡️ 💃, ✋️ 🚥 👆 ✔️ 📟 👈 ⚙️ ⚫️, 👆 💪 💪 **↔** <a href="https://github.com/ciscorn/starlette-graphene3" class="external-link" target="_blank">💃-Graphene3️⃣</a>, 👈 📔 🎏 ⚙️ 💼 & ✔️ **🌖 🌓 🔢**.
|
||||
|
||||
!!! tip
|
||||
🚥 👆 💪 🕹, 👤 🔜 👍 👆 ✅ 👅 <a href="https://strawberry.rocks/" class="external-link" target="_blank">🍓</a>, ⚫️ ⚓️ 🔛 🆎 ✍ ↩️ 🛃 🎓 & 🆎.
|
||||
|
||||
## 💡 🌅
|
||||
|
||||
👆 💪 💡 🌅 🔃 **🕹** <a href="https://graphql.org/" class="external-link" target="_blank">🛂 🕹 🧾</a>.
|
||||
|
||||
👆 💪 ✍ 🌅 🔃 🔠 👈 🗃 🔬 🔛 👫 🔗.
|
||||
24
docs/em/docs/advanced/index.md
Normal file
24
docs/em/docs/advanced/index.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# 🏧 👩💻 🦮 - 🎶
|
||||
|
||||
## 🌖 ⚒
|
||||
|
||||
👑 [🔰 - 👩💻 🦮](../tutorial/){.internal-link target=_blank} 🔜 🥃 🤝 👆 🎫 🔘 🌐 👑 ⚒ **FastAPI**.
|
||||
|
||||
⏭ 📄 👆 🔜 👀 🎏 🎛, 📳, & 🌖 ⚒.
|
||||
|
||||
!!! tip
|
||||
⏭ 📄 **🚫 🎯 "🏧"**.
|
||||
|
||||
& ⚫️ 💪 👈 👆 ⚙️ 💼, ⚗ 1️⃣ 👫.
|
||||
|
||||
## ✍ 🔰 🥇
|
||||
|
||||
👆 💪 ⚙️ 🏆 ⚒ **FastAPI** ⏮️ 💡 ⚪️➡️ 👑 [🔰 - 👩💻 🦮](../tutorial/){.internal-link target=_blank}.
|
||||
|
||||
& ⏭ 📄 🤔 👆 ⏪ ✍ ⚫️, & 🤔 👈 👆 💭 👈 👑 💭.
|
||||
|
||||
## 🏎.🅾 ↗️
|
||||
|
||||
🚥 👆 🔜 💖 ✊ 🏧-🔰 ↗️ 🔗 👉 📄 🩺, 👆 💪 💚 ✅: <a href="https://testdriven.io/courses/tdd-fastapi/" class="external-link" target="_blank">💯-💾 🛠️ ⏮️ FastAPI & ☁</a> **🏎.🅾**.
|
||||
|
||||
👫 ⏳ 🩸 1️⃣0️⃣ 💯 🌐 💰 🛠️ **FastAPI**. 👶 👶
|
||||
99
docs/em/docs/advanced/middleware.md
Normal file
99
docs/em/docs/advanced/middleware.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# 🏧 🛠️
|
||||
|
||||
👑 🔰 👆 ✍ ❔ 🚮 [🛃 🛠️](../tutorial/middleware.md){.internal-link target=_blank} 👆 🈸.
|
||||
|
||||
& ⤴️ 👆 ✍ ❔ 🍵 [⚜ ⏮️ `CORSMiddleware`](../tutorial/cors.md){.internal-link target=_blank}.
|
||||
|
||||
👉 📄 👥 🔜 👀 ❔ ⚙️ 🎏 🛠️.
|
||||
|
||||
## ❎ 🔫 🛠️
|
||||
|
||||
**FastAPI** ⚓️ 🔛 💃 & 🛠️ <abbr title="Asynchronous Server Gateway Interface">🔫</abbr> 🔧, 👆 💪 ⚙️ 🙆 🔫 🛠️.
|
||||
|
||||
🛠️ 🚫 ✔️ ⚒ FastAPI ⚖️ 💃 👷, 📏 ⚫️ ⏩ 🔫 🔌.
|
||||
|
||||
🏢, 🔫 🛠️ 🎓 👈 ⌛ 📨 🔫 📱 🥇 ❌.
|
||||
|
||||
, 🧾 🥉-🥳 🔫 🛠️ 👫 🔜 🎲 💬 👆 🕳 💖:
|
||||
|
||||
```Python
|
||||
from unicorn import UnicornMiddleware
|
||||
|
||||
app = SomeASGIApp()
|
||||
|
||||
new_app = UnicornMiddleware(app, some_config="rainbow")
|
||||
```
|
||||
|
||||
✋️ FastAPI (🤙 💃) 🚚 🙅 🌌 ⚫️ 👈 ⚒ 💭 👈 🔗 🛠️ 🍵 💽 ❌ & 🛃 ⚠ 🐕🦺 👷 ☑.
|
||||
|
||||
👈, 👆 ⚙️ `app.add_middleware()` (🖼 ⚜).
|
||||
|
||||
```Python
|
||||
from fastapi import FastAPI
|
||||
from unicorn import UnicornMiddleware
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
app.add_middleware(UnicornMiddleware, some_config="rainbow")
|
||||
```
|
||||
|
||||
`app.add_middleware()` 📨 🛠️ 🎓 🥇 ❌ & 🙆 🌖 ❌ 🚶♀️ 🛠️.
|
||||
|
||||
## 🛠️ 🛠️
|
||||
|
||||
**FastAPI** 🔌 📚 🛠️ ⚠ ⚙️ 💼, 👥 🔜 👀 ⏭ ❔ ⚙️ 👫.
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
⏭ 🖼, 👆 💪 ⚙️ `from starlette.middleware.something import SomethingMiddleware`.
|
||||
|
||||
**FastAPI** 🚚 📚 🛠️ `fastapi.middleware` 🏪 👆, 👩💻. ✋️ 🌅 💪 🛠️ 👟 🔗 ⚪️➡️ 💃.
|
||||
|
||||
## `HTTPSRedirectMiddleware`
|
||||
|
||||
🛠️ 👈 🌐 📨 📨 🔜 👯♂️ `https` ⚖️ `wss`.
|
||||
|
||||
🙆 📨 📨 `http` ⚖️ `ws` 🔜 ❎ 🔐 ⚖ ↩️.
|
||||
|
||||
```Python hl_lines="2 6"
|
||||
{!../../../docs_src/advanced_middleware/tutorial001.py!}
|
||||
```
|
||||
|
||||
## `TrustedHostMiddleware`
|
||||
|
||||
🛠️ 👈 🌐 📨 📨 ✔️ ☑ ⚒ `Host` 🎚, ✔ 💂♂ 🛡 🇺🇸🔍 🦠 🎚 👊.
|
||||
|
||||
```Python hl_lines="2 6-8"
|
||||
{!../../../docs_src/advanced_middleware/tutorial002.py!}
|
||||
```
|
||||
|
||||
📄 ❌ 🐕🦺:
|
||||
|
||||
* `allowed_hosts` - 📇 🆔 📛 👈 🔜 ✔ 📛. 🃏 🆔 ✅ `*.example.com` 🐕🦺 🎀 📁. ✔ 🙆 📛 👯♂️ ⚙️ `allowed_hosts=["*"]` ⚖️ 🚫 🛠️.
|
||||
|
||||
🚥 📨 📨 🔨 🚫 ✔ ☑ ⤴️ `400` 📨 🔜 📨.
|
||||
|
||||
## `GZipMiddleware`
|
||||
|
||||
🍵 🗜 📨 🙆 📨 👈 🔌 `"gzip"` `Accept-Encoding` 🎚.
|
||||
|
||||
🛠️ 🔜 🍵 👯♂️ 🐩 & 🎥 📨.
|
||||
|
||||
```Python hl_lines="2 6"
|
||||
{!../../../docs_src/advanced_middleware/tutorial003.py!}
|
||||
```
|
||||
|
||||
📄 ❌ 🐕🦺:
|
||||
|
||||
* `minimum_size` - 🚫 🗜 📨 👈 🤪 🌘 👉 💯 📐 🔢. 🔢 `500`.
|
||||
|
||||
## 🎏 🛠️
|
||||
|
||||
📤 📚 🎏 🔫 🛠️.
|
||||
|
||||
🖼:
|
||||
|
||||
* <a href="https://docs.sentry.io/platforms/python/asgi/" class="external-link" target="_blank">🔫</a>
|
||||
* <a href="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py" class="external-link" target="_blank">Uvicorn `ProxyHeadersMiddleware`</a>
|
||||
* <a href="https://github.com/florimondmanca/msgpack-asgi" class="external-link" target="_blank">🇸🇲</a>
|
||||
|
||||
👀 🎏 💪 🛠️ ✅ <a href="https://www.starlette.io/middleware/" class="external-link" target="_blank">💃 🛠️ 🩺</a> & <a href="https://github.com/florimondmanca/awesome-asgi" class="external-link" target="_blank">🔫 👌 📇</a>.
|
||||
156
docs/em/docs/advanced/nosql-databases.md
Normal file
156
docs/em/docs/advanced/nosql-databases.md
Normal file
@@ -0,0 +1,156 @@
|
||||
# ☁ (📎 / 🦏 💽) 💽
|
||||
|
||||
**FastAPI** 💪 🛠️ ⏮️ 🙆 <abbr title="Distributed database (Big Data), also 'Not Only SQL'">☁</abbr>.
|
||||
|
||||
📥 👥 🔜 👀 🖼 ⚙️ **<a href="https://www.couchbase.com/" class="external-link" target="_blank">🗄</a>**, <abbr title="Document here refers to a JSON object (a dict), with keys and values, and those values can also be other JSON objects, arrays (lists), numbers, strings, booleans, etc.">📄</abbr> 🧢 ☁ 💽.
|
||||
|
||||
👆 💪 🛠️ ⚫️ 🙆 🎏 ☁ 💽 💖:
|
||||
|
||||
* **✳**
|
||||
* **👸**
|
||||
* **✳**
|
||||
* **🇸🇲**
|
||||
* **✳**, ♒️.
|
||||
|
||||
!!! tip
|
||||
📤 🛂 🏗 🚂 ⏮️ **FastAPI** & **🗄**, 🌐 ⚓️ 🔛 **☁**, 🔌 🕸 & 🌖 🧰: <a href="https://github.com/tiangolo/full-stack-fastapi-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-fastapi-couchbase</a>
|
||||
|
||||
## 🗄 🗄 🦲
|
||||
|
||||
🔜, 🚫 💸 🙋 🎂, 🕴 🗄:
|
||||
|
||||
```Python hl_lines="3-5"
|
||||
{!../../../docs_src/nosql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
## 🔬 📉 ⚙️ "📄 🆎"
|
||||
|
||||
👥 🔜 ⚙️ ⚫️ ⏪ 🔧 🏑 `type` 👆 📄.
|
||||
|
||||
👉 🚫 ✔ 🗄, ✋️ 👍 💡 👈 🔜 ℹ 👆 ⏮️.
|
||||
|
||||
```Python hl_lines="9"
|
||||
{!../../../docs_src/nosql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
## 🚮 🔢 🤚 `Bucket`
|
||||
|
||||
**🗄**, 🥡 ⚒ 📄, 👈 💪 🎏 🆎.
|
||||
|
||||
👫 🛎 🌐 🔗 🎏 🈸.
|
||||
|
||||
🔑 🔗 💽 🌏 🔜 "💽" (🎯 💽, 🚫 💽 💽).
|
||||
|
||||
🔑 **✳** 🔜 "🗃".
|
||||
|
||||
📟, `Bucket` 🎨 👑 🇨🇻 📻 ⏮️ 💽.
|
||||
|
||||
👉 🚙 🔢 🔜:
|
||||
|
||||
* 🔗 **🗄** 🌑 (👈 💪 👁 🎰).
|
||||
* ⚒ 🔢 ⏲.
|
||||
* 🔓 🌑.
|
||||
* 🤚 `Bucket` 👐.
|
||||
* ⚒ 🔢 ⏲.
|
||||
* 📨 ⚫️.
|
||||
|
||||
```Python hl_lines="12-21"
|
||||
{!../../../docs_src/nosql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
## ✍ Pydantic 🏷
|
||||
|
||||
**🗄** "📄" 🤙 "🎻 🎚", 👥 💪 🏷 👫 ⏮️ Pydantic.
|
||||
|
||||
### `User` 🏷
|
||||
|
||||
🥇, ➡️ ✍ `User` 🏷:
|
||||
|
||||
```Python hl_lines="24-28"
|
||||
{!../../../docs_src/nosql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
👥 🔜 ⚙️ 👉 🏷 👆 *➡ 🛠️ 🔢*,, 👥 🚫 🔌 ⚫️ `hashed_password`.
|
||||
|
||||
### `UserInDB` 🏷
|
||||
|
||||
🔜, ➡️ ✍ `UserInDB` 🏷.
|
||||
|
||||
👉 🔜 ✔️ 💽 👈 🤙 🏪 💽.
|
||||
|
||||
👥 🚫 ✍ ⚫️ 🏿 Pydantic `BaseModel` ✋️ 🏿 👆 👍 `User`, ↩️ ⚫️ 🔜 ✔️ 🌐 🔢 `User` ➕ 👩❤👨 🌅:
|
||||
|
||||
```Python hl_lines="31-33"
|
||||
{!../../../docs_src/nosql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
👀 👈 👥 ✔️ `hashed_password` & `type` 🏑 👈 🔜 🏪 💽.
|
||||
|
||||
✋️ ⚫️ 🚫 🍕 🏢 `User` 🏷 (1️⃣ 👥 🔜 📨 *➡ 🛠️*).
|
||||
|
||||
## 🤚 👩💻
|
||||
|
||||
🔜 ✍ 🔢 👈 🔜:
|
||||
|
||||
* ✊ 🆔.
|
||||
* 🏗 📄 🆔 ⚪️➡️ ⚫️.
|
||||
* 🤚 📄 ⏮️ 👈 🆔.
|
||||
* 🚮 🎚 📄 `UserInDB` 🏷.
|
||||
|
||||
🏗 🔢 👈 🕴 💡 🤚 👆 👩💻 ⚪️➡️ `username` (⚖️ 🙆 🎏 🔢) 🔬 👆 *➡ 🛠️ 🔢*, 👆 💪 🌖 💪 🏤-⚙️ ⚫️ 💗 🍕 & 🚮 <abbr title="Automated test, written in code, that checks if another piece of code is working correctly.">⚒ 💯</abbr> ⚫️:
|
||||
|
||||
```Python hl_lines="36-42"
|
||||
{!../../../docs_src/nosql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
### Ⓜ-🎻
|
||||
|
||||
🚥 👆 🚫 😰 ⏮️ `f"userprofile::{username}"`, ⚫️ 🐍 "<a href="https://docs.python.org/3/glossary.html#term-f-string" class="external-link" target="_blank">Ⓜ-🎻</a>".
|
||||
|
||||
🙆 🔢 👈 🚮 🔘 `{}` Ⓜ-🎻 🔜 ↔ / 💉 🎻.
|
||||
|
||||
### `dict` 🏗
|
||||
|
||||
🚥 👆 🚫 😰 ⏮️ `UserInDB(**result.value)`, <a href="https://docs.python.org/3/glossary.html#term-argument" class="external-link" target="_blank">⚫️ ⚙️ `dict` "🏗"</a>.
|
||||
|
||||
⚫️ 🔜 ✊ `dict` `result.value`, & ✊ 🔠 🚮 🔑 & 💲 & 🚶♀️ 👫 🔑-💲 `UserInDB` 🇨🇻 ❌.
|
||||
|
||||
, 🚥 `dict` 🔌:
|
||||
|
||||
```Python
|
||||
{
|
||||
"username": "johndoe",
|
||||
"hashed_password": "some_hash",
|
||||
}
|
||||
```
|
||||
|
||||
⚫️ 🔜 🚶♀️ `UserInDB` :
|
||||
|
||||
```Python
|
||||
UserInDB(username="johndoe", hashed_password="some_hash")
|
||||
```
|
||||
|
||||
## ✍ 👆 **FastAPI** 📟
|
||||
|
||||
### ✍ `FastAPI` 📱
|
||||
|
||||
```Python hl_lines="46"
|
||||
{!../../../docs_src/nosql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
### ✍ *➡ 🛠️ 🔢*
|
||||
|
||||
👆 📟 🤙 🗄 & 👥 🚫 ⚙️ <a href="https://docs.couchbase.com/python-sdk/2.5/async-programming.html#asyncio-python-3-5" class="external-link" target="_blank">🥼 🐍 <code>await</code> 🐕🦺</a>, 👥 🔜 📣 👆 🔢 ⏮️ 😐 `def` ↩️ `async def`.
|
||||
|
||||
, 🗄 👍 🚫 ⚙️ 👁 `Bucket` 🎚 💗 "<abbr title="A sequence of code being executed by the program, while at the same time, or at intervals, there can be others being executed too.">🧵</abbr>Ⓜ",, 👥 💪 🤚 🥡 🔗 & 🚶♀️ ⚫️ 👆 🚙 🔢:
|
||||
|
||||
```Python hl_lines="49-53"
|
||||
{!../../../docs_src/nosql_databases/tutorial001.py!}
|
||||
```
|
||||
|
||||
## 🌃
|
||||
|
||||
👆 💪 🛠️ 🙆 🥉 🥳 ☁ 💽, ⚙️ 👫 🐩 📦.
|
||||
|
||||
🎏 ✔ 🙆 🎏 🔢 🧰, ⚙️ ⚖️ 🛠️.
|
||||
179
docs/em/docs/advanced/openapi-callbacks.md
Normal file
179
docs/em/docs/advanced/openapi-callbacks.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# 🗄 ⏲
|
||||
|
||||
👆 💪 ✍ 🛠️ ⏮️ *➡ 🛠️* 👈 💪 ⏲ 📨 *🔢 🛠️* ✍ 👱 🙆 (🎲 🎏 👩💻 👈 🔜 *⚙️* 👆 🛠️).
|
||||
|
||||
🛠️ 👈 🔨 🕐❔ 👆 🛠️ 📱 🤙 *🔢 🛠️* 📛 "⏲". ↩️ 🖥 👈 🔢 👩💻 ✍ 📨 📨 👆 🛠️ & ⤴️ 👆 🛠️ *🤙 🔙*, 📨 📨 *🔢 🛠️* (👈 🎲 ✍ 🎏 👩💻).
|
||||
|
||||
👉 💼, 👆 💪 💚 📄 ❔ 👈 🔢 🛠️ *🔜* 👀 💖. ⚫️❔ *➡ 🛠️* ⚫️ 🔜 ✔️, ⚫️❔ 💪 ⚫️ 🔜 ⌛, ⚫️❔ 📨 ⚫️ 🔜 📨, ♒️.
|
||||
|
||||
## 📱 ⏮️ ⏲
|
||||
|
||||
➡️ 👀 🌐 👉 ⏮️ 🖼.
|
||||
|
||||
🌈 👆 🛠️ 📱 👈 ✔ 🏗 🧾.
|
||||
|
||||
👉 🧾 🔜 ✔️ `id`, `title` (📦), `customer`, & `total`.
|
||||
|
||||
👩💻 👆 🛠️ (🔢 👩💻) 🔜 ✍ 🧾 👆 🛠️ ⏮️ 🏤 📨.
|
||||
|
||||
⤴️ 👆 🛠️ 🔜 (➡️ 🌈):
|
||||
|
||||
* 📨 🧾 🕴 🔢 👩💻.
|
||||
* 📈 💸.
|
||||
* 📨 📨 🔙 🛠️ 👩💻 (🔢 👩💻).
|
||||
* 👉 🔜 🔨 📨 🏤 📨 (⚪️➡️ *👆 🛠️*) *🔢 🛠️* 🚚 👈 🔢 👩💻 (👉 "⏲").
|
||||
|
||||
## 😐 **FastAPI** 📱
|
||||
|
||||
➡️ 🥇 👀 ❔ 😐 🛠️ 📱 🔜 👀 💖 ⏭ ❎ ⏲.
|
||||
|
||||
⚫️ 🔜 ✔️ *➡ 🛠️* 👈 🔜 📨 `Invoice` 💪, & 🔢 🔢 `callback_url` 👈 🔜 🔌 📛 ⏲.
|
||||
|
||||
👉 🍕 📶 😐, 🌅 📟 🎲 ⏪ 😰 👆:
|
||||
|
||||
```Python hl_lines="9-13 36-53"
|
||||
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
`callback_url` 🔢 🔢 ⚙️ Pydantic <a href="https://pydantic-docs.helpmanual.io/usage/types/#urls" class="external-link" target="_blank">📛</a> 🆎.
|
||||
|
||||
🕴 🆕 👜 `callbacks=messages_callback_router.routes` ❌ *➡ 🛠️ 👨🎨*. 👥 🔜 👀 ⚫️❔ 👈 ⏭.
|
||||
|
||||
## 🔬 ⏲
|
||||
|
||||
☑ ⏲ 📟 🔜 🪀 🙇 🔛 👆 👍 🛠️ 📱.
|
||||
|
||||
& ⚫️ 🔜 🎲 🪀 📚 ⚪️➡️ 1️⃣ 📱 ⏭.
|
||||
|
||||
⚫️ 💪 1️⃣ ⚖️ 2️⃣ ⏸ 📟, 💖:
|
||||
|
||||
```Python
|
||||
callback_url = "https://example.com/api/v1/invoices/events/"
|
||||
httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
|
||||
```
|
||||
|
||||
✋️ 🎲 🏆 ⚠ 🍕 ⏲ ⚒ 💭 👈 👆 🛠️ 👩💻 (🔢 👩💻) 🛠️ *🔢 🛠️* ☑, 🛄 💽 👈 *👆 🛠️* 🔜 📨 📨 💪 ⏲, ♒️.
|
||||
|
||||
, ⚫️❔ 👥 🔜 ⏭ 🚮 📟 📄 ❔ 👈 *🔢 🛠️* 🔜 👀 💖 📨 ⏲ ⚪️➡️ *👆 🛠️*.
|
||||
|
||||
👈 🧾 🔜 🎦 🆙 🦁 🎚 `/docs` 👆 🛠️, & ⚫️ 🔜 ➡️ 🔢 👩💻 💭 ❔ 🏗 *🔢 🛠️*.
|
||||
|
||||
👉 🖼 🚫 🛠️ ⏲ ⚫️ (👈 💪 ⏸ 📟), 🕴 🧾 🍕.
|
||||
|
||||
!!! tip
|
||||
☑ ⏲ 🇺🇸🔍 📨.
|
||||
|
||||
🕐❔ 🛠️ ⏲ 👆, 👆 💪 ⚙️ 🕳 💖 <a href="https://www.python-httpx.org" class="external-link" target="_blank">🇸🇲</a> ⚖️ <a href="https://requests.readthedocs.io/" class="external-link" target="_blank">📨</a>.
|
||||
|
||||
## ✍ ⏲ 🧾 📟
|
||||
|
||||
👉 📟 🏆 🚫 🛠️ 👆 📱, 👥 🕴 💪 ⚫️ *📄* ❔ 👈 *🔢 🛠️* 🔜 👀 💖.
|
||||
|
||||
✋️, 👆 ⏪ 💭 ❔ 💪 ✍ 🏧 🧾 🛠️ ⏮️ **FastAPI**.
|
||||
|
||||
👥 🔜 ⚙️ 👈 🎏 💡 📄 ❔ *🔢 🛠️* 🔜 👀 💖... 🏗 *➡ 🛠️(Ⓜ)* 👈 🔢 🛠️ 🔜 🛠️ (🕐 👆 🛠️ 🔜 🤙).
|
||||
|
||||
!!! tip
|
||||
🕐❔ ✍ 📟 📄 ⏲, ⚫️ 💪 ⚠ 🌈 👈 👆 👈 *🔢 👩💻*. & 👈 👆 ⏳ 🛠️ *🔢 🛠️*, 🚫 *👆 🛠️*.
|
||||
|
||||
🍕 🛠️ 👉 ☝ 🎑 ( *🔢 👩💻*) 💪 ℹ 👆 💭 💖 ⚫️ 🌅 ⭐ 🌐❔ 🚮 🔢, Pydantic 🏷 💪, 📨, ♒️. 👈 *🔢 🛠️*.
|
||||
|
||||
### ✍ ⏲ `APIRouter`
|
||||
|
||||
🥇 ✍ 🆕 `APIRouter` 👈 🔜 🔌 1️⃣ ⚖️ 🌅 ⏲.
|
||||
|
||||
```Python hl_lines="3 25"
|
||||
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
|
||||
```
|
||||
|
||||
### ✍ ⏲ *➡ 🛠️*
|
||||
|
||||
✍ ⏲ *➡ 🛠️* ⚙️ 🎏 `APIRouter` 👆 ✍ 🔛.
|
||||
|
||||
⚫️ 🔜 👀 💖 😐 FastAPI *➡ 🛠️*:
|
||||
|
||||
* ⚫️ 🔜 🎲 ✔️ 📄 💪 ⚫️ 🔜 📨, ✅ `body: InvoiceEvent`.
|
||||
* & ⚫️ 💪 ✔️ 📄 📨 ⚫️ 🔜 📨, ✅ `response_model=InvoiceEventReceived`.
|
||||
|
||||
```Python hl_lines="16-18 21-22 28-32"
|
||||
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
|
||||
```
|
||||
|
||||
📤 2️⃣ 👑 🔺 ⚪️➡️ 😐 *➡ 🛠️*:
|
||||
|
||||
* ⚫️ 🚫 💪 ✔️ 🙆 ☑ 📟, ↩️ 👆 📱 🔜 🙅 🤙 👉 📟. ⚫️ 🕴 ⚙️ 📄 *🔢 🛠️*. , 🔢 💪 ✔️ `pass`.
|
||||
* *➡* 💪 🔌 <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#key-expression" class="external-link" target="_blank">🗄 3️⃣ 🧬</a> (👀 🌖 🔛) 🌐❔ ⚫️ 💪 ⚙️ 🔢 ⏮️ 🔢 & 🍕 ⏮️ 📨 📨 *👆 🛠️*.
|
||||
|
||||
### ⏲ ➡ 🧬
|
||||
|
||||
⏲ *➡* 💪 ✔️ <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#key-expression" class="external-link" target="_blank">🗄 3️⃣ 🧬</a> 👈 💪 🔌 🍕 ⏮️ 📨 📨 *👆 🛠️*.
|
||||
|
||||
👉 💼, ⚫️ `str`:
|
||||
|
||||
```Python
|
||||
"{$callback_url}/invoices/{$request.body.id}"
|
||||
```
|
||||
|
||||
, 🚥 👆 🛠️ 👩💻 (🔢 👩💻) 📨 📨 *👆 🛠️* :
|
||||
|
||||
```
|
||||
https://yourapi.com/invoices/?callback_url=https://www.external.org/events
|
||||
```
|
||||
|
||||
⏮️ 🎻 💪:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"id": "2expen51ve",
|
||||
"customer": "Mr. Richie Rich",
|
||||
"total": "9999"
|
||||
}
|
||||
```
|
||||
|
||||
⤴️ *👆 🛠️* 🔜 🛠️ 🧾, & ☝ ⏪, 📨 ⏲ 📨 `callback_url` ( *🔢 🛠️*):
|
||||
|
||||
```
|
||||
https://www.external.org/events/invoices/2expen51ve
|
||||
```
|
||||
|
||||
⏮️ 🎻 💪 ⚗ 🕳 💖:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"description": "Payment celebration",
|
||||
"paid": true
|
||||
}
|
||||
```
|
||||
|
||||
& ⚫️ 🔜 ⌛ 📨 ⚪️➡️ 👈 *🔢 🛠️* ⏮️ 🎻 💪 💖:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"ok": true
|
||||
}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👀 ❔ ⏲ 📛 ⚙️ 🔌 📛 📨 🔢 🔢 `callback_url` (`https://www.external.org/events`) & 🧾 `id` ⚪️➡️ 🔘 🎻 💪 (`2expen51ve`).
|
||||
|
||||
### 🚮 ⏲ 📻
|
||||
|
||||
👉 ☝ 👆 ✔️ *⏲ ➡ 🛠️(Ⓜ)* 💪 (1️⃣(Ⓜ) 👈 *🔢 👩💻* 🔜 🛠️ *🔢 🛠️*) ⏲ 📻 👆 ✍ 🔛.
|
||||
|
||||
🔜 ⚙️ 🔢 `callbacks` *👆 🛠️ ➡ 🛠️ 👨🎨* 🚶♀️ 🔢 `.routes` (👈 🤙 `list` 🛣/*➡ 🛠️*) ⚪️➡️ 👈 ⏲ 📻:
|
||||
|
||||
```Python hl_lines="35"
|
||||
{!../../../docs_src/openapi_callbacks/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👀 👈 👆 🚫 🚶♀️ 📻 ⚫️ (`invoices_callback_router`) `callback=`, ✋️ 🔢 `.routes`, `invoices_callback_router.routes`.
|
||||
|
||||
### ✅ 🩺
|
||||
|
||||
🔜 👆 💪 ▶️ 👆 📱 ⏮️ Uvicorn & 🚶 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
👆 🔜 👀 👆 🩺 ✅ "⏲" 📄 👆 *➡ 🛠️* 👈 🎦 ❔ *🔢 🛠️* 🔜 👀 💖:
|
||||
|
||||
<img src="/img/tutorial/openapi-callbacks/image01.png">
|
||||
170
docs/em/docs/advanced/path-operation-advanced-configuration.md
Normal file
170
docs/em/docs/advanced/path-operation-advanced-configuration.md
Normal file
@@ -0,0 +1,170 @@
|
||||
# ➡ 🛠️ 🏧 📳
|
||||
|
||||
## 🗄 {
|
||||
|
||||
!!! warning
|
||||
🚥 👆 🚫 "🕴" 🗄, 👆 🎲 🚫 💪 👉.
|
||||
|
||||
👆 💪 ⚒ 🗄 `operationId` ⚙️ 👆 *➡ 🛠️* ⏮️ 🔢 `operation_id`.
|
||||
|
||||
👆 🔜 ✔️ ⚒ 💭 👈 ⚫️ 😍 🔠 🛠️.
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial001.py!}
|
||||
```
|
||||
|
||||
### ⚙️ *➡ 🛠️ 🔢* 📛 {
|
||||
|
||||
🚥 👆 💚 ⚙️ 👆 🔗' 🔢 📛 `operationId`Ⓜ, 👆 💪 🔁 🤭 🌐 👫 & 🔐 🔠 *➡ 🛠️* `operation_id` ⚙️ 👫 `APIRoute.name`.
|
||||
|
||||
👆 🔜 ⚫️ ⏮️ ❎ 🌐 👆 *➡ 🛠️*.
|
||||
|
||||
```Python hl_lines="2 12-21 24"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
🚥 👆 ❎ 🤙 `app.openapi()`, 👆 🔜 ℹ `operationId`Ⓜ ⏭ 👈.
|
||||
|
||||
!!! warning
|
||||
🚥 👆 👉, 👆 ✔️ ⚒ 💭 🔠 1️⃣ 👆 *➡ 🛠️ 🔢* ✔️ 😍 📛.
|
||||
|
||||
🚥 👫 🎏 🕹 (🐍 📁).
|
||||
|
||||
## 🚫 ⚪️➡️ 🗄
|
||||
|
||||
🚫 *➡ 🛠️* ⚪️➡️ 🏗 🗄 🔗 (& ➡️, ⚪️➡️ 🏧 🧾 ⚙️), ⚙️ 🔢 `include_in_schema` & ⚒ ⚫️ `False`:
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial003.py!}
|
||||
```
|
||||
|
||||
## 🏧 📛 ⚪️➡️ #️⃣
|
||||
|
||||
👆 💪 📉 ⏸ ⚙️ ⚪️➡️ #️⃣ *➡ 🛠️ 🔢* 🗄.
|
||||
|
||||
❎ `\f` (😖 "📨 🍼" 🦹) 🤕 **FastAPI** 🔁 🔢 ⚙️ 🗄 👉 ☝.
|
||||
|
||||
⚫️ 🏆 🚫 🎦 🆙 🧾, ✋️ 🎏 🧰 (✅ 🐉) 🔜 💪 ⚙️ 🎂.
|
||||
|
||||
```Python hl_lines="19-29"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial004.py!}
|
||||
```
|
||||
|
||||
## 🌖 📨
|
||||
|
||||
👆 🎲 ✔️ 👀 ❔ 📣 `response_model` & `status_code` *➡ 🛠️*.
|
||||
|
||||
👈 🔬 🗃 🔃 👑 📨 *➡ 🛠️*.
|
||||
|
||||
👆 💪 📣 🌖 📨 ⏮️ 👫 🏷, 👔 📟, ♒️.
|
||||
|
||||
📤 🎂 📃 📥 🧾 🔃 ⚫️, 👆 💪 ✍ ⚫️ [🌖 📨 🗄](./additional-responses.md){.internal-link target=_blank}.
|
||||
|
||||
## 🗄 ➕
|
||||
|
||||
🕐❔ 👆 📣 *➡ 🛠️* 👆 🈸, **FastAPI** 🔁 🏗 🔗 🗃 🔃 👈 *➡ 🛠️* 🔌 🗄 🔗.
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
🗄 🔧 ⚫️ 🤙 <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">🛠️ 🎚</a>.
|
||||
|
||||
⚫️ ✔️ 🌐 ℹ 🔃 *➡ 🛠️* & ⚙️ 🏗 🏧 🧾.
|
||||
|
||||
⚫️ 🔌 `tags`, `parameters`, `requestBody`, `responses`, ♒️.
|
||||
|
||||
👉 *➡ 🛠️*-🎯 🗄 🔗 🛎 🏗 🔁 **FastAPI**, ✋️ 👆 💪 ↔ ⚫️.
|
||||
|
||||
!!! tip
|
||||
👉 🔅 🎚 ↔ ☝.
|
||||
|
||||
🚥 👆 🕴 💪 📣 🌖 📨, 🌅 🏪 🌌 ⚫️ ⏮️ [🌖 📨 🗄](./additional-responses.md){.internal-link target=_blank}.
|
||||
|
||||
👆 💪 ↔ 🗄 🔗 *➡ 🛠️* ⚙️ 🔢 `openapi_extra`.
|
||||
|
||||
### 🗄 ↔
|
||||
|
||||
👉 `openapi_extra` 💪 👍, 🖼, 📣 [🗄 ↔](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
|
||||
|
||||
```Python hl_lines="6"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial005.py!}
|
||||
```
|
||||
|
||||
🚥 👆 📂 🏧 🛠️ 🩺, 👆 ↔ 🔜 🎦 🆙 🔝 🎯 *➡ 🛠️*.
|
||||
|
||||
<img src="/img/tutorial/path-operation-advanced-configuration/image01.png">
|
||||
|
||||
& 🚥 👆 👀 📉 🗄 ( `/openapi.json` 👆 🛠️), 👆 🔜 👀 👆 ↔ 🍕 🎯 *➡ 🛠️* 💁♂️:
|
||||
|
||||
```JSON hl_lines="22"
|
||||
{
|
||||
"openapi": "3.0.2",
|
||||
"info": {
|
||||
"title": "FastAPI",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"paths": {
|
||||
"/items/": {
|
||||
"get": {
|
||||
"summary": "Read Items",
|
||||
"operationId": "read_items_items__get",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful Response",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-aperture-labs-portal": "blue"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 🛃 🗄 *➡ 🛠️* 🔗
|
||||
|
||||
📖 `openapi_extra` 🔜 🙇 🔗 ⏮️ 🔁 🏗 🗄 🔗 *➡ 🛠️*.
|
||||
|
||||
, 👆 💪 🚮 🌖 💽 🔁 🏗 🔗.
|
||||
|
||||
🖼, 👆 💪 💭 ✍ & ✔ 📨 ⏮️ 👆 👍 📟, 🍵 ⚙️ 🏧 ⚒ FastAPI ⏮️ Pydantic, ✋️ 👆 💪 💚 🔬 📨 🗄 🔗.
|
||||
|
||||
👆 💪 👈 ⏮️ `openapi_extra`:
|
||||
|
||||
```Python hl_lines="20-37 39-40"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial006.py!}
|
||||
```
|
||||
|
||||
👉 🖼, 👥 🚫 📣 🙆 Pydantic 🏷. 👐, 📨 💪 🚫 <abbr title="converted from some plain format, like bytes, into Python objects">🎻</abbr> 🎻, ⚫️ ✍ 🔗 `bytes`, & 🔢 `magic_data_reader()` 🔜 🈚 🎻 ⚫️ 🌌.
|
||||
|
||||
👐, 👥 💪 📣 📈 🔗 📨 💪.
|
||||
|
||||
### 🛃 🗄 🎚 🆎
|
||||
|
||||
⚙️ 👉 🎏 🎱, 👆 💪 ⚙️ Pydantic 🏷 🔬 🎻 🔗 👈 ⤴️ 🔌 🛃 🗄 🔗 📄 *➡ 🛠️*.
|
||||
|
||||
& 👆 💪 👉 🚥 💽 🆎 📨 🚫 🎻.
|
||||
|
||||
🖼, 👉 🈸 👥 🚫 ⚙️ FastAPI 🛠️ 🛠️ ⚗ 🎻 🔗 ⚪️➡️ Pydantic 🏷 🚫 🏧 🔬 🎻. 👐, 👥 📣 📨 🎚 🆎 📁, 🚫 🎻:
|
||||
|
||||
```Python hl_lines="17-22 24"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
|
||||
```
|
||||
|
||||
👐, 👐 👥 🚫 ⚙️ 🔢 🛠️ 🛠️, 👥 ⚙️ Pydantic 🏷 ❎ 🏗 🎻 🔗 💽 👈 👥 💚 📨 📁.
|
||||
|
||||
⤴️ 👥 ⚙️ 📨 🔗, & ⚗ 💪 `bytes`. 👉 ⛓ 👈 FastAPI 🏆 🚫 🔄 🎻 📨 🚀 🎻.
|
||||
|
||||
& ⤴️ 👆 📟, 👥 🎻 👈 📁 🎚 🔗, & ⤴️ 👥 🔄 ⚙️ 🎏 Pydantic 🏷 ✔ 📁 🎚:
|
||||
|
||||
```Python hl_lines="26-33"
|
||||
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
📥 👥 🏤-⚙️ 🎏 Pydantic 🏷.
|
||||
|
||||
✋️ 🎏 🌌, 👥 💪 ✔️ ✔ ⚫️ 🎏 🌌.
|
||||
33
docs/em/docs/advanced/response-change-status-code.md
Normal file
33
docs/em/docs/advanced/response-change-status-code.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# 📨 - 🔀 👔 📟
|
||||
|
||||
👆 🎲 ✍ ⏭ 👈 👆 💪 ⚒ 🔢 [📨 👔 📟](../tutorial/response-status-code.md){.internal-link target=_blank}.
|
||||
|
||||
✋️ 💼 👆 💪 📨 🎏 👔 📟 🌘 🔢.
|
||||
|
||||
## ⚙️ 💼
|
||||
|
||||
🖼, 🌈 👈 👆 💚 📨 🇺🇸🔍 👔 📟 "👌" `200` 🔢.
|
||||
|
||||
✋️ 🚥 💽 🚫 🔀, 👆 💚 ✍ ⚫️, & 📨 🇺🇸🔍 👔 📟 "✍" `201`.
|
||||
|
||||
✋️ 👆 💚 💪 ⛽ & 🗜 💽 👆 📨 ⏮️ `response_model`.
|
||||
|
||||
📚 💼, 👆 💪 ⚙️ `Response` 🔢.
|
||||
|
||||
## ⚙️ `Response` 🔢
|
||||
|
||||
👆 💪 📣 🔢 🆎 `Response` 👆 *➡ 🛠️ 🔢* (👆 💪 🍪 & 🎚).
|
||||
|
||||
& ⤴️ 👆 💪 ⚒ `status_code` 👈 *🔀* 📨 🎚.
|
||||
|
||||
```Python hl_lines="1 9 12"
|
||||
{!../../../docs_src/response_change_status_code/tutorial001.py!}
|
||||
```
|
||||
|
||||
& ⤴️ 👆 💪 📨 🙆 🎚 👆 💪, 👆 🛎 🔜 ( `dict`, 💽 🏷, ♒️).
|
||||
|
||||
& 🚥 👆 📣 `response_model`, ⚫️ 🔜 ⚙️ ⛽ & 🗜 🎚 👆 📨.
|
||||
|
||||
**FastAPI** 🔜 ⚙️ 👈 *🔀* 📨 ⚗ 👔 📟 (🍪 & 🎚), & 🔜 🚮 👫 🏁 📨 👈 🔌 💲 👆 📨, ⛽ 🙆 `response_model`.
|
||||
|
||||
👆 💪 📣 `Response` 🔢 🔗, & ⚒ 👔 📟 👫. ✋️ ✔️ 🤯 👈 🏁 1️⃣ ⚒ 🔜 🏆.
|
||||
49
docs/em/docs/advanced/response-cookies.md
Normal file
49
docs/em/docs/advanced/response-cookies.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# 📨 🍪
|
||||
|
||||
## ⚙️ `Response` 🔢
|
||||
|
||||
👆 💪 📣 🔢 🆎 `Response` 👆 *➡ 🛠️ 🔢*.
|
||||
|
||||
& ⤴️ 👆 💪 ⚒ 🍪 👈 *🔀* 📨 🎚.
|
||||
|
||||
```Python hl_lines="1 8-9"
|
||||
{!../../../docs_src/response_cookies/tutorial002.py!}
|
||||
```
|
||||
|
||||
& ⤴️ 👆 💪 📨 🙆 🎚 👆 💪, 👆 🛎 🔜 ( `dict`, 💽 🏷, ♒️).
|
||||
|
||||
& 🚥 👆 📣 `response_model`, ⚫️ 🔜 ⚙️ ⛽ & 🗜 🎚 👆 📨.
|
||||
|
||||
**FastAPI** 🔜 ⚙️ 👈 *🔀* 📨 ⚗ 🍪 (🎚 & 👔 📟), & 🔜 🚮 👫 🏁 📨 👈 🔌 💲 👆 📨, ⛽ 🙆 `response_model`.
|
||||
|
||||
👆 💪 📣 `Response` 🔢 🔗, & ⚒ 🍪 (& 🎚) 👫.
|
||||
|
||||
## 📨 `Response` 🔗
|
||||
|
||||
👆 💪 ✍ 🍪 🕐❔ 🛬 `Response` 🔗 👆 📟.
|
||||
|
||||
👈, 👆 💪 ✍ 📨 🔬 [📨 📨 🔗](response-directly.md){.internal-link target=_blank}.
|
||||
|
||||
⤴️ ⚒ 🍪 ⚫️, & ⤴️ 📨 ⚫️:
|
||||
|
||||
```Python hl_lines="10-12"
|
||||
{!../../../docs_src/response_cookies/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
✔️ 🤯 👈 🚥 👆 📨 📨 🔗 ↩️ ⚙️ `Response` 🔢, FastAPI 🔜 📨 ⚫️ 🔗.
|
||||
|
||||
, 👆 🔜 ✔️ ⚒ 💭 👆 💽 ☑ 🆎. 🤶 Ⓜ. ⚫️ 🔗 ⏮️ 🎻, 🚥 👆 🛬 `JSONResponse`.
|
||||
|
||||
& 👈 👆 🚫 📨 🙆 📊 👈 🔜 ✔️ ⛽ `response_model`.
|
||||
|
||||
### 🌅 ℹ
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
👆 💪 ⚙️ `from starlette.responses import Response` ⚖️ `from starlette.responses import JSONResponse`.
|
||||
|
||||
**FastAPI** 🚚 🎏 `starlette.responses` `fastapi.responses` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃.
|
||||
|
||||
& `Response` 💪 ⚙️ 🛎 ⚒ 🎚 & 🍪, **FastAPI** 🚚 ⚫️ `fastapi.Response`.
|
||||
|
||||
👀 🌐 💪 🔢 & 🎛, ✅ <a href="https://www.starlette.io/responses/#set-cookie" class="external-link" target="_blank">🧾 💃</a>.
|
||||
63
docs/em/docs/advanced/response-directly.md
Normal file
63
docs/em/docs/advanced/response-directly.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# 📨 📨 🔗
|
||||
|
||||
🕐❔ 👆 ✍ **FastAPI** *➡ 🛠️* 👆 💪 🛎 📨 🙆 📊 ⚪️➡️ ⚫️: `dict`, `list`, Pydantic 🏷, 💽 🏷, ♒️.
|
||||
|
||||
🔢, **FastAPI** 🔜 🔁 🗜 👈 📨 💲 🎻 ⚙️ `jsonable_encoder` 🔬 [🎻 🔗 🔢](../tutorial/encoder.md){.internal-link target=_blank}.
|
||||
|
||||
⤴️, ⛅ 🎑, ⚫️ 🔜 🚮 👈 🎻-🔗 💽 (✅ `dict`) 🔘 `JSONResponse` 👈 🔜 ⚙️ 📨 📨 👩💻.
|
||||
|
||||
✋️ 👆 💪 📨 `JSONResponse` 🔗 ⚪️➡️ 👆 *➡ 🛠️*.
|
||||
|
||||
⚫️ 💪 ⚠, 🖼, 📨 🛃 🎚 ⚖️ 🍪.
|
||||
|
||||
## 📨 `Response`
|
||||
|
||||
👐, 👆 💪 📨 🙆 `Response` ⚖️ 🙆 🎧-🎓 ⚫️.
|
||||
|
||||
!!! tip
|
||||
`JSONResponse` ⚫️ 🎧-🎓 `Response`.
|
||||
|
||||
& 🕐❔ 👆 📨 `Response`, **FastAPI** 🔜 🚶♀️ ⚫️ 🔗.
|
||||
|
||||
⚫️ 🏆 🚫 🙆 💽 🛠️ ⏮️ Pydantic 🏷, ⚫️ 🏆 🚫 🗜 🎚 🙆 🆎, ♒️.
|
||||
|
||||
👉 🤝 👆 📚 💪. 👆 💪 📨 🙆 📊 🆎, 🔐 🙆 💽 📄 ⚖️ 🔬, ♒️.
|
||||
|
||||
## ⚙️ `jsonable_encoder` `Response`
|
||||
|
||||
↩️ **FastAPI** 🚫 🙆 🔀 `Response` 👆 📨, 👆 ✔️ ⚒ 💭 ⚫️ 🎚 🔜 ⚫️.
|
||||
|
||||
🖼, 👆 🚫🔜 🚮 Pydantic 🏷 `JSONResponse` 🍵 🥇 🏭 ⚫️ `dict` ⏮️ 🌐 📊 🆎 (💖 `datetime`, `UUID`, ♒️) 🗜 🎻-🔗 🆎.
|
||||
|
||||
📚 💼, 👆 💪 ⚙️ `jsonable_encoder` 🗜 👆 📊 ⏭ 🚶♀️ ⚫️ 📨:
|
||||
|
||||
```Python hl_lines="6-7 21-22"
|
||||
{!../../../docs_src/response_directly/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
👆 💪 ⚙️ `from starlette.responses import JSONResponse`.
|
||||
|
||||
**FastAPI** 🚚 🎏 `starlette.responses` `fastapi.responses` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃.
|
||||
|
||||
## 🛬 🛃 `Response`
|
||||
|
||||
🖼 🔛 🎦 🌐 🍕 👆 💪, ✋️ ⚫️ 🚫 📶 ⚠, 👆 💪 ✔️ 📨 `item` 🔗, & **FastAPI** 🔜 🚮 ⚫️ `JSONResponse` 👆, 🏭 ⚫️ `dict`, ♒️. 🌐 👈 🔢.
|
||||
|
||||
🔜, ➡️ 👀 ❔ 👆 💪 ⚙️ 👈 📨 🛃 📨.
|
||||
|
||||
➡️ 💬 👈 👆 💚 📨 <a href="https://en.wikipedia.org/wiki/XML" class="external-link" target="_blank">📂</a> 📨.
|
||||
|
||||
👆 💪 🚮 👆 📂 🎚 🎻, 🚮 ⚫️ `Response`, & 📨 ⚫️:
|
||||
|
||||
```Python hl_lines="1 18"
|
||||
{!../../../docs_src/response_directly/tutorial002.py!}
|
||||
```
|
||||
|
||||
## 🗒
|
||||
|
||||
🕐❔ 👆 📨 `Response` 🔗 🚮 📊 🚫 ✔, 🗜 (🎻), 🚫 📄 🔁.
|
||||
|
||||
✋️ 👆 💪 📄 ⚫️ 🔬 [🌖 📨 🗄](additional-responses.md){.internal-link target=_blank}.
|
||||
|
||||
👆 💪 👀 ⏪ 📄 ❔ ⚙️/📣 👉 🛃 `Response`Ⓜ ⏪ ✔️ 🏧 💽 🛠️, 🧾, ♒️.
|
||||
42
docs/em/docs/advanced/response-headers.md
Normal file
42
docs/em/docs/advanced/response-headers.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# 📨 🎚
|
||||
|
||||
## ⚙️ `Response` 🔢
|
||||
|
||||
👆 💪 📣 🔢 🆎 `Response` 👆 *➡ 🛠️ 🔢* (👆 💪 🍪).
|
||||
|
||||
& ⤴️ 👆 💪 ⚒ 🎚 👈 *🔀* 📨 🎚.
|
||||
|
||||
```Python hl_lines="1 7-8"
|
||||
{!../../../docs_src/response_headers/tutorial002.py!}
|
||||
```
|
||||
|
||||
& ⤴️ 👆 💪 📨 🙆 🎚 👆 💪, 👆 🛎 🔜 ( `dict`, 💽 🏷, ♒️).
|
||||
|
||||
& 🚥 👆 📣 `response_model`, ⚫️ 🔜 ⚙️ ⛽ & 🗜 🎚 👆 📨.
|
||||
|
||||
**FastAPI** 🔜 ⚙️ 👈 *🔀* 📨 ⚗ 🎚 (🍪 & 👔 📟), & 🔜 🚮 👫 🏁 📨 👈 🔌 💲 👆 📨, ⛽ 🙆 `response_model`.
|
||||
|
||||
👆 💪 📣 `Response` 🔢 🔗, & ⚒ 🎚 (& 🍪) 👫.
|
||||
|
||||
## 📨 `Response` 🔗
|
||||
|
||||
👆 💪 🚮 🎚 🕐❔ 👆 📨 `Response` 🔗.
|
||||
|
||||
✍ 📨 🔬 [📨 📨 🔗](response-directly.md){.internal-link target=_blank} & 🚶♀️ 🎚 🌖 🔢:
|
||||
|
||||
```Python hl_lines="10-12"
|
||||
{!../../../docs_src/response_headers/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
👆 💪 ⚙️ `from starlette.responses import Response` ⚖️ `from starlette.responses import JSONResponse`.
|
||||
|
||||
**FastAPI** 🚚 🎏 `starlette.responses` `fastapi.responses` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃.
|
||||
|
||||
& `Response` 💪 ⚙️ 🛎 ⚒ 🎚 & 🍪, **FastAPI** 🚚 ⚫️ `fastapi.Response`.
|
||||
|
||||
## 🛃 🎚
|
||||
|
||||
✔️ 🤯 👈 🛃 © 🎚 💪 🚮 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">⚙️ '✖-' 🔡</a>.
|
||||
|
||||
✋️ 🚥 👆 ✔️ 🛃 🎚 👈 👆 💚 👩💻 🖥 💪 👀, 👆 💪 🚮 👫 👆 ⚜ 📳 (✍ 🌅 [⚜ (✖️-🇨🇳 ℹ 🤝)](../tutorial/cors.md){.internal-link target=_blank}), ⚙️ 🔢 `expose_headers` 📄 <a href="https://www.starlette.io/middleware/#corsmiddleware" class="external-link" target="_blank">💃 ⚜ 🩺</a>.
|
||||
113
docs/em/docs/advanced/security/http-basic-auth.md
Normal file
113
docs/em/docs/advanced/security/http-basic-auth.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# 🇺🇸🔍 🔰 🔐
|
||||
|
||||
🙅 💼, 👆 💪 ⚙️ 🇺🇸🔍 🔰 🔐.
|
||||
|
||||
🇺🇸🔍 🔰 🔐, 🈸 ⌛ 🎚 👈 🔌 🆔 & 🔐.
|
||||
|
||||
🚥 ⚫️ 🚫 📨 ⚫️, ⚫️ 📨 🇺🇸🔍 4️⃣0️⃣1️⃣ "⛔" ❌.
|
||||
|
||||
& 📨 🎚 `WWW-Authenticate` ⏮️ 💲 `Basic`, & 📦 `realm` 🔢.
|
||||
|
||||
👈 💬 🖥 🎦 🛠️ 📋 🆔 & 🔐.
|
||||
|
||||
⤴️, 🕐❔ 👆 🆎 👈 🆔 & 🔐, 🖥 📨 👫 🎚 🔁.
|
||||
|
||||
## 🙅 🇺🇸🔍 🔰 🔐
|
||||
|
||||
* 🗄 `HTTPBasic` & `HTTPBasicCredentials`.
|
||||
* ✍ "`security` ⚖" ⚙️ `HTTPBasic`.
|
||||
* ⚙️ 👈 `security` ⏮️ 🔗 👆 *➡ 🛠️*.
|
||||
* ⚫️ 📨 🎚 🆎 `HTTPBasicCredentials`:
|
||||
* ⚫️ 🔌 `username` & `password` 📨.
|
||||
|
||||
```Python hl_lines="2 6 10"
|
||||
{!../../../docs_src/security/tutorial006.py!}
|
||||
```
|
||||
|
||||
🕐❔ 👆 🔄 📂 📛 🥇 🕰 (⚖️ 🖊 "🛠️" 🔼 🩺) 🖥 🔜 💭 👆 👆 🆔 & 🔐:
|
||||
|
||||
<img src="/img/tutorial/security/image12.png">
|
||||
|
||||
## ✅ 🆔
|
||||
|
||||
📥 🌅 🏁 🖼.
|
||||
|
||||
⚙️ 🔗 ✅ 🚥 🆔 & 🔐 ☑.
|
||||
|
||||
👉, ⚙️ 🐍 🐩 🕹 <a href="https://docs.python.org/3/library/secrets.html" class="external-link" target="_blank">`secrets`</a> ✅ 🆔 & 🔐.
|
||||
|
||||
`secrets.compare_digest()` 💪 ✊ `bytes` ⚖️ `str` 👈 🕴 🔌 🔠 🦹 (🕐 🇪🇸), 👉 ⛓ ⚫️ 🚫🔜 👷 ⏮️ 🦹 💖 `á`, `Sebastián`.
|
||||
|
||||
🍵 👈, 👥 🥇 🗜 `username` & `password` `bytes` 🔢 👫 ⏮️ 🔠-8️⃣.
|
||||
|
||||
⤴️ 👥 💪 ⚙️ `secrets.compare_digest()` 🚚 👈 `credentials.username` `"stanleyjobson"`, & 👈 `credentials.password` `"swordfish"`.
|
||||
|
||||
```Python hl_lines="1 11-21"
|
||||
{!../../../docs_src/security/tutorial007.py!}
|
||||
```
|
||||
|
||||
👉 🔜 🎏:
|
||||
|
||||
```Python
|
||||
if not (credentials.username == "stanleyjobson") or not (credentials.password == "swordfish"):
|
||||
# Return some error
|
||||
...
|
||||
```
|
||||
|
||||
✋️ ⚙️ `secrets.compare_digest()` ⚫️ 🔜 🔐 🛡 🆎 👊 🤙 "🕰 👊".
|
||||
|
||||
### ⏲ 👊
|
||||
|
||||
✋️ ⚫️❔ "⏲ 👊"❓
|
||||
|
||||
➡️ 🌈 👊 🔄 💭 🆔 & 🔐.
|
||||
|
||||
& 👫 📨 📨 ⏮️ 🆔 `johndoe` & 🔐 `love123`.
|
||||
|
||||
⤴️ 🐍 📟 👆 🈸 🔜 🌓 🕳 💖:
|
||||
|
||||
```Python
|
||||
if "johndoe" == "stanleyjobson" and "love123" == "swordfish":
|
||||
...
|
||||
```
|
||||
|
||||
✋️ ▶️️ 🙍 🐍 🔬 🥇 `j` `johndoe` 🥇 `s` `stanleyjobson`, ⚫️ 🔜 📨 `False`, ↩️ ⚫️ ⏪ 💭 👈 📚 2️⃣ 🎻 🚫 🎏, 💭 👈 "📤 🙅♂ 💪 🗑 🌅 📊 ⚖ 🎂 🔤". & 👆 🈸 🔜 💬 "❌ 👩💻 ⚖️ 🔐".
|
||||
|
||||
✋️ ⤴️ 👊 🔄 ⏮️ 🆔 `stanleyjobsox` & 🔐 `love123`.
|
||||
|
||||
& 👆 🈸 📟 🔨 🕳 💖:
|
||||
|
||||
```Python
|
||||
if "stanleyjobsox" == "stanleyjobson" and "love123" == "swordfish":
|
||||
...
|
||||
```
|
||||
|
||||
🐍 🔜 ✔️ 🔬 🎂 `stanleyjobso` 👯♂️ `stanleyjobsox` & `stanleyjobson` ⏭ 🤔 👈 👯♂️ 🎻 🚫 🎏. ⚫️ 🔜 ✊ ➕ ⏲ 📨 🔙 "❌ 👩💻 ⚖️ 🔐".
|
||||
|
||||
#### 🕰 ❔ ℹ 👊
|
||||
|
||||
👈 ☝, 👀 👈 💽 ✊ ⏲ 📏 📨 "❌ 👩💻 ⚖️ 🔐" 📨, 👊 🔜 💭 👈 👫 🤚 _🕳_ ▶️️, ▶️ 🔤 ▶️️.
|
||||
|
||||
& ⤴️ 👫 💪 🔄 🔄 🤔 👈 ⚫️ 🎲 🕳 🌖 🎏 `stanleyjobsox` 🌘 `johndoe`.
|
||||
|
||||
#### "🕴" 👊
|
||||
|
||||
↗️, 👊 🔜 🚫 🔄 🌐 👉 ✋, 👫 🔜 ✍ 📋 ⚫️, 🎲 ⏮️ 💯 ⚖️ 💯 💯 📍 🥈. & 🔜 🤚 1️⃣ ➕ ☑ 🔤 🕰.
|
||||
|
||||
✋️ 🔨 👈, ⏲ ⚖️ 📆 👊 🔜 ✔️ 💭 ☑ 🆔 & 🔐, ⏮️ "ℹ" 👆 🈸, ⚙️ 🕰 ✊ ❔.
|
||||
|
||||
#### 🔧 ⚫️ ⏮️ `secrets.compare_digest()`
|
||||
|
||||
✋️ 👆 📟 👥 🤙 ⚙️ `secrets.compare_digest()`.
|
||||
|
||||
📏, ⚫️ 🔜 ✊ 🎏 🕰 🔬 `stanleyjobsox` `stanleyjobson` 🌘 ⚫️ ✊ 🔬 `johndoe` `stanleyjobson`. & 🎏 🔐.
|
||||
|
||||
👈 🌌, ⚙️ `secrets.compare_digest()` 👆 🈸 📟, ⚫️ 🔜 🔒 🛡 👉 🎂 ↔ 💂♂ 👊.
|
||||
|
||||
### 📨 ❌
|
||||
|
||||
⏮️ 🔍 👈 🎓 ❌, 📨 `HTTPException` ⏮️ 👔 📟 4️⃣0️⃣1️⃣ (🎏 📨 🕐❔ 🙅♂ 🎓 🚚) & 🚮 🎚 `WWW-Authenticate` ⚒ 🖥 🎦 💳 📋 🔄:
|
||||
|
||||
```Python hl_lines="23-27"
|
||||
{!../../../docs_src/security/tutorial007.py!}
|
||||
```
|
||||
16
docs/em/docs/advanced/security/index.md
Normal file
16
docs/em/docs/advanced/security/index.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# 🏧 💂♂ - 🎶
|
||||
|
||||
## 🌖 ⚒
|
||||
|
||||
📤 ➕ ⚒ 🍵 💂♂ ↖️ ⚪️➡️ 🕐 📔 [🔰 - 👩💻 🦮: 💂♂](../../tutorial/security/){.internal-link target=_blank}.
|
||||
|
||||
!!! tip
|
||||
⏭ 📄 **🚫 🎯 "🏧"**.
|
||||
|
||||
& ⚫️ 💪 👈 👆 ⚙️ 💼, ⚗ 1️⃣ 👫.
|
||||
|
||||
## ✍ 🔰 🥇
|
||||
|
||||
⏭ 📄 🤔 👆 ⏪ ✍ 👑 [🔰 - 👩💻 🦮: 💂♂](../../tutorial/security/){.internal-link target=_blank}.
|
||||
|
||||
👫 🌐 ⚓️ 🔛 🎏 🔧, ✋️ ✔ ➕ 🛠️.
|
||||
269
docs/em/docs/advanced/security/oauth2-scopes.md
Normal file
269
docs/em/docs/advanced/security/oauth2-scopes.md
Normal file
@@ -0,0 +1,269 @@
|
||||
# Oauth2️⃣ ↔
|
||||
|
||||
👆 💪 ⚙️ Oauth2️⃣ ↔ 🔗 ⏮️ **FastAPI**, 👫 🛠️ 👷 💎.
|
||||
|
||||
👉 🔜 ✔ 👆 ✔️ 🌖 👌-🧽 ✔ ⚙️, 📄 Oauth2️⃣ 🐩, 🛠️ 🔘 👆 🗄 🈸 (& 🛠️ 🩺).
|
||||
|
||||
Oauth2️⃣ ⏮️ ↔ 🛠️ ⚙️ 📚 🦏 🤝 🐕🦺, 💖 👱📔, 🇺🇸🔍, 📂, 🤸♂, 👱📔, ♒️. 👫 ⚙️ ⚫️ 🚚 🎯 ✔ 👩💻 & 🈸.
|
||||
|
||||
🔠 🕰 👆 "🕹 ⏮️" 👱📔, 🇺🇸🔍, 📂, 🤸♂, 👱📔, 👈 🈸 ⚙️ Oauth2️⃣ ⏮️ ↔.
|
||||
|
||||
👉 📄 👆 🔜 👀 ❔ 🛠️ 🤝 & ✔ ⏮️ 🎏 Oauth2️⃣ ⏮️ ↔ 👆 **FastAPI** 🈸.
|
||||
|
||||
!!! warning
|
||||
👉 🌅 ⚖️ 🌘 🏧 📄. 🚥 👆 ▶️, 👆 💪 🚶 ⚫️.
|
||||
|
||||
👆 🚫 🎯 💪 Oauth2️⃣ ↔, & 👆 💪 🍵 🤝 & ✔ 👐 👆 💚.
|
||||
|
||||
✋️ Oauth2️⃣ ⏮️ ↔ 💪 🎆 🛠️ 🔘 👆 🛠️ (⏮️ 🗄) & 👆 🛠️ 🩺.
|
||||
|
||||
👐, 👆 🛠️ 📚 ↔, ⚖️ 🙆 🎏 💂♂/✔ 📄, 👐 👆 💪, 👆 📟.
|
||||
|
||||
📚 💼, Oauth2️⃣ ⏮️ ↔ 💪 👹.
|
||||
|
||||
✋️ 🚥 👆 💭 👆 💪 ⚫️, ⚖️ 👆 😟, 🚧 👂.
|
||||
|
||||
## Oauth2️⃣ ↔ & 🗄
|
||||
|
||||
Oauth2️⃣ 🔧 🔬 "↔" 📇 🎻 🎏 🚀.
|
||||
|
||||
🎚 🔠 👉 🎻 💪 ✔️ 🙆 📁, ✋️ 🔜 🚫 🔌 🚀.
|
||||
|
||||
👫 ↔ 🎨 "✔".
|
||||
|
||||
🗄 (✅ 🛠️ 🩺), 👆 💪 🔬 "💂♂ ⚖".
|
||||
|
||||
🕐❔ 1️⃣ 👫 💂♂ ⚖ ⚙️ Oauth2️⃣, 👆 💪 📣 & ⚙️ ↔.
|
||||
|
||||
🔠 "↔" 🎻 (🍵 🚀).
|
||||
|
||||
👫 🛎 ⚙️ 📣 🎯 💂♂ ✔, 🖼:
|
||||
|
||||
* `users:read` ⚖️ `users:write` ⚠ 🖼.
|
||||
* `instagram_basic` ⚙️ 👱📔 / 👱📔.
|
||||
* `https://www.googleapis.com/auth/drive` ⚙️ 🇺🇸🔍.
|
||||
|
||||
!!! info
|
||||
Oauth2️⃣ "↔" 🎻 👈 📣 🎯 ✔ ✔.
|
||||
|
||||
⚫️ 🚫 🤔 🚥 ⚫️ ✔️ 🎏 🦹 💖 `:` ⚖️ 🚥 ⚫️ 📛.
|
||||
|
||||
👈 ℹ 🛠️ 🎯.
|
||||
|
||||
Oauth2️⃣ 👫 🎻.
|
||||
|
||||
## 🌐 🎑
|
||||
|
||||
🥇, ➡️ 🔜 👀 🍕 👈 🔀 ⚪️➡️ 🖼 👑 **🔰 - 👩💻 🦮** [Oauth2️⃣ ⏮️ 🔐 (& 🔁), 📨 ⏮️ 🥙 🤝](../../tutorial/security/oauth2-jwt.md){.internal-link target=_blank}. 🔜 ⚙️ Oauth2️⃣ ↔:
|
||||
|
||||
```Python hl_lines="2 4 8 12 46 64 105 107-115 121-124 128-134 139 153"
|
||||
{!../../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
🔜 ➡️ 📄 👈 🔀 🔁 🔁.
|
||||
|
||||
## Oauth2️⃣ 💂♂ ⚖
|
||||
|
||||
🥇 🔀 👈 🔜 👥 📣 Oauth2️⃣ 💂♂ ⚖ ⏮️ 2️⃣ 💪 ↔, `me` & `items`.
|
||||
|
||||
`scopes` 🔢 📨 `dict` ⏮️ 🔠 ↔ 🔑 & 📛 💲:
|
||||
|
||||
```Python hl_lines="62-65"
|
||||
{!../../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
↩️ 👥 🔜 📣 📚 ↔, 👫 🔜 🎦 🆙 🛠️ 🩺 🕐❔ 👆 🕹-/✔.
|
||||
|
||||
& 👆 🔜 💪 🖊 ❔ ↔ 👆 💚 🤝 🔐: `me` & `items`.
|
||||
|
||||
👉 🎏 🛠️ ⚙️ 🕐❔ 👆 🤝 ✔ ⏪ 🚨 ⏮️ 👱📔, 🇺🇸🔍, 📂, ♒️:
|
||||
|
||||
<img src="/img/tutorial/security/image11.png">
|
||||
|
||||
## 🥙 🤝 ⏮️ ↔
|
||||
|
||||
🔜, 🔀 🤝 *➡ 🛠️* 📨 ↔ 📨.
|
||||
|
||||
👥 ⚙️ 🎏 `OAuth2PasswordRequestForm`. ⚫️ 🔌 🏠 `scopes` ⏮️ `list` `str`, ⏮️ 🔠 ↔ ⚫️ 📨 📨.
|
||||
|
||||
& 👥 📨 ↔ 🍕 🥙 🤝.
|
||||
|
||||
!!! danger
|
||||
🦁, 📥 👥 ❎ ↔ 📨 🔗 🤝.
|
||||
|
||||
✋️ 👆 🈸, 💂♂, 👆 🔜 ⚒ 💭 👆 🕴 🚮 ↔ 👈 👩💻 🤙 💪 ✔️, ⚖️ 🕐 👆 ✔️ 🔁.
|
||||
|
||||
```Python hl_lines="153"
|
||||
{!../../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
## 📣 ↔ *➡ 🛠️* & 🔗
|
||||
|
||||
🔜 👥 📣 👈 *➡ 🛠️* `/users/me/items/` 🚚 ↔ `items`.
|
||||
|
||||
👉, 👥 🗄 & ⚙️ `Security` ⚪️➡️ `fastapi`.
|
||||
|
||||
👆 💪 ⚙️ `Security` 📣 🔗 (💖 `Depends`), ✋️ `Security` 📨 🔢 `scopes` ⏮️ 📇 ↔ (🎻).
|
||||
|
||||
👉 💼, 👥 🚶♀️ 🔗 🔢 `get_current_active_user` `Security` (🎏 🌌 👥 🔜 ⏮️ `Depends`).
|
||||
|
||||
✋️ 👥 🚶♀️ `list` ↔, 👉 💼 ⏮️ 1️⃣ ↔: `items` (⚫️ 💪 ✔️ 🌅).
|
||||
|
||||
& 🔗 🔢 `get_current_active_user` 💪 📣 🎧-🔗, 🚫 🕴 ⏮️ `Depends` ✋️ ⏮️ `Security`. 📣 🚮 👍 🎧-🔗 🔢 (`get_current_user`), & 🌖 ↔ 📄.
|
||||
|
||||
👉 💼, ⚫️ 🚚 ↔ `me` (⚫️ 💪 🚚 🌅 🌘 1️⃣ ↔).
|
||||
|
||||
!!! note
|
||||
👆 🚫 🎯 💪 🚮 🎏 ↔ 🎏 🥉.
|
||||
|
||||
👥 🔨 ⚫️ 📥 🎦 ❔ **FastAPI** 🍵 ↔ 📣 🎏 🎚.
|
||||
|
||||
```Python hl_lines="4 139 166"
|
||||
{!../../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
!!! info "📡 ℹ"
|
||||
`Security` 🤙 🏿 `Depends`, & ⚫️ ✔️ 1️⃣ ➕ 🔢 👈 👥 🔜 👀 ⏪.
|
||||
|
||||
✋️ ⚙️ `Security` ↩️ `Depends`, **FastAPI** 🔜 💭 👈 ⚫️ 💪 📣 💂♂ ↔, ⚙️ 👫 🔘, & 📄 🛠️ ⏮️ 🗄.
|
||||
|
||||
✋️ 🕐❔ 👆 🗄 `Query`, `Path`, `Depends`, `Security` & 🎏 ⚪️➡️ `fastapi`, 👈 🤙 🔢 👈 📨 🎁 🎓.
|
||||
|
||||
## ⚙️ `SecurityScopes`
|
||||
|
||||
🔜 ℹ 🔗 `get_current_user`.
|
||||
|
||||
👉 1️⃣ ⚙️ 🔗 🔛.
|
||||
|
||||
📥 👥 ⚙️ 🎏 Oauth2️⃣ ⚖ 👥 ✍ ⏭, 📣 ⚫️ 🔗: `oauth2_scheme`.
|
||||
|
||||
↩️ 👉 🔗 🔢 🚫 ✔️ 🙆 ↔ 📄 ⚫️, 👥 💪 ⚙️ `Depends` ⏮️ `oauth2_scheme`, 👥 🚫 ✔️ ⚙️ `Security` 🕐❔ 👥 🚫 💪 ✔ 💂♂ ↔.
|
||||
|
||||
👥 📣 🎁 🔢 🆎 `SecurityScopes`, 🗄 ⚪️➡️ `fastapi.security`.
|
||||
|
||||
👉 `SecurityScopes` 🎓 🎏 `Request` (`Request` ⚙️ 🤚 📨 🎚 🔗).
|
||||
|
||||
```Python hl_lines="8 105"
|
||||
{!../../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
## ⚙️ `scopes`
|
||||
|
||||
🔢 `security_scopes` 🔜 🆎 `SecurityScopes`.
|
||||
|
||||
⚫️ 🔜 ✔️ 🏠 `scopes` ⏮️ 📇 ⚗ 🌐 ↔ ✔ ⚫️ & 🌐 🔗 👈 ⚙️ 👉 🎧-🔗. 👈 ⛓, 🌐 "⚓️"... 👉 💪 🔊 😨, ⚫️ 🔬 🔄 ⏪ 🔛.
|
||||
|
||||
`security_scopes` 🎚 (🎓 `SecurityScopes`) 🚚 `scope_str` 🔢 ⏮️ 👁 🎻, 🔌 👈 ↔ 👽 🚀 (👥 🔜 ⚙️ ⚫️).
|
||||
|
||||
👥 ✍ `HTTPException` 👈 👥 💪 🏤-⚙️ (`raise`) ⏪ 📚 ☝.
|
||||
|
||||
👉 ⚠, 👥 🔌 ↔ 🚚 (🚥 🙆) 🎻 👽 🚀 (⚙️ `scope_str`). 👥 🚮 👈 🎻 ⚗ ↔ `WWW-Authenticate` 🎚 (👉 🍕 🔌).
|
||||
|
||||
```Python hl_lines="105 107-115"
|
||||
{!../../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
## ✔ `username` & 💽 💠
|
||||
|
||||
👥 ✔ 👈 👥 🤚 `username`, & ⚗ ↔.
|
||||
|
||||
& ⤴️ 👥 ✔ 👈 📊 ⏮️ Pydantic 🏷 (✊ `ValidationError` ⚠), & 🚥 👥 🤚 ❌ 👂 🥙 🤝 ⚖️ ⚖ 📊 ⏮️ Pydantic, 👥 🤚 `HTTPException` 👥 ✍ ⏭.
|
||||
|
||||
👈, 👥 ℹ Pydantic 🏷 `TokenData` ⏮️ 🆕 🏠 `scopes`.
|
||||
|
||||
⚖ 📊 ⏮️ Pydantic 👥 💪 ⚒ 💭 👈 👥 ✔️, 🖼, ⚫️❔ `list` `str` ⏮️ ↔ & `str` ⏮️ `username`.
|
||||
|
||||
↩️, 🖼, `dict`, ⚖️ 🕳 🙆, ⚫️ 💪 💔 🈸 ☝ ⏪, ⚒ ⚫️ 💂♂ ⚠.
|
||||
|
||||
👥 ✔ 👈 👥 ✔️ 👩💻 ⏮️ 👈 🆔, & 🚥 🚫, 👥 🤚 👈 🎏 ⚠ 👥 ✍ ⏭.
|
||||
|
||||
```Python hl_lines="46 116-127"
|
||||
{!../../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
## ✔ `scopes`
|
||||
|
||||
👥 🔜 ✔ 👈 🌐 ↔ ✔, 👉 🔗 & 🌐 ⚓️ (🔌 *➡ 🛠️*), 🔌 ↔ 🚚 🤝 📨, ⏪ 🤚 `HTTPException`.
|
||||
|
||||
👉, 👥 ⚙️ `security_scopes.scopes`, 👈 🔌 `list` ⏮️ 🌐 👫 ↔ `str`.
|
||||
|
||||
```Python hl_lines="128-134"
|
||||
{!../../../docs_src/security/tutorial005.py!}
|
||||
```
|
||||
|
||||
## 🔗 🌲 & ↔
|
||||
|
||||
➡️ 📄 🔄 👉 🔗 🌲 & ↔.
|
||||
|
||||
`get_current_active_user` 🔗 ✔️ 🎧-🔗 🔛 `get_current_user`, ↔ `"me"` 📣 `get_current_active_user` 🔜 🔌 📇 ✔ ↔ `security_scopes.scopes` 🚶♀️ `get_current_user`.
|
||||
|
||||
*➡ 🛠️* ⚫️ 📣 ↔, `"items"`, 👉 🔜 📇 `security_scopes.scopes` 🚶♀️ `get_current_user`.
|
||||
|
||||
📥 ❔ 🔗 🔗 & ↔ 👀 💖:
|
||||
|
||||
* *➡ 🛠️* `read_own_items` ✔️:
|
||||
* ✔ ↔ `["items"]` ⏮️ 🔗:
|
||||
* `get_current_active_user`:
|
||||
* 🔗 🔢 `get_current_active_user` ✔️:
|
||||
* ✔ ↔ `["me"]` ⏮️ 🔗:
|
||||
* `get_current_user`:
|
||||
* 🔗 🔢 `get_current_user` ✔️:
|
||||
* 🙅♂ ↔ ✔ ⚫️.
|
||||
* 🔗 ⚙️ `oauth2_scheme`.
|
||||
* `security_scopes` 🔢 🆎 `SecurityScopes`:
|
||||
* 👉 `security_scopes` 🔢 ✔️ 🏠 `scopes` ⏮️ `list` ⚗ 🌐 👫 ↔ 📣 🔛,:
|
||||
* `security_scopes.scopes` 🔜 🔌 `["me", "items"]` *➡ 🛠️* `read_own_items`.
|
||||
* `security_scopes.scopes` 🔜 🔌 `["me"]` *➡ 🛠️* `read_users_me`, ↩️ ⚫️ 📣 🔗 `get_current_active_user`.
|
||||
* `security_scopes.scopes` 🔜 🔌 `[]` (🕳) *➡ 🛠️* `read_system_status`, ↩️ ⚫️ 🚫 📣 🙆 `Security` ⏮️ `scopes`, & 🚮 🔗, `get_current_user`, 🚫 📣 🙆 `scope` 👯♂️.
|
||||
|
||||
!!! tip
|
||||
⚠ & "🎱" 👜 📥 👈 `get_current_user` 🔜 ✔️ 🎏 📇 `scopes` ✅ 🔠 *➡ 🛠️*.
|
||||
|
||||
🌐 ⚓️ 🔛 `scopes` 📣 🔠 *➡ 🛠️* & 🔠 🔗 🔗 🌲 👈 🎯 *➡ 🛠️*.
|
||||
|
||||
## 🌖 ℹ 🔃 `SecurityScopes`
|
||||
|
||||
👆 💪 ⚙️ `SecurityScopes` 🙆 ☝, & 💗 🥉, ⚫️ 🚫 ✔️ "🌱" 🔗.
|
||||
|
||||
⚫️ 🔜 🕧 ✔️ 💂♂ ↔ 📣 ⏮️ `Security` 🔗 & 🌐 ⚓️ **👈 🎯** *➡ 🛠️* & **👈 🎯** 🔗 🌲.
|
||||
|
||||
↩️ `SecurityScopes` 🔜 ✔️ 🌐 ↔ 📣 ⚓️, 👆 💪 ⚙️ ⚫️ ✔ 👈 🤝 ✔️ 🚚 ↔ 🇨🇫 🔗 🔢, & ⤴️ 📣 🎏 ↔ 📄 🎏 *➡ 🛠️*.
|
||||
|
||||
👫 🔜 ✅ ➡ 🔠 *➡ 🛠️*.
|
||||
|
||||
## ✅ ⚫️
|
||||
|
||||
🚥 👆 📂 🛠️ 🩺, 👆 💪 🔓 & ✔ ❔ ↔ 👆 💚 ✔.
|
||||
|
||||
<img src="/img/tutorial/security/image11.png">
|
||||
|
||||
🚥 👆 🚫 🖊 🙆 ↔, 👆 🔜 "🔓", ✋️ 🕐❔ 👆 🔄 🔐 `/users/me/` ⚖️ `/users/me/items/` 👆 🔜 🤚 ❌ 💬 👈 👆 🚫 ✔️ 🥃 ✔. 👆 🔜 💪 🔐 `/status/`.
|
||||
|
||||
& 🚥 👆 🖊 ↔ `me` ✋️ 🚫 ↔ `items`, 👆 🔜 💪 🔐 `/users/me/` ✋️ 🚫 `/users/me/items/`.
|
||||
|
||||
👈 ⚫️❔ 🔜 🔨 🥉 🥳 🈸 👈 🔄 🔐 1️⃣ 👫 *➡ 🛠️* ⏮️ 🤝 🚚 👩💻, ⚓️ 🔛 ❔ 📚 ✔ 👩💻 🤝 🈸.
|
||||
|
||||
## 🔃 🥉 🥳 🛠️
|
||||
|
||||
👉 🖼 👥 ⚙️ Oauth2️⃣ "🔐" 💧.
|
||||
|
||||
👉 ☑ 🕐❔ 👥 🚨 👆 👍 🈸, 🎲 ⏮️ 👆 👍 🕸.
|
||||
|
||||
↩️ 👥 💪 💙 ⚫️ 📨 `username` & `password`, 👥 🎛 ⚫️.
|
||||
|
||||
✋️ 🚥 👆 🏗 Oauth2️⃣ 🈸 👈 🎏 🔜 🔗 (➡, 🚥 👆 🏗 🤝 🐕🦺 🌓 👱📔, 🇺🇸🔍, 📂, ♒️.) 👆 🔜 ⚙️ 1️⃣ 🎏 💧.
|
||||
|
||||
🌅 ⚠ 🔑 💧.
|
||||
|
||||
🏆 🔐 📟 💧, ✋️ 🌖 🏗 🛠️ ⚫️ 🚚 🌅 📶. ⚫️ 🌅 🏗, 📚 🐕🦺 🔚 🆙 ✔ 🔑 💧.
|
||||
|
||||
!!! note
|
||||
⚫️ ⚠ 👈 🔠 🤝 🐕🦺 📛 👫 💧 🎏 🌌, ⚒ ⚫️ 🍕 👫 🏷.
|
||||
|
||||
✋️ 🔚, 👫 🛠️ 🎏 Oauth2️⃣ 🐩.
|
||||
|
||||
**FastAPI** 🔌 🚙 🌐 👫 Oauth2️⃣ 🤝 💧 `fastapi.security.oauth2`.
|
||||
|
||||
## `Security` 👨🎨 `dependencies`
|
||||
|
||||
🎏 🌌 👆 💪 🔬 `list` `Depends` 👨🎨 `dependencies` 🔢 (🔬 [🔗 ➡ 🛠️ 👨🎨](../../tutorial/dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), 👆 💪 ⚙️ `Security` ⏮️ `scopes` 📤.
|
||||
382
docs/em/docs/advanced/settings.md
Normal file
382
docs/em/docs/advanced/settings.md
Normal file
@@ -0,0 +1,382 @@
|
||||
# ⚒ & 🌐 🔢
|
||||
|
||||
📚 💼 👆 🈸 💪 💪 🔢 ⚒ ⚖️ 📳, 🖼 ㊙ 🔑, 💽 🎓, 🎓 📧 🐕🦺, ♒️.
|
||||
|
||||
🏆 👫 ⚒ 🔢 (💪 🔀), 💖 💽 📛. & 📚 💪 🚿, 💖 ㊙.
|
||||
|
||||
👉 🤔 ⚫️ ⚠ 🚚 👫 🌐 🔢 👈 ✍ 🈸.
|
||||
|
||||
## 🌐 🔢
|
||||
|
||||
!!! tip
|
||||
🚥 👆 ⏪ 💭 ⚫️❔ "🌐 🔢" & ❔ ⚙️ 👫, 💭 🆓 🚶 ⏭ 📄 🔛.
|
||||
|
||||
<a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">🌐 🔢</a> (💭 "🇨🇻 {") 🔢 👈 🖖 🏞 🐍 📟, 🏃♂ ⚙️, & 💪 ✍ 👆 🐍 📟 (⚖️ 🎏 📋 👍).
|
||||
|
||||
👆 💪 ✍ & ⚙️ 🌐 🔢 🐚, 🍵 💆♂ 🐍:
|
||||
|
||||
=== "💾, 🇸🇻, 🚪 🎉"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// You could create an env var MY_NAME with
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// Then you could use it with other programs, like
|
||||
$ echo "Hello $MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
=== "🚪 📋"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Create an env var MY_NAME
|
||||
$ $Env:MY_NAME = "Wade Wilson"
|
||||
|
||||
// Use it with other programs, like
|
||||
$ echo "Hello $Env:MY_NAME"
|
||||
|
||||
Hello Wade Wilson
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### ✍ 🇨🇻 {🐍
|
||||
|
||||
👆 💪 ✍ 🌐 🔢 🏞 🐍, 📶 (⚖️ ⏮️ 🙆 🎏 👩🔬), & ⤴️ ✍ 👫 🐍.
|
||||
|
||||
🖼 👆 💪 ✔️ 📁 `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"` 🔢 💲 ⚙️.
|
||||
|
||||
⤴️ 👆 💪 🤙 👈 🐍 📋:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Here we don't set the env var yet
|
||||
$ python main.py
|
||||
|
||||
// As we didn't set the env var, we get the default value
|
||||
|
||||
Hello World from Python
|
||||
|
||||
// But if we create an environment variable first
|
||||
$ export MY_NAME="Wade Wilson"
|
||||
|
||||
// And then call the program again
|
||||
$ python main.py
|
||||
|
||||
// Now it can read the environment variable
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
🌐 🔢 💪 ⚒ 🏞 📟, ✋️ 💪 ✍ 📟, & 🚫 ✔️ 🏪 (💕 `git`) ⏮️ 🎂 📁, ⚫️ ⚠ ⚙️ 👫 📳 ⚖️ ⚒.
|
||||
|
||||
👆 💪 ✍ 🌐 🔢 🕴 🎯 📋 👼, 👈 🕴 💪 👈 📋, & 🕴 🚮 📐.
|
||||
|
||||
👈, ✍ ⚫️ ▶️️ ⏭ 📋 ⚫️, 🔛 🎏 ⏸:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Create an env var MY_NAME in line for this program call
|
||||
$ MY_NAME="Wade Wilson" python main.py
|
||||
|
||||
// Now it can read the environment variable
|
||||
|
||||
Hello Wade Wilson from Python
|
||||
|
||||
// The env var no longer exists afterwards
|
||||
$ python main.py
|
||||
|
||||
Hello World from Python
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! tip
|
||||
👆 💪 ✍ 🌅 🔃 ⚫️ <a href="https://12factor.net/config" class="external-link" target="_blank">1️⃣2️⃣-⚖ 📱: 📁</a>.
|
||||
|
||||
### 🆎 & 🔬
|
||||
|
||||
👫 🌐 🔢 💪 🕴 🍵 ✍ 🎻, 👫 🔢 🐍 & ✔️ 🔗 ⏮️ 🎏 📋 & 🎂 ⚙️ (& ⏮️ 🎏 🏃♂ ⚙️, 💾, 🚪, 🇸🇻).
|
||||
|
||||
👈 ⛓ 👈 🙆 💲 ✍ 🐍 ⚪️➡️ 🌐 🔢 🔜 `str`, & 🙆 🛠️ 🎏 🆎 ⚖️ 🔬 ✔️ 🔨 📟.
|
||||
|
||||
## Pydantic `Settings`
|
||||
|
||||
👐, Pydantic 🚚 👑 🚙 🍵 👫 ⚒ 👟 ⚪️➡️ 🌐 🔢 ⏮️ <a href="https://pydantic-docs.helpmanual.io/usage/settings/" class="external-link" target="_blank">Pydantic: ⚒ 🧾</a>.
|
||||
|
||||
### ✍ `Settings` 🎚
|
||||
|
||||
🗄 `BaseSettings` ⚪️➡️ Pydantic & ✍ 🎧-🎓, 📶 🌅 💖 ⏮️ Pydantic 🏷.
|
||||
|
||||
🎏 🌌 ⏮️ Pydantic 🏷, 👆 📣 🎓 🔢 ⏮️ 🆎 ✍, & 🎲 🔢 💲.
|
||||
|
||||
👆 💪 ⚙️ 🌐 🎏 🔬 ⚒ & 🧰 👆 ⚙️ Pydantic 🏷, 💖 🎏 📊 🆎 & 🌖 🔬 ⏮️ `Field()`.
|
||||
|
||||
```Python hl_lines="2 5-8 11"
|
||||
{!../../../docs_src/settings/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
🚥 👆 💚 🕳 ⏩ 📁 & 📋, 🚫 ⚙️ 👉 🖼, ⚙️ 🏁 1️⃣ 🔛.
|
||||
|
||||
⤴️, 🕐❔ 👆 ✍ 👐 👈 `Settings` 🎓 (👉 💼, `settings` 🎚), Pydantic 🔜 ✍ 🌐 🔢 💼-😛 🌌,, ↖-💼 🔢 `APP_NAME` 🔜 ✍ 🔢 `app_name`.
|
||||
|
||||
⏭ ⚫️ 🔜 🗜 & ✔ 💽. , 🕐❔ 👆 ⚙️ 👈 `settings` 🎚, 👆 🔜 ✔️ 📊 🆎 👆 📣 (✅ `items_per_user` 🔜 `int`).
|
||||
|
||||
### ⚙️ `settings`
|
||||
|
||||
⤴️ 👆 💪 ⚙️ 🆕 `settings` 🎚 👆 🈸:
|
||||
|
||||
```Python hl_lines="18-20"
|
||||
{!../../../docs_src/settings/tutorial001.py!}
|
||||
```
|
||||
|
||||
### 🏃 💽
|
||||
|
||||
⏭, 👆 🔜 🏃 💽 🚶♀️ 📳 🌐 🔢, 🖼 👆 💪 ⚒ `ADMIN_EMAIL` & `APP_NAME` ⏮️:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" uvicorn main:app
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! tip
|
||||
⚒ 💗 🇨🇻 {👁 📋 🎏 👫 ⏮️ 🚀, & 🚮 👫 🌐 ⏭ 📋.
|
||||
|
||||
& ⤴️ `admin_email` ⚒ 🔜 ⚒ `"deadpool@example.com"`.
|
||||
|
||||
`app_name` 🔜 `"ChimichangApp"`.
|
||||
|
||||
& `items_per_user` 🔜 🚧 🚮 🔢 💲 `50`.
|
||||
|
||||
## ⚒ ➕1️⃣ 🕹
|
||||
|
||||
👆 💪 🚮 👈 ⚒ ➕1️⃣ 🕹 📁 👆 👀 [🦏 🈸 - 💗 📁](../tutorial/bigger-applications.md){.internal-link target=_blank}.
|
||||
|
||||
🖼, 👆 💪 ✔️ 📁 `config.py` ⏮️:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/settings/app01/config.py!}
|
||||
```
|
||||
|
||||
& ⤴️ ⚙️ ⚫️ 📁 `main.py`:
|
||||
|
||||
```Python hl_lines="3 11-13"
|
||||
{!../../../docs_src/settings/app01/main.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👆 🔜 💪 📁 `__init__.py` 👆 👀 🔛 [🦏 🈸 - 💗 📁](../tutorial/bigger-applications.md){.internal-link target=_blank}.
|
||||
|
||||
## ⚒ 🔗
|
||||
|
||||
🍾 ⚫️ 5️⃣📆 ⚠ 🚚 ⚒ ⚪️➡️ 🔗, ↩️ ✔️ 🌐 🎚 ⏮️ `settings` 👈 ⚙️ 🌐.
|
||||
|
||||
👉 💪 ✴️ ⚠ ⏮️ 🔬, ⚫️ 📶 ⏩ 🔐 🔗 ⏮️ 👆 👍 🛃 ⚒.
|
||||
|
||||
### 📁 📁
|
||||
|
||||
👟 ⚪️➡️ ⏮️ 🖼, 👆 `config.py` 📁 💪 👀 💖:
|
||||
|
||||
```Python hl_lines="10"
|
||||
{!../../../docs_src/settings/app02/config.py!}
|
||||
```
|
||||
|
||||
👀 👈 🔜 👥 🚫 ✍ 🔢 👐 `settings = Settings()`.
|
||||
|
||||
### 👑 📱 📁
|
||||
|
||||
🔜 👥 ✍ 🔗 👈 📨 🆕 `config.Settings()`.
|
||||
|
||||
```Python hl_lines="5 11-12"
|
||||
{!../../../docs_src/settings/app02/main.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👥 🔜 🔬 `@lru_cache()` 🍖.
|
||||
|
||||
🔜 👆 💪 🤔 `get_settings()` 😐 🔢.
|
||||
|
||||
& ⤴️ 👥 💪 🚚 ⚫️ ⚪️➡️ *➡ 🛠️ 🔢* 🔗 & ⚙️ ⚫️ 🙆 👥 💪 ⚫️.
|
||||
|
||||
```Python hl_lines="16 18-20"
|
||||
{!../../../docs_src/settings/app02/main.py!}
|
||||
```
|
||||
|
||||
### ⚒ & 🔬
|
||||
|
||||
⤴️ ⚫️ 🔜 📶 ⏩ 🚚 🎏 ⚒ 🎚 ⏮️ 🔬 🏗 🔗 🔐 `get_settings`:
|
||||
|
||||
```Python hl_lines="9-10 13 21"
|
||||
{!../../../docs_src/settings/app02/test_main.py!}
|
||||
```
|
||||
|
||||
🔗 🔐 👥 ⚒ 🆕 💲 `admin_email` 🕐❔ 🏗 🆕 `Settings` 🎚, & ⤴️ 👥 📨 👈 🆕 🎚.
|
||||
|
||||
⤴️ 👥 💪 💯 👈 ⚫️ ⚙️.
|
||||
|
||||
## 👂 `.env` 📁
|
||||
|
||||
🚥 👆 ✔️ 📚 ⚒ 👈 🎲 🔀 📚, 🎲 🎏 🌐, ⚫️ 5️⃣📆 ⚠ 🚮 👫 🔛 📁 & ⤴️ ✍ 👫 ⚪️➡️ ⚫️ 🚥 👫 🌐 🔢.
|
||||
|
||||
👉 💡 ⚠ 🥃 👈 ⚫️ ✔️ 📛, 👫 🌐 🔢 🛎 🥉 📁 `.env`, & 📁 🤙 "🇨🇻".
|
||||
|
||||
!!! tip
|
||||
📁 ▶️ ⏮️ ❣ (`.`) 🕵♂ 📁 🖥-💖 ⚙️, 💖 💾 & 🇸🇻.
|
||||
|
||||
✋️ 🇨🇻 📁 🚫 🤙 ✔️ ✔️ 👈 ☑ 📁.
|
||||
|
||||
Pydantic ✔️ 🐕🦺 👂 ⚪️➡️ 👉 🆎 📁 ⚙️ 🔢 🗃. 👆 💪 ✍ 🌖 <a href="https://pydantic-docs.helpmanual.io/usage/settings/#dotenv-env-support" class="external-link" target="_blank">Pydantic ⚒: 🇨🇻 (.🇨🇻) 🐕🦺</a>.
|
||||
|
||||
!!! tip
|
||||
👉 👷, 👆 💪 `pip install python-dotenv`.
|
||||
|
||||
### `.env` 📁
|
||||
|
||||
👆 💪 ✔️ `.env` 📁 ⏮️:
|
||||
|
||||
```bash
|
||||
ADMIN_EMAIL="deadpool@example.com"
|
||||
APP_NAME="ChimichangApp"
|
||||
```
|
||||
|
||||
### ✍ ⚒ ⚪️➡️ `.env`
|
||||
|
||||
& ⤴️ ℹ 👆 `config.py` ⏮️:
|
||||
|
||||
```Python hl_lines="9-10"
|
||||
{!../../../docs_src/settings/app03/config.py!}
|
||||
```
|
||||
|
||||
📥 👥 ✍ 🎓 `Config` 🔘 👆 Pydantic `Settings` 🎓, & ⚒ `env_file` 📁 ⏮️ 🇨🇻 📁 👥 💚 ⚙️.
|
||||
|
||||
!!! tip
|
||||
`Config` 🎓 ⚙️ Pydantic 📳. 👆 💪 ✍ 🌖 <a href="https://pydantic-docs.helpmanual.io/usage/model_config/" class="external-link" target="_blank">Pydantic 🏷 📁</a>
|
||||
|
||||
### 🏗 `Settings` 🕴 🕐 ⏮️ `lru_cache`
|
||||
|
||||
👂 📁 ⚪️➡️ 💾 🛎 ⚠ (🐌) 🛠️, 👆 🎲 💚 ⚫️ 🕴 🕐 & ⤴️ 🏤-⚙️ 🎏 ⚒ 🎚, ↩️ 👂 ⚫️ 🔠 📨.
|
||||
|
||||
✋️ 🔠 🕰 👥:
|
||||
|
||||
```Python
|
||||
Settings()
|
||||
```
|
||||
|
||||
🆕 `Settings` 🎚 🔜 ✍, & 🏗 ⚫️ 🔜 ✍ `.env` 📁 🔄.
|
||||
|
||||
🚥 🔗 🔢 💖:
|
||||
|
||||
```Python
|
||||
def get_settings():
|
||||
return Settings()
|
||||
```
|
||||
|
||||
👥 🔜 ✍ 👈 🎚 🔠 📨, & 👥 🔜 👂 `.env` 📁 🔠 📨. 👶 👶
|
||||
|
||||
✋️ 👥 ⚙️ `@lru_cache()` 👨🎨 🔛 🔝, `Settings` 🎚 🔜 ✍ 🕴 🕐, 🥇 🕰 ⚫️ 🤙. 👶 👶
|
||||
|
||||
```Python hl_lines="1 10"
|
||||
{!../../../docs_src/settings/app03/main.py!}
|
||||
```
|
||||
|
||||
⤴️ 🙆 🏁 🤙 `get_settings()` 🔗 ⏭ 📨, ↩️ 🛠️ 🔗 📟 `get_settings()` & 🏗 🆕 `Settings` 🎚, ⚫️ 🔜 📨 🎏 🎚 👈 📨 🔛 🥇 🤙, 🔄 & 🔄.
|
||||
|
||||
#### `lru_cache` 📡 ℹ
|
||||
|
||||
`@lru_cache()` 🔀 🔢 ⚫️ 🎀 📨 🎏 💲 👈 📨 🥇 🕰, ↩️ 💻 ⚫️ 🔄, 🛠️ 📟 🔢 🔠 🕰.
|
||||
|
||||
, 🔢 🔛 ⚫️ 🔜 🛠️ 🕐 🔠 🌀 ❌. & ⤴️ 💲 📨 🔠 👈 🌀 ❌ 🔜 ⚙️ 🔄 & 🔄 🕐❔ 🔢 🤙 ⏮️ ⚫️❔ 🎏 🌀 ❌.
|
||||
|
||||
🖼, 🚥 👆 ✔️ 🔢:
|
||||
|
||||
```Python
|
||||
@lru_cache()
|
||||
def say_hi(name: str, salutation: str = "Ms."):
|
||||
return f"Hello {salutation} {name}"
|
||||
```
|
||||
|
||||
👆 📋 💪 🛠️ 💖 👉:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
|
||||
participant code as Code
|
||||
participant function as say_hi()
|
||||
participant execute as Execute function
|
||||
|
||||
rect rgba(0, 255, 0, .1)
|
||||
code ->> function: say_hi(name="Camila")
|
||||
function ->> execute: execute function code
|
||||
execute ->> code: return the result
|
||||
end
|
||||
|
||||
rect rgba(0, 255, 255, .1)
|
||||
code ->> function: say_hi(name="Camila")
|
||||
function ->> code: return stored result
|
||||
end
|
||||
|
||||
rect rgba(0, 255, 0, .1)
|
||||
code ->> function: say_hi(name="Rick")
|
||||
function ->> execute: execute function code
|
||||
execute ->> code: return the result
|
||||
end
|
||||
|
||||
rect rgba(0, 255, 0, .1)
|
||||
code ->> function: say_hi(name="Rick", salutation="Mr.")
|
||||
function ->> execute: execute function code
|
||||
execute ->> code: return the result
|
||||
end
|
||||
|
||||
rect rgba(0, 255, 255, .1)
|
||||
code ->> function: say_hi(name="Rick")
|
||||
function ->> code: return stored result
|
||||
end
|
||||
|
||||
rect rgba(0, 255, 255, .1)
|
||||
code ->> function: say_hi(name="Camila")
|
||||
function ->> code: return stored result
|
||||
end
|
||||
```
|
||||
|
||||
💼 👆 🔗 `get_settings()`, 🔢 🚫 ✊ 🙆 ❌, ⚫️ 🕧 📨 🎏 💲.
|
||||
|
||||
👈 🌌, ⚫️ 🎭 🌖 🚥 ⚫️ 🌐 🔢. ✋️ ⚫️ ⚙️ 🔗 🔢, ⤴️ 👥 💪 🔐 ⚫️ 💪 🔬.
|
||||
|
||||
`@lru_cache()` 🍕 `functools` ❔ 🍕 🐍 🐩 🗃, 👆 💪 ✍ 🌅 🔃 ⚫️ <a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" class="external-link" target="_blank">🐍 🩺 `@lru_cache()`</a>.
|
||||
|
||||
## 🌃
|
||||
|
||||
👆 💪 ⚙️ Pydantic ⚒ 🍵 ⚒ ⚖️ 📳 👆 🈸, ⏮️ 🌐 🏋️ Pydantic 🏷.
|
||||
|
||||
* ⚙️ 🔗 👆 💪 📉 🔬.
|
||||
* 👆 💪 ⚙️ `.env` 📁 ⏮️ ⚫️.
|
||||
* ⚙️ `@lru_cache()` ➡️ 👆 ❎ 👂 🇨🇻 📁 🔄 & 🔄 🔠 📨, ⏪ 🤝 👆 🔐 ⚫️ ⏮️ 🔬.
|
||||
529
docs/em/docs/advanced/sql-databases-peewee.md
Normal file
529
docs/em/docs/advanced/sql-databases-peewee.md
Normal file
@@ -0,0 +1,529 @@
|
||||
# 🗄 (🔗) 💽 ⏮️ 🏒
|
||||
|
||||
!!! warning
|
||||
🚥 👆 ▶️, 🔰 [🗄 (🔗) 💽](../tutorial/sql-databases.md){.internal-link target=_blank} 👈 ⚙️ 🇸🇲 🔜 🥃.
|
||||
|
||||
💭 🆓 🚶 👉.
|
||||
|
||||
🚥 👆 ▶️ 🏗 ⚪️➡️ 🖌, 👆 🎲 👻 📆 ⏮️ 🇸🇲 🐜 ([🗄 (🔗) 💽](../tutorial/sql-databases.md){.internal-link target=_blank}), ⚖️ 🙆 🎏 🔁 🐜.
|
||||
|
||||
🚥 👆 ⏪ ✔️ 📟 🧢 👈 ⚙️ <a href="https://docs.peewee-orm.com/en/latest/" class="external-link" target="_blank">🏒 🐜</a>, 👆 💪 ✅ 📥 ❔ ⚙️ ⚫️ ⏮️ **FastAPI**.
|
||||
|
||||
!!! warning "🐍 3️⃣.7️⃣ ➕ ✔"
|
||||
👆 🔜 💪 🐍 3️⃣.7️⃣ ⚖️ 🔛 🔒 ⚙️ 🏒 ⏮️ FastAPI.
|
||||
|
||||
## 🏒 🔁
|
||||
|
||||
🏒 🚫 🔧 🔁 🛠️, ⚖️ ⏮️ 👫 🤯.
|
||||
|
||||
🏒 ✔️ 🏋️ 🔑 🔃 🚮 🔢 & 🔃 ❔ ⚫️ 🔜 ⚙️.
|
||||
|
||||
🚥 👆 🛠️ 🈸 ⏮️ 🗝 🚫-🔁 🛠️, & 💪 👷 ⏮️ 🌐 🚮 🔢, **⚫️ 💪 👑 🧰**.
|
||||
|
||||
✋️ 🚥 👆 💪 🔀 🔢, 🐕🦺 🌖 🌘 1️⃣ 🔁 💽, 👷 ⏮️ 🔁 🛠️ (💖 FastAPI), ♒️, 👆 🔜 💪 🚮 🏗 ➕ 📟 🔐 👈 🔢.
|
||||
|
||||
👐, ⚫️ 💪 ⚫️, & 📥 👆 🔜 👀 ⚫️❔ ⚫️❔ 📟 👆 ✔️ 🚮 💪 ⚙️ 🏒 ⏮️ FastAPI.
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
👆 💪 ✍ 🌅 🔃 🏒 🧍 🔃 🔁 🐍 <a href="https://docs.peewee-orm.com/en/latest/peewee/database.html#async-with-gevent" class="external-link" target="_blank">🩺</a>, <a href="https://github.com/coleifer/peewee/issues/263#issuecomment-517347032" class="external-link" target="_blank">❔</a>, <a href="https://github.com/coleifer/peewee/pull/2072#issuecomment-563215132" class="external-link" target="_blank">🇵🇷</a>.
|
||||
|
||||
## 🎏 📱
|
||||
|
||||
👥 🔜 ✍ 🎏 🈸 🇸🇲 🔰 ([🗄 (🔗) 💽](../tutorial/sql-databases.md){.internal-link target=_blank}).
|
||||
|
||||
🌅 📟 🤙 🎏.
|
||||
|
||||
, 👥 🔜 🎯 🕴 🔛 🔺.
|
||||
|
||||
## 📁 📊
|
||||
|
||||
➡️ 💬 👆 ✔️ 📁 📛 `my_super_project` 👈 🔌 🎧-📁 🤙 `sql_app` ⏮️ 📊 💖 👉:
|
||||
|
||||
```
|
||||
.
|
||||
└── sql_app
|
||||
├── __init__.py
|
||||
├── crud.py
|
||||
├── database.py
|
||||
├── main.py
|
||||
└── schemas.py
|
||||
```
|
||||
|
||||
👉 🌖 🎏 📊 👥 ✔️ 🇸🇲 🔰.
|
||||
|
||||
🔜 ➡️ 👀 ⚫️❔ 🔠 📁/🕹 🔨.
|
||||
|
||||
## ✍ 🏒 🍕
|
||||
|
||||
➡️ 🔗 📁 `sql_app/database.py`.
|
||||
|
||||
### 🐩 🏒 📟
|
||||
|
||||
➡️ 🥇 ✅ 🌐 😐 🏒 📟, ✍ 🏒 💽:
|
||||
|
||||
```Python hl_lines="3 5 22"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
✔️ 🤯 👈 🚥 👆 💚 ⚙️ 🎏 💽, 💖 ✳, 👆 🚫 🚫 🔀 🎻. 👆 🔜 💪 ⚙️ 🎏 🏒 💽 🎓.
|
||||
|
||||
#### 🗒
|
||||
|
||||
❌:
|
||||
|
||||
```Python
|
||||
check_same_thread=False
|
||||
```
|
||||
|
||||
🌓 1️⃣ 🇸🇲 🔰:
|
||||
|
||||
```Python
|
||||
connect_args={"check_same_thread": False}
|
||||
```
|
||||
|
||||
...⚫️ 💪 🕴 `SQLite`.
|
||||
|
||||
!!! info "📡 ℹ"
|
||||
|
||||
⚫️❔ 🎏 📡 ℹ [🗄 (🔗) 💽](../tutorial/sql-databases.md#note){.internal-link target=_blank} ✔.
|
||||
|
||||
### ⚒ 🏒 🔁-🔗 `PeeweeConnectionState`
|
||||
|
||||
👑 ❔ ⏮️ 🏒 & FastAPI 👈 🏒 ⚓️ 🙇 🔛 <a href="https://docs.python.org/3/library/threading.html#thread-local-data" class="external-link" target="_blank">🐍 `threading.local`</a>, & ⚫️ 🚫 ✔️ 🎯 🌌 🔐 ⚫️ ⚖️ ➡️ 👆 🍵 🔗/🎉 🔗 (🔨 🇸🇲 🔰).
|
||||
|
||||
& `threading.local` 🚫 🔗 ⏮️ 🆕 🔁 ⚒ 🏛 🐍.
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
`threading.local` ⚙️ ✔️ "🎱" 🔢 👈 ✔️ 🎏 💲 🔠 🧵.
|
||||
|
||||
👉 ⚠ 🗝 🛠️ 🏗 ✔️ 1️⃣ 👁 🧵 📍 📨, 🙅♂ 🌖, 🙅♂ 🌘.
|
||||
|
||||
⚙️ 👉, 🔠 📨 🔜 ✔️ 🚮 👍 💽 🔗/🎉, ❔ ☑ 🏁 🥅.
|
||||
|
||||
✋️ FastAPI, ⚙️ 🆕 🔁 ⚒, 💪 🍵 🌅 🌘 1️⃣ 📨 🔛 🎏 🧵. & 🎏 🕰, 👁 📨, ⚫️ 💪 🏃 💗 👜 🎏 🧵 (🧵), ⚓️ 🔛 🚥 👆 ⚙️ `async def` ⚖️ 😐 `def`. 👉 ⚫️❔ 🤝 🌐 🎭 📈 FastAPI.
|
||||
|
||||
✋️ 🐍 3️⃣.7️⃣ & 🔛 🚚 🌖 🏧 🎛 `threading.local`, 👈 💪 ⚙️ 🥉 🌐❔ `threading.local` 🔜 ⚙️, ✋️ 🔗 ⏮️ 🆕 🔁 ⚒.
|
||||
|
||||
👥 🔜 ⚙️ 👈. ⚫️ 🤙 <a href="https://docs.python.org/3/library/contextvars.html" class="external-link" target="_blank">`contextvars`</a>.
|
||||
|
||||
👥 🔜 🔐 🔗 🍕 🏒 👈 ⚙️ `threading.local` & ❎ 👫 ⏮️ `contextvars`, ⏮️ 🔗 ℹ.
|
||||
|
||||
👉 5️⃣📆 😑 🍖 🏗 (& ⚫️ 🤙), 👆 🚫 🤙 💪 🍕 🤔 ❔ ⚫️ 👷 ⚙️ ⚫️.
|
||||
|
||||
👥 🔜 ✍ `PeeweeConnectionState`:
|
||||
|
||||
```Python hl_lines="10-19"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
|
||||
```
|
||||
|
||||
👉 🎓 😖 ⚪️➡️ 🎁 🔗 🎓 ⚙️ 🏒.
|
||||
|
||||
⚫️ ✔️ 🌐 ⚛ ⚒ 🏒 ⚙️ `contextvars` ↩️ `threading.local`.
|
||||
|
||||
`contextvars` 👷 🍖 🎏 🌘 `threading.local`. ✋️ 🎂 🏒 🔗 📟 🤔 👈 👉 🎓 👷 ⏮️ `threading.local`.
|
||||
|
||||
, 👥 💪 ➕ 🎱 ⚒ ⚫️ 👷 🚥 ⚫️ ⚙️ `threading.local`. `__init__`, `__setattr__`, & `__getattr__` 🛠️ 🌐 ✔ 🎱 👉 ⚙️ 🏒 🍵 🤔 👈 ⚫️ 🔜 🔗 ⏮️ FastAPI.
|
||||
|
||||
!!! tip
|
||||
👉 🔜 ⚒ 🏒 🎭 ☑ 🕐❔ ⚙️ ⏮️ FastAPI. 🚫 🎲 📂 ⚖️ 📪 🔗 👈 ➖ ⚙️, 🏗 ❌, ♒️.
|
||||
|
||||
✋️ ⚫️ 🚫 🤝 🏒 🔁 💎-🏋️. 👆 🔜 ⚙️ 😐 `def` 🔢 & 🚫 `async def`.
|
||||
|
||||
### ⚙️ 🛃 `PeeweeConnectionState` 🎓
|
||||
|
||||
🔜, 📁 `._state` 🔗 🔢 🏒 💽 `db` 🎚 ⚙️ 🆕 `PeeweeConnectionState`:
|
||||
|
||||
```Python hl_lines="24"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
⚒ 💭 👆 📁 `db._state` *⏮️* 🏗 `db`.
|
||||
|
||||
!!! tip
|
||||
👆 🔜 🎏 🙆 🎏 🏒 💽, 🔌 `PostgresqlDatabase`, `MySQLDatabase`, ♒️.
|
||||
|
||||
## ✍ 💽 🏷
|
||||
|
||||
➡️ 🔜 👀 📁 `sql_app/models.py`.
|
||||
|
||||
### ✍ 🏒 🏷 👆 💽
|
||||
|
||||
🔜 ✍ 🏒 🏷 (🎓) `User` & `Item`.
|
||||
|
||||
👉 🎏 👆 🔜 🚥 👆 ⏩ 🏒 🔰 & ℹ 🏷 ✔️ 🎏 💽 🇸🇲 🔰.
|
||||
|
||||
!!! tip
|
||||
🏒 ⚙️ ⚖ "**🏷**" 🔗 👉 🎓 & 👐 👈 🔗 ⏮️ 💽.
|
||||
|
||||
✋️ Pydantic ⚙️ ⚖ "**🏷**" 🔗 🕳 🎏, 💽 🔬, 🛠️, & 🧾 🎓 & 👐.
|
||||
|
||||
🗄 `db` ⚪️➡️ `database` (📁 `database.py` ⚪️➡️ 🔛) & ⚙️ ⚫️ 📥.
|
||||
|
||||
```Python hl_lines="3 6-12 15-21"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/models.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
🏒 ✍ 📚 🎱 🔢.
|
||||
|
||||
⚫️ 🔜 🔁 🚮 `id` 🔢 🔢 👑 🔑.
|
||||
|
||||
⚫️ 🔜 ⚒ 📛 🏓 ⚓️ 🔛 🎓 📛.
|
||||
|
||||
`Item`, ⚫️ 🔜 ✍ 🔢 `owner_id` ⏮️ 🔢 🆔 `User`. ✋️ 👥 🚫 📣 ⚫️ 🙆.
|
||||
|
||||
## ✍ Pydantic 🏷
|
||||
|
||||
🔜 ➡️ ✅ 📁 `sql_app/schemas.py`.
|
||||
|
||||
!!! tip
|
||||
❎ 😨 🖖 🏒 *🏷* & Pydantic *🏷*, 👥 🔜 ✔️ 📁 `models.py` ⏮️ 🏒 🏷, & 📁 `schemas.py` ⏮️ Pydantic 🏷.
|
||||
|
||||
👫 Pydantic 🏷 🔬 🌅 ⚖️ 🌘 "🔗" (☑ 📊 💠).
|
||||
|
||||
👉 🔜 ℹ 👥 ❎ 😨 ⏪ ⚙️ 👯♂️.
|
||||
|
||||
### ✍ Pydantic *🏷* / 🔗
|
||||
|
||||
✍ 🌐 🎏 Pydantic 🏷 🇸🇲 🔰:
|
||||
|
||||
```Python hl_lines="16-18 21-22 25-30 34-35 38-39 42-48"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
📥 👥 🏗 🏷 ⏮️ `id`.
|
||||
|
||||
👥 🚫 🎯 ✔ `id` 🔢 🏒 🏷, ✋️ 🏒 🚮 1️⃣ 🔁.
|
||||
|
||||
👥 ❎ 🎱 `owner_id` 🔢 `Item`.
|
||||
|
||||
### ✍ `PeeweeGetterDict` Pydantic *🏷* / 🔗
|
||||
|
||||
🕐❔ 👆 🔐 💛 🏒 🎚, 💖 `some_user.items`, 🏒 🚫 🚚 `list` `Item`.
|
||||
|
||||
⚫️ 🚚 🎁 🛃 🎚 🎓 `ModelSelect`.
|
||||
|
||||
⚫️ 💪 ✍ `list` 🚮 🏬 ⏮️ `list(some_user.items)`.
|
||||
|
||||
✋️ 🎚 ⚫️ 🚫 `list`. & ⚫️ 🚫 ☑ 🐍 <a href="https://docs.python.org/3/glossary.html#term-generator" class="external-link" target="_blank">🚂</a>. ↩️ 👉, Pydantic 🚫 💭 🔢 ❔ 🗜 ⚫️ `list` Pydantic *🏷* / 🔗.
|
||||
|
||||
✋️ ⏮️ ⏬ Pydantic ✔ 🚚 🛃 🎓 👈 😖 ⚪️➡️ `pydantic.utils.GetterDict`, 🚚 🛠️ ⚙️ 🕐❔ ⚙️ `orm_mode = True` 🗃 💲 🐜 🏷 🔢.
|
||||
|
||||
👥 🔜 ✍ 🛃 `PeeweeGetterDict` 🎓 & ⚙️ ⚫️ 🌐 🎏 Pydantic *🏷* / 🔗 👈 ⚙️ `orm_mode`:
|
||||
|
||||
```Python hl_lines="3 8-13 31 49"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
|
||||
```
|
||||
|
||||
📥 👥 ✅ 🚥 🔢 👈 ➖ 🔐 (✅ `.items` `some_user.items`) 👐 `peewee.ModelSelect`.
|
||||
|
||||
& 🚥 👈 💼, 📨 `list` ⏮️ ⚫️.
|
||||
|
||||
& ⤴️ 👥 ⚙️ ⚫️ Pydantic *🏷* / 🔗 👈 ⚙️ `orm_mode = True`, ⏮️ 📳 🔢 `getter_dict = PeeweeGetterDict`.
|
||||
|
||||
!!! tip
|
||||
👥 🕴 💪 ✍ 1️⃣ `PeeweeGetterDict` 🎓, & 👥 💪 ⚙️ ⚫️ 🌐 Pydantic *🏷* / 🔗.
|
||||
|
||||
## 💩 🇨🇻
|
||||
|
||||
🔜 ➡️ 👀 📁 `sql_app/crud.py`.
|
||||
|
||||
### ✍ 🌐 💩 🇨🇻
|
||||
|
||||
✍ 🌐 🎏 💩 🇨🇻 🇸🇲 🔰, 🌐 📟 📶 🎏:
|
||||
|
||||
```Python hl_lines="1 4-5 8-9 12-13 16-20 23-24 27-30"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/crud.py!}
|
||||
```
|
||||
|
||||
📤 🔺 ⏮️ 📟 🇸🇲 🔰.
|
||||
|
||||
👥 🚫 🚶♀️ `db` 🔢 🤭. ↩️ 👥 ⚙️ 🏷 🔗. 👉 ↩️ `db` 🎚 🌐 🎚, 👈 🔌 🌐 🔗 ⚛. 👈 ⚫️❔ 👥 ✔️ 🌐 `contextvars` ℹ 🔛.
|
||||
|
||||
🆖, 🕐❔ 🛬 📚 🎚, 💖 `get_users`, 👥 🔗 🤙 `list`, 💖:
|
||||
|
||||
```Python
|
||||
list(models.User.select())
|
||||
```
|
||||
|
||||
👉 🎏 🤔 👈 👥 ✔️ ✍ 🛃 `PeeweeGetterDict`. ✋️ 🛬 🕳 👈 ⏪ `list` ↩️ `peewee.ModelSelect` `response_model` *➡ 🛠️* ⏮️ `List[models.User]` (👈 👥 🔜 👀 ⏪) 🔜 👷 ☑.
|
||||
|
||||
## 👑 **FastAPI** 📱
|
||||
|
||||
& 🔜 📁 `sql_app/main.py` ➡️ 🛠️ & ⚙️ 🌐 🎏 🍕 👥 ✍ ⏭.
|
||||
|
||||
### ✍ 💽 🏓
|
||||
|
||||
📶 🙃 🌌 ✍ 💽 🏓:
|
||||
|
||||
```Python hl_lines="9-11"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
|
||||
```
|
||||
|
||||
### ✍ 🔗
|
||||
|
||||
✍ 🔗 👈 🔜 🔗 💽 ▶️️ ▶️ 📨 & 🔌 ⚫️ 🔚:
|
||||
|
||||
```Python hl_lines="23-29"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
|
||||
```
|
||||
|
||||
📥 👥 ✔️ 🛁 `yield` ↩️ 👥 🤙 🚫 ⚙️ 💽 🎚 🔗.
|
||||
|
||||
⚫️ 🔗 💽 & ♻ 🔗 💽 🔗 🔢 👈 🔬 🔠 📨 (⚙️ `contextvars` 🎱 ⚪️➡️ 🔛).
|
||||
|
||||
↩️ 💽 🔗 ⚠ 👤/🅾 🚧, 👉 🔗 ✍ ⏮️ 😐 `def` 🔢.
|
||||
|
||||
& ⤴️, 🔠 *➡ 🛠️ 🔢* 👈 💪 🔐 💽 👥 🚮 ⚫️ 🔗.
|
||||
|
||||
✋️ 👥 🚫 ⚙️ 💲 👐 👉 🔗 (⚫️ 🤙 🚫 🤝 🙆 💲, ⚫️ ✔️ 🛁 `yield`). , 👥 🚫 🚮 ⚫️ *➡ 🛠️ 🔢* ✋️ *➡ 🛠️ 👨🎨* `dependencies` 🔢:
|
||||
|
||||
```Python hl_lines="32 40 47 59 65 72"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
|
||||
```
|
||||
|
||||
### 🔑 🔢 🎧-🔗
|
||||
|
||||
🌐 `contextvars` 🍕 👷, 👥 💪 ⚒ 💭 👥 ✔️ 🔬 💲 `ContextVar` 🔠 📨 👈 ⚙️ 💽, & 👈 💲 🔜 ⚙️ 💽 🇵🇸 (🔗, 💵, ♒️) 🎂 📨.
|
||||
|
||||
👈, 👥 💪 ✍ ➕1️⃣ `async` 🔗 `reset_db_state()` 👈 ⚙️ 🎧-🔗 `get_db()`. ⚫️ 🔜 ⚒ 💲 🔑 🔢 (⏮️ 🔢 `dict`) 👈 🔜 ⚙️ 💽 🇵🇸 🎂 📨. & ⤴️ 🔗 `get_db()` 🔜 🏪 ⚫️ 💽 🇵🇸 (🔗, 💵, ♒️).
|
||||
|
||||
```Python hl_lines="18-20"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
|
||||
```
|
||||
|
||||
**⏭ 📨**, 👥 🔜 ⏲ 👈 🔑 🔢 🔄 `async` 🔗 `reset_db_state()` & ⤴️ ✍ 🆕 🔗 `get_db()` 🔗, 👈 🆕 📨 🔜 ✔️ 🚮 👍 💽 🇵🇸 (🔗, 💵, ♒️).
|
||||
|
||||
!!! tip
|
||||
FastAPI 🔁 🛠️, 1️⃣ 📨 💪 ▶️ ➖ 🛠️, & ⏭ 🏁, ➕1️⃣ 📨 💪 📨 & ▶️ 🏭 👍, & ⚫️ 🌐 💪 🛠️ 🎏 🧵.
|
||||
|
||||
✋️ 🔑 🔢 🤔 👫 🔁 ⚒,, 🏒 💽 🇵🇸 ⚒ `async` 🔗 `reset_db_state()` 🔜 🚧 🚮 👍 💽 🎂 🎂 📨.
|
||||
|
||||
& 🎏 🕰, 🎏 🛠️ 📨 🔜 ✔️ 🚮 👍 💽 🇵🇸 👈 🔜 🔬 🎂 📨.
|
||||
|
||||
#### 🏒 🗳
|
||||
|
||||
🚥 👆 ⚙️ <a href="https://docs.peewee-orm.com/en/latest/peewee/database.html#dynamically-defining-a-database" class="external-link" target="_blank">🏒 🗳</a>, ☑ 💽 `db.obj`.
|
||||
|
||||
, 👆 🔜 ⏲ ⚫️ ⏮️:
|
||||
|
||||
```Python hl_lines="3-4"
|
||||
async def reset_db_state():
|
||||
database.db.obj._state._state.set(db_state_default.copy())
|
||||
database.db.obj._state.reset()
|
||||
```
|
||||
|
||||
### ✍ 👆 **FastAPI** *➡ 🛠️*
|
||||
|
||||
🔜, 😒, 📥 🐩 **FastAPI** *➡ 🛠️* 📟.
|
||||
|
||||
```Python hl_lines="32-37 40-43 46-53 56-62 65-68 71-79"
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
|
||||
```
|
||||
|
||||
### 🔃 `def` 🆚 `async def`
|
||||
|
||||
🎏 ⏮️ 🇸🇲, 👥 🚫 🔨 🕳 💖:
|
||||
|
||||
```Python
|
||||
user = await models.User.select().first()
|
||||
```
|
||||
|
||||
...✋️ ↩️ 👥 ⚙️:
|
||||
|
||||
```Python
|
||||
user = models.User.select().first()
|
||||
```
|
||||
|
||||
, 🔄, 👥 🔜 📣 *➡ 🛠️ 🔢* & 🔗 🍵 `async def`, ⏮️ 😐 `def`,:
|
||||
|
||||
```Python hl_lines="2"
|
||||
# Something goes here
|
||||
def read_users(skip: int = 0, limit: int = 100):
|
||||
# Something goes here
|
||||
```
|
||||
|
||||
## 🔬 🏒 ⏮️ 🔁
|
||||
|
||||
👉 🖼 🔌 ➕ *➡ 🛠️* 👈 🔬 📏 🏭 📨 ⏮️ `time.sleep(sleep_time)`.
|
||||
|
||||
⚫️ 🔜 ✔️ 💽 🔗 📂 ▶️ & 🔜 ⌛ 🥈 ⏭ 🙇 🔙. & 🔠 🆕 📨 🔜 ⌛ 🕐 🥈 🌘.
|
||||
|
||||
👉 🔜 💪 ➡️ 👆 💯 👈 👆 📱 ⏮️ 🏒 & FastAPI 🎭 ☑ ⏮️ 🌐 💩 🔃 🧵.
|
||||
|
||||
🚥 👆 💚 ✅ ❔ 🏒 🔜 💔 👆 📱 🚥 ⚙️ 🍵 🛠️, 🚶 `sql_app/database.py` 📁 & 🏤 ⏸:
|
||||
|
||||
```Python
|
||||
# db._state = PeeweeConnectionState()
|
||||
```
|
||||
|
||||
& 📁 `sql_app/main.py` 📁, 🏤 💪 `async` 🔗 `reset_db_state()` & ❎ ⚫️ ⏮️ `pass`:
|
||||
|
||||
```Python
|
||||
async def reset_db_state():
|
||||
# database.db._state._state.set(db_state_default.copy())
|
||||
# database.db._state.reset()
|
||||
pass
|
||||
```
|
||||
|
||||
⤴️ 🏃 👆 📱 ⏮️ Uvicorn:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn sql_app.main:app --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
📂 👆 🖥 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a> & ✍ 👩❤👨 👩💻.
|
||||
|
||||
⤴️ 📂 1️⃣0️⃣ 📑 <a href="http://127.0.0.1:8000/docs#/default/read_slow_users_slowusers__get" class="external-link" target="_blank">http://127.0.0.1:8000/docs#/default/read_🐌_👩💻_slowusers_ = </a> 🎏 🕰.
|
||||
|
||||
🚶 *➡ 🛠️* "🤚 `/slowusers/`" 🌐 📑. ⚙️ "🔄 ⚫️ 👅" 🔼 & 🛠️ 📨 🔠 📑, 1️⃣ ▶️️ ⏮️ 🎏.
|
||||
|
||||
📑 🔜 ⌛ 🍖 & ⤴️ 👫 🔜 🎦 `Internal Server Error`.
|
||||
|
||||
### ⚫️❔ 🔨
|
||||
|
||||
🥇 📑 🔜 ⚒ 👆 📱 ✍ 🔗 💽 & ⌛ 🥈 ⏭ 🙇 🔙 & 📪 💽 🔗.
|
||||
|
||||
⤴️, 📨 ⏭ 📑, 👆 📱 🔜 ⌛ 🕐 🥈 🌘, & 🔛.
|
||||
|
||||
👉 ⛓ 👈 ⚫️ 🔜 🔚 🆙 🏁 🏁 📑' 📨 ⏪ 🌘 ⏮️ 🕐.
|
||||
|
||||
⤴️ 1️⃣ 🏁 📨 👈 ⌛ 🌘 🥈 🔜 🔄 📂 💽 🔗, ✋️ 1️⃣ 📚 ⏮️ 📨 🎏 📑 🔜 🎲 🍵 🎏 🧵 🥇 🕐, ⚫️ 🔜 ✔️ 🎏 💽 🔗 👈 ⏪ 📂, & 🏒 🔜 🚮 ❌ & 👆 🔜 👀 ⚫️ 📶, & 📨 🔜 ✔️ `Internal Server Error`.
|
||||
|
||||
👉 🔜 🎲 🔨 🌅 🌘 1️⃣ 📚 📑.
|
||||
|
||||
🚥 👆 ✔️ 💗 👩💻 💬 👆 📱 ⚫️❔ 🎏 🕰, 👉 ⚫️❔ 💪 🔨.
|
||||
|
||||
& 👆 📱 ▶️ 🍵 🌅 & 🌖 👩💻 🎏 🕰, ⌛ 🕰 👁 📨 💪 📏 & 📏 ⏲ ❌.
|
||||
|
||||
### 🔧 🏒 ⏮️ FastAPI
|
||||
|
||||
🔜 🚶 🔙 📁 `sql_app/database.py`, & ✍ ⏸:
|
||||
|
||||
```Python
|
||||
db._state = PeeweeConnectionState()
|
||||
```
|
||||
|
||||
& 📁 `sql_app/main.py` 📁, ✍ 💪 `async` 🔗 `reset_db_state()`:
|
||||
|
||||
```Python
|
||||
async def reset_db_state():
|
||||
database.db._state._state.set(db_state_default.copy())
|
||||
database.db._state.reset()
|
||||
```
|
||||
|
||||
❎ 👆 🏃♂ 📱 & ▶️ ⚫️ 🔄.
|
||||
|
||||
🔁 🎏 🛠️ ⏮️ 1️⃣0️⃣ 📑. 👉 🕰 🌐 👫 🔜 ⌛ & 👆 🔜 🤚 🌐 🏁 🍵 ❌.
|
||||
|
||||
...👆 🔧 ⚫️ ❗
|
||||
|
||||
## 📄 🌐 📁
|
||||
|
||||
💭 👆 🔜 ✔️ 📁 📛 `my_super_project` (⚖️ 👐 👆 💚) 👈 🔌 🎧-📁 🤙 `sql_app`.
|
||||
|
||||
`sql_app` 🔜 ✔️ 📄 📁:
|
||||
|
||||
* `sql_app/__init__.py`: 🛁 📁.
|
||||
|
||||
* `sql_app/database.py`:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/database.py!}
|
||||
```
|
||||
|
||||
* `sql_app/models.py`:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/models.py!}
|
||||
```
|
||||
|
||||
* `sql_app/schemas.py`:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/schemas.py!}
|
||||
```
|
||||
|
||||
* `sql_app/crud.py`:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/crud.py!}
|
||||
```
|
||||
|
||||
* `sql_app/main.py`:
|
||||
|
||||
```Python
|
||||
{!../../../docs_src/sql_databases_peewee/sql_app/main.py!}
|
||||
```
|
||||
|
||||
## 📡 ℹ
|
||||
|
||||
!!! warning
|
||||
👉 📶 📡 ℹ 👈 👆 🎲 🚫 💪.
|
||||
|
||||
### ⚠
|
||||
|
||||
🏒 ⚙️ <a href="https://docs.python.org/3/library/threading.html#thread-local-data" class="external-link" target="_blank">`threading.local`</a> 🔢 🏪 ⚫️ 💽 "🇵🇸" 💽 (🔗, 💵, ♒️).
|
||||
|
||||
`threading.local` ✍ 💲 🌟 ⏮️ 🧵, ✋️ 🔁 🛠️ 🔜 🏃 🌐 📟 (✅ 🔠 📨) 🎏 🧵, & 🎲 🚫 ✔.
|
||||
|
||||
🔛 🔝 👈, 🔁 🛠️ 💪 🏃 🔁 📟 🧵 (⚙️ `asyncio.run_in_executor`), ✋️ 🔗 🎏 📨.
|
||||
|
||||
👉 ⛓ 👈, ⏮️ 🏒 ⏮️ 🛠️, 💗 📋 💪 ⚙️ 🎏 `threading.local` 🔢 & 🔚 🆙 🤝 🎏 🔗 & 💽 (👈 👫 🚫🔜 🚫), & 🎏 🕰, 🚥 👫 🛠️ 🔁 👤/🅾-🚧 📟 🧵 (⏮️ 😐 `def` 🔢 FastAPI, *➡ 🛠️* & 🔗), 👈 📟 🏆 🚫 ✔️ 🔐 💽 🇵🇸 🔢, ⏪ ⚫️ 🍕 🎏 📨 & ⚫️ 🔜 💪 🤚 🔐 🎏 💽 🇵🇸.
|
||||
|
||||
### 🔑 🔢
|
||||
|
||||
🐍 3️⃣.7️⃣ ✔️ <a href="https://docs.python.org/3/library/contextvars.html" class="external-link" target="_blank">`contextvars`</a> 👈 💪 ✍ 🇧🇿 🔢 📶 🎏 `threading.local`, ✋️ 🔗 👫 🔁 ⚒.
|
||||
|
||||
📤 📚 👜 ✔️ 🤯.
|
||||
|
||||
`ContextVar` ✔️ ✍ 🔝 🕹, 💖:
|
||||
|
||||
```Python
|
||||
some_var = ContextVar("some_var", default="default value")
|
||||
```
|
||||
|
||||
⚒ 💲 ⚙️ ⏮️ "🔑" (✅ ⏮️ 📨) ⚙️:
|
||||
|
||||
```Python
|
||||
some_var.set("new value")
|
||||
```
|
||||
|
||||
🤚 💲 🙆 🔘 🔑 (✅ 🙆 🍕 🚚 ⏮️ 📨) ⚙️:
|
||||
|
||||
```Python
|
||||
some_var.get()
|
||||
```
|
||||
|
||||
### ⚒ 🔑 🔢 `async` 🔗 `reset_db_state()`
|
||||
|
||||
🚥 🍕 🔁 📟 ⚒ 💲 ⏮️ `some_var.set("updated in function")` (✅ 💖 `async` 🔗), 🎂 📟 ⚫️ & 📟 👈 🚶 ⏮️ (✅ 📟 🔘 `async` 🔢 🤙 ⏮️ `await`) 🔜 👀 👈 🆕 💲.
|
||||
|
||||
, 👆 💼, 🚥 👥 ⚒ 🏒 🇵🇸 🔢 (⏮️ 🔢 `dict`) `async` 🔗, 🌐 🎂 🔗 📟 👆 📱 🔜 👀 👉 💲 & 🔜 💪 ♻ ⚫️ 🎂 📨.
|
||||
|
||||
& 🔑 🔢 🔜 ⚒ 🔄 ⏭ 📨, 🚥 👫 🛠️.
|
||||
|
||||
### ⚒ 💽 🇵🇸 🔗 `get_db()`
|
||||
|
||||
`get_db()` 😐 `def` 🔢, **FastAPI** 🔜 ⚒ ⚫️ 🏃 🧵, ⏮️ *📁* "🔑", 🧑🤝🧑 🎏 💲 🔑 🔢 ( `dict` ⏮️ ⏲ 💽 🇵🇸). ⤴️ ⚫️ 💪 🚮 💽 🇵🇸 👈 `dict`, 💖 🔗, ♒️.
|
||||
|
||||
✋️ 🚥 💲 🔑 🔢 (🔢 `dict`) ⚒ 👈 😐 `def` 🔢, ⚫️ 🔜 ✍ 🆕 💲 👈 🔜 🚧 🕴 👈 🧵 🧵, & 🎂 📟 (💖 *➡ 🛠️ 🔢*) 🚫🔜 ✔️ 🔐 ⚫️. `get_db()` 👥 💪 🕴 ⚒ 💲 `dict`, ✋️ 🚫 🎂 `dict` ⚫️.
|
||||
|
||||
, 👥 💪 ✔️ `async` 🔗 `reset_db_state()` ⚒ `dict` 🔑 🔢. 👈 🌌, 🌐 📟 ✔️ 🔐 🎏 `dict` 💽 🇵🇸 👁 📨.
|
||||
|
||||
### 🔗 & 🔌 🔗 `get_db()`
|
||||
|
||||
⤴️ ⏭ ❔ 🔜, ⚫️❔ 🚫 🔗 & 🔌 💽 `async` 🔗 ⚫️, ↩️ `get_db()`❓
|
||||
|
||||
`async` 🔗 ✔️ `async` 🔑 🔢 🛡 🎂 📨, ✋️ 🏗 & 📪 💽 🔗 ⚠ 🚧, ⚫️ 💪 📉 🎭 🚥 ⚫️ 📤.
|
||||
|
||||
👥 💪 😐 `def` 🔗 `get_db()`.
|
||||
73
docs/em/docs/advanced/sub-applications.md
Normal file
73
docs/em/docs/advanced/sub-applications.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# 🎧 🈸 - 🗻
|
||||
|
||||
🚥 👆 💪 ✔️ 2️⃣ 🔬 FastAPI 🈸, ⏮️ 👫 👍 🔬 🗄 & 👫 👍 🩺 ⚜, 👆 💪 ✔️ 👑 📱 & "🗻" 1️⃣ (⚖️ 🌅) 🎧-🈸(Ⓜ).
|
||||
|
||||
## 🗜 **FastAPI** 🈸
|
||||
|
||||
"🗜" ⛓ ❎ 🍕 "🔬" 🈸 🎯 ➡, 👈 ⤴️ ✊ 💅 🚚 🌐 🔽 👈 ➡, ⏮️ _➡ 🛠️_ 📣 👈 🎧-🈸.
|
||||
|
||||
### 🔝-🎚 🈸
|
||||
|
||||
🥇, ✍ 👑, 🔝-🎚, **FastAPI** 🈸, & 🚮 *➡ 🛠️*:
|
||||
|
||||
```Python hl_lines="3 6-8"
|
||||
{!../../../docs_src/sub_applications/tutorial001.py!}
|
||||
```
|
||||
|
||||
### 🎧-🈸
|
||||
|
||||
⤴️, ✍ 👆 🎧-🈸, & 🚮 *➡ 🛠️*.
|
||||
|
||||
👉 🎧-🈸 ➕1️⃣ 🐩 FastAPI 🈸, ✋️ 👉 1️⃣ 👈 🔜 "🗻":
|
||||
|
||||
```Python hl_lines="11 14-16"
|
||||
{!../../../docs_src/sub_applications/tutorial001.py!}
|
||||
```
|
||||
|
||||
### 🗻 🎧-🈸
|
||||
|
||||
👆 🔝-🎚 🈸, `app`, 🗻 🎧-🈸, `subapi`.
|
||||
|
||||
👉 💼, ⚫️ 🔜 📌 ➡ `/subapi`:
|
||||
|
||||
```Python hl_lines="11 19"
|
||||
{!../../../docs_src/sub_applications/tutorial001.py!}
|
||||
```
|
||||
|
||||
### ✅ 🏧 🛠️ 🩺
|
||||
|
||||
🔜, 🏃 `uvicorn` ⏮️ 👑 📱, 🚥 👆 📁 `main.py`, ⚫️ 🔜:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
& 📂 🩺 <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
|
||||
|
||||
👆 🔜 👀 🏧 🛠️ 🩺 👑 📱, 🔌 🕴 🚮 👍 _➡ 🛠️_:
|
||||
|
||||
<img src="/img/tutorial/sub-applications/image01.png">
|
||||
|
||||
& ⤴️, 📂 🩺 🎧-🈸, <a href="http://127.0.0.1:8000/subapi/docs" class="external-link" target="_blank">http://127.0.0.1:8000/subapi/docs</a>.
|
||||
|
||||
👆 🔜 👀 🏧 🛠️ 🩺 🎧-🈸, ✅ 🕴 🚮 👍 _➡ 🛠️_, 🌐 🔽 ☑ 🎧-➡ 🔡 `/subapi`:
|
||||
|
||||
<img src="/img/tutorial/sub-applications/image02.png">
|
||||
|
||||
🚥 👆 🔄 🔗 ⏮️ 🙆 2️⃣ 👩💻 🔢, 👫 🔜 👷 ☑, ↩️ 🖥 🔜 💪 💬 🔠 🎯 📱 ⚖️ 🎧-📱.
|
||||
|
||||
### 📡 ℹ: `root_path`
|
||||
|
||||
🕐❔ 👆 🗻 🎧-🈸 🔬 🔛, FastAPI 🔜 ✊ 💅 🔗 🗻 ➡ 🎧-🈸 ⚙️ 🛠️ ⚪️➡️ 🔫 🔧 🤙 `root_path`.
|
||||
|
||||
👈 🌌, 🎧-🈸 🔜 💭 ⚙️ 👈 ➡ 🔡 🩺 🎚.
|
||||
|
||||
& 🎧-🈸 💪 ✔️ 🚮 👍 📌 🎧-🈸 & 🌐 🔜 👷 ☑, ↩️ FastAPI 🍵 🌐 👉 `root_path`Ⓜ 🔁.
|
||||
|
||||
👆 🔜 💡 🌅 🔃 `root_path` & ❔ ⚙️ ⚫️ 🎯 📄 🔃 [⛅ 🗳](./behind-a-proxy.md){.internal-link target=_blank}.
|
||||
77
docs/em/docs/advanced/templates.md
Normal file
77
docs/em/docs/advanced/templates.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 📄
|
||||
|
||||
👆 💪 ⚙️ 🙆 📄 🚒 👆 💚 ⏮️ **FastAPI**.
|
||||
|
||||
⚠ ⚒ Jinja2️⃣, 🎏 1️⃣ ⚙️ 🏺 & 🎏 🧰.
|
||||
|
||||
📤 🚙 🔗 ⚫️ 💪 👈 👆 💪 ⚙️ 🔗 👆 **FastAPI** 🈸 (🚚 💃).
|
||||
|
||||
## ❎ 🔗
|
||||
|
||||
❎ `jinja2`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install jinja2
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## ⚙️ `Jinja2Templates`
|
||||
|
||||
* 🗄 `Jinja2Templates`.
|
||||
* ✍ `templates` 🎚 👈 👆 💪 🏤-⚙️ ⏪.
|
||||
* 📣 `Request` 🔢 *➡ 🛠️* 👈 🔜 📨 📄.
|
||||
* ⚙️ `templates` 👆 ✍ ✍ & 📨 `TemplateResponse`, 🚶♀️ `request` 1️⃣ 🔑-💲 👫 Jinja2️⃣ "🔑".
|
||||
|
||||
```Python hl_lines="4 11 15-16"
|
||||
{!../../../docs_src/templates/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
👀 👈 👆 ✔️ 🚶♀️ `request` 🍕 🔑-💲 👫 🔑 Jinja2️⃣. , 👆 ✔️ 📣 ⚫️ 👆 *➡ 🛠️*.
|
||||
|
||||
!!! tip
|
||||
📣 `response_class=HTMLResponse` 🩺 🎚 🔜 💪 💭 👈 📨 🔜 🕸.
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
👆 💪 ⚙️ `from starlette.templating import Jinja2Templates`.
|
||||
|
||||
**FastAPI** 🚚 🎏 `starlette.templating` `fastapi.templating` 🏪 👆, 👩💻. ✋️ 🌅 💪 📨 👟 🔗 ⚪️➡️ 💃. 🎏 ⏮️ `Request` & `StaticFiles`.
|
||||
|
||||
## ✍ 📄
|
||||
|
||||
⤴️ 👆 💪 ✍ 📄 `templates/item.html` ⏮️:
|
||||
|
||||
```jinja hl_lines="7"
|
||||
{!../../../docs_src/templates/templates/item.html!}
|
||||
```
|
||||
|
||||
⚫️ 🔜 🎦 `id` ✊ ⚪️➡️ "🔑" `dict` 👆 🚶♀️:
|
||||
|
||||
```Python
|
||||
{"request": request, "id": id}
|
||||
```
|
||||
|
||||
## 📄 & 🎻 📁
|
||||
|
||||
& 👆 💪 ⚙️ `url_for()` 🔘 📄, & ⚙️ ⚫️, 🖼, ⏮️ `StaticFiles` 👆 📌.
|
||||
|
||||
```jinja hl_lines="4"
|
||||
{!../../../docs_src/templates/templates/item.html!}
|
||||
```
|
||||
|
||||
👉 🖼, ⚫️ 🔜 🔗 🎚 📁 `static/styles.css` ⏮️:
|
||||
|
||||
```CSS hl_lines="4"
|
||||
{!../../../docs_src/templates/static/styles.css!}
|
||||
```
|
||||
|
||||
& ↩️ 👆 ⚙️ `StaticFiles`, 👈 🎚 📁 🔜 🍦 🔁 👆 **FastAPI** 🈸 📛 `/static/styles.css`.
|
||||
|
||||
## 🌅 ℹ
|
||||
|
||||
🌅 ℹ, 🔌 ❔ 💯 📄, ✅ <a href="https://www.starlette.io/templates/" class="external-link" target="_blank">💃 🩺 🔛 📄</a>.
|
||||
95
docs/em/docs/advanced/testing-database.md
Normal file
95
docs/em/docs/advanced/testing-database.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# 🔬 💽
|
||||
|
||||
👆 💪 ⚙️ 🎏 🔗 🔐 ⚪️➡️ [🔬 🔗 ⏮️ 🔐](testing-dependencies.md){.internal-link target=_blank} 📉 💽 🔬.
|
||||
|
||||
👆 💪 💚 ⚒ 🆙 🎏 💽 🔬, 💾 💽 ⏮️ 💯, 🏤-🥧 ⚫️ ⏮️ 🔬 💽, ♒️.
|
||||
|
||||
👑 💭 ⚫️❔ 🎏 👆 👀 👈 ⏮️ 📃.
|
||||
|
||||
## 🚮 💯 🗄 📱
|
||||
|
||||
➡️ ℹ 🖼 ⚪️➡️ [🗄 (🔗) 💽](../tutorial/sql-databases.md){.internal-link target=_blank} ⚙️ 🔬 💽.
|
||||
|
||||
🌐 📱 📟 🎏, 👆 💪 🚶 🔙 👈 📃 ✅ ❔ ⚫️.
|
||||
|
||||
🕴 🔀 📥 🆕 🔬 📁.
|
||||
|
||||
👆 😐 🔗 `get_db()` 🔜 📨 💽 🎉.
|
||||
|
||||
💯, 👆 💪 ⚙️ 🔗 🔐 📨 👆 *🛃* 💽 🎉 ↩️ 1️⃣ 👈 🔜 ⚙️ 🛎.
|
||||
|
||||
👉 🖼 👥 🔜 ✍ 🍕 💽 🕴 💯.
|
||||
|
||||
## 📁 📊
|
||||
|
||||
👥 ✍ 🆕 📁 `sql_app/tests/test_sql_app.py`.
|
||||
|
||||
🆕 📁 📊 👀 💖:
|
||||
|
||||
``` hl_lines="9-11"
|
||||
.
|
||||
└── sql_app
|
||||
├── __init__.py
|
||||
├── crud.py
|
||||
├── database.py
|
||||
├── main.py
|
||||
├── models.py
|
||||
├── schemas.py
|
||||
└── tests
|
||||
├── __init__.py
|
||||
└── test_sql_app.py
|
||||
```
|
||||
|
||||
## ✍ 🆕 💽 🎉
|
||||
|
||||
🥇, 👥 ✍ 🆕 💽 🎉 ⏮️ 🆕 💽.
|
||||
|
||||
💯 👥 🔜 ⚙️ 📁 `test.db` ↩️ `sql_app.db`.
|
||||
|
||||
✋️ 🎂 🎉 📟 🌅 ⚖️ 🌘 🎏, 👥 📁 ⚫️.
|
||||
|
||||
```Python hl_lines="8-13"
|
||||
{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👆 💪 📉 ❎ 👈 📟 🚮 ⚫️ 🔢 & ⚙️ ⚫️ ⚪️➡️ 👯♂️ `database.py` & `tests/test_sql_app.py`.
|
||||
|
||||
🦁 & 🎯 🔛 🎯 🔬 📟, 👥 🖨 ⚫️.
|
||||
|
||||
## ✍ 💽
|
||||
|
||||
↩️ 🔜 👥 🔜 ⚙️ 🆕 💽 🆕 📁, 👥 💪 ⚒ 💭 👥 ✍ 💽 ⏮️:
|
||||
|
||||
```Python
|
||||
Base.metadata.create_all(bind=engine)
|
||||
```
|
||||
|
||||
👈 🛎 🤙 `main.py`, ✋️ ⏸ `main.py` ⚙️ 💽 📁 `sql_app.db`, & 👥 💪 ⚒ 💭 👥 ✍ `test.db` 💯.
|
||||
|
||||
👥 🚮 👈 ⏸ 📥, ⏮️ 🆕 📁.
|
||||
|
||||
```Python hl_lines="16"
|
||||
{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
|
||||
```
|
||||
|
||||
## 🔗 🔐
|
||||
|
||||
🔜 👥 ✍ 🔗 🔐 & 🚮 ⚫️ 🔐 👆 📱.
|
||||
|
||||
```Python hl_lines="19-24 27"
|
||||
{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
📟 `override_get_db()` 🌖 ⚫️❔ 🎏 `get_db()`, ✋️ `override_get_db()` 👥 ⚙️ `TestingSessionLocal` 🔬 💽 ↩️.
|
||||
|
||||
## 💯 📱
|
||||
|
||||
⤴️ 👥 💪 💯 📱 🛎.
|
||||
|
||||
```Python hl_lines="32-47"
|
||||
{!../../../docs_src/sql_databases/sql_app/tests/test_sql_app.py!}
|
||||
```
|
||||
|
||||
& 🌐 🛠️ 👥 ⚒ 💽 ⏮️ 💯 🔜 `test.db` 💽 ↩️ 👑 `sql_app.db`.
|
||||
49
docs/em/docs/advanced/testing-dependencies.md
Normal file
49
docs/em/docs/advanced/testing-dependencies.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# 🔬 🔗 ⏮️ 🔐
|
||||
|
||||
## 🔑 🔗 ⏮️ 🔬
|
||||
|
||||
📤 😐 🌐❔ 👆 💪 💚 🔐 🔗 ⏮️ 🔬.
|
||||
|
||||
👆 🚫 💚 ⏮️ 🔗 🏃 (🚫 🙆 🎧-🔗 ⚫️ 💪 ✔️).
|
||||
|
||||
↩️, 👆 💚 🚚 🎏 🔗 👈 🔜 ⚙️ 🕴 ⏮️ 💯 (🎲 🕴 🎯 💯), & 🔜 🚚 💲 👈 💪 ⚙️ 🌐❔ 💲 ⏮️ 🔗 ⚙️.
|
||||
|
||||
### ⚙️ 💼: 🔢 🐕🦺
|
||||
|
||||
🖼 💪 👈 👆 ✔️ 🔢 🤝 🐕🦺 👈 👆 💪 🤙.
|
||||
|
||||
👆 📨 ⚫️ 🤝 & ⚫️ 📨 🔓 👩💻.
|
||||
|
||||
👉 🐕🦺 5️⃣📆 🔌 👆 📍 📨, & 🤙 ⚫️ 💪 ✊ ➕ 🕰 🌘 🚥 👆 ✔️ 🔧 🎁 👩💻 💯.
|
||||
|
||||
👆 🎲 💚 💯 🔢 🐕🦺 🕐, ✋️ 🚫 🎯 🤙 ⚫️ 🔠 💯 👈 🏃.
|
||||
|
||||
👉 💼, 👆 💪 🔐 🔗 👈 🤙 👈 🐕🦺, & ⚙️ 🛃 🔗 👈 📨 🎁 👩💻, 🕴 👆 💯.
|
||||
|
||||
### ⚙️ `app.dependency_overrides` 🔢
|
||||
|
||||
👫 💼, 👆 **FastAPI** 🈸 ✔️ 🔢 `app.dependency_overrides`, ⚫️ 🙅 `dict`.
|
||||
|
||||
🔐 🔗 🔬, 👆 🚮 🔑 ⏮️ 🔗 (🔢), & 💲, 👆 🔗 🔐 (➕1️⃣ 🔢).
|
||||
|
||||
& ⤴️ **FastAPI** 🔜 🤙 👈 🔐 ↩️ ⏮️ 🔗.
|
||||
|
||||
```Python hl_lines="28-29 32"
|
||||
{!../../../docs_src/dependency_testing/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👆 💪 ⚒ 🔗 🔐 🔗 ⚙️ 🙆 👆 **FastAPI** 🈸.
|
||||
|
||||
⏮️ 🔗 💪 ⚙️ *➡ 🛠️ 🔢*, *➡ 🛠️ 👨🎨* (🕐❔ 👆 🚫 ⚙️ 📨 💲), `.include_router()` 🤙, ♒️.
|
||||
|
||||
FastAPI 🔜 💪 🔐 ⚫️.
|
||||
|
||||
⤴️ 👆 💪 ⏲ 👆 🔐 (❎ 👫) ⚒ `app.dependency_overrides` 🛁 `dict`:
|
||||
|
||||
```Python
|
||||
app.dependency_overrides = {}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
🚥 👆 💚 🔐 🔗 🕴 ⏮️ 💯, 👆 💪 ⚒ 🔐 ▶️ 💯 (🔘 💯 🔢) & ⏲ ⚫️ 🔚 (🔚 💯 🔢).
|
||||
7
docs/em/docs/advanced/testing-events.md
Normal file
7
docs/em/docs/advanced/testing-events.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# 🔬 🎉: 🕴 - 🤫
|
||||
|
||||
🕐❔ 👆 💪 👆 🎉 🐕🦺 (`startup` & `shutdown`) 🏃 👆 💯, 👆 💪 ⚙️ `TestClient` ⏮️ `with` 📄:
|
||||
|
||||
```Python hl_lines="9-12 20-24"
|
||||
{!../../../docs_src/app_testing/tutorial003.py!}
|
||||
```
|
||||
12
docs/em/docs/advanced/testing-websockets.md
Normal file
12
docs/em/docs/advanced/testing-websockets.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# 🔬 *️⃣
|
||||
|
||||
👆 💪 ⚙️ 🎏 `TestClient` 💯*️⃣.
|
||||
|
||||
👉, 👆 ⚙️ `TestClient` `with` 📄, 🔗*️⃣:
|
||||
|
||||
```Python hl_lines="27-31"
|
||||
{!../../../docs_src/app_testing/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! note
|
||||
🌅 ℹ, ✅ 💃 🧾 <a href="https://www.starlette.io/testclient/#testing-websocket-sessions" class="external-link" target="_blank">🔬 *️⃣ </a>.
|
||||
52
docs/em/docs/advanced/using-request-directly.md
Normal file
52
docs/em/docs/advanced/using-request-directly.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# ⚙️ 📨 🔗
|
||||
|
||||
🆙 🔜, 👆 ✔️ 📣 🍕 📨 👈 👆 💪 ⏮️ 👫 🆎.
|
||||
|
||||
✊ 📊 ⚪️➡️:
|
||||
|
||||
* ➡ 🔢.
|
||||
* 🎚.
|
||||
* 🍪.
|
||||
* ♒️.
|
||||
|
||||
& 🔨, **FastAPI** ⚖ 👈 💽, 🏭 ⚫️ & 🏭 🧾 👆 🛠️ 🔁.
|
||||
|
||||
✋️ 📤 ⚠ 🌐❔ 👆 💪 💪 🔐 `Request` 🎚 🔗.
|
||||
|
||||
## ℹ 🔃 `Request` 🎚
|
||||
|
||||
**FastAPI** 🤙 **💃** 🔘, ⏮️ 🧽 📚 🧰 🔛 🔝, 👆 💪 ⚙️ 💃 <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">`Request`</a> 🎚 🔗 🕐❔ 👆 💪.
|
||||
|
||||
⚫️ 🔜 ⛓ 👈 🚥 👆 🤚 📊 ⚪️➡️ `Request` 🎚 🔗 (🖼, ✍ 💪) ⚫️ 🏆 🚫 ✔, 🗜 ⚖️ 📄 (⏮️ 🗄, 🏧 🛠️ 👩💻 🔢) FastAPI.
|
||||
|
||||
👐 🙆 🎏 🔢 📣 🛎 (🖼, 💪 ⏮️ Pydantic 🏷) 🔜 ✔, 🗜, ✍, ♒️.
|
||||
|
||||
✋️ 📤 🎯 💼 🌐❔ ⚫️ ⚠ 🤚 `Request` 🎚.
|
||||
|
||||
## ⚙️ `Request` 🎚 🔗
|
||||
|
||||
➡️ 🌈 👆 💚 🤚 👩💻 📢 📢/🦠 🔘 👆 *➡ 🛠️ 🔢*.
|
||||
|
||||
👈 👆 💪 🔐 📨 🔗.
|
||||
|
||||
```Python hl_lines="1 7-8"
|
||||
{!../../../docs_src/using_request_directly/tutorial001.py!}
|
||||
```
|
||||
|
||||
📣 *➡ 🛠️ 🔢* 🔢 ⏮️ 🆎 ➖ `Request` **FastAPI** 🔜 💭 🚶♀️ `Request` 👈 🔢.
|
||||
|
||||
!!! tip
|
||||
🗒 👈 👉 💼, 👥 📣 ➡ 🔢 ⤴️ 📨 🔢.
|
||||
|
||||
, ➡ 🔢 🔜 ⚗, ✔, 🗜 ✔ 🆎 & ✍ ⏮️ 🗄.
|
||||
|
||||
🎏 🌌, 👆 💪 📣 🙆 🎏 🔢 🛎, & ➡, 🤚 `Request` 💁♂️.
|
||||
|
||||
## `Request` 🧾
|
||||
|
||||
👆 💪 ✍ 🌅 ℹ 🔃 <a href="https://www.starlette.io/requests/" class="external-link" target="_blank">`Request` 🎚 🛂 💃 🧾 🕸</a>.
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
👆 💪 ⚙️ `from starlette.requests import Request`.
|
||||
|
||||
**FastAPI** 🚚 ⚫️ 🔗 🏪 👆, 👩💻. ✋️ ⚫️ 👟 🔗 ⚪️➡️ 💃.
|
||||
184
docs/em/docs/advanced/websockets.md
Normal file
184
docs/em/docs/advanced/websockets.md
Normal file
@@ -0,0 +1,184 @@
|
||||
# *️⃣
|
||||
|
||||
👆 💪 ⚙️ <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank"> *️⃣ </a> ⏮️ **FastAPI**.
|
||||
|
||||
## ❎ `WebSockets`
|
||||
|
||||
🥇 👆 💪 ❎ `WebSockets`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install websockets
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## *️⃣ 👩💻
|
||||
|
||||
### 🏭
|
||||
|
||||
👆 🏭 ⚙️, 👆 🎲 ✔️ 🕸 ✍ ⏮️ 🏛 🛠️ 💖 😥, Vue.js ⚖️ 📐.
|
||||
|
||||
& 🔗 ⚙️ *️⃣ ⏮️ 👆 👩💻 👆 🔜 🎲 ⚙️ 👆 🕸 🚙.
|
||||
|
||||
⚖️ 👆 💪 ✔️ 🇦🇸 📱 🈸 👈 🔗 ⏮️ 👆 *️⃣ 👩💻 🔗, 🇦🇸 📟.
|
||||
|
||||
⚖️ 👆 5️⃣📆 ✔️ 🙆 🎏 🌌 🔗 ⏮️ *️⃣ 🔗.
|
||||
|
||||
---
|
||||
|
||||
✋️ 👉 🖼, 👥 🔜 ⚙️ 📶 🙅 🕸 📄 ⏮️ 🕸, 🌐 🔘 📏 🎻.
|
||||
|
||||
👉, ↗️, 🚫 ⚖ & 👆 🚫🔜 ⚙️ ⚫️ 🏭.
|
||||
|
||||
🏭 👆 🔜 ✔️ 1️⃣ 🎛 🔛.
|
||||
|
||||
✋️ ⚫️ 🙅 🌌 🎯 🔛 💽-🚄 *️⃣ & ✔️ 👷 🖼:
|
||||
|
||||
```Python hl_lines="2 6-38 41-43"
|
||||
{!../../../docs_src/websockets/tutorial001.py!}
|
||||
```
|
||||
|
||||
## ✍ `websocket`
|
||||
|
||||
👆 **FastAPI** 🈸, ✍ `websocket`:
|
||||
|
||||
```Python hl_lines="1 46-47"
|
||||
{!../../../docs_src/websockets/tutorial001.py!}
|
||||
```
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
👆 💪 ⚙️ `from starlette.websockets import WebSocket`.
|
||||
|
||||
**FastAPI** 🚚 🎏 `WebSocket` 🔗 🏪 👆, 👩💻. ✋️ ⚫️ 👟 🔗 ⚪️➡️ 💃.
|
||||
|
||||
## ⌛ 📧 & 📨 📧
|
||||
|
||||
👆 *️⃣ 🛣 👆 💪 `await` 📧 & 📨 📧.
|
||||
|
||||
```Python hl_lines="48-52"
|
||||
{!../../../docs_src/websockets/tutorial001.py!}
|
||||
```
|
||||
|
||||
👆 💪 📨 & 📨 💱, ✍, & 🎻 💽.
|
||||
|
||||
## 🔄 ⚫️
|
||||
|
||||
🚥 👆 📁 📛 `main.py`, 🏃 👆 🈸 ⏮️:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
📂 👆 🖥 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
|
||||
|
||||
👆 🔜 👀 🙅 📃 💖:
|
||||
|
||||
<img src="/img/tutorial/websockets/image01.png">
|
||||
|
||||
👆 💪 🆎 📧 🔢 📦, & 📨 👫:
|
||||
|
||||
<img src="/img/tutorial/websockets/image02.png">
|
||||
|
||||
& 👆 **FastAPI** 🈸 ⏮️ *️⃣ 🔜 📨 🔙:
|
||||
|
||||
<img src="/img/tutorial/websockets/image03.png">
|
||||
|
||||
👆 💪 📨 (& 📨) 📚 📧:
|
||||
|
||||
<img src="/img/tutorial/websockets/image04.png">
|
||||
|
||||
& 🌐 👫 🔜 ⚙️ 🎏 *️⃣ 🔗.
|
||||
|
||||
## ⚙️ `Depends` & 🎏
|
||||
|
||||
*️⃣ 🔗 👆 💪 🗄 ⚪️➡️ `fastapi` & ⚙️:
|
||||
|
||||
* `Depends`
|
||||
* `Security`
|
||||
* `Cookie`
|
||||
* `Header`
|
||||
* `Path`
|
||||
* `Query`
|
||||
|
||||
👫 👷 🎏 🌌 🎏 FastAPI 🔗/*➡ 🛠️*:
|
||||
|
||||
```Python hl_lines="66-77 76-91"
|
||||
{!../../../docs_src/websockets/tutorial002.py!}
|
||||
```
|
||||
|
||||
!!! info
|
||||
👉 *️⃣ ⚫️ 🚫 🤙 ⚒ 🔑 🤚 `HTTPException`, ↩️ 👥 🤚 `WebSocketException`.
|
||||
|
||||
👆 💪 ⚙️ 📪 📟 ⚪️➡️ <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">☑ 📟 🔬 🔧</a>.
|
||||
|
||||
### 🔄 *️⃣ ⏮️ 🔗
|
||||
|
||||
🚥 👆 📁 📛 `main.py`, 🏃 👆 🈸 ⏮️:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn main:app --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
📂 👆 🖥 <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>.
|
||||
|
||||
📤 👆 💪 ⚒:
|
||||
|
||||
* "🏬 🆔", ⚙️ ➡.
|
||||
* "🤝" ⚙️ 🔢 🔢.
|
||||
|
||||
!!! tip
|
||||
👀 👈 🔢 `token` 🔜 🍵 🔗.
|
||||
|
||||
⏮️ 👈 👆 💪 🔗 *️⃣ & ⤴️ 📨 & 📨 📧:
|
||||
|
||||
<img src="/img/tutorial/websockets/image05.png">
|
||||
|
||||
## 🚚 🔀 & 💗 👩💻
|
||||
|
||||
🕐❔ *️⃣ 🔗 📪, `await websocket.receive_text()` 🔜 🤚 `WebSocketDisconnect` ⚠, ❔ 👆 💪 ⤴️ ✊ & 🍵 💖 👉 🖼.
|
||||
|
||||
```Python hl_lines="81-83"
|
||||
{!../../../docs_src/websockets/tutorial003.py!}
|
||||
```
|
||||
|
||||
🔄 ⚫️ 👅:
|
||||
|
||||
* 📂 📱 ⏮️ 📚 🖥 📑.
|
||||
* ✍ 📧 ⚪️➡️ 👫.
|
||||
* ⤴️ 🔐 1️⃣ 📑.
|
||||
|
||||
👈 🔜 🤚 `WebSocketDisconnect` ⚠, & 🌐 🎏 👩💻 🔜 📨 📧 💖:
|
||||
|
||||
```
|
||||
Client #1596980209979 left the chat
|
||||
```
|
||||
|
||||
!!! tip
|
||||
📱 🔛 ⭐ & 🙅 🖼 🎦 ❔ 🍵 & 📻 📧 📚 *️⃣ 🔗.
|
||||
|
||||
✋️ ✔️ 🤯 👈, 🌐 🍵 💾, 👁 📇, ⚫️ 🔜 🕴 👷 ⏪ 🛠️ 🏃, & 🔜 🕴 👷 ⏮️ 👁 🛠️.
|
||||
|
||||
🚥 👆 💪 🕳 ⏩ 🛠️ ⏮️ FastAPI ✋️ 👈 🌖 🏋️, 🐕🦺 ✳, ✳ ⚖️ 🎏, ✅ <a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">🗜/📻</a>.
|
||||
|
||||
## 🌅 ℹ
|
||||
|
||||
💡 🌅 🔃 🎛, ✅ 💃 🧾:
|
||||
|
||||
* <a href="https://www.starlette.io/websockets/" class="external-link" target="_blank"> `WebSocket` 🎓</a>.
|
||||
* <a href="https://www.starlette.io/endpoints/#websocketendpoint" class="external-link" target="_blank">🎓-⚓️ *️⃣ 🚚</a>.
|
||||
37
docs/em/docs/advanced/wsgi.md
Normal file
37
docs/em/docs/advanced/wsgi.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# ✅ 🇨🇻 - 🏺, ✳, 🎏
|
||||
|
||||
👆 💪 🗻 🇨🇻 🈸 👆 👀 ⏮️ [🎧 🈸 - 🗻](./sub-applications.md){.internal-link target=_blank}, [⛅ 🗳](./behind-a-proxy.md){.internal-link target=_blank}.
|
||||
|
||||
👈, 👆 💪 ⚙️ `WSGIMiddleware` & ⚙️ ⚫️ 🎁 👆 🇨🇻 🈸, 🖼, 🏺, ✳, ♒️.
|
||||
|
||||
## ⚙️ `WSGIMiddleware`
|
||||
|
||||
👆 💪 🗄 `WSGIMiddleware`.
|
||||
|
||||
⤴️ 🎁 🇨🇻 (✅ 🏺) 📱 ⏮️ 🛠️.
|
||||
|
||||
& ⤴️ 🗻 👈 🔽 ➡.
|
||||
|
||||
```Python hl_lines="2-3 22"
|
||||
{!../../../docs_src/wsgi/tutorial001.py!}
|
||||
```
|
||||
|
||||
## ✅ ⚫️
|
||||
|
||||
🔜, 🔠 📨 🔽 ➡ `/v1/` 🔜 🍵 🏺 🈸.
|
||||
|
||||
& 🎂 🔜 🍵 **FastAPI**.
|
||||
|
||||
🚥 👆 🏃 ⚫️ ⏮️ Uvicorn & 🚶 <a href="http://localhost:8000/v1/" class="external-link" target="_blank">http://localhost:8000/v1/</a> 👆 🔜 👀 📨 ⚪️➡️ 🏺:
|
||||
|
||||
```txt
|
||||
Hello, World from Flask!
|
||||
```
|
||||
|
||||
& 🚥 👆 🚶 <a href="http://localhost:8000/v2" class="external-link" target="_blank">http://localhost:8000/v2</a> 👆 🔜 👀 📨 ⚪️➡️ FastAPI:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"message": "Hello World"
|
||||
}
|
||||
```
|
||||
414
docs/em/docs/alternatives.md
Normal file
414
docs/em/docs/alternatives.md
Normal file
@@ -0,0 +1,414 @@
|
||||
# 🎛, 🌈 & 🔺
|
||||
|
||||
⚫️❔ 😮 **FastAPI**, ❔ ⚫️ 🔬 🎏 🎛 & ⚫️❔ ⚫️ 🇭🇲 ⚪️➡️ 👫.
|
||||
|
||||
## 🎶
|
||||
|
||||
**FastAPI** 🚫🔜 🔀 🚥 🚫 ⏮️ 👷 🎏.
|
||||
|
||||
📤 ✔️ 📚 🧰 ✍ ⏭ 👈 ✔️ ℹ 😮 🚮 🏗.
|
||||
|
||||
👤 ✔️ ❎ 🏗 🆕 🛠️ 📚 1️⃣2️⃣🗓️. 🥇 👤 🔄 ❎ 🌐 ⚒ 📔 **FastAPI** ⚙️ 📚 🎏 🛠️, 🔌-🔌, & 🧰.
|
||||
|
||||
✋️ ☝, 📤 🙅♂ 🎏 🎛 🌘 🏗 🕳 👈 🚚 🌐 👫 ⚒, ✊ 🏆 💭 ⚪️➡️ ⏮️ 🧰, & 🌀 👫 🏆 🌌 💪, ⚙️ 🇪🇸 ⚒ 👈 ➖🚫 💪 ⏭ (🐍 3️⃣.6️⃣ ➕ 🆎 🔑).
|
||||
|
||||
## ⏮️ 🧰
|
||||
|
||||
### <a href="https://www.djangoproject.com/" class="external-link" target="_blank">✳</a>
|
||||
|
||||
⚫️ 🌅 🌟 🐍 🛠️ & 🛎 🕴. ⚫️ ⚙️ 🏗 ⚙️ 💖 👱📔.
|
||||
|
||||
⚫️ 📶 😆 🔗 ⏮️ 🔗 💽 (💖 ✳ ⚖️ ✳),, ✔️ ☁ 💽 (💖 🗄, ✳, 👸, ♒️) 👑 🏪 🚒 🚫 📶 ⏩.
|
||||
|
||||
⚫️ ✍ 🏗 🕸 👩💻, 🚫 ✍ 🔗 ⚙️ 🏛 🕸 (💖 😥, Vue.js & 📐) ⚖️ 🎏 ⚙️ (💖 <abbr title="Internet of Things">☁</abbr> 📳) 🔗 ⏮️ ⚫️.
|
||||
|
||||
### <a href="https://www.django-rest-framework.org/" class="external-link" target="_blank">✳ 🎂 🛠️</a>
|
||||
|
||||
✳ 🎂 🛠️ ✍ 🗜 🧰 🏗 🕸 🔗 ⚙️ ✳ 🔘, 📉 🚮 🛠️ 🛠️.
|
||||
|
||||
⚫️ ⚙️ 📚 🏢 ✅ 🦎, 🟥 👒 & 🎟.
|
||||
|
||||
⚫️ 🕐 🥇 🖼 **🏧 🛠️ 🧾**, & 👉 🎯 🕐 🥇 💭 👈 😮 "🔎" **FastAPI**.
|
||||
|
||||
!!! note
|
||||
✳ 🎂 🛠️ ✍ ✡ 🇺🇸🏛. 🎏 👼 💃 & Uvicorn, 🔛 ❔ **FastAPI** ⚓️.
|
||||
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
✔️ 🏧 🛠️ 🧾 🕸 👩💻 🔢.
|
||||
|
||||
### <a href="https://flask.palletsprojects.com" class="external-link" target="_blank">🏺</a>
|
||||
|
||||
🏺 "🕸", ⚫️ 🚫 🔌 💽 🛠️ 🚫 📚 👜 👈 👟 🔢 ✳.
|
||||
|
||||
👉 🦁 & 💪 ✔ 🔨 👜 💖 ⚙️ ☁ 💽 👑 💽 💾 ⚙️.
|
||||
|
||||
⚫️ 📶 🙅, ⚫️ 📶 🏋️ 💡, 👐 🧾 🤚 🙁 📡 ☝.
|
||||
|
||||
⚫️ 🛎 ⚙️ 🎏 🈸 👈 🚫 🎯 💪 💽, 👩💻 🧾, ⚖️ 🙆 📚 ⚒ 👈 👟 🏤-🏗 ✳. 👐 📚 👫 ⚒ 💪 🚮 ⏮️ 🔌-🔌.
|
||||
|
||||
👉 ⚖ 🍕, & ➖ "🕸" 👈 💪 ↔ 📔 ⚫️❔ ⚫️❔ 💪 🔑 ⚒ 👈 👤 💚 🚧.
|
||||
|
||||
👐 🦁 🏺, ⚫️ 😑 💖 👍 🏏 🏗 🔗. ⏭ 👜 🔎 "✳ 🎂 🛠️" 🏺.
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
◾-🛠️. ⚒ ⚫️ ⏩ 🌀 & 🏏 🧰 & 🍕 💪.
|
||||
|
||||
✔️ 🙅 & ⏩ ⚙️ 🕹 ⚙️.
|
||||
|
||||
|
||||
### <a href="https://requests.readthedocs.io" class="external-link" target="_blank">📨</a>
|
||||
|
||||
**FastAPI** 🚫 🤙 🎛 **📨**. 👫 ↔ 📶 🎏.
|
||||
|
||||
⚫️ 🔜 🤙 ⚠ ⚙️ 📨 *🔘* FastAPI 🈸.
|
||||
|
||||
✋️, FastAPI 🤚 🌈 ⚪️➡️ 📨.
|
||||
|
||||
**📨** 🗃 *🔗* ⏮️ 🔗 (👩💻), ⏪ **FastAPI** 🗃 *🏗* 🔗 (💽).
|
||||
|
||||
👫, 🌖 ⚖️ 🌘, 🔄 🔚, 🔗 🔠 🎏.
|
||||
|
||||
📨 ✔️ 📶 🙅 & 🏋️ 🔧, ⚫️ 📶 ⏩ ⚙️, ⏮️ 🤔 🔢. ✋️ 🎏 🕰, ⚫️ 📶 🏋️ & 🛃.
|
||||
|
||||
👈 ⚫️❔, 💬 🛂 🕸:
|
||||
|
||||
> 📨 1️⃣ 🏆 ⏬ 🐍 📦 🌐 🕰
|
||||
|
||||
🌌 👆 ⚙️ ⚫️ 📶 🙅. 🖼, `GET` 📨, 👆 🔜 ✍:
|
||||
|
||||
```Python
|
||||
response = requests.get("http://example.com/some/url")
|
||||
```
|
||||
|
||||
FastAPI 😑 🛠️ *➡ 🛠️* 💪 👀 💖:
|
||||
|
||||
```Python hl_lines="1"
|
||||
@app.get("/some/url")
|
||||
def read_url():
|
||||
return {"message": "Hello World"}
|
||||
```
|
||||
|
||||
👀 🔀 `requests.get(...)` & `@app.get(...)`.
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
* ✔️ 🙅 & 🏋️ 🛠️.
|
||||
* ⚙️ 🇺🇸🔍 👩🔬 📛 (🛠️) 🔗, 🎯 & 🏋️ 🌌.
|
||||
* ✔️ 🤔 🔢, ✋️ 🏋️ 🛃.
|
||||
|
||||
|
||||
### <a href="https://swagger.io/" class="external-link" target="_blank">🦁</a> / <a href="https://github.com/OAI/OpenAPI-Specification/" class="external-link" target="_blank">🗄</a>
|
||||
|
||||
👑 ⚒ 👤 💚 ⚪️➡️ ✳ 🎂 🛠️ 🏧 🛠️ 🧾.
|
||||
|
||||
⤴️ 👤 🔎 👈 📤 🐩 📄 🔗, ⚙️ 🎻 (⚖️ 📁, ↔ 🎻) 🤙 🦁.
|
||||
|
||||
& 📤 🕸 👩💻 🔢 🦁 🛠️ ⏪ ✍. , 💆♂ 💪 🏗 🦁 🧾 🛠️ 🔜 ✔ ⚙️ 👉 🕸 👩💻 🔢 🔁.
|
||||
|
||||
☝, 🦁 👐 💾 🏛, 📁 🗄.
|
||||
|
||||
👈 ⚫️❔ 🕐❔ 💬 🔃 ⏬ 2️⃣.0️⃣ ⚫️ ⚠ 💬 "🦁", & ⏬ 3️⃣ ➕ "🗄".
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
🛠️ & ⚙️ 📂 🐩 🛠️ 🔧, ↩️ 🛃 🔗.
|
||||
|
||||
& 🛠️ 🐩-⚓️ 👩💻 🔢 🧰:
|
||||
|
||||
* <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">🦁 🎚</a>
|
||||
* <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">📄</a>
|
||||
|
||||
👫 2️⃣ 👐 ➖ 📶 🌟 & ⚖, ✋️ 🔨 ⏩ 🔎, 👆 💪 🔎 💯 🌖 🎛 👩💻 🔢 🗄 (👈 👆 💪 ⚙️ ⏮️ **FastAPI**).
|
||||
|
||||
### 🏺 🎂 🛠️
|
||||
|
||||
📤 📚 🏺 🎂 🛠️, ✋️ ⏮️ 💰 🕰 & 👷 🔘 🔬 👫, 👤 🔎 👈 📚 😞 ⚖️ 🚫, ⏮️ 📚 🧍 ❔ 👈 ⚒ 👫 🙃.
|
||||
|
||||
### <a href="https://marshmallow.readthedocs.io/en/stable/" class="external-link" target="_blank">🍭</a>
|
||||
|
||||
1️⃣ 👑 ⚒ 💪 🛠️ ⚙️ 📊 "<abbr title="also called marshalling, conversion">🛠️</abbr>" ❔ ✊ 📊 ⚪️➡️ 📟 (🐍) & 🏭 ⚫️ 🔘 🕳 👈 💪 📨 🔘 🕸. 🖼, 🏭 🎚 ⚗ 📊 ⚪️➡️ 💽 🔘 🎻 🎚. 🏭 `datetime` 🎚 🔘 🎻, ♒️.
|
||||
|
||||
➕1️⃣ 🦏 ⚒ 💚 🔗 💽 🔬, ⚒ 💭 👈 💽 ☑, 🤝 🎯 🔢. 🖼, 👈 🏑 `int`, & 🚫 🎲 🎻. 👉 ✴️ ⚠ 📨 💽.
|
||||
|
||||
🍵 💽 🔬 ⚙️, 👆 🔜 ✔️ 🌐 ✅ ✋, 📟.
|
||||
|
||||
👫 ⚒ ⚫️❔ 🍭 🏗 🚚. ⚫️ 👑 🗃, & 👤 ✔️ ⚙️ ⚫️ 📚 ⏭.
|
||||
|
||||
✋️ ⚫️ ✍ ⏭ 📤 🔀 🐍 🆎 🔑. , 🔬 🔠 <abbr title="the definition of how data should be formed">🔗</abbr> 👆 💪 ⚙️ 🎯 🇨🇻 & 🎓 🚚 🍭.
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
⚙️ 📟 🔬 "🔗" 👈 🚚 💽 🆎 & 🔬, 🔁.
|
||||
|
||||
### <a href="https://webargs.readthedocs.io/en/latest/" class="external-link" target="_blank">Webarg</a>
|
||||
|
||||
➕1️⃣ 🦏 ⚒ ✔ 🔗 <abbr title="reading and converting to Python data">✍</abbr> 📊 ⚪️➡️ 📨 📨.
|
||||
|
||||
Webarg 🧰 👈 ⚒ 🚚 👈 🔛 🔝 📚 🛠️, 🔌 🏺.
|
||||
|
||||
⚫️ ⚙️ 🍭 🔘 💽 🔬. & ⚫️ ✍ 🎏 👩💻.
|
||||
|
||||
⚫️ 👑 🧰 & 👤 ✔️ ⚙️ ⚫️ 📚 💁♂️, ⏭ ✔️ **FastAPI**.
|
||||
|
||||
!!! info
|
||||
Webarg ✍ 🎏 🍭 👩💻.
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
✔️ 🏧 🔬 📨 📨 💽.
|
||||
|
||||
### <a href="https://apispec.readthedocs.io/en/stable/" class="external-link" target="_blank">APISpec</a>
|
||||
|
||||
🍭 & Webarg 🚚 🔬, ✍ & 🛠️ 🔌-🔌.
|
||||
|
||||
✋️ 🧾 ❌. ⤴️ APISpec ✍.
|
||||
|
||||
⚫️ 🔌-📚 🛠️ (& 📤 🔌-💃 💁♂️).
|
||||
|
||||
🌌 ⚫️ 👷 👈 👆 ✍ 🔑 🔗 ⚙️ 📁 📁 🔘 #️⃣ 🔠 🔢 🚚 🛣.
|
||||
|
||||
& ⚫️ 🏗 🗄 🔗.
|
||||
|
||||
👈 ❔ ⚫️ 👷 🏺, 💃, 🆘, ♒️.
|
||||
|
||||
✋️ ⤴️, 👥 ✔️ 🔄 ⚠ ✔️ ◾-❕, 🔘 🐍 🎻 (🦏 📁).
|
||||
|
||||
👨🎨 💪 🚫 ℹ 🌅 ⏮️ 👈. & 🚥 👥 🔀 🔢 ⚖️ 🍭 🔗 & 💭 🔀 👈 📁#️⃣, 🏗 🔗 🔜 ❌.
|
||||
|
||||
!!! info
|
||||
APISpec ✍ 🎏 🍭 👩💻.
|
||||
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
🐕🦺 📂 🐩 🛠️, 🗄.
|
||||
|
||||
### <a href="https://flask-apispec.readthedocs.io/en/latest/" class="external-link" target="_blank">🏺-Apispec</a>
|
||||
|
||||
⚫️ 🏺 🔌 -, 👈 👔 👯♂️ Webarg, 🍭 & APISpec.
|
||||
|
||||
⚫️ ⚙️ ℹ ⚪️➡️ Webarg & 🍭 🔁 🏗 🗄 🔗, ⚙️ APISpec.
|
||||
|
||||
⚫️ 👑 🧰, 📶 🔽-📈. ⚫️ 🔜 🌌 🌖 🌟 🌘 📚 🏺 🔌-🔌 👅 📤. ⚫️ 💪 ↩️ 🚮 🧾 ➖ 💁♂️ 🩲 & 📝.
|
||||
|
||||
👉 ❎ ✔️ ✍ 📁 (➕1️⃣ ❕) 🔘 🐍 ✍.
|
||||
|
||||
👉 🌀 🏺, 🏺-Apispec ⏮️ 🍭 & Webarg 👇 💕 👩💻 📚 ⏭ 🏗 **FastAPI**.
|
||||
|
||||
⚙️ ⚫️ ↘️ 🏗 📚 🏺 🌕-📚 🚂. 👫 👑 📚 👤 (& 📚 🔢 🏉) ✔️ ⚙️ 🆙 🔜:
|
||||
|
||||
* <a href="https://github.com/tiangolo/full-stack" class="external-link" target="_blank">https://github.com/tiangolo/full-stack</a>
|
||||
* <a href="https://github.com/tiangolo/full-stack-flask-couchbase" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchbase</a>
|
||||
* <a href="https://github.com/tiangolo/full-stack-flask-couchdb" class="external-link" target="_blank">https://github.com/tiangolo/full-stack-flask-couchdb</a>
|
||||
|
||||
& 👫 🎏 🌕-📚 🚂 🧢 [**FastAPI** 🏗 🚂](project-generation.md){.internal-link target=_blank}.
|
||||
|
||||
!!! info
|
||||
🏺-Apispec ✍ 🎏 🍭 👩💻.
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
🏗 🗄 🔗 🔁, ⚪️➡️ 🎏 📟 👈 🔬 🛠️ & 🔬.
|
||||
|
||||
### <a href="https://nestjs.com/" class="external-link" target="_blank">NestJS</a> (& <a href="https://angular.io/" class="external-link" target="_blank">📐</a>)
|
||||
|
||||
👉 ➖🚫 🚫 🐍, NestJS 🕸 (📕) ✳ 🛠️ 😮 📐.
|
||||
|
||||
⚫️ 🏆 🕳 🙁 🎏 ⚫️❔ 💪 🔨 ⏮️ 🏺-Apispec.
|
||||
|
||||
⚫️ ✔️ 🛠️ 🔗 💉 ⚙️, 😮 📐 2️⃣. ⚫️ 🚚 🏤-® "💉" (💖 🌐 🎏 🔗 💉 ⚙️ 👤 💭),, ⚫️ 🚮 🎭 & 📟 🔁.
|
||||
|
||||
🔢 🔬 ⏮️ 📕 🆎 (🎏 🐍 🆎 🔑), 👨🎨 🐕🦺 👍.
|
||||
|
||||
✋️ 📕 📊 🚫 🛡 ⏮️ 📹 🕸, ⚫️ 🚫🔜 ⚓️ 🔛 🆎 🔬 🔬, 🛠️ & 🧾 🎏 🕰. ↩️ 👉 & 🔧 🚫, 🤚 🔬, 🛠️ & 🏧 🔗 ⚡, ⚫️ 💪 🚮 👨🎨 📚 🥉. , ⚫️ ▶️️ 🔁.
|
||||
|
||||
⚫️ 💪 🚫 🍵 🔁 🏷 📶 👍. , 🚥 🎻 💪 📨 🎻 🎚 👈 ✔️ 🔘 🏑 👈 🔄 🐦 🎻 🎚, ⚫️ 🚫🔜 ☑ 📄 & ✔.
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
⚙️ 🐍 🆎 ✔️ 👑 👨🎨 🐕🦺.
|
||||
|
||||
✔️ 🏋️ 🔗 💉 ⚙️. 🔎 🌌 📉 📟 🔁.
|
||||
|
||||
### <a href="https://sanic.readthedocs.io/en/latest/" class="external-link" target="_blank">🤣</a>
|
||||
|
||||
⚫️ 🕐 🥇 📶 ⏩ 🐍 🛠️ ⚓️ 🔛 `asyncio`. ⚫️ ⚒ 📶 🎏 🏺.
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
⚫️ ⚙️ <a href="https://github.com/MagicStack/uvloop" class="external-link" target="_blank">`uvloop`</a> ↩️ 🔢 🐍 `asyncio` ➰. 👈 ⚫️❔ ⚒ ⚫️ ⏩.
|
||||
|
||||
⚫️ 🎯 😮 Uvicorn & 💃, 👈 ⏳ ⏩ 🌘 🤣 📂 📇.
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
🔎 🌌 ✔️ 😜 🎭.
|
||||
|
||||
👈 ⚫️❔ **FastAPI** ⚓️ 🔛 💃, ⚫️ ⏩ 🛠️ 💪 (💯 🥉-🥳 📇).
|
||||
|
||||
### <a href="https://falconframework.org/" class="external-link" target="_blank">🦅</a>
|
||||
|
||||
🦅 ➕1️⃣ ↕ 🎭 🐍 🛠️, ⚫️ 🔧 ⭐, & 👷 🏛 🎏 🛠️ 💖 🤗.
|
||||
|
||||
⚫️ 🏗 ✔️ 🔢 👈 📨 2️⃣ 🔢, 1️⃣ "📨" & 1️⃣ "📨". ⤴️ 👆 "✍" 🍕 ⚪️➡️ 📨, & "✍" 🍕 📨. ↩️ 👉 🔧, ⚫️ 🚫 💪 📣 📨 🔢 & 💪 ⏮️ 🐩 🐍 🆎 🔑 🔢 🔢.
|
||||
|
||||
, 💽 🔬, 🛠️, & 🧾, ✔️ ⌛ 📟, 🚫 🔁. ⚖️ 👫 ✔️ 🛠️ 🛠️ 🔛 🔝 🦅, 💖 🤗. 👉 🎏 🔺 🔨 🎏 🛠️ 👈 😮 🦅 🔧, ✔️ 1️⃣ 📨 🎚 & 1️⃣ 📨 🎚 🔢.
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
🔎 🌌 🤚 👑 🎭.
|
||||
|
||||
⤴️ ⏮️ 🤗 (🤗 ⚓️ 🔛 🦅) 😮 **FastAPI** 📣 `response` 🔢 🔢.
|
||||
|
||||
👐 FastAPI ⚫️ 📦, & ⚙️ ✴️ ⚒ 🎚, 🍪, & 🎛 👔 📟.
|
||||
|
||||
### <a href="https://moltenframework.com/" class="external-link" target="_blank">♨</a>
|
||||
|
||||
👤 🔎 ♨ 🥇 ▶️ 🏗 **FastAPI**. & ⚫️ ✔️ 🎏 💭:
|
||||
|
||||
* ⚓️ 🔛 🐍 🆎 🔑.
|
||||
* 🔬 & 🧾 ⚪️➡️ 👫 🆎.
|
||||
* 🔗 💉 ⚙️.
|
||||
|
||||
⚫️ 🚫 ⚙️ 💽 🔬, 🛠️ & 🧾 🥉-🥳 🗃 💖 Pydantic, ⚫️ ✔️ 🚮 👍. , 👫 💽 🆎 🔑 🔜 🚫 ♻ 💪.
|
||||
|
||||
⚫️ 🚚 🐥 🍖 🌅 🔁 📳. & ⚫️ ⚓️ 🔛 🇨🇻 (↩️ 🔫), ⚫️ 🚫 🔧 ✊ 📈 ↕-🎭 🚚 🧰 💖 Uvicorn, 💃 & 🤣.
|
||||
|
||||
🔗 💉 ⚙️ 🚚 🏤-® 🔗 & 🔗 ❎ 🧢 🔛 📣 🆎. , ⚫️ 🚫 💪 📣 🌅 🌘 1️⃣ "🦲" 👈 🚚 🎯 🆎.
|
||||
|
||||
🛣 📣 👁 🥉, ⚙️ 🔢 📣 🎏 🥉 (↩️ ⚙️ 👨🎨 👈 💪 🥉 ▶️️ 🔛 🔝 🔢 👈 🍵 🔗). 👉 🔐 ❔ ✳ 🔨 ⚫️ 🌘 ❔ 🏺 (& 💃) 🔨 ⚫️. ⚫️ 🎏 📟 👜 👈 📶 😆 🔗.
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
🔬 ➕ 🔬 💽 🆎 ⚙️ "🔢" 💲 🏷 🔢. 👉 📉 👨🎨 🐕🦺, & ⚫️ 🚫 💪 Pydantic ⏭.
|
||||
|
||||
👉 🤙 😮 🛠️ 🍕 Pydantic, 🐕🦺 🎏 🔬 📄 👗 (🌐 👉 🛠️ 🔜 ⏪ 💪 Pydantic).
|
||||
|
||||
### <a href="https://www.hug.rest/" class="external-link" target="_blank">🤗</a>
|
||||
|
||||
🤗 🕐 🥇 🛠️ 🛠️ 📄 🛠️ 🔢 🆎 ⚙️ 🐍 🆎 🔑. 👉 👑 💭 👈 😮 🎏 🧰 🎏.
|
||||
|
||||
⚫️ ⚙️ 🛃 🆎 🚮 📄 ↩️ 🐩 🐍 🆎, ✋️ ⚫️ 🦏 🔁 ⏩.
|
||||
|
||||
⚫️ 🕐 🥇 🛠️ 🏗 🛃 🔗 📣 🎂 🛠️ 🎻.
|
||||
|
||||
⚫️ 🚫 ⚓️ 🔛 🐩 💖 🗄 & 🎻 🔗. ⚫️ 🚫🔜 🎯 🛠️ ⚫️ ⏮️ 🎏 🧰, 💖 🦁 🎚. ✋️ 🔄, ⚫️ 📶 💡 💭.
|
||||
|
||||
⚫️ ✔️ 😌, ⭐ ⚒: ⚙️ 🎏 🛠️, ⚫️ 💪 ✍ 🔗 & 🇳🇨.
|
||||
|
||||
⚫️ ⚓️ 🔛 ⏮️ 🐩 🔁 🐍 🕸 🛠️ (🇨🇻), ⚫️ 💪 🚫 🍵 *️⃣ & 🎏 👜, 👐 ⚫️ ✔️ ↕ 🎭 💁♂️.
|
||||
|
||||
!!! info
|
||||
🤗 ✍ ✡ 🗄, 🎏 👼 <a href="https://github.com/timothycrosley/isort" class="external-link" target="_blank">`isort`</a>, 👑 🧰 🔁 😇 🗄 🐍 📁.
|
||||
|
||||
!!! check "💭 😮 **FastAPI**"
|
||||
🤗 😮 🍕 APIStar, & 1️⃣ 🧰 👤 🔎 🏆 👍, 🌟 APIStar.
|
||||
|
||||
🤗 ℹ 😍 **FastAPI** ⚙️ 🐍 🆎 🔑 📣 🔢, & 🏗 🔗 ⚖ 🛠️ 🔁.
|
||||
|
||||
🤗 😮 **FastAPI** 📣 `response` 🔢 🔢 ⚒ 🎚 & 🍪.
|
||||
|
||||
### <a href="https://github.com/encode/apistar" class="external-link" target="_blank">APIStar</a> (<= 0️⃣.5️⃣)
|
||||
|
||||
▶️️ ⏭ 🤔 🏗 **FastAPI** 👤 🔎 **APIStar** 💽. ⚫️ ✔️ 🌖 🌐 👤 👀 & ✔️ 👑 🔧.
|
||||
|
||||
⚫️ 🕐 🥇 🛠️ 🛠️ ⚙️ 🐍 🆎 🔑 📣 🔢 & 📨 👈 👤 ⏱ 👀 (⏭ NestJS & ♨). 👤 🔎 ⚫️ 🌅 ⚖️ 🌘 🎏 🕰 🤗. ✋️ APIStar ⚙️ 🗄 🐩.
|
||||
|
||||
⚫️ ✔️ 🏧 💽 🔬, 💽 🛠️ & 🗄 🔗 ⚡ ⚓️ 🔛 🎏 🆎 🔑 📚 🥉.
|
||||
|
||||
💪 🔗 🔑 🚫 ⚙️ 🎏 🐍 🆎 🔑 💖 Pydantic, ⚫️ 🍖 🌅 🎏 🍭,, 👨🎨 🐕🦺 🚫🔜 👍, ✋️, APIStar 🏆 💪 🎛.
|
||||
|
||||
⚫️ ✔️ 🏆 🎭 📇 🕰 (🕴 💥 💃).
|
||||
|
||||
🥇, ⚫️ 🚫 ✔️ 🏧 🛠️ 🧾 🕸 🎚, ✋️ 👤 💭 👤 💪 🚮 🦁 🎚 ⚫️.
|
||||
|
||||
⚫️ ✔️ 🔗 💉 ⚙️. ⚫️ ✔ 🏤-® 🦲, 🎏 🧰 🔬 🔛. ✋️, ⚫️ 👑 ⚒.
|
||||
|
||||
👤 🙅 💪 ⚙️ ⚫️ 🌕 🏗, ⚫️ 🚫 ✔️ 💂♂ 🛠️,, 👤 🚫 🚫 ❎ 🌐 ⚒ 👤 ✔️ ⏮️ 🌕-📚 🚂 ⚓️ 🔛 🏺-Apispec. 👤 ✔️ 👇 📈 🏗 ✍ 🚲 📨 ❎ 👈 🛠️.
|
||||
|
||||
✋️ ⤴️, 🏗 🎯 🔀.
|
||||
|
||||
⚫️ 🙅♂ 📏 🛠️ 🕸 🛠️, 👼 💪 🎯 🔛 💃.
|
||||
|
||||
🔜 APIStar ⚒ 🧰 ✔ 🗄 🔧, 🚫 🕸 🛠️.
|
||||
|
||||
!!! info
|
||||
APIStar ✍ ✡ 🇺🇸🏛. 🎏 👨 👈 ✍:
|
||||
|
||||
* ✳ 🎂 🛠️
|
||||
* 💃 (❔ **FastAPI** ⚓️)
|
||||
* Uvicorn (⚙️ 💃 & **FastAPI**)
|
||||
|
||||
!!! check "😮 **FastAPI** "
|
||||
🔀.
|
||||
|
||||
💭 📣 💗 👜 (💽 🔬, 🛠️ & 🧾) ⏮️ 🎏 🐍 🆎, 👈 🎏 🕰 🚚 👑 👨🎨 🐕🦺, 🕳 👤 🤔 💎 💭.
|
||||
|
||||
& ⏮️ 🔎 📏 🕰 🎏 🛠️ & 🔬 📚 🎏 🎛, APIStar 🏆 🎛 💪.
|
||||
|
||||
⤴️ APIStar ⛔️ 🔀 💽 & 💃 ✍, & 🆕 👻 🏛 ✅ ⚙️. 👈 🏁 🌈 🏗 **FastAPI**.
|
||||
|
||||
👤 🤔 **FastAPI** "🛐 👨💼" APIStar, ⏪ 📉 & 📈 ⚒, ⌨ ⚙️, & 🎏 🍕, ⚓️ 🔛 🏫 ⚪️➡️ 🌐 👉 ⏮️ 🧰.
|
||||
|
||||
## ⚙️ **FastAPI**
|
||||
|
||||
### <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a>
|
||||
|
||||
Pydantic 🗃 🔬 💽 🔬, 🛠️ & 🧾 (⚙️ 🎻 🔗) ⚓️ 🔛 🐍 🆎 🔑.
|
||||
|
||||
👈 ⚒ ⚫️ 📶 🏋️.
|
||||
|
||||
⚫️ ⭐ 🍭. 👐 ⚫️ ⏩ 🌘 🍭 📇. & ⚫️ ⚓️ 🔛 🎏 🐍 🆎 🔑, 👨🎨 🐕🦺 👑.
|
||||
|
||||
!!! check "**FastAPI** ⚙️ ⚫️"
|
||||
🍵 🌐 💽 🔬, 💽 🛠️ & 🏧 🏷 🧾 (⚓️ 🔛 🎻 🔗).
|
||||
|
||||
**FastAPI** ⤴️ ✊ 👈 🎻 🔗 💽 & 🚮 ⚫️ 🗄, ↖️ ⚪️➡️ 🌐 🎏 👜 ⚫️ 🔨.
|
||||
|
||||
### <a href="https://www.starlette.io/" class="external-link" target="_blank">💃</a>
|
||||
|
||||
💃 💿 <abbr title="The new standard for building asynchronous Python web">🔫</abbr> 🛠️/🧰, ❔ 💯 🏗 ↕-🎭 ✳ 🐕🦺.
|
||||
|
||||
⚫️ 📶 🙅 & 🏋️. ⚫️ 🔧 💪 🏧, & ✔️ 🔧 🦲.
|
||||
|
||||
⚫️ ✔️:
|
||||
|
||||
* 🤙 🎆 🎭.
|
||||
* *️⃣ 🐕🦺.
|
||||
* -🛠️ 🖥 📋.
|
||||
* 🕴 & 🤫 🎉.
|
||||
* 💯 👩💻 🏗 🔛 🇸🇲.
|
||||
* ⚜, 🗜, 🎻 📁, 🎏 📨.
|
||||
* 🎉 & 🍪 🐕🦺.
|
||||
* 1️⃣0️⃣0️⃣ 💯 💯 💰.
|
||||
* 1️⃣0️⃣0️⃣ 💯 🆎 ✍ ✍.
|
||||
* 👩❤👨 🏋️ 🔗.
|
||||
|
||||
💃 ⏳ ⏩ 🐍 🛠️ 💯. 🕴 💥 Uvicorn, ❔ 🚫 🛠️, ✋️ 💽.
|
||||
|
||||
💃 🚚 🌐 🔰 🕸 🕸 🛠️.
|
||||
|
||||
✋️ ⚫️ 🚫 🚚 🏧 💽 🔬, 🛠️ ⚖️ 🧾.
|
||||
|
||||
👈 1️⃣ 👑 👜 👈 **FastAPI** 🚮 🔛 🔝, 🌐 ⚓️ 🔛 🐍 🆎 🔑 (⚙️ Pydantic). 👈, ➕ 🔗 💉 ⚙️, 💂♂ 🚙, 🗄 🔗 ⚡, ♒️.
|
||||
|
||||
!!! note "📡 ℹ"
|
||||
🔫 🆕 "🐩" ➖ 🛠️ ✳ 🐚 🏉 👨🎓. ⚫️ 🚫 "🐍 🐩" (🇩🇬), 👐 👫 🛠️ 🔨 👈.
|
||||
|
||||
👐, ⚫️ ⏪ ➖ ⚙️ "🐩" 📚 🧰. 👉 📉 📉 🛠️, 👆 💪 🎛 Uvicorn 🙆 🎏 🔫 💽 (💖 👸 ⚖️ Hypercorn), ⚖️ 👆 💪 🚮 🔫 🔗 🧰, 💖 `python-socketio`.
|
||||
|
||||
!!! check "**FastAPI** ⚙️ ⚫️"
|
||||
🍵 🌐 🐚 🕸 🍕. ❎ ⚒ 🔛 🔝.
|
||||
|
||||
🎓 `FastAPI` ⚫️ 😖 🔗 ⚪️➡️ 🎓 `Starlette`.
|
||||
|
||||
, 🕳 👈 👆 💪 ⏮️ 💃, 👆 💪 ⚫️ 🔗 ⏮️ **FastAPI**, ⚫️ 🌖 💃 🔛 💊.
|
||||
|
||||
### <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a>
|
||||
|
||||
Uvicorn 🌩-⏩ 🔫 💽, 🏗 🔛 uvloop & httptool.
|
||||
|
||||
⚫️ 🚫 🕸 🛠️, ✋️ 💽. 🖼, ⚫️ 🚫 🚚 🧰 🕹 ➡. 👈 🕳 👈 🛠️ 💖 💃 (⚖️ **FastAPI**) 🔜 🚚 🔛 🔝.
|
||||
|
||||
⚫️ 👍 💽 💃 & **FastAPI**.
|
||||
|
||||
!!! check "**FastAPI** 👍 ⚫️"
|
||||
👑 🕸 💽 🏃 **FastAPI** 🈸.
|
||||
|
||||
👆 💪 🌀 ⚫️ ⏮️ 🐁, ✔️ 🔁 👁-🛠️ 💽.
|
||||
|
||||
✅ 🌅 ℹ [🛠️](deployment/index.md){.internal-link target=_blank} 📄.
|
||||
|
||||
## 📇 & 🚅
|
||||
|
||||
🤔, 🔬, & 👀 🔺 🖖 Uvicorn, 💃 & FastAPI, ✅ 📄 🔃 [📇](benchmarks.md){.internal-link target=_blank}.
|
||||
430
docs/em/docs/async.md
Normal file
430
docs/em/docs/async.md
Normal file
@@ -0,0 +1,430 @@
|
||||
# 🛠️ & 🔁 / ⌛
|
||||
|
||||
ℹ 🔃 `async def` ❕ *➡ 🛠️ 🔢* & 🖥 🔃 🔁 📟, 🛠️, & 🔁.
|
||||
|
||||
## 🏃 ❓
|
||||
|
||||
<abbr title="too long; didn't read"><strong>🆑;👩⚕️:</strong></abbr>
|
||||
|
||||
🚥 👆 ⚙️ 🥉 🥳 🗃 👈 💬 👆 🤙 👫 ⏮️ `await`, 💖:
|
||||
|
||||
```Python
|
||||
results = await some_library()
|
||||
```
|
||||
|
||||
⤴️, 📣 👆 *➡ 🛠️ 🔢* ⏮️ `async def` 💖:
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
async def read_results():
|
||||
results = await some_library()
|
||||
return results
|
||||
```
|
||||
|
||||
!!! note
|
||||
👆 💪 🕴 ⚙️ `await` 🔘 🔢 ✍ ⏮️ `async def`.
|
||||
|
||||
---
|
||||
|
||||
🚥 👆 ⚙️ 🥉 🥳 🗃 👈 🔗 ⏮️ 🕳 (💽, 🛠️, 📁 ⚙️, ♒️.) & 🚫 ✔️ 🐕🦺 ⚙️ `await`, (👉 ⏳ 💼 🌅 💽 🗃), ⤴️ 📣 👆 *➡ 🛠️ 🔢* 🛎, ⏮️ `def`, 💖:
|
||||
|
||||
```Python hl_lines="2"
|
||||
@app.get('/')
|
||||
def results():
|
||||
results = some_library()
|
||||
return results
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
🚥 👆 🈸 (😫) 🚫 ✔️ 🔗 ⏮️ 🕳 🙆 & ⌛ ⚫️ 📨, ⚙️ `async def`.
|
||||
|
||||
---
|
||||
|
||||
🚥 👆 🚫 💭, ⚙️ 😐 `def`.
|
||||
|
||||
---
|
||||
|
||||
**🗒**: 👆 💪 🌀 `def` & `async def` 👆 *➡ 🛠️ 🔢* 🌅 👆 💪 & 🔬 🔠 1️⃣ ⚙️ 🏆 🎛 👆. FastAPI 🔜 ▶️️ 👜 ⏮️ 👫.
|
||||
|
||||
😆, 🙆 💼 🔛, FastAPI 🔜 👷 🔁 & 📶 ⏩.
|
||||
|
||||
✋️ 📄 📶 🔛, ⚫️ 🔜 💪 🎭 🛠️.
|
||||
|
||||
## 📡 ℹ
|
||||
|
||||
🏛 ⏬ 🐍 ✔️ 🐕🦺 **"🔁 📟"** ⚙️ 🕳 🤙 **"🔁"**, ⏮️ **`async` & `await`** ❕.
|
||||
|
||||
➡️ 👀 👈 🔤 🍕 📄 🔛:
|
||||
|
||||
* **🔁 📟**
|
||||
* **`async` & `await`**
|
||||
* **🔁**
|
||||
|
||||
## 🔁 📟
|
||||
|
||||
🔁 📟 ⛓ 👈 🇪🇸 👶 ✔️ 🌌 💬 💻 / 📋 👶 👈 ☝ 📟, ⚫️ 👶 🔜 ✔️ ⌛ *🕳 🙆* 🏁 👱 🙆. ➡️ 💬 👈 *🕳 🙆* 🤙 "🐌-📁" 👶.
|
||||
|
||||
, ⏮️ 👈 🕰, 💻 💪 🚶 & 🎏 👷, ⏪ "🐌-📁" 👶 🏁.
|
||||
|
||||
⤴️ 💻 / 📋 👶 🔜 👟 🔙 🔠 🕰 ⚫️ ✔️ 🤞 ↩️ ⚫️ ⌛ 🔄, ⚖️ 🕐❔ ⚫️ 👶 🏁 🌐 👷 ⚫️ ✔️ 👈 ☝. & ⚫️ 👶 🔜 👀 🚥 🙆 📋 ⚫️ ⌛ ✔️ ⏪ 🏁, 🤸 ⚫️❔ ⚫️ ✔️.
|
||||
|
||||
⏭, ⚫️ 👶 ✊ 🥇 📋 🏁 (➡️ 💬, 👆 "🐌-📁" 👶) & 😣 ⚫️❔ ⚫️ ✔️ ⏮️ ⚫️.
|
||||
|
||||
👈 "⌛ 🕳 🙆" 🛎 🔗 <abbr title="Input and Output">👤/🅾</abbr> 🛠️ 👈 📶 "🐌" (🔬 🚅 🕹 & 💾 💾), 💖 ⌛:
|
||||
|
||||
* 📊 ⚪️➡️ 👩💻 📨 🔘 🕸
|
||||
* 📊 📨 👆 📋 📨 👩💻 🔘 🕸
|
||||
* 🎚 📁 💾 ✍ ⚙️ & 🤝 👆 📋
|
||||
* 🎚 👆 📋 🤝 ⚙️ ✍ 💾
|
||||
* 🛰 🛠️ 🛠️
|
||||
* 💽 🛠️ 🏁
|
||||
* 💽 🔢 📨 🏁
|
||||
* ♒️.
|
||||
|
||||
🛠️ 🕰 🍴 ✴️ ⌛ <abbr title="Input and Output">👤/🅾</abbr> 🛠️, 👫 🤙 👫 "👤/🅾 🔗" 🛠️.
|
||||
|
||||
⚫️ 🤙 "🔁" ↩️ 💻 / 📋 🚫 ✔️ "🔁" ⏮️ 🐌 📋, ⌛ ☑ 🙍 👈 📋 🏁, ⏪ 🔨 🕳, 💪 ✊ 📋 🏁 & 😣 👷.
|
||||
|
||||
↩️ 👈, 💆♂ "🔁" ⚙️, 🕐 🏁, 📋 💪 ⌛ ⏸ 🐥 👄 (⏲) 💻 / 📋 🏁 ⚫️❔ ⚫️ 🚶, & ⤴️ 👟 🔙 ✊ 🏁 & 😣 👷 ⏮️ 👫.
|
||||
|
||||
"🔁" (👽 "🔁") 👫 🛎 ⚙️ ⚖ "🔁", ↩️ 💻 / 📋 ⏩ 🌐 📶 🔁 ⏭ 🔀 🎏 📋, 🚥 👈 🔁 🔌 ⌛.
|
||||
|
||||
### 🛠️ & 🍔
|
||||
|
||||
👉 💭 **🔁** 📟 🔬 🔛 🕣 🤙 **"🛠️"**. ⚫️ 🎏 ⚪️➡️ **"🔁"**.
|
||||
|
||||
**🛠️** & **🔁** 👯♂️ 🔗 "🎏 👜 😥 🌅 ⚖️ 🌘 🎏 🕰".
|
||||
|
||||
✋️ ℹ 🖖 *🛠️* & *🔁* 🎏.
|
||||
|
||||
👀 🔺, 🌈 📄 📖 🔃 🍔:
|
||||
|
||||
### 🛠️ 🍔
|
||||
|
||||
👆 🚶 ⏮️ 👆 🥰 🤚 ⏩ 🥕, 👆 🧍 ⏸ ⏪ 🏧 ✊ ✔ ⚪️➡️ 👫👫 🚪 👆. 👶
|
||||
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-01.png" class="illustration">
|
||||
|
||||
⤴️ ⚫️ 👆 🔄, 👆 🥉 👆 ✔ 2️⃣ 📶 🎀 🍔 👆 🥰 & 👆. 👶 👶
|
||||
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-02.png" class="illustration">
|
||||
|
||||
🏧 💬 🕳 🍳 👨🍳 👫 💭 👫 ✔️ 🏗 👆 🍔 (✋️ 👫 ⏳ 🏗 🕐 ⏮️ 👩💻).
|
||||
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-03.png" class="illustration">
|
||||
|
||||
👆 💸. 👶
|
||||
|
||||
🏧 🤝 👆 🔢 👆 🔄.
|
||||
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-04.png" class="illustration">
|
||||
|
||||
⏪ 👆 ⌛, 👆 🚶 ⏮️ 👆 🥰 & ⚒ 🏓, 👆 🧎 & 💬 ⏮️ 👆 🥰 📏 🕰 (👆 🍔 📶 🎀 & ✊ 🕰 🏗).
|
||||
|
||||
👆 🏖 🏓 ⏮️ 👆 🥰, ⏪ 👆 ⌛ 🍔, 👆 💪 💸 👈 🕰 😮 ❔ 👌, 🐨 & 🙃 👆 🥰 👶 👶 👶.
|
||||
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-05.png" class="illustration">
|
||||
|
||||
⏪ ⌛ & 💬 👆 🥰, ⚪️➡️ 🕰 🕰, 👆 ✅ 🔢 🖥 🔛 ⏲ 👀 🚥 ⚫️ 👆 🔄 ⏪.
|
||||
|
||||
⤴️ ☝, ⚫️ 😒 👆 🔄. 👆 🚶 ⏲, 🤚 👆 🍔 & 👟 🔙 🏓.
|
||||
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-06.png" class="illustration">
|
||||
|
||||
👆 & 👆 🥰 🍴 🍔 & ✔️ 👌 🕰. 👶
|
||||
|
||||
<img src="/img/async/concurrent-burgers/concurrent-burgers-07.png" class="illustration">
|
||||
|
||||
!!! info
|
||||
🌹 🖼 <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">👯 🍏</a>. 👶
|
||||
|
||||
---
|
||||
|
||||
🌈 👆 💻 / 📋 👶 👈 📖.
|
||||
|
||||
⏪ 👆 ⏸, 👆 ⛽ 👶, ⌛ 👆 🔄, 🚫 🔨 🕳 📶 "😌". ✋️ ⏸ ⏩ ↩️ 🏧 🕴 ✊ ✔ (🚫 🏗 👫), 👈 👌.
|
||||
|
||||
⤴️, 🕐❔ ⚫️ 👆 🔄, 👆 ☑ "😌" 👷, 👆 🛠️ 🍣, 💭 ⚫️❔ 👆 💚, 🤚 👆 🥰 ⚒, 💸, ✅ 👈 👆 🤝 ☑ 💵 ⚖️ 💳, ✅ 👈 👆 🈚 ☑, ✅ 👈 ✔ ✔️ ☑ 🏬, ♒️.
|
||||
|
||||
✋️ ⤴️, ✋️ 👆 🚫 ✔️ 👆 🍔, 👆 👷 ⏮️ 🏧 "🔛 ⏸" ⏸, ↩️ 👆 ✔️ ⌛ 👶 👆 🍔 🔜.
|
||||
|
||||
✋️ 👆 🚶 ↖️ ⚪️➡️ ⏲ & 🧎 🏓 ⏮️ 🔢 👆 🔄, 👆 💪 🎛 👶 👆 🙋 👆 🥰, & "👷" 👶 👶 🔛 👈. ⤴️ 👆 🔄 🔨 🕳 📶 "😌" 😏 ⏮️ 👆 🥰 👶.
|
||||
|
||||
⤴️ 🏧 👶 💬 "👤 🏁 ⏮️ 🔨 🍔" 🚮 👆 🔢 🔛 ⏲ 🖥, ✋️ 👆 🚫 🦘 💖 😜 ⏪ 🕐❔ 🖥 🔢 🔀 👆 🔄 🔢. 👆 💭 🙅♂ 1️⃣ 🔜 📎 👆 🍔 ↩️ 👆 ✔️ 🔢 👆 🔄, & 👫 ✔️ 👫.
|
||||
|
||||
👆 ⌛ 👆 🥰 🏁 📖 (🏁 ⏮️ 👷 👶 / 📋 ➖ 🛠️ 👶), 😀 🖐 & 💬 👈 👆 🔜 🍔 ⏸.
|
||||
|
||||
⤴️ 👆 🚶 ⏲ 👶, ▶️ 📋 👈 🔜 🏁 👶, ⚒ 🍔, 💬 👏 & ✊ 👫 🏓. 👈 🏁 👈 🔁 / 📋 🔗 ⏮️ ⏲ ⏹. 👈 🔄, ✍ 🆕 📋, "🍴 🍔" 👶 👶, ✋️ ⏮️ 1️⃣ "🤚 🍔" 🏁 ⏹.
|
||||
|
||||
### 🔗 🍔
|
||||
|
||||
🔜 ➡️ 🌈 👫 ➖🚫 🚫 "🛠️ 🍔", ✋️ "🔗 🍔".
|
||||
|
||||
👆 🚶 ⏮️ 👆 🥰 🤚 🔗 ⏩ 🥕.
|
||||
|
||||
👆 🧍 ⏸ ⏪ 📚 (➡️ 💬 8️⃣) 🏧 👈 🎏 🕰 🍳 ✊ ✔ ⚪️➡️ 👫👫 🚪 👆.
|
||||
|
||||
👱 ⏭ 👆 ⌛ 👫 🍔 🔜 ⏭ 🍂 ⏲ ↩️ 🔠 8️⃣ 🏧 🚶 & 🏗 🍔 ▶️️ ↖️ ⏭ 💆♂ ⏭ ✔.
|
||||
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-01.png" class="illustration">
|
||||
|
||||
⤴️ ⚫️ 😒 👆 🔄, 👆 🥉 👆 ✔ 2️⃣ 📶 🎀 🍔 👆 🥰 & 👆.
|
||||
|
||||
👆 💸 👶.
|
||||
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-02.png" class="illustration">
|
||||
|
||||
🏧 🚶 👨🍳.
|
||||
|
||||
👆 ⌛, 🧍 🚪 ⏲ 👶, 👈 🙅♂ 1️⃣ 🙆 ✊ 👆 🍔 ⏭ 👆, 📤 🙅♂ 🔢 🔄.
|
||||
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-03.png" class="illustration">
|
||||
|
||||
👆 & 👆 🥰 😩 🚫 ➡️ 🙆 🤚 🚪 👆 & ✊ 👆 🍔 🕐❔ 👫 🛬, 👆 🚫🔜 💸 🙋 👆 🥰. 👶
|
||||
|
||||
👉 "🔁" 👷, 👆 "🔁" ⏮️ 🏧/🍳 👶 👶. 👆 ✔️ ⌛ 👶 & 📤 ☑ 🙍 👈 🏧/🍳 👶 👶 🏁 🍔 & 🤝 👫 👆, ⚖️ ⏪, 👱 🙆 💪 ✊ 👫.
|
||||
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-04.png" class="illustration">
|
||||
|
||||
⤴️ 👆 🏧/🍳 👶 👶 😒 👟 🔙 ⏮️ 👆 🍔, ⏮️ 📏 🕰 ⌛ 👶 📤 🚪 ⏲.
|
||||
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-05.png" class="illustration">
|
||||
|
||||
👆 ✊ 👆 🍔 & 🚶 🏓 ⏮️ 👆 🥰.
|
||||
|
||||
👆 🍴 👫, & 👆 🔨. ⏹
|
||||
|
||||
<img src="/img/async/parallel-burgers/parallel-burgers-06.png" class="illustration">
|
||||
|
||||
📤 🚫 🌅 💬 ⚖️ 😏 🌅 🕰 💸 ⌛ 👶 🚪 ⏲. 👶
|
||||
|
||||
!!! info
|
||||
🌹 🖼 <a href="https://www.instagram.com/ketrinadrawsalot" class="external-link" target="_blank">👯 🍏</a>. 👶
|
||||
|
||||
---
|
||||
|
||||
👉 😐 🔗 🍔, 👆 💻 / 📋 👶 ⏮️ 2️⃣ 🕹 (👆 & 👆 🥰), 👯♂️ ⌛ 👶 & 💡 👫 🙋 👶 "⌛ 🔛 ⏲" 👶 📏 🕰.
|
||||
|
||||
⏩ 🥕 🏪 ✔️ 8️⃣ 🕹 (🏧/🍳). ⏪ 🛠️ 🍔 🏪 💪 ✔️ ✔️ 🕴 2️⃣ (1️⃣ 🏧 & 1️⃣ 🍳).
|
||||
|
||||
✋️, 🏁 💡 🚫 🏆. 👶
|
||||
|
||||
---
|
||||
|
||||
👉 🔜 🔗 🌓 📖 🍔. 👶
|
||||
|
||||
🌅 "🎰 👨❤👨" 🖼 👉, 🌈 🏦.
|
||||
|
||||
🆙 ⏳, 🏆 🏦 ✔️ 💗 🏧 👶 👶 👶 👶 👶 👶 👶 👶 & 🦏 ⏸ 👶 👶 👶 👶 👶 👶 👶 👶.
|
||||
|
||||
🌐 🏧 🔨 🌐 👷 ⏮️ 1️⃣ 👩💻 ⏮️ 🎏 👶 👶 👶.
|
||||
|
||||
& 👆 ✔️ ⌛ 👶 ⏸ 📏 🕰 ⚖️ 👆 💸 👆 🔄.
|
||||
|
||||
👆 🎲 🚫🔜 💚 ✊ 👆 🥰 👶 ⏮️ 👆 👷 🏦 👶.
|
||||
|
||||
### 🍔 🏁
|
||||
|
||||
👉 😐 "⏩ 🥕 🍔 ⏮️ 👆 🥰", 📤 📚 ⌛ 👶, ⚫️ ⚒ 📚 🌅 🔑 ✔️ 🛠️ ⚙️ ⏸ 👶 👶.
|
||||
|
||||
👉 💼 🌅 🕸 🈸.
|
||||
|
||||
📚, 📚 👩💻, ✋️ 👆 💽 ⌛ 👶 👫 🚫--👍 🔗 📨 👫 📨.
|
||||
|
||||
& ⤴️ ⌛ 👶 🔄 📨 👟 🔙.
|
||||
|
||||
👉 "⌛" 👶 ⚖ ⏲, ✋️, ⚖ ⚫️ 🌐, ⚫️ 📚 ⌛ 🔚.
|
||||
|
||||
👈 ⚫️❔ ⚫️ ⚒ 📚 🔑 ⚙️ 🔁 ⏸ 👶 👶 📟 🕸 🔗.
|
||||
|
||||
👉 😇 🔀 ⚫️❔ ⚒ ✳ 🌟 (✋️ ✳ 🚫 🔗) & 👈 💪 🚶 🛠️ 🇪🇸.
|
||||
|
||||
& 👈 🎏 🎚 🎭 👆 🤚 ⏮️ **FastAPI**.
|
||||
|
||||
& 👆 💪 ✔️ 🔁 & 🔀 🎏 🕰, 👆 🤚 ↕ 🎭 🌘 🌅 💯 ✳ 🛠️ & 🔛 🇷🇪 ⏮️ 🚶, ❔ ✍ 🇪🇸 🔐 🅱 <a href="https://www.techempower.com/benchmarks/#section=data-r17&hw=ph&test=query&l=zijmkf-1" class="external-link" target="_blank">(🌐 👏 💃)</a>.
|
||||
|
||||
### 🛠️ 👍 🌘 🔁 ❓
|
||||
|
||||
😆 ❗ 👈 🚫 🛐 📖.
|
||||
|
||||
🛠️ 🎏 🌘 🔁. & ⚫️ 👻 🔛 **🎯** 😐 👈 🔌 📚 ⌛. ↩️ 👈, ⚫️ 🛎 📚 👍 🌘 🔁 🕸 🈸 🛠️. ✋️ 🚫 🌐.
|
||||
|
||||
, ⚖ 👈 👅, 🌈 📄 📏 📖:
|
||||
|
||||
> 👆 ✔️ 🧹 🦏, 💩 🏠.
|
||||
|
||||
*😆, 👈 🎂 📖*.
|
||||
|
||||
---
|
||||
|
||||
📤 🙅♂ ⌛ 👶 🙆, 📚 👷 🔨, 🔛 💗 🥉 🏠.
|
||||
|
||||
👆 💪 ✔️ 🔄 🍔 🖼, 🥇 🏠 🧖♂, ⤴️ 👨🍳, ✋️ 👆 🚫 ⌛ 👶 🕳, 🧹 & 🧹, 🔄 🚫🔜 📉 🕳.
|
||||
|
||||
⚫️ 🔜 ✊ 🎏 💸 🕰 🏁 ⏮️ ⚖️ 🍵 🔄 (🛠️) & 👆 🔜 ✔️ ⌛ 🎏 💸 👷.
|
||||
|
||||
✋️ 👉 💼, 🚥 👆 💪 ✊️ 8️⃣ 👰-🏧/🍳/🔜-🧹, & 🔠 1️⃣ 👫 (➕ 👆) 💪 ✊ 🏒 🏠 🧹 ⚫️, 👆 💪 🌐 👷 **🔗**, ⏮️ ➕ ℹ, & 🏁 🌅 🔜.
|
||||
|
||||
👉 😐, 🔠 1️⃣ 🧹 (🔌 👆) 🔜 🕹, 🤸 👫 🍕 👨🏭.
|
||||
|
||||
& 🏆 🛠️ 🕰 ✊ ☑ 👷 (↩️ ⌛), & 👷 💻 ⌛ <abbr title="Central Processing Unit">💽</abbr>, 👫 🤙 👫 ⚠ "💽 🎁".
|
||||
|
||||
---
|
||||
|
||||
⚠ 🖼 💽 🔗 🛠️ 👜 👈 🚚 🏗 🧪 🏭.
|
||||
|
||||
🖼:
|
||||
|
||||
* **🎧** ⚖️ **🖼 🏭**.
|
||||
* **💻 👓**: 🖼 ✍ 💯 🔅, 🔠 🔅 ✔️ 3️⃣ 💲 / 🎨, 🏭 👈 🛎 🚚 💻 🕳 🔛 📚 🔅, 🌐 🎏 🕰.
|
||||
* **🎰 🏫**: ⚫️ 🛎 🚚 📚 "✖" & "🖼" ✖. 💭 🦏 📋 ⏮️ 🔢 & ✖ 🌐 👫 👯♂️ 🎏 🕰.
|
||||
* **⏬ 🏫**: 👉 🎧-🏑 🎰 🏫,, 🎏 ✔. ⚫️ 👈 📤 🚫 👁 📋 🔢 ✖, ✋️ 🦏 ⚒ 👫, & 📚 💼, 👆 ⚙️ 🎁 🕹 🏗 & / ⚖️ ⚙️ 👈 🏷.
|
||||
|
||||
### 🛠️ ➕ 🔁: 🕸 ➕ 🎰 🏫
|
||||
|
||||
⏮️ **FastAPI** 👆 💪 ✊ 📈 🛠️ 👈 📶 ⚠ 🕸 🛠️ (🎏 👑 🧲 ✳).
|
||||
|
||||
✋️ 👆 💪 🐄 💰 🔁 & 💾 (✔️ 💗 🛠️ 🏃♂ 🔗) **💽 🎁** ⚖ 💖 👈 🎰 🏫 ⚙️.
|
||||
|
||||
👈, ➕ 🙅 👐 👈 🐍 👑 🇪🇸 **💽 🧪**, 🎰 🏫 & ✴️ ⏬ 🏫, ⚒ FastAPI 📶 👍 🏏 💽 🧪 / 🎰 🏫 🕸 🔗 & 🈸 (👪 📚 🎏).
|
||||
|
||||
👀 ❔ 🏆 👉 🔁 🏭 👀 📄 🔃 [🛠️](deployment/index.md){.internal-link target=_blank}.
|
||||
|
||||
## `async` & `await`
|
||||
|
||||
🏛 ⏬ 🐍 ✔️ 📶 🏋️ 🌌 🔬 🔁 📟. 👉 ⚒ ⚫️ 👀 💖 😐 "🔁" 📟 & "⌛" 👆 ▶️️ 🙍.
|
||||
|
||||
🕐❔ 📤 🛠️ 👈 🔜 🚚 ⌛ ⏭ 🤝 🏁 & ✔️ 🐕🦺 👉 🆕 🐍 ⚒, 👆 💪 📟 ⚫️ 💖:
|
||||
|
||||
```Python
|
||||
burgers = await get_burgers(2)
|
||||
```
|
||||
|
||||
🔑 📥 `await`. ⚫️ 💬 🐍 👈 ⚫️ ✔️ ⌛ ⏸ `get_burgers(2)` 🏁 🔨 🚮 👜 👶 ⏭ ♻ 🏁 `burgers`. ⏮️ 👈, 🐍 🔜 💭 👈 ⚫️ 💪 🚶 & 🕳 🙆 👶 👶 👐 (💖 📨 ➕1️⃣ 📨).
|
||||
|
||||
`await` 👷, ⚫️ ✔️ 🔘 🔢 👈 🐕🦺 👉 🔀. 👈, 👆 📣 ⚫️ ⏮️ `async def`:
|
||||
|
||||
```Python hl_lines="1"
|
||||
async def get_burgers(number: int):
|
||||
# Do some asynchronous stuff to create the burgers
|
||||
return burgers
|
||||
```
|
||||
|
||||
...↩️ `def`:
|
||||
|
||||
```Python hl_lines="2"
|
||||
# This is not asynchronous
|
||||
def get_sequential_burgers(number: int):
|
||||
# Do some sequential stuff to create the burgers
|
||||
return burgers
|
||||
```
|
||||
|
||||
⏮️ `async def`, 🐍 💭 👈, 🔘 👈 🔢, ⚫️ ✔️ 🤔 `await` 🧬, & 👈 ⚫️ 💪 "⏸" ⏸ 🛠️ 👈 🔢 & 🚶 🕳 🙆 👶 ⏭ 👟 🔙.
|
||||
|
||||
🕐❔ 👆 💚 🤙 `async def` 🔢, 👆 ✔️ "⌛" ⚫️. , 👉 🏆 🚫 👷:
|
||||
|
||||
```Python
|
||||
# This won't work, because get_burgers was defined with: async def
|
||||
burgers = get_burgers(2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
, 🚥 👆 ⚙️ 🗃 👈 💬 👆 👈 👆 💪 🤙 ⚫️ ⏮️ `await`, 👆 💪 ✍ *➡ 🛠️ 🔢* 👈 ⚙️ ⚫️ ⏮️ `async def`, 💖:
|
||||
|
||||
```Python hl_lines="2-3"
|
||||
@app.get('/burgers')
|
||||
async def read_burgers():
|
||||
burgers = await get_burgers(2)
|
||||
return burgers
|
||||
```
|
||||
|
||||
### 🌅 📡 ℹ
|
||||
|
||||
👆 💪 ✔️ 👀 👈 `await` 💪 🕴 ⚙️ 🔘 🔢 🔬 ⏮️ `async def`.
|
||||
|
||||
✋️ 🎏 🕰, 🔢 🔬 ⏮️ `async def` ✔️ "⌛". , 🔢 ⏮️ `async def` 💪 🕴 🤙 🔘 🔢 🔬 ⏮️ `async def` 💁♂️.
|
||||
|
||||
, 🔃 🥚 & 🐔, ❔ 👆 🤙 🥇 `async` 🔢 ❓
|
||||
|
||||
🚥 👆 👷 ⏮️ **FastAPI** 👆 🚫 ✔️ 😟 🔃 👈, ↩️ 👈 "🥇" 🔢 🔜 👆 *➡ 🛠️ 🔢*, & FastAPI 🔜 💭 ❔ ▶️️ 👜.
|
||||
|
||||
✋️ 🚥 👆 💚 ⚙️ `async` / `await` 🍵 FastAPI, 👆 💪 ⚫️ 👍.
|
||||
|
||||
### ✍ 👆 👍 🔁 📟
|
||||
|
||||
💃 (& **FastAPI**) ⚓️ 🔛 <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a>, ❔ ⚒ ⚫️ 🔗 ⏮️ 👯♂️ 🐍 🐩 🗃 <a href="https://docs.python.org/3/library/asyncio-task.html" class="external-link" target="_blank">✳</a> & <a href="https://trio.readthedocs.io/en/stable/" class="external-link" target="_blank">🎻</a>.
|
||||
|
||||
🎯, 👆 💪 🔗 ⚙️ <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> 👆 🏧 🛠️ ⚙️ 💼 👈 🚚 🌅 🏧 ⚓ 👆 👍 📟.
|
||||
|
||||
& 🚥 👆 🚫 ⚙️ FastAPI, 👆 💪 ✍ 👆 👍 🔁 🈸 ⏮️ <a href="https://anyio.readthedocs.io/en/stable/" class="external-link" target="_blank">AnyIO</a> 🏆 🔗 & 🤚 🚮 💰 (✅ *📊 🛠️*).
|
||||
|
||||
### 🎏 📨 🔁 📟
|
||||
|
||||
👉 👗 ⚙️ `async` & `await` 📶 🆕 🇪🇸.
|
||||
|
||||
✋️ ⚫️ ⚒ 👷 ⏮️ 🔁 📟 📚 ⏩.
|
||||
|
||||
👉 🎏 ❕ (⚖️ 🌖 🌓) 🔌 ⏳ 🏛 ⏬ 🕸 (🖥 & ✳).
|
||||
|
||||
✋️ ⏭ 👈, 🚚 🔁 📟 🌖 🏗 & ⚠.
|
||||
|
||||
⏮️ ⏬ 🐍, 👆 💪 ✔️ ⚙️ 🧵 ⚖️ <a href="https://www.gevent.org/" class="external-link" target="_blank">🐁</a>. ✋️ 📟 🌌 🌖 🏗 🤔, ℹ, & 💭 🔃.
|
||||
|
||||
⏮️ ⏬ ✳ / 🖥 🕸, 👆 🔜 ✔️ ⚙️ "⏲". ❔ ↘️ <a href="http://callbackhell.com/" class="external-link" target="_blank">⏲ 🔥😈</a>.
|
||||
|
||||
## 🔁
|
||||
|
||||
**🔁** 📶 🎀 ⚖ 👜 📨 `async def` 🔢. 🐍 💭 👈 ⚫️ 🕳 💖 🔢 👈 ⚫️ 💪 ▶️ & 👈 ⚫️ 🔜 🔚 ☝, ✋️ 👈 ⚫️ 5️⃣📆 ⏸ ⏸ 🔘 💁♂️, 🕐❔ 📤 `await` 🔘 ⚫️.
|
||||
|
||||
✋️ 🌐 👉 🛠️ ⚙️ 🔁 📟 ⏮️ `async` & `await` 📚 🕰 🔬 ⚙️ "🔁". ⚫️ ⭐ 👑 🔑 ⚒ 🚶, "🔁".
|
||||
|
||||
## 🏁
|
||||
|
||||
➡️ 👀 🎏 🔤 ⚪️➡️ 🔛:
|
||||
|
||||
> 🏛 ⏬ 🐍 ✔️ 🐕🦺 **"🔁 📟"** ⚙️ 🕳 🤙 **"🔁"**, ⏮️ **`async` & `await`** ❕.
|
||||
|
||||
👈 🔜 ⚒ 🌅 🔑 🔜. 👶
|
||||
|
||||
🌐 👈 ⚫️❔ 🏋️ FastAPI (🔘 💃) & ⚫️❔ ⚒ ⚫️ ✔️ ✅ 🎆 🎭.
|
||||
|
||||
## 📶 📡 ℹ
|
||||
|
||||
!!! warning
|
||||
👆 💪 🎲 🚶 👉.
|
||||
|
||||
👉 📶 📡 ℹ ❔ **FastAPI** 👷 🔘.
|
||||
|
||||
🚥 👆 ✔️ 📡 💡 (🈶-🏋, 🧵, 🍫, ♒️.) & 😟 🔃 ❔ FastAPI 🍵 `async def` 🆚 😐 `def`, 🚶 ⤴️.
|
||||
|
||||
### ➡ 🛠️ 🔢
|
||||
|
||||
🕐❔ 👆 📣 *➡ 🛠️ 🔢* ⏮️ 😐 `def` ↩️ `async def`, ⚫️ 🏃 🔢 🧵 👈 ⤴️ ⌛, ↩️ ➖ 🤙 🔗 (⚫️ 🔜 🍫 💽).
|
||||
|
||||
🚥 👆 👟 ⚪️➡️ ➕1️⃣ 🔁 🛠️ 👈 🔨 🚫 👷 🌌 🔬 🔛 & 👆 ⚙️ ⚖ 🙃 📊-🕴 *➡ 🛠️ 🔢* ⏮️ ✅ `def` 🤪 🎭 📈 (🔃 1️⃣0️⃣0️⃣ 💓), 🙏 🗒 👈 **FastAPI** ⭐ 🔜 🔄. 👫 💼, ⚫️ 👻 ⚙️ `async def` 🚥 👆 *➡ 🛠️ 🔢* ⚙️ 📟 👈 🎭 🚧 <abbr title="Input/Output: disk reading or writing, network communications.">👤/🅾</abbr>.
|
||||
|
||||
, 👯♂️ ⚠, 🤞 👈 **FastAPI** 🔜 [⏩](/#performance){.internal-link target=_blank} 🌘 (⚖️ 🌘 ⭐) 👆 ⏮️ 🛠️.
|
||||
|
||||
### 🔗
|
||||
|
||||
🎏 ✔ [🔗](/tutorial/dependencies/index.md){.internal-link target=_blank}. 🚥 🔗 🐩 `def` 🔢 ↩️ `async def`, ⚫️ 🏃 🔢 🧵.
|
||||
|
||||
### 🎧-🔗
|
||||
|
||||
👆 💪 ✔️ 💗 🔗 & [🎧-🔗](/tutorial/dependencies/sub-dependencies.md){.internal-link target=_blank} 🚫 🔠 🎏 (🔢 🔢 🔑), 👫 💪 ✍ ⏮️ `async def` & ⏮️ 😐 `def`. ⚫️ 🔜 👷, & 🕐 ✍ ⏮️ 😐 `def` 🔜 🤙 🔛 🔢 🧵 (⚪️➡️ 🧵) ↩️ ➖ "⌛".
|
||||
|
||||
### 🎏 🚙 🔢
|
||||
|
||||
🙆 🎏 🚙 🔢 👈 👆 🤙 🔗 💪 ✍ ⏮️ 😐 `def` ⚖️ `async def` & FastAPI 🏆 🚫 📉 🌌 👆 🤙 ⚫️.
|
||||
|
||||
👉 🔅 🔢 👈 FastAPI 🤙 👆: *➡ 🛠️ 🔢* & 🔗.
|
||||
|
||||
🚥 👆 🚙 🔢 😐 🔢 ⏮️ `def`, ⚫️ 🔜 🤙 🔗 (👆 ✍ ⚫️ 👆 📟), 🚫 🧵, 🚥 🔢 ✍ ⏮️ `async def` ⤴️ 👆 🔜 `await` 👈 🔢 🕐❔ 👆 🤙 ⚫️ 👆 📟.
|
||||
|
||||
---
|
||||
|
||||
🔄, 👉 📶 📡 ℹ 👈 🔜 🎲 ⚠ 🚥 👆 👟 🔎 👫.
|
||||
|
||||
⏪, 👆 🔜 👍 ⏮️ 📄 ⚪️➡️ 📄 🔛: <a href="#in-a-hurry">🏃 ❓</a>.
|
||||
34
docs/em/docs/benchmarks.md
Normal file
34
docs/em/docs/benchmarks.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# 📇
|
||||
|
||||
🔬 🇸🇲 📇 🎦 **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">1️⃣ ⏩ 🐍 🛠️ 💪</a>, 🕴 🔛 💃 & Uvicorn 👫 (⚙️ 🔘 FastAPI). (*)
|
||||
|
||||
✋️ 🕐❔ ✅ 📇 & 🔺 👆 🔜 ✔️ 📄 🤯.
|
||||
|
||||
## 📇 & 🚅
|
||||
|
||||
🕐❔ 👆 ✅ 📇, ⚫️ ⚠ 👀 📚 🧰 🎏 🆎 🔬 🌓.
|
||||
|
||||
🎯, 👀 Uvicorn, 💃 & FastAPI 🔬 👯♂️ (👪 📚 🎏 🧰).
|
||||
|
||||
🙅 ⚠ ❎ 🧰, 👍 🎭 ⚫️ 🔜 🤚. & 🏆 📇 🚫 💯 🌖 ⚒ 🚚 🧰.
|
||||
|
||||
🔗 💖:
|
||||
|
||||
* **Uvicorn**: 🔫 💽
|
||||
* **💃**: (⚙️ Uvicorn) 🕸 🕸
|
||||
* **FastAPI**: (⚙️ 💃) 🛠️ 🕸 ⏮️ 📚 🌖 ⚒ 🏗 🔗, ⏮️ 💽 🔬, ♒️.
|
||||
|
||||
* **Uvicorn**:
|
||||
* 🔜 ✔️ 🏆 🎭, ⚫️ 🚫 ✔️ 🌅 ➕ 📟 ↖️ ⚪️➡️ 💽 ⚫️.
|
||||
* 👆 🚫🔜 ✍ 🈸 Uvicorn 🔗. 👈 🔜 ⛓ 👈 👆 📟 🔜 ✔️ 🔌 🌖 ⚖️ 🌘, 🌘, 🌐 📟 🚚 💃 (⚖️ **FastAPI**). & 🚥 👆 👈, 👆 🏁 🈸 🔜 ✔️ 🎏 🌥 ✔️ ⚙️ 🛠️ & 📉 👆 📱 📟 & 🐛.
|
||||
* 🚥 👆 ⚖ Uvicorn, 🔬 ⚫️ 🛡 👸, Hypercorn, ✳, ♒️. 🈸 💽.
|
||||
* **💃**:
|
||||
* 🔜 ✔️ ⏭ 🏆 🎭, ⏮️ Uvicorn. 👐, 💃 ⚙️ Uvicorn 🏃. , ⚫️ 🎲 💪 🕴 🤚 "🐌" 🌘 Uvicorn ✔️ 🛠️ 🌅 📟.
|
||||
* ✋️ ⚫️ 🚚 👆 🧰 🏗 🙅 🕸 🈸, ⏮️ 🕹 ⚓️ 🔛 ➡, ♒️.
|
||||
* 🚥 👆 ⚖ 💃, 🔬 ⚫️ 🛡 🤣, 🏺, ✳, ♒️. 🕸 🛠️ (⚖️ 🕸).
|
||||
* **FastAPI**:
|
||||
* 🎏 🌌 👈 💃 ⚙️ Uvicorn & 🚫🔜 ⏩ 🌘 ⚫️, **FastAPI** ⚙️ 💃, ⚫️ 🚫🔜 ⏩ 🌘 ⚫️.
|
||||
* FastAPI 🚚 🌅 ⚒ 🔛 🔝 💃. ⚒ 👈 👆 🌖 🕧 💪 🕐❔ 🏗 🔗, 💖 💽 🔬 & 🛠️. & ⚙️ ⚫️, 👆 🤚 🏧 🧾 🆓 (🏧 🧾 🚫 🚮 🌥 🏃♂ 🈸, ⚫️ 🏗 🔛 🕴).
|
||||
* 🚥 👆 🚫 ⚙️ FastAPI & ⚙️ 💃 🔗 (⚖️ ➕1️⃣ 🧰, 💖 🤣, 🏺, 🆘, ♒️) 👆 🔜 ✔️ 🛠️ 🌐 💽 🔬 & 🛠️ 👆. , 👆 🏁 🈸 🔜 ✔️ 🎏 🌥 🚥 ⚫️ 🏗 ⚙️ FastAPI. & 📚 💼, 👉 💽 🔬 & 🛠️ 🦏 💸 📟 ✍ 🈸.
|
||||
* , ⚙️ FastAPI 👆 ♻ 🛠️ 🕰, 🐛, ⏸ 📟, & 👆 🔜 🎲 🤚 🎏 🎭 (⚖️ 👍) 👆 🔜 🚥 👆 🚫 ⚙️ ⚫️ (👆 🔜 ✔️ 🛠️ ⚫️ 🌐 👆 📟).
|
||||
* 🚥 👆 ⚖ FastAPI, 🔬 ⚫️ 🛡 🕸 🈸 🛠️ (⚖️ ⚒ 🧰) 👈 🚚 💽 🔬, 🛠️ & 🧾, 💖 🏺-apispec, NestJS, ♨, ♒️. 🛠️ ⏮️ 🛠️ 🏧 💽 🔬, 🛠️ & 🧾.
|
||||
465
docs/em/docs/contributing.md
Normal file
465
docs/em/docs/contributing.md
Normal file
@@ -0,0 +1,465 @@
|
||||
# 🛠️ - 📉
|
||||
|
||||
🥇, 👆 💪 💚 👀 🔰 🌌 [ℹ FastAPI & 🤚 ℹ](help-fastapi.md){.internal-link target=_blank}.
|
||||
|
||||
## 🛠️
|
||||
|
||||
🚥 👆 ⏪ 🖖 🗃 & 👆 💭 👈 👆 💪 ⏬ 🤿 📟, 📥 📄 ⚒ 🆙 👆 🌐.
|
||||
|
||||
### 🕹 🌐 ⏮️ `venv`
|
||||
|
||||
👆 💪 ✍ 🕹 🌐 📁 ⚙️ 🐍 `venv` 🕹:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python -m venv env
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
👈 🔜 ✍ 📁 `./env/` ⏮️ 🐍 💱 & ⤴️ 👆 🔜 💪 ❎ 📦 👈 ❎ 🌐.
|
||||
|
||||
### 🔓 🌐
|
||||
|
||||
🔓 🆕 🌐 ⏮️:
|
||||
|
||||
=== "💾, 🇸🇻"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source ./env/bin/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
=== "🚪 📋"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ .\env\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
=== "🚪 🎉"
|
||||
|
||||
⚖️ 🚥 👆 ⚙️ 🎉 🖥 (✅ <a href="https://gitforwindows.org/" class="external-link" target="_blank">🐛 🎉</a>):
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ source ./env/Scripts/activate
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
✅ ⚫️ 👷, ⚙️:
|
||||
|
||||
=== "💾, 🇸🇻, 🚪 🎉"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ which pip
|
||||
|
||||
some/directory/fastapi/env/bin/pip
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
=== "🚪 📋"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ Get-Command pip
|
||||
|
||||
some/directory/fastapi/env/bin/pip
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
🚥 ⚫️ 🎦 `pip` 💱 `env/bin/pip` ⤴️ ⚫️ 👷. 👶
|
||||
|
||||
⚒ 💭 👆 ✔️ 📰 🐖 ⏬ 🔛 👆 🕹 🌐 ❎ ❌ 🔛 ⏭ 📶:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python -m pip install --upgrade pip
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! tip
|
||||
🔠 🕰 👆 ❎ 🆕 📦 ⏮️ `pip` 🔽 👈 🌐, 🔓 🌐 🔄.
|
||||
|
||||
👉 ⚒ 💭 👈 🚥 👆 ⚙️ 📶 📋 ❎ 👈 📦, 👆 ⚙️ 1️⃣ ⚪️➡️ 👆 🇧🇿 🌐 & 🚫 🙆 🎏 👈 💪 ❎ 🌐.
|
||||
|
||||
### 🐖
|
||||
|
||||
⏮️ 🔓 🌐 🔬 🔛:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -e ."[dev,doc,test]"
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
⚫️ 🔜 ❎ 🌐 🔗 & 👆 🇧🇿 FastAPI 👆 🇧🇿 🌐.
|
||||
|
||||
#### ⚙️ 👆 🇧🇿 FastAPI
|
||||
|
||||
🚥 👆 ✍ 🐍 📁 👈 🗄 & ⚙️ FastAPI, & 🏃 ⚫️ ⏮️ 🐍 ⚪️➡️ 👆 🇧🇿 🌐, ⚫️ 🔜 ⚙️ 👆 🇧🇿 FastAPI ℹ 📟.
|
||||
|
||||
& 🚥 👆 ℹ 👈 🇧🇿 FastAPI ℹ 📟, ⚫️ ❎ ⏮️ `-e`, 🕐❔ 👆 🏃 👈 🐍 📁 🔄, ⚫️ 🔜 ⚙️ 🍋 ⏬ FastAPI 👆 ✍.
|
||||
|
||||
👈 🌌, 👆 🚫 ✔️ "❎" 👆 🇧🇿 ⏬ 💪 💯 🔠 🔀.
|
||||
|
||||
### 📁
|
||||
|
||||
📤 ✍ 👈 👆 💪 🏃 👈 🔜 📁 & 🧹 🌐 👆 📟:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ bash scripts/format.sh
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
⚫️ 🔜 🚘-😇 🌐 👆 🗄.
|
||||
|
||||
⚫️ 😇 👫 ☑, 👆 💪 ✔️ FastAPI ❎ 🌐 👆 🌐, ⏮️ 📋 📄 🔛 ⚙️ `-e`.
|
||||
|
||||
## 🩺
|
||||
|
||||
🥇, ⚒ 💭 👆 ⚒ 🆙 👆 🌐 🔬 🔛, 👈 🔜 ❎ 🌐 📄.
|
||||
|
||||
🧾 ⚙️ <a href="https://www.mkdocs.org/" class="external-link" target="_blank">⬜</a>.
|
||||
|
||||
& 📤 ➕ 🧰/✍ 🥉 🍵 ✍ `./scripts/docs.py`.
|
||||
|
||||
!!! tip
|
||||
👆 🚫 💪 👀 📟 `./scripts/docs.py`, 👆 ⚙️ ⚫️ 📋 ⏸.
|
||||
|
||||
🌐 🧾 ✍ 📁 📁 `./docs/en/`.
|
||||
|
||||
📚 🔰 ✔️ 🍫 📟.
|
||||
|
||||
🌅 💼, 👫 🍫 📟 ☑ 🏁 🈸 👈 💪 🏃.
|
||||
|
||||
👐, 👈 🍫 📟 🚫 ✍ 🔘 ✍, 👫 🐍 📁 `./docs_src/` 📁.
|
||||
|
||||
& 👈 🐍 📁 🔌/💉 🧾 🕐❔ 🏭 🕸.
|
||||
|
||||
### 🩺 💯
|
||||
|
||||
🏆 💯 🤙 🏃 🛡 🖼 ℹ 📁 🧾.
|
||||
|
||||
👉 ℹ ⚒ 💭 👈:
|
||||
|
||||
* 🧾 🆙 📅.
|
||||
* 🧾 🖼 💪 🏃.
|
||||
* 🌅 ⚒ 📔 🧾, 🚚 💯 💰.
|
||||
|
||||
⏮️ 🇧🇿 🛠️, 📤 ✍ 👈 🏗 🕸 & ✅ 🙆 🔀, 🖖-🔫:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ python ./scripts/docs.py live
|
||||
|
||||
<span style="color: green;">[INFO]</span> Serving on http://127.0.0.1:8008
|
||||
<span style="color: green;">[INFO]</span> Start watching changes
|
||||
<span style="color: green;">[INFO]</span> Start detecting changes
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
⚫️ 🔜 🍦 🧾 🔛 `http://127.0.0.1:8008`.
|
||||
|
||||
👈 🌌, 👆 💪 ✍ 🧾/ℹ 📁 & 👀 🔀 🖖.
|
||||
|
||||
#### 🏎 ✳ (📦)
|
||||
|
||||
👩🌾 📥 🎦 👆 ❔ ⚙️ ✍ `./scripts/docs.py` ⏮️ `python` 📋 🔗.
|
||||
|
||||
✋️ 👆 💪 ⚙️ <a href="https://typer.tiangolo.com/typer-cli/" class="external-link" target="_blank">🏎 ✳</a>, & 👆 🔜 🤚 ✍ 👆 📶 📋 ⏮️ ❎ 🛠️.
|
||||
|
||||
🚥 👆 ❎ 🏎 ✳, 👆 💪 ❎ 🛠️ ⏮️:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ typer --install-completion
|
||||
|
||||
zsh completion installed in /home/user/.bashrc.
|
||||
Completion will take effect once you restart the terminal.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
### 📱 & 🩺 🎏 🕰
|
||||
|
||||
🚥 👆 🏃 🖼 ⏮️, ✅:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ uvicorn tutorial001:app --reload
|
||||
|
||||
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
Uvicorn 🔢 🔜 ⚙️ ⛴ `8000`, 🧾 🔛 ⛴ `8008` 🏆 🚫 ⚔.
|
||||
|
||||
### ✍
|
||||
|
||||
ℹ ⏮️ ✍ 📶 🌅 👍 ❗ & ⚫️ 💪 🚫 🔨 🍵 ℹ ⚪️➡️ 👪. 👶 👶
|
||||
|
||||
📥 📶 ℹ ⏮️ ✍.
|
||||
|
||||
#### 💁♂ & 📄
|
||||
|
||||
* ✅ ⏳ <a href="https://github.com/tiangolo/fastapi/pulls" class="external-link" target="_blank">♻ 🚲 📨</a> 👆 🇪🇸 & 🚮 📄 ✔ 🔀 ⚖️ ✔ 👫.
|
||||
|
||||
!!! tip
|
||||
👆 💪 <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request" class="external-link" target="_blank">🚮 🏤 ⏮️ 🔀 🔑</a> ♻ 🚲 📨.
|
||||
|
||||
✅ 🩺 🔃 <a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews" class="external-link" target="_blank">❎ 🚲 📨 📄</a> ✔ ⚫️ ⚖️ 📨 🔀.
|
||||
|
||||
* ✅ <a href="https://github.com/tiangolo/fastapi/issues" class="external-link" target="_blank">❔</a> 👀 🚥 📤 1️⃣ 🛠️ ✍ 👆 🇪🇸.
|
||||
|
||||
* 🚮 👁 🚲 📨 📍 📃 💬. 👈 🔜 ⚒ ⚫️ 🌅 ⏩ 🎏 📄 ⚫️.
|
||||
|
||||
🇪🇸 👤 🚫 💬, 👤 🔜 ⌛ 📚 🎏 📄 ✍ ⏭ 🔗.
|
||||
|
||||
* 👆 💪 ✅ 🚥 📤 ✍ 👆 🇪🇸 & 🚮 📄 👫, 👈 🔜 ℹ 👤 💭 👈 ✍ ☑ & 👤 💪 🔗 ⚫️.
|
||||
|
||||
* ⚙️ 🎏 🐍 🖼 & 🕴 💬 ✍ 🩺. 👆 🚫 ✔️ 🔀 🕳 👉 👷.
|
||||
|
||||
* ⚙️ 🎏 🖼, 📁 📛, & 🔗. 👆 🚫 ✔️ 🔀 🕳 ⚫️ 👷.
|
||||
|
||||
* ✅ 2️⃣-🔤 📟 🇪🇸 👆 💚 💬 👆 💪 ⚙️ 🏓 <a href="https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes" class="external-link" target="_blank">📇 💾 6️⃣3️⃣9️⃣-1️⃣ 📟</a>.
|
||||
|
||||
#### ♻ 🇪🇸
|
||||
|
||||
➡️ 💬 👆 💚 💬 📃 🇪🇸 👈 ⏪ ✔️ ✍ 📃, 💖 🇪🇸.
|
||||
|
||||
💼 🇪🇸, 2️⃣-🔤 📟 `es`. , 📁 🇪🇸 ✍ 🔎 `docs/es/`.
|
||||
|
||||
!!! tip
|
||||
👑 ("🛂") 🇪🇸 🇪🇸, 🔎 `docs/en/`.
|
||||
|
||||
🔜 🏃 🖖 💽 🩺 🇪🇸:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Use the command "live" and pass the language code as a CLI argument
|
||||
$ python ./scripts/docs.py live es
|
||||
|
||||
<span style="color: green;">[INFO]</span> Serving on http://127.0.0.1:8008
|
||||
<span style="color: green;">[INFO]</span> Start watching changes
|
||||
<span style="color: green;">[INFO]</span> Start detecting changes
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
🔜 👆 💪 🚶 <a href="http://127.0.0.1:8008" class="external-link" target="_blank">http://127.0.0.1:8008</a> & 👀 👆 🔀 🖖.
|
||||
|
||||
🚥 👆 👀 FastAPI 🩺 🕸, 👆 🔜 👀 👈 🔠 🇪🇸 ✔️ 🌐 📃. ✋️ 📃 🚫 💬 & ✔️ 📨 🔃 ❌ ✍.
|
||||
|
||||
✋️ 🕐❔ 👆 🏃 ⚫️ 🌐 💖 👉, 👆 🔜 🕴 👀 📃 👈 ⏪ 💬.
|
||||
|
||||
🔜 ➡️ 💬 👈 👆 💚 🚮 ✍ 📄 [⚒](features.md){.internal-link target=_blank}.
|
||||
|
||||
* 📁 📁:
|
||||
|
||||
```
|
||||
docs/en/docs/features.md
|
||||
```
|
||||
|
||||
* 📋 ⚫️ ⚫️❔ 🎏 🗺 ✋️ 🇪🇸 👆 💚 💬, ✅:
|
||||
|
||||
```
|
||||
docs/es/docs/features.md
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👀 👈 🕴 🔀 ➡ & 📁 📛 🇪🇸 📟, ⚪️➡️ `en` `es`.
|
||||
|
||||
* 🔜 📂 ⬜ 📁 📁 🇪🇸:
|
||||
|
||||
```
|
||||
docs/en/mkdocs.yml
|
||||
```
|
||||
|
||||
* 🔎 🥉 🌐❔ 👈 `docs/features.md` 🔎 📁 📁. 👱 💖:
|
||||
|
||||
```YAML hl_lines="8"
|
||||
site_name: FastAPI
|
||||
# More stuff
|
||||
nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- es: /es/
|
||||
- features.md
|
||||
```
|
||||
|
||||
* 📂 ⬜ 📁 📁 🇪🇸 👆 ✍, ✅:
|
||||
|
||||
```
|
||||
docs/es/mkdocs.yml
|
||||
```
|
||||
|
||||
* 🚮 ⚫️ 📤 ☑ 🎏 🗺 ⚫️ 🇪🇸, ✅:
|
||||
|
||||
```YAML hl_lines="8"
|
||||
site_name: FastAPI
|
||||
# More stuff
|
||||
nav:
|
||||
- FastAPI: index.md
|
||||
- Languages:
|
||||
- en: /
|
||||
- es: /es/
|
||||
- features.md
|
||||
```
|
||||
|
||||
⚒ 💭 👈 🚥 📤 🎏 ⛔, 🆕 ⛔ ⏮️ 👆 ✍ ⚫️❔ 🎏 ✔ 🇪🇸 ⏬.
|
||||
|
||||
🚥 👆 🚶 👆 🖥 👆 🔜 👀 👈 🔜 🩺 🎦 👆 🆕 📄. 👶
|
||||
|
||||
🔜 👆 💪 💬 ⚫️ 🌐 & 👀 ❔ ⚫️ 👀 👆 🖊 📁.
|
||||
|
||||
#### 🆕 🇪🇸
|
||||
|
||||
➡️ 💬 👈 👆 💚 🚮 ✍ 🇪🇸 👈 🚫 💬, 🚫 📃.
|
||||
|
||||
➡️ 💬 👆 💚 🚮 ✍ 🇭🇹, & ⚫️ 🚫 📤 🩺.
|
||||
|
||||
✅ 🔗 ⚪️➡️ 🔛, 📟 "🇭🇹" `ht`.
|
||||
|
||||
⏭ 🔁 🏃 ✍ 🏗 🆕 ✍ 📁:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Use the command new-lang, pass the language code as a CLI argument
|
||||
$ python ./scripts/docs.py new-lang ht
|
||||
|
||||
Successfully initialized: docs/ht
|
||||
Updating ht
|
||||
Updating en
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
🔜 👆 💪 ✅ 👆 📟 👨🎨 ⏳ ✍ 📁 `docs/ht/`.
|
||||
|
||||
!!! tip
|
||||
✍ 🥇 🚲 📨 ⏮️ 👉, ⚒ 🆙 📳 🆕 🇪🇸, ⏭ ❎ ✍.
|
||||
|
||||
👈 🌌 🎏 💪 ℹ ⏮️ 🎏 📃 ⏪ 👆 👷 🔛 🥇 🕐. 👶
|
||||
|
||||
▶️ ✍ 👑 📃, `docs/ht/index.md`.
|
||||
|
||||
⤴️ 👆 💪 😣 ⏮️ ⏮️ 👩🌾, "♻ 🇪🇸".
|
||||
|
||||
##### 🆕 🇪🇸 🚫 🐕🦺
|
||||
|
||||
🚥 🕐❔ 🏃♂ 🖖 💽 ✍ 👆 🤚 ❌ 🔃 🇪🇸 🚫 ➖ 🐕🦺, 🕳 💖:
|
||||
|
||||
```
|
||||
raise TemplateNotFound(template)
|
||||
jinja2.exceptions.TemplateNotFound: partials/language/xx.html
|
||||
```
|
||||
|
||||
👈 ⛓ 👈 🎢 🚫 🐕🦺 👈 🇪🇸 (👉 💼, ⏮️ ❌ 2️⃣-🔤 📟 `xx`).
|
||||
|
||||
✋️ 🚫 😟, 👆 💪 ⚒ 🎢 🇪🇸 🇪🇸 & ⤴️ 💬 🎚 🩺.
|
||||
|
||||
🚥 👆 💪 👈, ✍ `mkdocs.yml` 👆 🆕 🇪🇸, ⚫️ 🔜 ✔️ 🕳 💖:
|
||||
|
||||
```YAML hl_lines="5"
|
||||
site_name: FastAPI
|
||||
# More stuff
|
||||
theme:
|
||||
# More stuff
|
||||
language: xx
|
||||
```
|
||||
|
||||
🔀 👈 🇪🇸 ⚪️➡️ `xx` (⚪️➡️ 👆 🇪🇸 📟) `en`.
|
||||
|
||||
⤴️ 👆 💪 ▶️ 🖖 💽 🔄.
|
||||
|
||||
#### 🎮 🏁
|
||||
|
||||
🕐❔ 👆 ⚙️ ✍ `./scripts/docs.py` ⏮️ `live` 📋 ⚫️ 🕴 🎦 📁 & ✍ 💪 ⏮️ 🇪🇸.
|
||||
|
||||
✋️ 🕐 👆 🔨, 👆 💪 💯 ⚫️ 🌐 ⚫️ 🔜 👀 💳.
|
||||
|
||||
👈, 🥇 🏗 🌐 🩺:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Use the command "build-all", this will take a bit
|
||||
$ python ./scripts/docs.py build-all
|
||||
|
||||
Updating es
|
||||
Updating en
|
||||
Building docs for: en
|
||||
Building docs for: es
|
||||
Successfully built docs for: es
|
||||
Copying en index.md to README.md
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
👈 🏗 🌐 🩺 `./docs_build/` 🔠 🇪🇸. 👉 🔌 ❎ 🙆 📁 ⏮️ ❌ ✍, ⏮️ 🗒 💬 👈 "👉 📁 🚫 ✔️ ✍". ✋️ 👆 🚫 ✔️ 🕳 ⏮️ 👈 📁.
|
||||
|
||||
⤴️ ⚫️ 🏗 🌐 👈 🔬 ⬜ 🕸 🔠 🇪🇸, 🌀 👫, & 🏗 🏁 🔢 `./site/`.
|
||||
|
||||
⤴️ 👆 💪 🍦 👈 ⏮️ 📋 `serve`:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
// Use the command "serve" after running "build-all"
|
||||
$ python ./scripts/docs.py serve
|
||||
|
||||
Warning: this is a very simple server. For development, use mkdocs serve instead.
|
||||
This is here only to preview a site with translations already built.
|
||||
Make sure you run the build-all command first.
|
||||
Serving at: http://127.0.0.1:8008
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## 💯
|
||||
|
||||
📤 ✍ 👈 👆 💪 🏃 🌐 💯 🌐 📟 & 🏗 💰 📄 🕸:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ bash scripts/test-cov-html.sh
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
👉 📋 🏗 📁 `./htmlcov/`, 🚥 👆 📂 📁 `./htmlcov/index.html` 👆 🖥, 👆 💪 🔬 🖥 🇹🇼 📟 👈 📔 💯, & 👀 🚥 📤 🙆 🇹🇼 ❌.
|
||||
311
docs/em/docs/deployment/concepts.md
Normal file
311
docs/em/docs/deployment/concepts.md
Normal file
@@ -0,0 +1,311 @@
|
||||
# 🛠️ 🔧
|
||||
|
||||
🕐❔ 🛠️ **FastAPI** 🈸, ⚖️ 🤙, 🙆 🆎 🕸 🛠️, 📤 📚 🔧 👈 👆 🎲 💅 🔃, & ⚙️ 👫 👆 💪 🔎 **🏆 ☑** 🌌 **🛠️ 👆 🈸**.
|
||||
|
||||
⚠ 🔧:
|
||||
|
||||
* 💂♂ - 🇺🇸🔍
|
||||
* 🏃♂ 🔛 🕴
|
||||
* ⏏
|
||||
* 🧬 (🔢 🛠️ 🏃)
|
||||
* 💾
|
||||
* ⏮️ 🔁 ⏭ ▶️
|
||||
|
||||
👥 🔜 👀 ❔ 👫 🔜 📉 **🛠️**.
|
||||
|
||||
🔚, 🏆 🎯 💪 **🍦 👆 🛠️ 👩💻** 🌌 👈 **🔐**, **❎ 📉**, & ⚙️ **📊 ℹ** (🖼 🛰 💽/🕹 🎰) ♻ 💪. 👶
|
||||
|
||||
👤 🔜 💬 👆 🍖 🌖 🔃 👫 **🔧** 📥, & 👈 🔜 🤞 🤝 👆 **🤔** 👆 🔜 💪 💭 ❔ 🛠️ 👆 🛠️ 📶 🎏 🌐, 🎲 **🔮** 🕐 👈 🚫 🔀.
|
||||
|
||||
🤔 👫 🔧, 👆 🔜 💪 **🔬 & 🔧** 🏆 🌌 🛠️ **👆 👍 🔗**.
|
||||
|
||||
⏭ 📃, 👤 🔜 🤝 👆 🌅 **🧱 🍮** 🛠️ FastAPI 🈸.
|
||||
|
||||
✋️ 🔜, ➡️ ✅ 👉 ⚠ **⚛ 💭**. 👫 🔧 ✔ 🙆 🎏 🆎 🕸 🛠️. 👶
|
||||
|
||||
## 💂♂ - 🇺🇸🔍
|
||||
|
||||
[⏮️ 📃 🔃 🇺🇸🔍](./https.md){.internal-link target=_blank} 👥 🇭🇲 🔃 ❔ 🇺🇸🔍 🚚 🔐 👆 🛠️.
|
||||
|
||||
👥 👀 👈 🇺🇸🔍 🛎 🚚 🦲 **🔢** 👆 🈸 💽, **🤝 ❎ 🗳**.
|
||||
|
||||
& 📤 ✔️ 🕳 🈚 **♻ 🇺🇸🔍 📄**, ⚫️ 💪 🎏 🦲 ⚖️ ⚫️ 💪 🕳 🎏.
|
||||
|
||||
### 🖼 🧰 🇺🇸🔍
|
||||
|
||||
🧰 👆 💪 ⚙️ 🤝 ❎ 🗳:
|
||||
|
||||
* Traefik
|
||||
* 🔁 🍵 📄 🔕 👶
|
||||
* 📥
|
||||
* 🔁 🍵 📄 🔕 👶
|
||||
* 👌
|
||||
* ⏮️ 🔢 🦲 💖 Certbot 📄 🔕
|
||||
* ✳
|
||||
* ⏮️ 🔢 🦲 💖 Certbot 📄 🔕
|
||||
* Kubernete ⏮️ 🚧 🕹 💖 👌
|
||||
* ⏮️ 🔢 🦲 💖 🛂-👨💼 📄 🔕
|
||||
* 🍵 🔘 ☁ 🐕🦺 🍕 👫 🐕🦺 (✍ 🔛 👶)
|
||||
|
||||
➕1️⃣ 🎛 👈 👆 💪 ⚙️ **☁ 🐕🦺** 👈 🔨 🌖 👷 ✅ ⚒ 🆙 🇺🇸🔍. ⚫️ 💪 ✔️ 🚫 ⚖️ 🈚 👆 🌅, ♒️. ✋️ 👈 💼, 👆 🚫🔜 ✔️ ⚒ 🆙 🤝 ❎ 🗳 👆.
|
||||
|
||||
👤 🔜 🎦 👆 🧱 🖼 ⏭ 📃.
|
||||
|
||||
---
|
||||
|
||||
⤴️ ⏭ 🔧 🤔 🌐 🔃 📋 🏃 👆 ☑ 🛠️ (✅ Uvicorn).
|
||||
|
||||
## 📋 & 🛠️
|
||||
|
||||
👥 🔜 💬 📚 🔃 🏃 "**🛠️**", ⚫️ ⚠ ✔️ ☯ 🔃 ⚫️❔ ⚫️ ⛓, & ⚫️❔ 🔺 ⏮️ 🔤 "**📋**".
|
||||
|
||||
### ⚫️❔ 📋
|
||||
|
||||
🔤 **📋** 🛎 ⚙️ 🔬 📚 👜:
|
||||
|
||||
* **📟** 👈 👆 ✍, **🐍 📁**.
|
||||
* **📁** 👈 💪 **🛠️** 🏃♂ ⚙️, 🖼: `python`, `python.exe` ⚖️ `uvicorn`.
|
||||
* 🎯 📋 ⏪ ⚫️ **🏃♂** 🔛 🏗 ⚙️, ⚙️ 💽, & ♻ 👜 🔛 💾. 👉 🤙 **🛠️**.
|
||||
|
||||
### ⚫️❔ 🛠️
|
||||
|
||||
🔤 **🛠️** 🛎 ⚙️ 🌖 🎯 🌌, 🕴 🔗 👜 👈 🏃 🏃♂ ⚙️ (💖 🏁 ☝ 🔛):
|
||||
|
||||
* 🎯 📋 ⏪ ⚫️ **🏃♂** 🔛 🏃♂ ⚙️.
|
||||
* 👉 🚫 🔗 📁, 🚫 📟, ⚫️ 🔗 **🎯** 👜 👈 ➖ **🛠️** & 🔄 🏃♂ ⚙️.
|
||||
* 🙆 📋, 🙆 📟, **💪 🕴 👜** 🕐❔ ⚫️ ➖ **🛠️**. , 🕐❔ 📤 **🛠️ 🏃**.
|
||||
* 🛠️ 💪 **❎** (⚖️ "💥") 👆, ⚖️ 🏃♂ ⚙️. 👈 ☝, ⚫️ ⛔️ 🏃/➖ 🛠️, & ⚫️ 💪 **🙅♂ 📏 👜**.
|
||||
* 🔠 🈸 👈 👆 ✔️ 🏃 🔛 👆 💻 ✔️ 🛠️ ⛅ ⚫️, 🔠 🏃♂ 📋, 🔠 🚪, ♒️. & 📤 🛎 📚 🛠️ 🏃 **🎏 🕰** ⏪ 💻 🔛.
|
||||
* 📤 💪 **💗 🛠️** **🎏 📋** 🏃 🎏 🕰.
|
||||
|
||||
🚥 👆 ✅ 👅 "📋 👨💼" ⚖️ "⚙️ 🖥" (⚖️ 🎏 🧰) 👆 🏃♂ ⚙️, 👆 🔜 💪 👀 📚 👈 🛠️ 🏃♂.
|
||||
|
||||
& , 🖼, 👆 🔜 🎲 👀 👈 📤 💗 🛠️ 🏃 🎏 🖥 📋 (🦎, 💄, 📐, ♒️). 👫 🛎 🏃 1️⃣ 🛠️ 📍 📑, ➕ 🎏 ➕ 🛠️.
|
||||
|
||||
<img class="shadow" src="/img/deployment/concepts/image01.png">
|
||||
|
||||
---
|
||||
|
||||
🔜 👈 👥 💭 🔺 🖖 ⚖ **🛠️** & **📋**, ➡️ 😣 💬 🔃 🛠️.
|
||||
|
||||
## 🏃♂ 🔛 🕴
|
||||
|
||||
🌅 💼, 🕐❔ 👆 ✍ 🕸 🛠️, 👆 💚 ⚫️ **🕧 🏃♂**, ➡, 👈 👆 👩💻 💪 🕧 🔐 ⚫️. 👉 ↗️, 🚥 👆 ✔️ 🎯 🤔 ⚫️❔ 👆 💚 ⚫️ 🏃 🕴 🎯 ⚠, ✋️ 🌅 🕰 👆 💚 ⚫️ 🕧 🏃♂ & **💪**.
|
||||
|
||||
### 🛰 💽
|
||||
|
||||
🕐❔ 👆 ⚒ 🆙 🛰 💽 (☁ 💽, 🕹 🎰, ♒️.) 🙅 👜 👆 💪 🏃 Uvicorn (⚖️ 🎏) ❎, 🎏 🌌 👆 🕐❔ 🛠️ 🌐.
|
||||
|
||||
& ⚫️ 🔜 👷 & 🔜 ⚠ **⏮️ 🛠️**.
|
||||
|
||||
✋️ 🚥 👆 🔗 💽 💸, **🏃♂ 🛠️** 🔜 🎲 ☠️.
|
||||
|
||||
& 🚥 💽 ⏏ (🖼 ⏮️ ℹ, ⚖️ 🛠️ ⚪️➡️ ☁ 🐕🦺) 👆 🎲 **🏆 🚫 👀 ⚫️**. & ↩️ 👈, 👆 🏆 🚫 💭 👈 👆 ✔️ ⏏ 🛠️ ❎. , 👆 🛠️ 🔜 🚧 ☠️. 👶
|
||||
|
||||
### 🏃 🔁 🔛 🕴
|
||||
|
||||
🏢, 👆 🔜 🎲 💚 💽 📋 (✅ Uvicorn) ▶️ 🔁 🔛 💽 🕴, & 🍵 💪 🙆 **🗿 🏥**, ✔️ 🛠️ 🕧 🏃 ⏮️ 👆 🛠️ (✅ Uvicorn 🏃♂ 👆 FastAPI 📱).
|
||||
|
||||
### 🎏 📋
|
||||
|
||||
🏆 👉, 👆 🔜 🛎 ✔️ **🎏 📋** 👈 🔜 ⚒ 💭 👆 🈸 🏃 🔛 🕴. & 📚 💼, ⚫️ 🔜 ⚒ 💭 🎏 🦲 ⚖️ 🈸 🏃, 🖼, 💽.
|
||||
|
||||
### 🖼 🧰 🏃 🕴
|
||||
|
||||
🖼 🧰 👈 💪 👉 👨🏭:
|
||||
|
||||
* ☁
|
||||
* Kubernete
|
||||
* ☁ ✍
|
||||
* ☁ 🐝 📳
|
||||
* ✳
|
||||
* 👨💻
|
||||
* 🍵 🔘 ☁ 🐕🦺 🍕 👫 🐕🦺
|
||||
* 🎏...
|
||||
|
||||
👤 🔜 🤝 👆 🌅 🧱 🖼 ⏭ 📃.
|
||||
|
||||
## ⏏
|
||||
|
||||
🎏 ⚒ 💭 👆 🈸 🏃 🔛 🕴, 👆 🎲 💚 ⚒ 💭 ⚫️ **⏏** ⏮️ ❌.
|
||||
|
||||
### 👥 ⚒ ❌
|
||||
|
||||
👥, 🗿, ⚒ **❌**, 🌐 🕰. 🖥 🌖 *🕧* ✔️ **🐛** 🕵♂ 🎏 🥉. 👶
|
||||
|
||||
& 👥 👩💻 🚧 📉 📟 👥 🔎 👈 🐛 & 👥 🛠️ 🆕 ⚒ (🎲 ❎ 🆕 🐛 💁♂️ 👶).
|
||||
|
||||
### 🤪 ❌ 🔁 🍵
|
||||
|
||||
🕐❔ 🏗 🕸 🔗 ⏮️ FastAPI, 🚥 📤 ❌ 👆 📟, FastAPI 🔜 🛎 🔌 ⚫️ 👁 📨 👈 ⏲ ❌. 🛡
|
||||
|
||||
👩💻 🔜 🤚 **5️⃣0️⃣0️⃣ 🔗 💽 ❌** 👈 📨, ✋️ 🈸 🔜 😣 👷 ⏭ 📨 ↩️ 💥 🍕.
|
||||
|
||||
### 🦏 ❌ - 💥
|
||||
|
||||
👐, 📤 5️⃣📆 💼 🌐❔ 👥 ✍ 📟 👈 **💥 🎂 🈸** ⚒ Uvicorn & 🐍 💥. 👶
|
||||
|
||||
& , 👆 🔜 🎲 🚫 💚 🈸 🚧 ☠️ ↩️ 📤 ❌ 1️⃣ 🥉, 👆 🎲 💚 ⚫️ **😣 🏃** 🌘 *➡ 🛠️* 👈 🚫 💔.
|
||||
|
||||
### ⏏ ⏮️ 💥
|
||||
|
||||
✋️ 👈 💼 ⏮️ 🤙 👎 ❌ 👈 💥 🏃♂ **🛠️**, 👆 🔜 💚 🔢 🦲 👈 🈚 **🔁** 🛠️, 🌘 👩❤👨 🕰...
|
||||
|
||||
!!! tip
|
||||
...👐 🚥 🎂 🈸 **💥 ⏪** ⚫️ 🎲 🚫 ⚒ 🔑 🚧 🔁 ⚫️ ♾. ✋️ 📚 💼, 👆 🔜 🎲 👀 ⚫️ ⏮️ 🛠️, ⚖️ 🌘 ▶️️ ⏮️ 🛠️.
|
||||
|
||||
➡️ 🎯 🔛 👑 💼, 🌐❔ ⚫️ 💪 💥 🍕 🎯 💼 **🔮**, & ⚫️ ⚒ 🔑 ⏏ ⚫️.
|
||||
|
||||
👆 🔜 🎲 💚 ✔️ 👜 🈚 🔁 👆 🈸 **🔢 🦲**, ↩️ 👈 ☝, 🎏 🈸 ⏮️ Uvicorn & 🐍 ⏪ 💥, 📤 🕳 🎏 📟 🎏 📱 👈 💪 🕳 🔃 ⚫️.
|
||||
|
||||
### 🖼 🧰 ⏏ 🔁
|
||||
|
||||
🏆 💼, 🎏 🧰 👈 ⚙️ **🏃 📋 🔛 🕴** ⚙️ 🍵 🏧 **⏏**.
|
||||
|
||||
🖼, 👉 💪 🍵:
|
||||
|
||||
* ☁
|
||||
* Kubernete
|
||||
* ☁ ✍
|
||||
* ☁ 🐝 📳
|
||||
* ✳
|
||||
* 👨💻
|
||||
* 🍵 🔘 ☁ 🐕🦺 🍕 👫 🐕🦺
|
||||
* 🎏...
|
||||
|
||||
## 🧬 - 🛠️ & 💾
|
||||
|
||||
⏮️ FastAPI 🈸, ⚙️ 💽 📋 💖 Uvicorn, 🏃♂ ⚫️ 🕐 **1️⃣ 🛠️** 💪 🍦 💗 👩💻 🔁.
|
||||
|
||||
✋️ 📚 💼, 👆 🔜 💚 🏃 📚 👨🏭 🛠️ 🎏 🕰.
|
||||
|
||||
### 💗 🛠️ - 👨🏭
|
||||
|
||||
🚥 👆 ✔️ 🌅 👩💻 🌘 ⚫️❔ 👁 🛠️ 💪 🍵 (🖼 🚥 🕹 🎰 🚫 💁♂️ 🦏) & 👆 ✔️ **💗 🐚** 💽 💽, ⤴️ 👆 💪 ✔️ **💗 🛠️** 🏃♂ ⏮️ 🎏 🈸 🎏 🕰, & 📎 🌐 📨 👪 👫.
|
||||
|
||||
🕐❔ 👆 🏃 **💗 🛠️** 🎏 🛠️ 📋, 👫 🛎 🤙 **👨🏭**.
|
||||
|
||||
### 👨🏭 🛠️ & ⛴
|
||||
|
||||
💭 ⚪️➡️ 🩺 [🔃 🇺🇸🔍](./https.md){.internal-link target=_blank} 👈 🕴 1️⃣ 🛠️ 💪 👂 🔛 1️⃣ 🌀 ⛴ & 📢 📢 💽 ❓
|
||||
|
||||
👉 ☑.
|
||||
|
||||
, 💪 ✔️ **💗 🛠️** 🎏 🕰, 📤 ✔️ **👁 🛠️ 👂 🔛 ⛴** 👈 ⤴️ 📶 📻 🔠 👨🏭 🛠️ 🌌.
|
||||
|
||||
### 💾 📍 🛠️
|
||||
|
||||
🔜, 🕐❔ 📋 📐 👜 💾, 🖼, 🎰 🏫 🏷 🔢, ⚖️ 🎚 ⭕ 📁 🔢, 🌐 👈 **🍴 👄 💾 (💾)** 💽.
|
||||
|
||||
& 💗 🛠️ 🛎 **🚫 💰 🙆 💾**. 👉 ⛓ 👈 🔠 🏃 🛠️ ✔️ 🚮 👍 👜, 🔢, & 💾. & 🚥 👆 😩 ⭕ 💸 💾 👆 📟, **🔠 🛠️** 🔜 🍴 🌓 💸 💾.
|
||||
|
||||
### 💽 💾
|
||||
|
||||
🖼, 🚥 👆 📟 📐 🎰 🏫 🏷 ⏮️ **1️⃣ 💾 📐**, 🕐❔ 👆 🏃 1️⃣ 🛠️ ⏮️ 👆 🛠️, ⚫️ 🔜 🍴 🌘 1️⃣ 💾 💾. & 🚥 👆 ▶️ **4️⃣ 🛠️** (4️⃣ 👨🏭), 🔠 🔜 🍴 1️⃣ 💾 💾. 🌐, 👆 🛠️ 🔜 🍴 **4️⃣ 💾 💾**.
|
||||
|
||||
& 🚥 👆 🛰 💽 ⚖️ 🕹 🎰 🕴 ✔️ 3️⃣ 💾 💾, 🔄 📐 🌅 🌘 4️⃣ 💾 💾 🔜 🤕 ⚠. 👶
|
||||
|
||||
### 💗 🛠️ - 🖼
|
||||
|
||||
👉 🖼, 📤 **👨💼 🛠️** 👈 ▶️ & 🎛 2️⃣ **👨🏭 🛠️**.
|
||||
|
||||
👉 👨💼 🛠️ 🔜 🎲 1️⃣ 👂 🔛 **⛴** 📢. & ⚫️ 🔜 📶 🌐 📻 👨🏭 🛠️.
|
||||
|
||||
👈 👨🏭 🛠️ 🔜 🕐 🏃♂ 👆 🈸, 👫 🔜 🎭 👑 📊 📨 **📨** & 📨 **📨**, & 👫 🔜 📐 🕳 👆 🚮 🔢 💾.
|
||||
|
||||
<img src="/img/deployment/concepts/process-ram.svg">
|
||||
|
||||
& ↗️, 🎏 🎰 🔜 🎲 ✔️ **🎏 🛠️** 🏃 👍, ↖️ ⚪️➡️ 👆 🈸.
|
||||
|
||||
😌 ℹ 👈 🌐 **💽 ⚙️** 🔠 🛠️ 💪 **🪀** 📚 🤭 🕰, ✋️ **💾 (💾)** 🛎 🚧 🌖 ⚖️ 🌘 **⚖**.
|
||||
|
||||
🚥 👆 ✔️ 🛠️ 👈 🔨 ⭐ 💸 📊 🔠 🕰 & 👆 ✔️ 📚 👩💻, ⤴️ **💽 🛠️** 🔜 🎲 *⚖* (↩️ 🕧 🔜 🆙 & 🔽 🔜).
|
||||
|
||||
### 🖼 🧬 🧰 & 🎛
|
||||
|
||||
📤 💪 📚 🎯 🏆 👉, & 👤 🔜 💬 👆 🌅 🔃 🎯 🎛 ⏭ 📃, 🖼 🕐❔ 💬 🔃 ☁ & 📦.
|
||||
|
||||
👑 ⚛ 🤔 👈 📤 ✔️ **👁** 🦲 🚚 **⛴** **📢 📢**. & ⤴️ ⚫️ ✔️ ✔️ 🌌 **📶** 📻 🔁 **🛠️/👨🏭**.
|
||||
|
||||
📥 💪 🌀 & 🎛:
|
||||
|
||||
* **🐁** 🛠️ **Uvicorn 👨🏭**
|
||||
* 🐁 🔜 **🛠️ 👨💼** 👂 🔛 **📢** & **⛴**, 🧬 🔜 ✔️ **💗 Uvicorn 👨🏭 🛠️**
|
||||
* **Uvicorn** 🛠️ **Uvicorn 👨🏭**
|
||||
* 1️⃣ Uvicorn **🛠️ 👨💼** 🔜 👂 🔛 **📢** & **⛴**, & ⚫️ 🔜 ▶️ **💗 Uvicorn 👨🏭 🛠️**
|
||||
* **Kubernete** & 🎏 📎 **📦 ⚙️**
|
||||
* 🕳 **☁** 🧽 🔜 👂 🔛 **📢** & **⛴**. 🧬 🔜 ✔️ **💗 📦**, 🔠 ⏮️ **1️⃣ Uvicorn 🛠️** 🏃♂
|
||||
* **☁ 🐕🦺** 👈 🍵 👉 👆
|
||||
* ☁ 🐕🦺 🔜 🎲 **🍵 🧬 👆**. ⚫️ 🔜 🎲 ➡️ 👆 🔬 **🛠️ 🏃**, ⚖️ **📦 🖼** ⚙️, 🙆 💼, ⚫️ 🔜 🌅 🎲 **👁 Uvicorn 🛠️**, & ☁ 🐕🦺 🔜 🈚 🔁 ⚫️.
|
||||
|
||||
!!! tip
|
||||
🚫 😟 🚥 👫 🏬 🔃 **📦**, ☁, ⚖️ Kubernete 🚫 ⚒ 📚 🔑.
|
||||
|
||||
👤 🔜 💬 👆 🌅 🔃 📦 🖼, ☁, Kubernete, ♒️. 🔮 📃: [FastAPI 📦 - ☁](./docker.md){.internal-link target=_blank}.
|
||||
|
||||
## ⏮️ 🔁 ⏭ ▶️
|
||||
|
||||
📤 📚 💼 🌐❔ 👆 💚 🎭 📶 **⏭ ▶️** 👆 🈸.
|
||||
|
||||
🖼, 👆 💪 💚 🏃 **💽 🛠️**.
|
||||
|
||||
✋️ 🌅 💼, 👆 🔜 💚 🎭 👉 🔁 🕴 **🕐**.
|
||||
|
||||
, 👆 🔜 💚 ✔️ **👁 🛠️** 🎭 👈 **⏮️ 🔁**, ⏭ ▶️ 🈸.
|
||||
|
||||
& 👆 🔜 ✔️ ⚒ 💭 👈 ⚫️ 👁 🛠️ 🏃 👈 ⏮️ 🔁 ** 🚥 ⏮️, 👆 ▶️ **💗 🛠️** (💗 👨🏭) 🈸 ⚫️. 🚥 👈 🔁 🏃 **💗 🛠️**, 👫 🔜 **❎** 👷 🏃♂ ⚫️ 🔛 **🔗**, & 🚥 📶 🕳 💎 💖 💽 🛠️, 👫 💪 🤕 ⚔ ⏮️ 🔠 🎏.
|
||||
|
||||
↗️, 📤 💼 🌐❔ 📤 🙅♂ ⚠ 🏃 ⏮️ 🔁 💗 🕰, 👈 💼, ⚫️ 📚 ⏩ 🍵.
|
||||
|
||||
!!! tip
|
||||
, ✔️ 🤯 👈 ⚓️ 🔛 👆 🖥, 💼 👆 **5️⃣📆 🚫 💪 🙆 ⏮️ 🔁** ⏭ ▶️ 👆 🈸.
|
||||
|
||||
👈 💼, 👆 🚫🔜 ✔️ 😟 🔃 🙆 👉. 🤷
|
||||
|
||||
### 🖼 ⏮️ 🔁 🎛
|
||||
|
||||
👉 🔜 **🪀 🙇** 🔛 🌌 👆 **🛠️ 👆 ⚙️**, & ⚫️ 🔜 🎲 🔗 🌌 👆 ▶️ 📋, 🚚 ⏏, ♒️.
|
||||
|
||||
📥 💪 💭:
|
||||
|
||||
* "🕑 📦" Kubernete 👈 🏃 ⏭ 👆 📱 📦
|
||||
* 🎉 ✍ 👈 🏃 ⏮️ 🔁 & ⤴️ ▶️ 👆 🈸
|
||||
* 👆 🔜 💪 🌌 ▶️/⏏ *👈* 🎉 ✍, 🔍 ❌, ♒️.
|
||||
|
||||
!!! tip
|
||||
👤 🔜 🤝 👆 🌅 🧱 🖼 🔨 👉 ⏮️ 📦 🔮 📃: [FastAPI 📦 - ☁](./docker.md){.internal-link target=_blank}.
|
||||
|
||||
## ℹ 🛠️
|
||||
|
||||
👆 💽(Ⓜ) () **ℹ**, 👆 💪 🍴 ⚖️ **⚙️**, ⏮️ 👆 📋, 📊 🕰 🔛 💽, & 💾 💾 💪.
|
||||
|
||||
❔ 🌅 ⚙️ ℹ 👆 💚 😩/♻ ❓ ⚫️ 💪 ⏩ 💭 "🚫 🌅", ✋️ 🌌, 👆 🔜 🎲 💚 🍴 **🌅 💪 🍵 💥**.
|
||||
|
||||
🚥 👆 💸 3️⃣ 💽 ✋️ 👆 ⚙️ 🕴 🐥 🍖 👫 💾 & 💽, 👆 🎲 **🗑 💸** 👶, & 🎲 **🗑 💽 🔦 🏋️** 👶, ♒️.
|
||||
|
||||
👈 💼, ⚫️ 💪 👻 ✔️ 🕴 2️⃣ 💽 & ⚙️ ↕ 🌐 👫 ℹ (💽, 💾, 💾, 🕸 💿, ♒️).
|
||||
|
||||
🔛 🎏 ✋, 🚥 👆 ✔️ 2️⃣ 💽 & 👆 ⚙️ **1️⃣0️⃣0️⃣ 💯 👫 💽 & 💾**, ☝ 1️⃣ 🛠️ 🔜 💭 🌅 💾, & 💽 🔜 ✔️ ⚙️ 💾 "💾" (❔ 💪 💯 🕰 🐌), ⚖️ **💥**. ⚖️ 1️⃣ 🛠️ 💪 💪 📊 & 🔜 ✔️ ⌛ ⏭ 💽 🆓 🔄.
|
||||
|
||||
👉 💼, ⚫️ 🔜 👍 🤚 **1️⃣ ➕ 💽** & 🏃 🛠️ 🔛 ⚫️ 👈 👫 🌐 ✔️ **🥃 💾 & 💽 🕰**.
|
||||
|
||||
📤 🤞 👈 🤔 👆 ✔️ **🌵** ⚙️ 👆 🛠️. 🎲 ⚫️ 🚶 🦠, ⚖️ 🎲 🎏 🐕🦺 ⚖️ 🤖 ▶️ ⚙️ ⚫️. & 👆 💪 💚 ✔️ ➕ ℹ 🔒 👈 💼.
|
||||
|
||||
👆 💪 🚮 **❌ 🔢** 🎯, 🖼, 🕳 **🖖 5️⃣0️⃣ 💯 9️⃣0️⃣ 💯** ℹ 🛠️. ☝ 👈 📚 🎲 👑 👜 👆 🔜 💚 ⚖ & ⚙️ ⚒ 👆 🛠️.
|
||||
|
||||
👆 💪 ⚙️ 🙅 🧰 💖 `htop` 👀 💽 & 💾 ⚙️ 👆 💽 ⚖️ 💸 ⚙️ 🔠 🛠️. ⚖️ 👆 💪 ⚙️ 🌖 🏗 ⚖ 🧰, ❔ 5️⃣📆 📎 🤭 💽, ♒️.
|
||||
|
||||
## 🌃
|
||||
|
||||
👆 ✔️ 👂 📥 👑 🔧 👈 👆 🔜 🎲 💪 ✔️ 🤯 🕐❔ 🤔 ❔ 🛠️ 👆 🈸:
|
||||
|
||||
* 💂♂ - 🇺🇸🔍
|
||||
* 🏃♂ 🔛 🕴
|
||||
* ⏏
|
||||
* 🧬 (🔢 🛠️ 🏃)
|
||||
* 💾
|
||||
* ⏮️ 🔁 ⏭ ▶️
|
||||
|
||||
🤔 👉 💭 & ❔ ✔ 👫 🔜 🤝 👆 🤔 💪 ✊ 🙆 🚫 🕐❔ 🛠️ & 🛠️ 👆 🛠️. 👶
|
||||
|
||||
⏭ 📄, 👤 🔜 🤝 👆 🌅 🧱 🖼 💪 🎛 👆 💪 ⏩. 👶
|
||||
258
docs/em/docs/deployment/deta.md
Normal file
258
docs/em/docs/deployment/deta.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# 🛠️ FastAPI 🔛 🪔
|
||||
|
||||
👉 📄 👆 🔜 💡 ❔ 💪 🛠️ **FastAPI** 🈸 🔛 <a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">🪔</a> ⚙️ 🆓 📄. 👶
|
||||
|
||||
⚫️ 🔜 ✊ 👆 🔃 **1️⃣0️⃣ ⏲**.
|
||||
|
||||
!!! info
|
||||
<a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">🪔</a> **FastAPI** 💰. 👶
|
||||
|
||||
## 🔰 **FastAPI** 📱
|
||||
|
||||
* ✍ 📁 👆 📱, 🖼, `./fastapideta/` & ⛔ 🔘 ⚫️.
|
||||
|
||||
### FastAPI 📟
|
||||
|
||||
* ✍ `main.py` 📁 ⏮️:
|
||||
|
||||
```Python
|
||||
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):
|
||||
return {"item_id": item_id}
|
||||
```
|
||||
|
||||
### 📄
|
||||
|
||||
🔜, 🎏 📁 ✍ 📁 `requirements.txt` ⏮️:
|
||||
|
||||
```text
|
||||
fastapi
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👆 🚫 💪 ❎ Uvicorn 🛠️ 🔛 🪔, 👐 👆 🔜 🎲 💚 ❎ ⚫️ 🌐 💯 👆 📱.
|
||||
|
||||
### 📁 📊
|
||||
|
||||
👆 🔜 🔜 ✔️ 1️⃣ 📁 `./fastapideta/` ⏮️ 2️⃣ 📁:
|
||||
|
||||
```
|
||||
.
|
||||
└── main.py
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
## ✍ 🆓 🪔 🏧
|
||||
|
||||
🔜 ✍ <a href="https://www.deta.sh/?ref=fastapi" class="external-link" target="_blank">🆓 🏧 🔛 🪔</a>, 👆 💪 📧 & 🔐.
|
||||
|
||||
👆 🚫 💪 💳.
|
||||
|
||||
## ❎ ✳
|
||||
|
||||
🕐 👆 ✔️ 👆 🏧, ❎ 🪔 <abbr title="Command Line Interface application">✳</abbr>:
|
||||
|
||||
=== "💾, 🇸🇻"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ curl -fsSL https://get.deta.dev/cli.sh | sh
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
=== "🚪 📋"
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ iwr https://get.deta.dev/cli.ps1 -useb | iex
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
⏮️ ❎ ⚫️, 📂 🆕 📶 👈 ❎ ✳ 🔍.
|
||||
|
||||
🆕 📶, ✔ 👈 ⚫️ ☑ ❎ ⏮️:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta --help
|
||||
|
||||
Deta command line interface for managing deta micros.
|
||||
Complete documentation available at https://docs.deta.sh
|
||||
|
||||
Usage:
|
||||
deta [flags]
|
||||
deta [command]
|
||||
|
||||
Available Commands:
|
||||
auth Change auth settings for a deta micro
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! tip
|
||||
🚥 👆 ✔️ ⚠ ❎ ✳, ✅ <a href="https://docs.deta.sh/docs/micros/getting_started?ref=fastapi" class="external-link" target="_blank">🛂 🪔 🩺</a>.
|
||||
|
||||
## 💳 ⏮️ ✳
|
||||
|
||||
🔜 💳 🪔 ⚪️➡️ ✳ ⏮️:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta login
|
||||
|
||||
Please, log in from the web page. Waiting..
|
||||
Logged in successfully.
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
👉 🔜 📂 🕸 🖥 & 🔓 🔁.
|
||||
|
||||
## 🛠️ ⏮️ 🪔
|
||||
|
||||
⏭, 🛠️ 👆 🈸 ⏮️ 🪔 ✳:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta new
|
||||
|
||||
Successfully created a new micro
|
||||
|
||||
// Notice the "endpoint" 🔍
|
||||
|
||||
{
|
||||
"name": "fastapideta",
|
||||
"runtime": "python3.7",
|
||||
"endpoint": "https://qltnci.deta.dev",
|
||||
"visor": "enabled",
|
||||
"http_auth": "enabled"
|
||||
}
|
||||
|
||||
Adding dependencies...
|
||||
|
||||
|
||||
---> 100%
|
||||
|
||||
|
||||
Successfully installed fastapi-0.61.1 pydantic-1.7.2 starlette-0.13.6
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
👆 🔜 👀 🎻 📧 🎏:
|
||||
|
||||
```JSON hl_lines="4"
|
||||
{
|
||||
"name": "fastapideta",
|
||||
"runtime": "python3.7",
|
||||
"endpoint": "https://qltnci.deta.dev",
|
||||
"visor": "enabled",
|
||||
"http_auth": "enabled"
|
||||
}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
👆 🛠️ 🔜 ✔️ 🎏 `"endpoint"` 📛.
|
||||
|
||||
## ✅ ⚫️
|
||||
|
||||
🔜 📂 👆 🖥 👆 `endpoint` 📛. 🖼 🔛 ⚫️ `https://qltnci.deta.dev`, ✋️ 👆 🔜 🎏.
|
||||
|
||||
👆 🔜 👀 🎻 📨 ⚪️➡️ 👆 FastAPI 📱:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"Hello": "World"
|
||||
}
|
||||
```
|
||||
|
||||
& 🔜 🚶 `/docs` 👆 🛠️, 🖼 🔛 ⚫️ 🔜 `https://qltnci.deta.dev/docs`.
|
||||
|
||||
⚫️ 🔜 🎦 👆 🩺 💖:
|
||||
|
||||
<img src="/img/deployment/deta/image01.png">
|
||||
|
||||
## 🛠️ 📢 🔐
|
||||
|
||||
🔢, 🪔 🔜 🍵 🤝 ⚙️ 🍪 👆 🏧.
|
||||
|
||||
✋️ 🕐 👆 🔜, 👆 💪 ⚒ ⚫️ 📢 ⏮️:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ deta auth disable
|
||||
|
||||
Successfully disabled http auth
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
🔜 👆 💪 💰 👈 📛 ⏮️ 🙆 & 👫 🔜 💪 🔐 👆 🛠️. 👶
|
||||
|
||||
## 🇺🇸🔍
|
||||
|
||||
㊗ ❗ 👆 🛠️ 👆 FastAPI 📱 🪔 ❗ 👶 👶
|
||||
|
||||
, 👀 👈 🪔 ☑ 🍵 🇺🇸🔍 👆, 👆 🚫 ✔️ ✊ 💅 👈 & 💪 💭 👈 👆 👩💻 🔜 ✔️ 🔐 🗜 🔗. 👶 👶
|
||||
|
||||
## ✅ 🕶
|
||||
|
||||
⚪️➡️ 👆 🩺 🎚 (👫 🔜 📛 💖 `https://qltnci.deta.dev/docs`) 📨 📨 👆 *➡ 🛠️* `/items/{item_id}`.
|
||||
|
||||
🖼 ⏮️ 🆔 `5`.
|
||||
|
||||
🔜 🚶 <a href="https://web.deta.sh/" class="external-link" target="_blank">https://web.deta.sh</a>.
|
||||
|
||||
👆 🔜 👀 📤 📄 ◀️ 🤙 <abbr title="it comes from Micro(server)">"◾"</abbr> ⏮️ 🔠 👆 📱.
|
||||
|
||||
👆 🔜 👀 📑 ⏮️ "ℹ", & 📑 "🕶", 🚶 📑 "🕶".
|
||||
|
||||
📤 👆 💪 ✔ ⏮️ 📨 📨 👆 📱.
|
||||
|
||||
👆 💪 ✍ 👫 & 🏤-🤾 👫.
|
||||
|
||||
<img src="/img/deployment/deta/image02.png">
|
||||
|
||||
## 💡 🌅
|
||||
|
||||
☝, 👆 🔜 🎲 💚 🏪 💽 👆 📱 🌌 👈 😣 🔘 🕰. 👈 👆 💪 ⚙️ <a href="https://docs.deta.sh/docs/base/py_tutorial?ref=fastapi" class="external-link" target="_blank">🪔 🧢</a>, ⚫️ ✔️ 👍 **🆓 🎚**.
|
||||
|
||||
👆 💪 ✍ 🌅 <a href="https://docs.deta.sh?ref=fastapi" class="external-link" target="_blank">🪔 🩺</a>.
|
||||
|
||||
## 🛠️ 🔧
|
||||
|
||||
👟 🔙 🔧 👥 🔬 [🛠️ 🔧](./concepts.md){.internal-link target=_blank}, 📥 ❔ 🔠 👫 🔜 🍵 ⏮️ 🪔:
|
||||
|
||||
* **🇺🇸🔍**: 🍵 🪔, 👫 🔜 🤝 👆 📁 & 🍵 🇺🇸🔍 🔁.
|
||||
* **🏃♂ 🔛 🕴**: 🍵 🪔, 🍕 👫 🐕🦺.
|
||||
* **⏏**: 🍵 🪔, 🍕 👫 🐕🦺.
|
||||
* **🧬**: 🍵 🪔, 🍕 👫 🐕🦺.
|
||||
* **💾**: 📉 🔁 🪔, 👆 💪 📧 👫 📈 ⚫️.
|
||||
* **⏮️ 🔁 ⏭ ▶️**: 🚫 🔗 🐕🦺, 👆 💪 ⚒ ⚫️ 👷 ⏮️ 👫 💾 ⚙️ ⚖️ 🌖 ✍.
|
||||
|
||||
!!! note
|
||||
🪔 🔧 ⚒ ⚫️ ⏩ (& 🆓) 🛠️ 🙅 🈸 🔜.
|
||||
|
||||
⚫️ 💪 📉 📚 ⚙️ 💼, ✋️ 🎏 🕰, ⚫️ 🚫 🐕🦺 🎏, 💖 ⚙️ 🔢 💽 (↖️ ⚪️➡️ 🪔 👍 ☁ 💽 ⚙️), 🛃 🕹 🎰, ♒️.
|
||||
|
||||
👆 💪 ✍ 🌅 ℹ <a href="https://docs.deta.sh/docs/micros/about/" class="external-link" target="_blank">🪔 🩺</a> 👀 🚥 ⚫️ ▶️️ ⚒ 👆.
|
||||
698
docs/em/docs/deployment/docker.md
Normal file
698
docs/em/docs/deployment/docker.md
Normal file
@@ -0,0 +1,698 @@
|
||||
# FastAPI 📦 - ☁
|
||||
|
||||
🕐❔ 🛠️ FastAPI 🈸 ⚠ 🎯 🏗 **💾 📦 🖼**. ⚫️ 🛎 🔨 ⚙️ <a href="https://www.docker.com/" class="external-link" target="_blank">**☁**</a>. 👆 💪 ⤴️ 🛠️ 👈 📦 🖼 1️⃣ 👩❤👨 💪 🌌.
|
||||
|
||||
⚙️ 💾 📦 ✔️ 📚 📈 ✅ **💂♂**, **🔬**, **🦁**, & 🎏.
|
||||
|
||||
!!! tip
|
||||
🏃 & ⏪ 💭 👉 💩 ❓ 🦘 [`Dockerfile` 🔛 👶](#build-a-docker-image-for-fastapi).
|
||||
|
||||
<details>
|
||||
<summary>📁 🎮 👶</summary>
|
||||
|
||||
```Dockerfile
|
||||
FROM python:3.9
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
COPY ./requirements.txt /code/requirements.txt
|
||||
|
||||
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
||||
|
||||
COPY ./app /code/app
|
||||
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
|
||||
|
||||
# If running behind a proxy like Nginx or Traefik add --proxy-headers
|
||||
# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--proxy-headers"]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## ⚫️❔ 📦
|
||||
|
||||
📦 (✴️ 💾 📦) 📶 **💿** 🌌 📦 🈸 ✅ 🌐 👫 🔗 & 💪 📁 ⏪ 🚧 👫 ❎ ⚪️➡️ 🎏 📦 (🎏 🈸 ⚖️ 🦲) 🎏 ⚙️.
|
||||
|
||||
💾 📦 🏃 ⚙️ 🎏 💾 💾 🦠 (🎰, 🕹 🎰, ☁ 💽, ♒️). 👉 ⛓ 👈 👫 📶 💿 (🔬 🌕 🕹 🎰 👍 🎂 🏃♂ ⚙️).
|
||||
|
||||
👉 🌌, 📦 🍴 **🐥 ℹ**, 💸 ⭐ 🏃♂ 🛠️ 🔗 (🕹 🎰 🔜 🍴 🌅 🌅).
|
||||
|
||||
📦 ✔️ 👫 👍 **❎** 🏃♂ 🛠️ (🛎 1️⃣ 🛠️), 📁 ⚙️, & 🕸, 🔬 🛠️, 💂♂, 🛠️, ♒️.
|
||||
|
||||
## ⚫️❔ 📦 🖼
|
||||
|
||||
**📦** 🏃 ⚪️➡️ **📦 🖼**.
|
||||
|
||||
📦 🖼 **🎻** ⏬ 🌐 📁, 🌐 🔢, & 🔢 📋/📋 👈 🔜 🎁 📦. **🎻** 📥 ⛓ 👈 📦 **🖼** 🚫 🏃, ⚫️ 🚫 ➖ 🛠️, ⚫️ 🕴 📦 📁 & 🗃.
|
||||
|
||||
🔅 "**📦 🖼**" 👈 🏪 🎻 🎚,"**📦**" 🛎 🔗 🏃♂ 👐, 👜 👈 ➖ **🛠️**.
|
||||
|
||||
🕐❔ **📦** ▶️ & 🏃♂ (▶️ ⚪️➡️ **📦 🖼**) ⚫️ 💪 ✍ ⚖️ 🔀 📁, 🌐 🔢, ♒️. 👈 🔀 🔜 🔀 🕴 👈 📦, ✋️ 🔜 🚫 😣 👽 📦 🖼 (🔜 🚫 🖊 💾).
|
||||
|
||||
📦 🖼 ⭐ **📋** 📁 & 🎚, ✅ `python` & 📁 `main.py`.
|
||||
|
||||
& **📦** ⚫️ (🔅 **📦 🖼**) ☑ 🏃 👐 🖼, ⭐ **🛠️**. 👐, 📦 🏃 🕴 🕐❔ ⚫️ ✔️ **🛠️ 🏃** (& 🛎 ⚫️ 🕴 👁 🛠️). 📦 ⛔️ 🕐❔ 📤 🙅♂ 🛠️ 🏃 ⚫️.
|
||||
|
||||
## 📦 🖼
|
||||
|
||||
☁ ✔️ 1️⃣ 👑 🧰 ✍ & 🛠️ **📦 🖼** & **📦**.
|
||||
|
||||
& 📤 📢 <a href="https://hub.docker.com/" class="external-link" target="_blank">☁ 🎡</a> ⏮️ 🏤-⚒ **🛂 📦 🖼** 📚 🧰, 🌐, 💽, & 🈸.
|
||||
|
||||
🖼, 📤 🛂 <a href="https://hub.docker.com/_/python" class="external-link" target="_blank">🐍 🖼</a>.
|
||||
|
||||
& 📤 📚 🎏 🖼 🎏 👜 💖 💽, 🖼:
|
||||
|
||||
* <a href="https://hub.docker.com/_/postgres" class="external-link" target="_blank">✳</a>
|
||||
* <a href="https://hub.docker.com/_/mysql" class="external-link" target="_blank">✳</a>
|
||||
* <a href="https://hub.docker.com/_/mongo" class="external-link" target="_blank">✳</a>
|
||||
* <a href="https://hub.docker.com/_/redis" class="external-link" target="_blank">✳</a>, ♒️.
|
||||
|
||||
⚙️ 🏤-⚒ 📦 🖼 ⚫️ 📶 ⏩ **🌀** & ⚙️ 🎏 🧰. 🖼, 🔄 👅 🆕 💽. 🌅 💼, 👆 💪 ⚙️ **🛂 🖼**, & 🔗 👫 ⏮️ 🌐 🔢.
|
||||
|
||||
👈 🌌, 📚 💼 👆 💪 💡 🔃 📦 & ☁ & 🏤-⚙️ 👈 💡 ⏮️ 📚 🎏 🧰 & 🦲.
|
||||
|
||||
, 👆 🔜 🏃 **💗 📦** ⏮️ 🎏 👜, 💖 💽, 🐍 🈸, 🕸 💽 ⏮️ 😥 🕸 🈸, & 🔗 👫 👯♂️ 📨 👫 🔗 🕸.
|
||||
|
||||
🌐 📦 🧾 ⚙️ (💖 ☁ ⚖️ Kubernete) ✔️ 👫 🕸 ⚒ 🛠️ 🔘 👫.
|
||||
|
||||
## 📦 & 🛠️
|
||||
|
||||
**📦 🖼** 🛎 🔌 🚮 🗃 🔢 📋 ⚖️ 📋 👈 🔜 🏃 🕐❔ **📦** ▶️ & 🔢 🚶♀️ 👈 📋. 📶 🎏 ⚫️❔ 🔜 🚥 ⚫️ 📋 ⏸.
|
||||
|
||||
🕐❔ **📦** ▶️, ⚫️ 🔜 🏃 👈 📋/📋 (👐 👆 💪 🔐 ⚫️ & ⚒ ⚫️ 🏃 🎏 📋/📋).
|
||||
|
||||
📦 🏃 📏 **👑 🛠️** (📋 ⚖️ 📋) 🏃.
|
||||
|
||||
📦 🛎 ✔️ **👁 🛠️**, ✋️ ⚫️ 💪 ▶️ ✳ ⚪️➡️ 👑 🛠️, & 👈 🌌 👆 🔜 ✔️ **💗 🛠️** 🎏 📦.
|
||||
|
||||
✋️ ⚫️ 🚫 💪 ✔️ 🏃♂ 📦 🍵 **🌘 1️⃣ 🏃♂ 🛠️**. 🚥 👑 🛠️ ⛔️, 📦 ⛔️.
|
||||
|
||||
## 🏗 ☁ 🖼 FastAPI
|
||||
|
||||
🆗, ➡️ 🏗 🕳 🔜 ❗ 👶
|
||||
|
||||
👤 🔜 🎦 👆 ❔ 🏗 **☁ 🖼** FastAPI **⚪️➡️ 🖌**, ⚓️ 🔛 **🛂 🐍** 🖼.
|
||||
|
||||
👉 ⚫️❔ 👆 🔜 💚 **🏆 💼**, 🖼:
|
||||
|
||||
* ⚙️ **Kubernete** ⚖️ 🎏 🧰
|
||||
* 🕐❔ 🏃♂ 🔛 **🍓 👲**
|
||||
* ⚙️ ☁ 🐕🦺 👈 🔜 🏃 📦 🖼 👆, ♒️.
|
||||
|
||||
### 📦 📄
|
||||
|
||||
👆 🔜 🛎 ✔️ **📦 📄** 👆 🈸 📁.
|
||||
|
||||
⚫️ 🔜 🪀 ✴️ 🔛 🧰 👆 ⚙️ **❎** 👈 📄.
|
||||
|
||||
🌅 ⚠ 🌌 ⚫️ ✔️ 📁 `requirements.txt` ⏮️ 📦 📛 & 👫 ⏬, 1️⃣ 📍 ⏸.
|
||||
|
||||
👆 🔜 ↗️ ⚙️ 🎏 💭 👆 ✍ [🔃 FastAPI ⏬](./versions.md){.internal-link target=_blank} ⚒ ↔ ⏬.
|
||||
|
||||
🖼, 👆 `requirements.txt` 💪 👀 💖:
|
||||
|
||||
```
|
||||
fastapi>=0.68.0,<0.69.0
|
||||
pydantic>=1.8.0,<2.0.0
|
||||
uvicorn>=0.15.0,<0.16.0
|
||||
```
|
||||
|
||||
& 👆 🔜 🛎 ❎ 👈 📦 🔗 ⏮️ `pip`, 🖼:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ pip install -r requirements.txt
|
||||
---> 100%
|
||||
Successfully installed fastapi pydantic uvicorn
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! info
|
||||
📤 🎏 📁 & 🧰 🔬 & ❎ 📦 🔗.
|
||||
|
||||
👤 🔜 🎦 👆 🖼 ⚙️ 🎶 ⏪ 📄 🔛. 👶
|
||||
|
||||
### ✍ **FastAPI** 📟
|
||||
|
||||
* ✍ `app` 📁 & ⛔ ⚫️.
|
||||
* ✍ 🛁 📁 `__init__.py`.
|
||||
* ✍ `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}
|
||||
```
|
||||
|
||||
### 📁
|
||||
|
||||
🔜 🎏 🏗 📁 ✍ 📁 `Dockerfile` ⏮️:
|
||||
|
||||
```{ .dockerfile .annotate }
|
||||
# (1)
|
||||
FROM python:3.9
|
||||
|
||||
# (2)
|
||||
WORKDIR /code
|
||||
|
||||
# (3)
|
||||
COPY ./requirements.txt /code/requirements.txt
|
||||
|
||||
# (4)
|
||||
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
||||
|
||||
# (5)
|
||||
COPY ./app /code/app
|
||||
|
||||
# (6)
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
|
||||
```
|
||||
|
||||
1️⃣. ▶️ ⚪️➡️ 🛂 🐍 🧢 🖼.
|
||||
|
||||
2️⃣. ⚒ ⏮️ 👷 📁 `/code`.
|
||||
|
||||
👉 🌐❔ 👥 🔜 🚮 `requirements.txt` 📁 & `app` 📁.
|
||||
|
||||
3️⃣. 📁 📁 ⏮️ 📄 `/code` 📁.
|
||||
|
||||
📁 **🕴** 📁 ⏮️ 📄 🥇, 🚫 🎂 📟.
|
||||
|
||||
👉 📁 **🚫 🔀 🛎**, ☁ 🔜 🔍 ⚫️ & ⚙️ **💾** 👉 🔁, 🛠️ 💾 ⏭ 🔁 💁♂️.
|
||||
|
||||
4️⃣. ❎ 📦 🔗 📄 📁.
|
||||
|
||||
`--no-cache-dir` 🎛 💬 `pip` 🚫 🖊 ⏬ 📦 🌐, 👈 🕴 🚥 `pip` 🔜 🏃 🔄 ❎ 🎏 📦, ✋️ 👈 🚫 💼 🕐❔ 👷 ⏮️ 📦.
|
||||
|
||||
!!! note
|
||||
`--no-cache-dir` 🕴 🔗 `pip`, ⚫️ ✔️ 🕳 ⏮️ ☁ ⚖️ 📦.
|
||||
|
||||
`--upgrade` 🎛 💬 `pip` ♻ 📦 🚥 👫 ⏪ ❎.
|
||||
|
||||
↩️ ⏮️ 🔁 🖨 📁 💪 🔍 **☁ 💾**, 👉 🔁 🔜 **⚙️ ☁ 💾** 🕐❔ 💪.
|
||||
|
||||
⚙️ 💾 👉 🔁 🔜 **🖊** 👆 📚 **🕰** 🕐❔ 🏗 🖼 🔄 & 🔄 ⏮️ 🛠️, ↩️ **⏬ & ❎** 🌐 🔗 **🔠 🕰**.
|
||||
|
||||
5️⃣. 📁 `./app` 📁 🔘 `/code` 📁.
|
||||
|
||||
👉 ✔️ 🌐 📟 ❔ ⚫️❔ **🔀 🌅 🛎** ☁ **💾** 🏆 🚫 ⚙️ 👉 ⚖️ 🙆 **📄 🔁** 💪.
|
||||
|
||||
, ⚫️ ⚠ 🚮 👉 **🏘 🔚** `Dockerfile`, 🔬 📦 🖼 🏗 🕰.
|
||||
|
||||
6️⃣. ⚒ **📋** 🏃 `uvicorn` 💽.
|
||||
|
||||
`CMD` ✊ 📇 🎻, 🔠 👫 🎻 ⚫️❔ 👆 🔜 🆎 📋 ⏸ 👽 🚀.
|
||||
|
||||
👉 📋 🔜 🏃 ⚪️➡️ **⏮️ 👷 📁**, 🎏 `/code` 📁 👆 ⚒ 🔛 ⏮️ `WORKDIR /code`.
|
||||
|
||||
↩️ 📋 🔜 ▶️ `/code` & 🔘 ⚫️ 📁 `./app` ⏮️ 👆 📟, **Uvicorn** 🔜 💪 👀 & **🗄** `app` ⚪️➡️ `app.main`.
|
||||
|
||||
!!! tip
|
||||
📄 ⚫️❔ 🔠 ⏸ 🔨 🖊 🔠 🔢 💭 📟. 👶
|
||||
|
||||
👆 🔜 🔜 ✔️ 📁 📊 💖:
|
||||
|
||||
```
|
||||
.
|
||||
├── app
|
||||
│ ├── __init__.py
|
||||
│ └── main.py
|
||||
├── Dockerfile
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
#### ⛅ 🤝 ❎ 🗳
|
||||
|
||||
🚥 👆 🏃♂ 👆 📦 ⛅ 🤝 ❎ 🗳 (📐 ⚙) 💖 👌 ⚖️ Traefik, 🚮 🎛 `--proxy-headers`, 👉 🔜 💬 Uvicorn 💙 🎚 📨 👈 🗳 💬 ⚫️ 👈 🈸 🏃 ⛅ 🇺🇸🔍, ♒️.
|
||||
|
||||
```Dockerfile
|
||||
CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
|
||||
```
|
||||
|
||||
#### ☁ 💾
|
||||
|
||||
📤 ⚠ 🎱 👉 `Dockerfile`, 👥 🥇 📁 **📁 ⏮️ 🔗 😞**, 🚫 🎂 📟. ➡️ 👤 💬 👆 ⚫️❔ 👈.
|
||||
|
||||
```Dockerfile
|
||||
COPY ./requirements.txt /code/requirements.txt
|
||||
```
|
||||
|
||||
☁ & 🎏 🧰 **🏗** 👉 📦 🖼 **🔁**, 🚮 **1️⃣ 🧽 🔛 🔝 🎏**, ▶️ ⚪️➡️ 🔝 `Dockerfile` & ❎ 🙆 📁 ✍ 🔠 👩🌾 `Dockerfile`.
|
||||
|
||||
☁ & 🎏 🧰 ⚙️ **🔗 💾** 🕐❔ 🏗 🖼, 🚥 📁 🚫 🔀 ↩️ 🏁 🕰 🏗 📦 🖼, ⤴️ ⚫️ 🔜 **🏤-⚙️ 🎏 🧽** ✍ 🏁 🕰, ↩️ 🖨 📁 🔄 & 🏗 🆕 🧽 ⚪️➡️ 🖌.
|
||||
|
||||
❎ 📁 📁 🚫 🎯 📉 👜 💁♂️ 🌅, ✋️ ↩️ ⚫️ ⚙️ 💾 👈 🔁, ⚫️ 💪 **⚙️ 💾 ⏭ 🔁**. 🖼, ⚫️ 💪 ⚙️ 💾 👩🌾 👈 ❎ 🔗 ⏮️:
|
||||
|
||||
```Dockerfile
|
||||
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
||||
```
|
||||
|
||||
📁 ⏮️ 📦 📄 **🏆 🚫 🔀 🛎**. , 🖨 🕴 👈 📁, ☁ 🔜 💪 **⚙️ 💾** 👈 🔁.
|
||||
|
||||
& ⤴️, ☁ 🔜 💪 **⚙️ 💾 ⏭ 🔁** 👈 ⏬ & ❎ 👈 🔗. & 📥 🌐❔ 👥 **🖊 📚 🕰**. 👶 ...& ❎ 😩 ⌛. 👶 👶
|
||||
|
||||
⏬ & ❎ 📦 🔗 **💪 ✊ ⏲**, ✋️ ⚙️ **💾** 🔜 **✊ 🥈** 🌅.
|
||||
|
||||
& 👆 🔜 🏗 📦 🖼 🔄 & 🔄 ⏮️ 🛠️ ✅ 👈 👆 📟 🔀 👷, 📤 📚 📈 🕰 👉 🔜 🖊.
|
||||
|
||||
⤴️, 🏘 🔚 `Dockerfile`, 👥 📁 🌐 📟. 👉 ⚫️❔ **🔀 🏆 🛎**, 👥 🚮 ⚫️ 🏘 🔚, ↩️ 🌖 🕧, 🕳 ⏮️ 👉 🔁 🔜 🚫 💪 ⚙️ 💾.
|
||||
|
||||
```Dockerfile
|
||||
COPY ./app /code/app
|
||||
```
|
||||
|
||||
### 🏗 ☁ 🖼
|
||||
|
||||
🔜 👈 🌐 📁 🥉, ➡️ 🏗 📦 🖼.
|
||||
|
||||
* 🚶 🏗 📁 (🌐❔ 👆 `Dockerfile` , ⚗ 👆 `app` 📁).
|
||||
* 🏗 👆 FastAPI 🖼:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ docker build -t myimage .
|
||||
|
||||
---> 100%
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
!!! tip
|
||||
👀 `.` 🔚, ⚫️ 🌓 `./`, ⚫️ 💬 ☁ 📁 ⚙️ 🏗 📦 🖼.
|
||||
|
||||
👉 💼, ⚫️ 🎏 ⏮️ 📁 (`.`).
|
||||
|
||||
### ▶️ ☁ 📦
|
||||
|
||||
* 🏃 📦 ⚓️ 🔛 👆 🖼:
|
||||
|
||||
<div class="termy">
|
||||
|
||||
```console
|
||||
$ docker run -d --name mycontainer -p 80:80 myimage
|
||||
```
|
||||
|
||||
</div>
|
||||
|
||||
## ✅ ⚫️
|
||||
|
||||
👆 🔜 💪 ✅ ⚫️ 👆 ☁ 📦 📛, 🖼: <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> ⚖️ <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (⚖️ 🌓, ⚙️ 👆 ☁ 🦠).
|
||||
|
||||
👆 🔜 👀 🕳 💖:
|
||||
|
||||
```JSON
|
||||
{"item_id": 5, "q": "somequery"}
|
||||
```
|
||||
|
||||
## 🎓 🛠️ 🩺
|
||||
|
||||
🔜 👆 💪 🚶 <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> ⚖️ <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a> (⚖️ 🌓, ⚙️ 👆 ☁ 🦠).
|
||||
|
||||
👆 🔜 👀 🏧 🎓 🛠️ 🧾 (🚚 <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">🦁 🎚</a>):
|
||||
|
||||

|
||||
|
||||
## 🎛 🛠️ 🩺
|
||||
|
||||
& 👆 💪 🚶 <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> ⚖️ <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a> (⚖️ 🌓, ⚙️ 👆 ☁ 🦠).
|
||||
|
||||
👆 🔜 👀 🎛 🏧 🧾 (🚚 <a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">📄</a>):
|
||||
|
||||

|
||||
|
||||
## 🏗 ☁ 🖼 ⏮️ 👁-📁 FastAPI
|
||||
|
||||
🚥 👆 FastAPI 👁 📁, 🖼, `main.py` 🍵 `./app` 📁, 👆 📁 📊 💪 👀 💖 👉:
|
||||
|
||||
```
|
||||
.
|
||||
├── Dockerfile
|
||||
├── main.py
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
⤴️ 👆 🔜 ✔️ 🔀 🔗 ➡ 📁 📁 🔘 `Dockerfile`:
|
||||
|
||||
```{ .dockerfile .annotate hl_lines="10 13" }
|
||||
FROM python:3.9
|
||||
|
||||
WORKDIR /code
|
||||
|
||||
COPY ./requirements.txt /code/requirements.txt
|
||||
|
||||
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
||||
|
||||
# (1)
|
||||
COPY ./main.py /code/
|
||||
|
||||
# (2)
|
||||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
|
||||
```
|
||||
|
||||
1️⃣. 📁 `main.py` 📁 `/code` 📁 🔗 (🍵 🙆 `./app` 📁).
|
||||
|
||||
2️⃣. 🏃 Uvicorn & 💬 ⚫️ 🗄 `app` 🎚 ⚪️➡️ `main` (↩️ 🏭 ⚪️➡️ `app.main`).
|
||||
|
||||
⤴️ 🔆 Uvicorn 📋 ⚙️ 🆕 🕹 `main` ↩️ `app.main` 🗄 FastAPI 🎚 `app`.
|
||||
|
||||
## 🛠️ 🔧
|
||||
|
||||
➡️ 💬 🔄 🔃 🎏 [🛠️ 🔧](./concepts.md){.internal-link target=_blank} ⚖ 📦.
|
||||
|
||||
📦 ✴️ 🧰 📉 🛠️ **🏗 & 🛠️** 🈸, ✋️ 👫 🚫 🛠️ 🎯 🎯 🍵 👉 **🛠️ 🔧**, & 📤 📚 💪 🎛.
|
||||
|
||||
**👍 📰** 👈 ⏮️ 🔠 🎏 🎛 📤 🌌 📔 🌐 🛠️ 🔧. 👶
|
||||
|
||||
➡️ 📄 👉 **🛠️ 🔧** ⚖ 📦:
|
||||
|
||||
* 🇺🇸🔍
|
||||
* 🏃♂ 🔛 🕴
|
||||
* ⏏
|
||||
* 🧬 (🔢 🛠️ 🏃)
|
||||
* 💾
|
||||
* ⏮️ 🔁 ⏭ ▶️
|
||||
|
||||
## 🇺🇸🔍
|
||||
|
||||
🚥 👥 🎯 🔛 **📦 🖼** FastAPI 🈸 (& ⏪ 🏃♂ **📦**), 🇺🇸🔍 🛎 🔜 🍵 **🗜** ➕1️⃣ 🧰.
|
||||
|
||||
⚫️ 💪 ➕1️⃣ 📦, 🖼 ⏮️ <a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a>, 🚚 **🇺🇸🔍** & **🏧** 🛠️ **📄**.
|
||||
|
||||
!!! tip
|
||||
Traefik ✔️ 🛠️ ⏮️ ☁, Kubernete, & 🎏, ⚫️ 📶 ⏩ ⚒ 🆙 & 🔗 🇺🇸🔍 👆 📦 ⏮️ ⚫️.
|
||||
|
||||
👐, 🇺🇸🔍 💪 🍵 ☁ 🐕🦺 1️⃣ 👫 🐕🦺 (⏪ 🏃 🈸 📦).
|
||||
|
||||
## 🏃♂ 🔛 🕴 & ⏏
|
||||
|
||||
📤 🛎 ➕1️⃣ 🧰 🈚 **▶️ & 🏃♂** 👆 📦.
|
||||
|
||||
⚫️ 💪 **☁** 🔗, **☁ ✍**, **Kubernete**, **☁ 🐕🦺**, ♒️.
|
||||
|
||||
🌅 (⚖️ 🌐) 💼, 📤 🙅 🎛 🛠️ 🏃 📦 🔛 🕴 & 🛠️ ⏏ 🔛 ❌. 🖼, ☁, ⚫️ 📋 ⏸ 🎛 `--restart`.
|
||||
|
||||
🍵 ⚙️ 📦, ⚒ 🈸 🏃 🔛 🕴 & ⏮️ ⏏ 💪 ⚠ & ⚠. ✋️ 🕐❔ **👷 ⏮️ 📦** 🌅 💼 👈 🛠️ 🔌 🔢. 👶
|
||||
|
||||
## 🧬 - 🔢 🛠️
|
||||
|
||||
🚥 👆 ✔️ <abbr title="A group of machines that are configured to be connected and work together in some way.">🌑</abbr> 🎰 ⏮️ **☁**, ☁ 🐝 📳, 🖖, ⚖️ ➕1️⃣ 🎏 🏗 ⚙️ 🛠️ 📎 📦 🔛 💗 🎰, ⤴️ 👆 🔜 🎲 💚 **🍵 🧬** **🌑 🎚** ↩️ ⚙️ **🛠️ 👨💼** (💖 🐁 ⏮️ 👨🏭) 🔠 📦.
|
||||
|
||||
1️⃣ 📚 📎 📦 🧾 ⚙️ 💖 Kubernete 🛎 ✔️ 🛠️ 🌌 🚚 **🧬 📦** ⏪ 🔗 **📐 ⚖** 📨 📨. 🌐 **🌑 🎚**.
|
||||
|
||||
📚 💼, 👆 🔜 🎲 💚 🏗 **☁ 🖼 ⚪️➡️ 🖌** [🔬 🔛](#dockerfile), ❎ 👆 🔗, & 🏃♂ **👁 Uvicorn 🛠️** ↩️ 🏃♂ 🕳 💖 🐁 ⏮️ Uvicorn 👨🏭.
|
||||
|
||||
### 📐 ⚙
|
||||
|
||||
🕐❔ ⚙️ 📦, 👆 🔜 🛎 ✔️ 🦲 **👂 🔛 👑 ⛴**. ⚫️ 💪 🎲 ➕1️⃣ 📦 👈 **🤝 ❎ 🗳** 🍵 **🇺🇸🔍** ⚖️ 🎏 🧰.
|
||||
|
||||
👉 🦲 🔜 ✊ **📐** 📨 & 📎 👈 👪 👨🏭 (🤞) **⚖** 🌌, ⚫️ 🛎 🤙 **📐 ⚙**.
|
||||
|
||||
!!! tip
|
||||
🎏 **🤝 ❎ 🗳** 🦲 ⚙️ 🇺🇸🔍 🔜 🎲 **📐 ⚙**.
|
||||
|
||||
& 🕐❔ 👷 ⏮️ 📦, 🎏 ⚙️ 👆 ⚙️ ▶️ & 🛠️ 👫 🔜 ⏪ ✔️ 🔗 🧰 📶 **🕸 📻** (✅ 🇺🇸🔍 📨) ⚪️➡️ 👈 **📐 ⚙** (👈 💪 **🤝 ❎ 🗳**) 📦(Ⓜ) ⏮️ 👆 📱.
|
||||
|
||||
### 1️⃣ 📐 ⚙ - 💗 👨🏭 📦
|
||||
|
||||
🕐❔ 👷 ⏮️ **Kubernete** ⚖️ 🎏 📎 📦 🧾 ⚙️, ⚙️ 👫 🔗 🕸 🛠️ 🔜 ✔ 👁 **📐 ⚙** 👈 👂 🔛 👑 **⛴** 📶 📻 (📨) 🎲 **💗 📦** 🏃 👆 📱.
|
||||
|
||||
🔠 👫 📦 🏃♂ 👆 📱 🔜 🛎 ✔️ **1️⃣ 🛠️** (✅ Uvicorn 🛠️ 🏃 👆 FastAPI 🈸). 👫 🔜 🌐 **🌓 📦**, 🏃♂ 🎏 👜, ✋️ 🔠 ⏮️ 🚮 👍 🛠️, 💾, ♒️. 👈 🌌 👆 🔜 ✊ 📈 **🛠️** **🎏 🐚** 💽, ⚖️ **🎏 🎰**.
|
||||
|
||||
& 📎 📦 ⚙️ ⏮️ **📐 ⚙** 🔜 **📎 📨** 🔠 1️⃣ 📦 ⏮️ 👆 📱 **🔄**. , 🔠 📨 💪 🍵 1️⃣ 💗 **🔁 📦** 🏃 👆 📱.
|
||||
|
||||
& 🛎 👉 **📐 ⚙** 🔜 💪 🍵 📨 👈 🚶 *🎏* 📱 👆 🌑 (✅ 🎏 🆔, ⚖️ 🔽 🎏 📛 ➡ 🔡), & 🔜 📶 👈 📻 ▶️️ 📦 *👈 🎏* 🈸 🏃♂ 👆 🌑.
|
||||
|
||||
### 1️⃣ 🛠️ 📍 📦
|
||||
|
||||
👉 🆎 😐, 👆 🎲 🔜 💚 ✔️ **👁 (Uvicorn) 🛠️ 📍 📦**, 👆 🔜 ⏪ 🚚 🧬 🌑 🎚.
|
||||
|
||||
, 👉 💼, 👆 **🔜 🚫** 💚 ✔️ 🛠️ 👨💼 💖 🐁 ⏮️ Uvicorn 👨🏭, ⚖️ Uvicorn ⚙️ 🚮 👍 Uvicorn 👨🏭. 👆 🔜 💚 ✔️ **👁 Uvicorn 🛠️** 📍 📦 (✋️ 🎲 💗 📦).
|
||||
|
||||
✔️ ➕1️⃣ 🛠️ 👨💼 🔘 📦 (🔜 ⏮️ 🐁 ⚖️ Uvicorn 🛠️ Uvicorn 👨🏭) 🔜 🕴 🚮 **🙃 🔀** 👈 👆 🌅 🎲 ⏪ ✊ 💅 ⏮️ 👆 🌑 ⚙️.
|
||||
|
||||
### 📦 ⏮️ 💗 🛠️ & 🎁 💼
|
||||
|
||||
↗️, 📤 **🎁 💼** 🌐❔ 👆 💪 💚 ✔️ **📦** ⏮️ **🐁 🛠️ 👨💼** ▶️ 📚 **Uvicorn 👨🏭 🛠️** 🔘.
|
||||
|
||||
📚 💼, 👆 💪 ⚙️ **🛂 ☁ 🖼** 👈 🔌 **🐁** 🛠️ 👨💼 🏃♂ 💗 **Uvicorn 👨🏭 🛠️**, & 🔢 ⚒ 🔆 🔢 👨🏭 ⚓️ 🔛 ⏮️ 💽 🐚 🔁. 👤 🔜 💬 👆 🌅 🔃 ⚫️ 🔛 [🛂 ☁ 🖼 ⏮️ 🐁 - Uvicorn](#official-docker-image-with-gunicorn-uvicorn).
|
||||
|
||||
📥 🖼 🕐❔ 👈 💪 ⚒ 🔑:
|
||||
|
||||
#### 🙅 📱
|
||||
|
||||
👆 💪 💚 🛠️ 👨💼 📦 🚥 👆 🈸 **🙅 🥃** 👈 👆 🚫 💪 (🐥 🚫) 👌-🎶 🔢 🛠️ 💁♂️ 🌅, & 👆 💪 ⚙️ 🏧 🔢 (⏮️ 🛂 ☁ 🖼), & 👆 🏃♂ ⚫️ 🔛 **👁 💽**, 🚫 🌑.
|
||||
|
||||
#### ☁ ✍
|
||||
|
||||
👆 💪 🛠️ **👁 💽** (🚫 🌑) ⏮️ **☁ ✍**, 👆 🚫🔜 ✔️ ⏩ 🌌 🛠️ 🧬 📦 (⏮️ ☁ ✍) ⏪ 🛡 🔗 🕸 & **📐 ⚖**.
|
||||
|
||||
⤴️ 👆 💪 💚 ✔️ **👁 📦** ⏮️ **🛠️ 👨💼** ▶️ **📚 👨🏭 🛠️** 🔘.
|
||||
|
||||
#### 🤴 & 🎏 🤔
|
||||
|
||||
👆 💪 ✔️ **🎏 🤔** 👈 🔜 ⚒ ⚫️ ⏩ ✔️ **👁 📦** ⏮️ **💗 🛠️** ↩️ ✔️ **💗 📦** ⏮️ **👁 🛠️** 🔠 👫.
|
||||
|
||||
🖼 (🪀 🔛 👆 🖥) 👆 💪 ✔️ 🧰 💖 🤴 🏭 🎏 📦 👈 🔜 ✔️ 🔐 **🔠 📨** 👈 👟.
|
||||
|
||||
👉 💼, 🚥 👆 ✔️ **💗 📦**, 🔢, 🕐❔ 🤴 👟 **✍ ⚖**, ⚫️ 🔜 🤚 🕐 **👁 📦 🔠 🕰** (📦 👈 🍵 👈 🎯 📨), ↩️ 🤚 **📈 ⚖** 🌐 🔁 📦.
|
||||
|
||||
⤴️, 👈 💼, ⚫️ 💪 🙅 ✔️ **1️⃣ 📦** ⏮️ **💗 🛠️**, & 🇧🇿 🧰 (✅ 🤴 🏭) 🔛 🎏 📦 📈 🤴 ⚖ 🌐 🔗 🛠️ & 🎦 👈 ⚖ 🔛 👈 👁 📦.
|
||||
|
||||
---
|
||||
|
||||
👑 ☝, **👌** 👉 **🚫 ✍ 🗿** 👈 👆 ✔️ 😄 ⏩. 👆 💪 ⚙️ 👫 💭 **🔬 👆 👍 ⚙️ 💼** & 💭 ⚫️❔ 👍 🎯 👆 ⚙️, ✅ 👅 ❔ 🛠️ 🔧:
|
||||
|
||||
* 💂♂ - 🇺🇸🔍
|
||||
* 🏃♂ 🔛 🕴
|
||||
* ⏏
|
||||
* 🧬 (🔢 🛠️ 🏃)
|
||||
* 💾
|
||||
* ⏮️ 🔁 ⏭ ▶️
|
||||
|
||||
## 💾
|
||||
|
||||
🚥 👆 🏃 **👁 🛠️ 📍 📦** 👆 🔜 ✔️ 🌅 ⚖️ 🌘 👍-🔬, ⚖, & 📉 💸 💾 🍴 🔠 👈 📦 (🌅 🌘 1️⃣ 🚥 👫 🔁).
|
||||
|
||||
& ⤴️ 👆 💪 ⚒ 👈 🎏 💾 📉 & 📄 👆 📳 👆 📦 🧾 ⚙️ (🖼 **Kubernete**). 👈 🌌 ⚫️ 🔜 💪 **🔁 📦** **💪 🎰** ✊ 🔘 🏧 💸 💾 💪 👫, & 💸 💪 🎰 🌑.
|
||||
|
||||
🚥 👆 🈸 **🙅**, 👉 🔜 🎲 **🚫 ⚠**, & 👆 💪 🚫 💪 ✔ 🏋️ 💾 📉. ✋️ 🚥 👆 **⚙️ 📚 💾** (🖼 ⏮️ **🎰 🏫** 🏷), 👆 🔜 ✅ ❔ 🌅 💾 👆 😩 & 🔆 **🔢 📦** 👈 🏃 **🔠 🎰** (& 🎲 🚮 🌖 🎰 👆 🌑).
|
||||
|
||||
🚥 👆 🏃 **💗 🛠️ 📍 📦** (🖼 ⏮️ 🛂 ☁ 🖼) 👆 🔜 ✔️ ⚒ 💭 👈 🔢 🛠️ ▶️ 🚫 **🍴 🌖 💾** 🌘 ⚫️❔ 💪.
|
||||
|
||||
## ⏮️ 🔁 ⏭ ▶️ & 📦
|
||||
|
||||
🚥 👆 ⚙️ 📦 (✅ ☁, Kubernete), ⤴️ 📤 2️⃣ 👑 🎯 👆 💪 ⚙️.
|
||||
|
||||
### 💗 📦
|
||||
|
||||
🚥 👆 ✔️ **💗 📦**, 🎲 🔠 1️⃣ 🏃 **👁 🛠️** (🖼, **Kubernete** 🌑), ⤴️ 👆 🔜 🎲 💚 ✔️ **🎏 📦** 🔨 👷 **⏮️ 📶** 👁 📦, 🏃 👁 🛠️, **⏭** 🏃 🔁 👨🏭 📦.
|
||||
|
||||
!!! info
|
||||
🚥 👆 ⚙️ Kubernete, 👉 🔜 🎲 <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" class="external-link" target="_blank">🕑 📦</a>.
|
||||
|
||||
🚥 👆 ⚙️ 💼 📤 🙅♂ ⚠ 🏃♂ 👈 ⏮️ 📶 **💗 🕰 🔗** (🖼 🚥 👆 🚫 🏃 💽 🛠️, ✋️ ✅ 🚥 💽 🔜), ⤴️ 👆 💪 🚮 👫 🔠 📦 ▶️️ ⏭ ▶️ 👑 🛠️.
|
||||
|
||||
### 👁 📦
|
||||
|
||||
🚥 👆 ✔️ 🙅 🖥, ⏮️ **👁 📦** 👈 ⤴️ ▶️ 💗 **👨🏭 🛠️** (⚖️ 1️⃣ 🛠️), ⤴️ 👆 💪 🏃 👈 ⏮️ 🔁 🎏 📦, ▶️️ ⏭ ▶️ 🛠️ ⏮️ 📱. 🛂 ☁ 🖼 🐕🦺 👉 🔘.
|
||||
|
||||
## 🛂 ☁ 🖼 ⏮️ 🐁 - Uvicorn
|
||||
|
||||
📤 🛂 ☁ 🖼 👈 🔌 🐁 🏃♂ ⏮️ Uvicorn 👨🏭, ℹ ⏮️ 📃: [💽 👨🏭 - 🐁 ⏮️ Uvicorn](./server-workers.md){.internal-link target=_blank}.
|
||||
|
||||
👉 🖼 🔜 ⚠ ✴️ ⚠ 🔬 🔛: [📦 ⏮️ 💗 🛠️ & 🎁 💼](#containers-with-multiple-processes-and-special-cases).
|
||||
|
||||
* <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-🐁-fastapi</a>.
|
||||
|
||||
!!! warning
|
||||
📤 ↕ 🤞 👈 👆 **🚫** 💪 👉 🧢 🖼 ⚖️ 🙆 🎏 🎏 1️⃣, & 🔜 👻 📆 🏗 🖼 ⚪️➡️ 🖌 [🔬 🔛: 🏗 ☁ 🖼 FastAPI](#build-a-docker-image-for-fastapi).
|
||||
|
||||
👉 🖼 ✔️ **🚘-📳** 🛠️ 🔌 ⚒ **🔢 👨🏭 🛠️** ⚓️ 🔛 💽 🐚 💪.
|
||||
|
||||
⚫️ ✔️ **🤔 🔢**, ✋️ 👆 💪 🔀 & ℹ 🌐 📳 ⏮️ **🌐 🔢** ⚖️ 📳 📁.
|
||||
|
||||
⚫️ 🐕🦺 🏃 <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker#pre_start_path" class="external-link" target="_blank">**⏮️ 🔁 ⏭ ▶️**</a> ⏮️ ✍.
|
||||
|
||||
!!! tip
|
||||
👀 🌐 📳 & 🎛, 🚶 ☁ 🖼 📃: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">Tiangolo/uvicorn-🐁-fastapi</a>.
|
||||
|
||||
### 🔢 🛠️ 🔛 🛂 ☁ 🖼
|
||||
|
||||
**🔢 🛠️** 🔛 👉 🖼 **📊 🔁** ⚪️➡️ 💽 **🐚** 💪.
|
||||
|
||||
👉 ⛓ 👈 ⚫️ 🔜 🔄 **🗜** 🌅 **🎭** ⚪️➡️ 💽 💪.
|
||||
|
||||
👆 💪 🔆 ⚫️ ⏮️ 📳 ⚙️ **🌐 🔢**, ♒️.
|
||||
|
||||
✋️ ⚫️ ⛓ 👈 🔢 🛠️ 🪀 🔛 💽 📦 🏃, **💸 💾 🍴** 🔜 🪀 🔛 👈.
|
||||
|
||||
, 🚥 👆 🈸 🍴 📚 💾 (🖼 ⏮️ 🎰 🏫 🏷), & 👆 💽 ✔️ 📚 💽 🐚 **✋️ 🐥 💾**, ⤴️ 👆 📦 💪 🔚 🆙 🔄 ⚙️ 🌅 💾 🌘 ⚫️❔ 💪, & 🤕 🎭 📚 (⚖️ 💥). 👶
|
||||
|
||||
### ✍ `Dockerfile`
|
||||
|
||||
📥 ❔ 👆 🔜 ✍ `Dockerfile` ⚓️ 🔛 👉 🖼:
|
||||
|
||||
```Dockerfile
|
||||
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
|
||||
|
||||
COPY ./requirements.txt /app/requirements.txt
|
||||
|
||||
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
|
||||
|
||||
COPY ./app /app
|
||||
```
|
||||
|
||||
### 🦏 🈸
|
||||
|
||||
🚥 👆 ⏩ 📄 🔃 🏗 [🦏 🈸 ⏮️ 💗 📁](../tutorial/bigger-applications.md){.internal-link target=_blank}, 👆 `Dockerfile` 💪 ↩️ 👀 💖:
|
||||
|
||||
```Dockerfile hl_lines="7"
|
||||
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
|
||||
|
||||
COPY ./requirements.txt /app/requirements.txt
|
||||
|
||||
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
|
||||
|
||||
COPY ./app /app/app
|
||||
```
|
||||
|
||||
### 🕐❔ ⚙️
|
||||
|
||||
👆 🔜 🎲 **🚫** ⚙️ 👉 🛂 🧢 🖼 (⚖️ 🙆 🎏 🎏 1️⃣) 🚥 👆 ⚙️ **Kubernete** (⚖️ 🎏) & 👆 ⏪ ⚒ **🧬** 🌑 🎚, ⏮️ 💗 **📦**. 📚 💼, 👆 👍 📆 **🏗 🖼 ⚪️➡️ 🖌** 🔬 🔛: [🏗 ☁ 🖼 FastAPI](#build-a-docker-image-for-fastapi).
|
||||
|
||||
👉 🖼 🔜 ⚠ ✴️ 🎁 💼 🔬 🔛 [📦 ⏮️ 💗 🛠️ & 🎁 💼](#containers-with-multiple-processes-and-special-cases). 🖼, 🚥 👆 🈸 **🙅 🥃** 👈 ⚒ 🔢 🔢 🛠️ ⚓️ 🔛 💽 👷 👍, 👆 🚫 💚 😥 ⏮️ ❎ 🛠️ 🧬 🌑 🎚, & 👆 🚫 🏃 🌅 🌘 1️⃣ 📦 ⏮️ 👆 📱. ⚖️ 🚥 👆 🛠️ ⏮️ **☁ ✍**, 🏃 🔛 👁 💽, ♒️.
|
||||
|
||||
## 🛠️ 📦 🖼
|
||||
|
||||
⏮️ ✔️ 📦 (☁) 🖼 📤 📚 🌌 🛠️ ⚫️.
|
||||
|
||||
🖼:
|
||||
|
||||
* ⏮️ **☁ ✍** 👁 💽
|
||||
* ⏮️ **Kubernete** 🌑
|
||||
* ⏮️ ☁ 🐝 📳 🌑
|
||||
* ⏮️ ➕1️⃣ 🧰 💖 🖖
|
||||
* ⏮️ ☁ 🐕🦺 👈 ✊ 👆 📦 🖼 & 🛠️ ⚫️
|
||||
|
||||
## ☁ 🖼 ⏮️ 🎶
|
||||
|
||||
🚥 👆 ⚙️ <a href="https://python-poetry.org/" class="external-link" target="_blank">🎶</a> 🛠️ 👆 🏗 🔗, 👆 💪 ⚙️ ☁ 👁-▶️ 🏗:
|
||||
|
||||
```{ .dockerfile .annotate }
|
||||
# (1)
|
||||
FROM python:3.9 as requirements-stage
|
||||
|
||||
# (2)
|
||||
WORKDIR /tmp
|
||||
|
||||
# (3)
|
||||
RUN pip install poetry
|
||||
|
||||
# (4)
|
||||
COPY ./pyproject.toml ./poetry.lock* /tmp/
|
||||
|
||||
# (5)
|
||||
RUN poetry export -f requirements.txt --output requirements.txt --without-hashes
|
||||
|
||||
# (6)
|
||||
FROM python:3.9
|
||||
|
||||
# (7)
|
||||
WORKDIR /code
|
||||
|
||||
# (8)
|
||||
COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt
|
||||
|
||||
# (9)
|
||||
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
||||
|
||||
# (10)
|
||||
COPY ./app /code/app
|
||||
|
||||
# (11)
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
|
||||
```
|
||||
|
||||
1️⃣. 👉 🥇 ▶️, ⚫️ 🌟 `requirements-stage`.
|
||||
|
||||
2️⃣. ⚒ `/tmp` ⏮️ 👷 📁.
|
||||
|
||||
📥 🌐❔ 👥 🔜 🏗 📁 `requirements.txt`
|
||||
|
||||
3️⃣. ❎ 🎶 👉 ☁ ▶️.
|
||||
|
||||
4️⃣. 📁 `pyproject.toml` & `poetry.lock` 📁 `/tmp` 📁.
|
||||
|
||||
↩️ ⚫️ ⚙️ `./poetry.lock*` (▶️ ⏮️ `*`), ⚫️ 🏆 🚫 💥 🚥 👈 📁 🚫 💪.
|
||||
|
||||
5️⃣. 🏗 `requirements.txt` 📁.
|
||||
|
||||
6️⃣. 👉 🏁 ▶️, 🕳 📥 🔜 🛡 🏁 📦 🖼.
|
||||
|
||||
7️⃣. ⚒ ⏮️ 👷 📁 `/code`.
|
||||
|
||||
8️⃣. 📁 `requirements.txt` 📁 `/code` 📁.
|
||||
|
||||
👉 📁 🕴 🖖 ⏮️ ☁ ▶️, 👈 ⚫️❔ 👥 ⚙️ `--from-requirements-stage` 📁 ⚫️.
|
||||
|
||||
9️⃣. ❎ 📦 🔗 🏗 `requirements.txt` 📁.
|
||||
|
||||
1️⃣0️⃣. 📁 `app` 📁 `/code` 📁.
|
||||
|
||||
1️⃣1️⃣. 🏃 `uvicorn` 📋, 💬 ⚫️ ⚙️ `app` 🎚 🗄 ⚪️➡️ `app.main`.
|
||||
|
||||
!!! tip
|
||||
🖊 💭 🔢 👀 ⚫️❔ 🔠 ⏸ 🔨.
|
||||
|
||||
**☁ ▶️** 🍕 `Dockerfile` 👈 👷 **🍕 📦 🖼** 👈 🕴 ⚙️ 🏗 📁 ⚙️ ⏪.
|
||||
|
||||
🥇 ▶️ 🔜 🕴 ⚙️ **❎ 🎶** & **🏗 `requirements.txt`** ⏮️ 👆 🏗 🔗 ⚪️➡️ 🎶 `pyproject.toml` 📁.
|
||||
|
||||
👉 `requirements.txt` 📁 🔜 ⚙️ ⏮️ `pip` ⏪ **⏭ ▶️**.
|
||||
|
||||
🏁 📦 🖼 **🕴 🏁 ▶️** 🛡. ⏮️ ▶️(Ⓜ) 🔜 ❎.
|
||||
|
||||
🕐❔ ⚙️ 🎶, ⚫️ 🔜 ⚒ 🔑 ⚙️ **☁ 👁-▶️ 🏗** ↩️ 👆 🚫 🤙 💪 ✔️ 🎶 & 🚮 🔗 ❎ 🏁 📦 🖼, 👆 **🕴 💪** ✔️ 🏗 `requirements.txt` 📁 ❎ 👆 🏗 🔗.
|
||||
|
||||
⤴️ ⏭ (& 🏁) ▶️ 👆 🔜 🏗 🖼 🌅 ⚖️ 🌘 🎏 🌌 🔬 ⏭.
|
||||
|
||||
### ⛅ 🤝 ❎ 🗳 - 🎶
|
||||
|
||||
🔄, 🚥 👆 🏃♂ 👆 📦 ⛅ 🤝 ❎ 🗳 (📐 ⚙) 💖 👌 ⚖️ Traefik, 🚮 🎛 `--proxy-headers` 📋:
|
||||
|
||||
```Dockerfile
|
||||
CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
|
||||
```
|
||||
|
||||
## 🌃
|
||||
|
||||
⚙️ 📦 ⚙️ (✅ ⏮️ **☁** & **Kubernete**) ⚫️ ▶️️ 📶 🎯 🍵 🌐 **🛠️ 🔧**:
|
||||
|
||||
* 🇺🇸🔍
|
||||
* 🏃♂ 🔛 🕴
|
||||
* ⏏
|
||||
* 🧬 (🔢 🛠️ 🏃)
|
||||
* 💾
|
||||
* ⏮️ 🔁 ⏭ ▶️
|
||||
|
||||
🌅 💼, 👆 🎲 🏆 🚫 💚 ⚙️ 🙆 🧢 🖼, & ↩️ **🏗 📦 🖼 ⚪️➡️ 🖌** 1️⃣ ⚓️ 🔛 🛂 🐍 ☁ 🖼.
|
||||
|
||||
✊ 💅 **✔** 👩🌾 `Dockerfile` & **☁ 💾** 👆 💪 **📉 🏗 🕰**, 📉 👆 📈 (& ❎ 😩). 👶
|
||||
|
||||
🎯 🎁 💼, 👆 💪 💚 ⚙️ 🛂 ☁ 🖼 FastAPI. 👶
|
||||
190
docs/em/docs/deployment/https.md
Normal file
190
docs/em/docs/deployment/https.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# 🔃 🇺🇸🔍
|
||||
|
||||
⚫️ ⏩ 🤔 👈 🇺🇸🔍 🕳 👈 "🛠️" ⚖️ 🚫.
|
||||
|
||||
✋️ ⚫️ 🌌 🌖 🏗 🌘 👈.
|
||||
|
||||
!!! tip
|
||||
🚥 👆 🏃 ⚖️ 🚫 💅, 😣 ⏮️ ⏭ 📄 🔁 🔁 👩🌾 ⚒ 🌐 🆙 ⏮️ 🎏 ⚒.
|
||||
|
||||
**💡 🔰 🇺🇸🔍**, ⚪️➡️ 🏬 🤔, ✅ <a href="https://howhttps.works/" class="external-link" target="_blank">https://howhttps.works/</a>.
|
||||
|
||||
🔜, ⚪️➡️ **👩💻 🤔**, 📥 📚 👜 ✔️ 🤯 ⏪ 💭 🔃 🇺🇸🔍:
|
||||
|
||||
* 🇺🇸🔍, **💽** 💪 **✔️ "📄"** 🏗 **🥉 🥳**.
|
||||
* 📚 📄 🤙 **🏆** ⚪️➡️ 🥉 🥳, 🚫 "🏗".
|
||||
* 📄 ✔️ **1️⃣2️⃣🗓️**.
|
||||
* 👫 **🕛**.
|
||||
* & ⤴️ 👫 💪 **♻**, **🏆 🔄** ⚪️➡️ 🥉 🥳.
|
||||
* 🔐 🔗 🔨 **🕸 🎚**.
|
||||
* 👈 1️⃣ 🧽 **🔛 🇺🇸🔍**.
|
||||
* , **📄 & 🔐** 🍵 🔨 **⏭ 🇺🇸🔍**.
|
||||
* **🕸 🚫 💭 🔃 "🆔"**. 🕴 🔃 📢 📢.
|
||||
* ℹ 🔃 **🎯 🆔** 📨 🚶 **🇺🇸🔍 💽**.
|
||||
* **🇺🇸🔍 📄** "✔" **🎯 🆔**, ✋️ 🛠️ & 🔐 🔨 🕸 🎚, **⏭ 💭** ❔ 🆔 ➖ 🙅 ⏮️.
|
||||
* **🔢**, 👈 🔜 ⛓ 👈 👆 💪 🕴 ✔️ **1️⃣ 🇺🇸🔍 📄 📍 📢 📢**.
|
||||
* 🙅♂ 🤔 ❔ 🦏 👆 💽 ⚖️ ❔ 🤪 🔠 🈸 👆 ✔️ 🔛 ⚫️ 💪.
|
||||
* 📤 **⚗** 👉, 👐.
|
||||
* 📤 **↔** **🤝** 🛠️ (1️⃣ 🚚 🔐 🕸 🎚, ⏭ 🇺🇸🔍) 🤙 **<a href="https://en.wikipedia.org/wiki/Server_Name_Indication" class="external-link" target="_blank"><abbr title="Server Name Indication">👲</abbr></a>**.
|
||||
* 👉 👲 ↔ ✔ 1️⃣ 👁 💽 (⏮️ **👁 📢 📢**) ✔️ **📚 🇺🇸🔍 📄** & 🍦 **💗 🇺🇸🔍 🆔/🈸**.
|
||||
* 👉 👷, **👁** 🦲 (📋) 🏃 🔛 💽, 👂 🔛 **📢 📢 📢**, 🔜 ✔️ **🌐 🇺🇸🔍 📄** 💽.
|
||||
* **⏮️** 🏆 🔐 🔗, 📻 🛠️ **🇺🇸🔍**.
|
||||
* 🎚 **🗜**, ✋️ 👫 ➖ 📨 ⏮️ **🇺🇸🔍 🛠️**.
|
||||
|
||||
⚫️ ⚠ 💡 ✔️ **1️⃣ 📋/🇺🇸🔍 💽** 🏃 🔛 💽 (🎰, 🦠, ♒️.) & **🛠️ 🌐 🇺🇸🔍 🍕**: 📨 **🗜 🇺🇸🔍 📨**, 📨 **🗜 🇺🇸🔍 📨** ☑ 🇺🇸🔍 🈸 🏃 🎏 💽 ( **FastAPI** 🈸, 👉 💼), ✊ **🇺🇸🔍 📨** ⚪️➡️ 🈸, **🗜 ⚫️** ⚙️ ☑ **🇺🇸🔍 📄** & 📨 ⚫️ 🔙 👩💻 ⚙️ **🇺🇸🔍**. 👉 💽 🛎 🤙 **<a href="https://en.wikipedia.org/wiki/TLS_termination_proxy" class="external-link" target="_blank">🤝 ❎ 🗳</a>**.
|
||||
|
||||
🎛 👆 💪 ⚙️ 🤝 ❎ 🗳:
|
||||
|
||||
* Traefik (👈 💪 🍵 📄 🔕)
|
||||
* 📥 (👈 💪 🍵 📄 🔕)
|
||||
* 👌
|
||||
* ✳
|
||||
|
||||
## ➡️ 🗜
|
||||
|
||||
⏭ ➡️ 🗜, 👫 **🇺🇸🔍 📄** 💲 💙 🥉 🥳.
|
||||
|
||||
🛠️ 📎 1️⃣ 👫 📄 ⚙️ ⚠, 🚚 📠 & 📄 😥.
|
||||
|
||||
✋️ ⤴️ **<a href="https://letsencrypt.org/" class="external-link" target="_blank">➡️ 🗜</a>** ✍.
|
||||
|
||||
⚫️ 🏗 ⚪️➡️ 💾 🏛. ⚫️ 🚚 **🇺🇸🔍 📄 🆓**, 🏧 🌌. 👫 📄 ⚙️ 🌐 🐩 🔐 💂♂, & 📏-🖖 (🔃 3️⃣ 🗓️), **💂♂ 🤙 👍** ↩️ 👫 📉 🔆.
|
||||
|
||||
🆔 🔐 ✔ & 📄 🏗 🔁. 👉 ✔ 🏧 🔕 👫 📄.
|
||||
|
||||
💭 🏧 🛠️ & 🔕 👫 📄 👈 👆 💪 ✔️ **🔐 🇺🇸🔍, 🆓, ♾**.
|
||||
|
||||
## 🇺🇸🔍 👩💻
|
||||
|
||||
📥 🖼 ❔ 🇺🇸🔍 🛠️ 💪 👀 💖, 🔁 🔁, 💸 🙋 ✴️ 💭 ⚠ 👩💻.
|
||||
|
||||
### 🆔 📛
|
||||
|
||||
⚫️ 🔜 🎲 🌐 ▶️ 👆 **🏗** **🆔 📛**. ⤴️, 👆 🔜 🔗 ⚫️ 🏓 💽 (🎲 👆 🎏 ☁ 🐕🦺).
|
||||
|
||||
👆 🔜 🎲 🤚 ☁ 💽 (🕹 🎰) ⚖️ 🕳 🎏, & ⚫️ 🔜 ✔️ <abbr title="That doesn't change">🔧</abbr> **📢 📢 📢**.
|
||||
|
||||
🏓 💽(Ⓜ) 👆 🔜 🔗 ⏺ ("`A record`") ☝ **👆 🆔** 📢 **📢 📢 👆 💽**.
|
||||
|
||||
👆 🔜 🎲 👉 🕐, 🥇 🕰, 🕐❔ ⚒ 🌐 🆙.
|
||||
|
||||
!!! tip
|
||||
👉 🆔 📛 🍕 🌌 ⏭ 🇺🇸🔍, ✋️ 🌐 🪀 🔛 🆔 & 📢 📢, ⚫️ 💸 💬 ⚫️ 📥.
|
||||
|
||||
### 🏓
|
||||
|
||||
🔜 ➡️ 🎯 🔛 🌐 ☑ 🇺🇸🔍 🍕.
|
||||
|
||||
🥇, 🖥 🔜 ✅ ⏮️ **🏓 💽** ⚫️❔ **📢 🆔**, 👉 💼, `someapp.example.com`.
|
||||
|
||||
🏓 💽 🔜 💬 🖥 ⚙️ 🎯 **📢 📢**. 👈 🔜 📢 📢 📢 ⚙️ 👆 💽, 👈 👆 🔗 🏓 💽.
|
||||
|
||||
<img src="/img/deployment/https/https01.svg">
|
||||
|
||||
### 🤝 🤝 ▶️
|
||||
|
||||
🖥 🔜 ⤴️ 🔗 ⏮️ 👈 📢 📢 🔛 **⛴ 4️⃣4️⃣3️⃣** (🇺🇸🔍 ⛴).
|
||||
|
||||
🥇 🍕 📻 🛠️ 🔗 🖖 👩💻 & 💽 & 💭 🔐 🔑 👫 🔜 ⚙️, ♒️.
|
||||
|
||||
<img src="/img/deployment/https/https02.svg">
|
||||
|
||||
👉 🔗 🖖 👩💻 & 💽 🛠️ 🤝 🔗 🤙 **🤝 🤝**.
|
||||
|
||||
### 🤝 ⏮️ 👲 ↔
|
||||
|
||||
**🕴 1️⃣ 🛠️** 💽 💪 👂 🔛 🎯 **⛴** 🎯 **📢 📢**. 📤 💪 🎏 🛠️ 👂 🔛 🎏 ⛴ 🎏 📢 📢, ✋️ 🕴 1️⃣ 🔠 🌀 📢 📢 & ⛴.
|
||||
|
||||
🤝 (🇺🇸🔍) ⚙️ 🎯 ⛴ `443` 🔢. 👈 ⛴ 👥 🔜 💪.
|
||||
|
||||
🕴 1️⃣ 🛠️ 💪 👂 🔛 👉 ⛴, 🛠️ 👈 🔜 ⚫️ 🔜 **🤝 ❎ 🗳**.
|
||||
|
||||
🤝 ❎ 🗳 🔜 ✔️ 🔐 1️⃣ ⚖️ 🌅 **🤝 📄** (🇺🇸🔍 📄).
|
||||
|
||||
⚙️ **👲 ↔** 🔬 🔛, 🤝 ❎ 🗳 🔜 ✅ ❔ 🤝 (🇺🇸🔍) 📄 💪 ⚫️ 🔜 ⚙️ 👉 🔗, ⚙️ 1️⃣ 👈 🏏 🆔 📈 👩💻.
|
||||
|
||||
👉 💼, ⚫️ 🔜 ⚙️ 📄 `someapp.example.com`.
|
||||
|
||||
<img src="/img/deployment/https/https03.svg">
|
||||
|
||||
👩💻 ⏪ **💙** 👨💼 👈 🏗 👈 🤝 📄 (👉 💼 ➡️ 🗜, ✋️ 👥 🔜 👀 🔃 👈 ⏪), ⚫️ 💪 **✔** 👈 📄 ☑.
|
||||
|
||||
⤴️, ⚙️ 📄, 👩💻 & 🤝 ❎ 🗳 **💭 ❔ 🗜** 🎂 **🕸 📻**. 👉 🏁 **🤝 🤝** 🍕.
|
||||
|
||||
⏮️ 👉, 👩💻 & 💽 ✔️ **🗜 🕸 🔗**, 👉 ⚫️❔ 🤝 🚚. & ⤴️ 👫 💪 ⚙️ 👈 🔗 ▶️ ☑ **🇺🇸🔍 📻**.
|
||||
|
||||
& 👈 ⚫️❔ **🇺🇸🔍** , ⚫️ ✅ **🇺🇸🔍** 🔘 **🔐 🤝 🔗** ↩️ 😁 (💽) 🕸 🔗.
|
||||
|
||||
!!! tip
|
||||
👀 👈 🔐 📻 🔨 **🕸 🎚**, 🚫 🇺🇸🔍 🎚.
|
||||
|
||||
### 🇺🇸🔍 📨
|
||||
|
||||
🔜 👈 👩💻 & 💽 (🎯 🖥 & 🤝 ❎ 🗳) ✔️ **🗜 🕸 🔗**, 👫 💪 ▶️ **🇺🇸🔍 📻**.
|
||||
|
||||
, 👩💻 📨 **🇺🇸🔍 📨**. 👉 🇺🇸🔍 📨 🔘 🗜 🤝 🔗.
|
||||
|
||||
<img src="/img/deployment/https/https04.svg">
|
||||
|
||||
### 🗜 📨
|
||||
|
||||
🤝 ❎ 🗳 🔜 ⚙️ 🔐 ✔ **🗜 📨**, & 🔜 📶 **✅ (🗜) 🇺🇸🔍 📨** 🛠️ 🏃 🈸 (🖼 🛠️ ⏮️ Uvicorn 🏃♂ FastAPI 🈸).
|
||||
|
||||
<img src="/img/deployment/https/https05.svg">
|
||||
|
||||
### 🇺🇸🔍 📨
|
||||
|
||||
🈸 🔜 🛠️ 📨 & 📨 **✅ (💽) 🇺🇸🔍 📨** 🤝 ❎ 🗳.
|
||||
|
||||
<img src="/img/deployment/https/https06.svg">
|
||||
|
||||
### 🇺🇸🔍 📨
|
||||
|
||||
🤝 ❎ 🗳 🔜 ⤴️ **🗜 📨** ⚙️ ⚛ ✔ ⏭ (👈 ▶️ ⏮️ 📄 `someapp.example.com`), & 📨 ⚫️ 🔙 🖥.
|
||||
|
||||
⏭, 🖥 🔜 ✔ 👈 📨 ☑ & 🗜 ⏮️ ▶️️ 🔐 🔑, ♒️. ⚫️ 🔜 ⤴️ **🗜 📨** & 🛠️ ⚫️.
|
||||
|
||||
<img src="/img/deployment/https/https07.svg">
|
||||
|
||||
👩💻 (🖥) 🔜 💭 👈 📨 👟 ⚪️➡️ ☑ 💽 ↩️ ⚫️ ⚙️ ⚛ 👫 ✔ ⚙️ **🇺🇸🔍 📄** ⏭.
|
||||
|
||||
### 💗 🈸
|
||||
|
||||
🎏 💽 (⚖️ 💽), 📤 💪 **💗 🈸**, 🖼, 🎏 🛠️ 📋 ⚖️ 💽.
|
||||
|
||||
🕴 1️⃣ 🛠️ 💪 🚚 🎯 📢 & ⛴ (🤝 ❎ 🗳 👆 🖼) ✋️ 🎏 🈸/🛠️ 💪 🏃 🔛 💽(Ⓜ) 💁♂️, 📏 👫 🚫 🔄 ⚙️ 🎏 **🌀 📢 📢 & ⛴**.
|
||||
|
||||
<img src="/img/deployment/https/https08.svg">
|
||||
|
||||
👈 🌌, 🤝 ❎ 🗳 💪 🍵 🇺🇸🔍 & 📄 **💗 🆔**, 💗 🈸, & ⤴️ 📶 📨 ▶️️ 🈸 🔠 💼.
|
||||
|
||||
### 📄 🔕
|
||||
|
||||
☝ 🔮, 🔠 📄 🔜 **🕛** (🔃 3️⃣ 🗓️ ⏮️ 🏗 ⚫️).
|
||||
|
||||
& ⤴️, 📤 🔜 ➕1️⃣ 📋 (💼 ⚫️ ➕1️⃣ 📋, 💼 ⚫️ 💪 🎏 🤝 ❎ 🗳) 👈 🔜 💬 ➡️ 🗜, & ♻ 📄(Ⓜ).
|
||||
|
||||
<img src="/img/deployment/https/https.svg">
|
||||
|
||||
**🤝 📄** **🔗 ⏮️ 🆔 📛**, 🚫 ⏮️ 📢 📢.
|
||||
|
||||
, ♻ 📄, 🔕 📋 💪 **🎦** 🛃 (➡️ 🗜) 👈 ⚫️ 👐 **"👍" & 🎛 👈 🆔**.
|
||||
|
||||
👈, & 🏗 🎏 🈸 💪, 📤 📚 🌌 ⚫️ 💪 ⚫️. 🌟 🌌:
|
||||
|
||||
* **🔀 🏓 ⏺**.
|
||||
* 👉, 🔕 📋 💪 🐕🦺 🔗 🏓 🐕🦺,, ⚓️ 🔛 🏓 🐕🦺 👆 ⚙️, 👉 5️⃣📆 ⚖️ 💪 🚫 🎛.
|
||||
* **🏃 💽** (🌘 ⏮️ 📄 🛠️ 🛠️) 🔛 📢 📢 📢 🔗 ⏮️ 🆔.
|
||||
* 👥 💬 🔛, 🕴 1️⃣ 🛠️ 💪 👂 🔛 🎯 📢 & ⛴.
|
||||
* 👉 1️⃣ 🤔 ⚫️❔ ⚫️ 📶 ⚠ 🕐❔ 🎏 🤝 ❎ 🗳 ✊ 💅 📄 🔕 🛠️.
|
||||
* ⏪, 👆 💪 ✔️ ⛔️ 🤝 ❎ 🗳 😖, ▶️ 🔕 📋 📎 📄, ⤴️ 🔗 👫 ⏮️ 🤝 ❎ 🗳, & ⤴️ ⏏ 🤝 ❎ 🗳. 👉 🚫 💯, 👆 📱(Ⓜ) 🔜 🚫 💪 ⏮️ 🕰 👈 🤝 ❎ 🗳 📆.
|
||||
|
||||
🌐 👉 🔕 🛠️, ⏪ 🍦 📱, 1️⃣ 👑 🤔 ⚫️❔ 👆 🔜 💚 ✔️ **🎏 ⚙️ 🍵 🇺🇸🔍** ⏮️ 🤝 ❎ 🗳 ↩️ ⚙️ 🤝 📄 ⏮️ 🈸 💽 🔗 (✅ Uvicorn).
|
||||
|
||||
## 🌃
|
||||
|
||||
✔️ **🇺🇸🔍** 📶 ⚠, & **🎯** 🏆 💼. 🌅 🎯 👆 👩💻 ✔️ 🚮 🤭 🇺🇸🔍 🔃 **🤔 👉 🔧** & ❔ 👫 👷.
|
||||
|
||||
✋️ 🕐 👆 💭 🔰 ℹ **🇺🇸🔍 👩💻** 👆 💪 💪 🌀 & 🔗 🎏 🧰 ℹ 👆 🛠️ 🌐 🙅 🌌.
|
||||
|
||||
⏭ 📃, 👤 🔜 🎦 👆 📚 🧱 🖼 ❔ ⚒ 🆙 **🇺🇸🔍** **FastAPI** 🈸. 👶
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user