agNV1VSwF{q#q@t;_(rwJ`AYp`s`XvDv#FUzA(6~3>Xr6b
zrK}z=b;8b1{gKVa@ZZy)pfRsra40uxj(b%n{6xN?2!~ehXrmPf{t?3}AiXH8ni9s+?Voz7%-85A@u
z)xmI1rmT;f9Lh#^1@oh$_kQWcO_o>lmRt5Rb}YW)h9yl#x4fds$%<^>6CL0*ldBXA
zCo#wcEQ<*|s`G=od?&uONF>8}x3pM)(?)xE%%((NrGaGWHKz>O?+ZUePpP-i5EOT*
zgzWZ50gc0|uOW$S4MgCY(rpZ7UhSvBPteg(_FF$9@as1EgDJxrWcGc#{Swc2l_El)
z#gL{9`Q0orX{7F1Q_~J=7VL)DHzlwNT7EG0%9VwUA{B&_+*7EW`rOoGg+Ut^eTZc2
z77qi6!1uyQEbx4L3zcR!%VN*uZS(TEw~ob4inQzz(68xf;ZS0EHeATU{1TM#Q|?5hLY$M~NQHz$^=Q
zM3Vuyr4E%^tZ=C6qW&BCIrM@crKiws@Jm>1!{dvSA3v|uTUENN${^fy2e~i;|8zgEW<27LY0t(
zE-IrSs;}gyY#6M$-kqqe(tCA{O)YMnHrgBv`*usBB9RsG5tmID%jyEb!K~uEXp}U*
zgJiMs;K;}SR+R{QX&4N_KcP{8(=hk%I>)V53*I|IBegu(re?koNL_J*6EA*!#6jNv
zXTZ)e@!^!6pPleXEt0=0q
z*L{ma&$Jn}{IGLxWu@zMA+gZu%=>Mb9dK6L
zufqLFiqD_IU7VM@_)Cr>&Z~dycEYSwHFb8>(uq~Yh??m;r$m*%Bh^xZYkv1&yRe(B
zjlsIf%y&Ic)ywsZ^SlW#U#9wCx-Bs=_>l_6DHO?!+^4T8uI2fP(Iqu3C5PAFRWeYe
z9S*#@4J1l>y0jtt-B4Dq=lU-Cr2_w`j2&t0aNj|tix~ddHb3>v%;j#9%ykSJknU0_
zuQ@cxz)E{MctD)sgVm1B0#~@ljJ;`qksxNYLkp9{VGN+uUPJfO_sWSDwYxv^Q#$dM
z;BHu2iE7v-1rqM;uGD@Zp2PLWsR!r~pDiTh*lTsk2mxbLab9UvG6ktk{ayY2tF3Kz
z`ESJR&P(p$v9CA>A~rH_z@`tkW2-$fLe77o{gFb7hZ?mxwq(C+b|(03%U}oZ#2Z2n
zmzMtyb-<)>OTwBmCq5{;_{AS`2M40CroBiS9&e?^xH(TdK;ir5wG`X~d1NaKq_!NW
zD4=mZ>~r-=%}eWl5Y-Xgnxmw+=xFEif?R$7Fw2GC2HAl87@chK`1{j{>~~S*t7?-0
z-e5ao=Ol7=Tn=prh@OASurQETbI|V%UuqYS=Bxfxa89_YzTEWu_p7j}cRZi$LCk@s
zli@zfi@}rQn1*&Qzw9XN#cSGnf@htOkvLSgZS5kF|Mb3guUv5@07CoaWN$lrKPV$!v5U@0gnJjxDwglR|
zk&0ml2L5-4?Ops8Sype)HM@RSzqSMJQ-DsAsIAD!%s)%&;WmR}ZK10J
zD#wWE&uc~%q7c73yh7i9>VZAVrjvC+QG4^{fe5LFie{0l8`#Y@`%Km~d!}jpGA|ua
z;rpQTcLzH*LT(hvoJ~V)~}gBzzA!E_`>Q3iS>Qa${aN^4vOjh>DdQtjt`1
zMj!b#)e!IBULuONik#L`@vb5(@Ov)9qu|GT1V{JR)buBLQsVT)3^L&5nNc6a6VoHg
zK&XUP2TERVF#Pu23G%YX0Lw&mjq-ZaXO}@4w>7whh>y1}{2G|{?KXm8d`=lh7sSSr
zkA$j{o%slK?dg;?1f=H=RA`6_RQwr&`1{x$Yg*xi8F3=@J
zYeVx>n-73oY=rSc%96sX73Ld7*;FjwPgFl&um?XeX|in}Pvn)+^wA?+HZx#~7;lH0Fi_UA+pM)OM(rrKEA=lPXN8+E&nuW=7$gB%8FW(y7N%Bb+mcW
zw)~Md0&UTGu_FsO$7j}%RPsSgQ{tMeE#!y@=*aC7zgwjBKWOcC)N?)GH$DD|gpSts#(I@*Jr)s!wrH^9l9mQwz)r
zSKk9B*ZaRVK<0Ckh=X9}L0mA?ATH2&CUhea@fdo=Bmoi-q>nimFh(3&PCoscy2{VV
z2t2PCx4il3Fuowcdw=0iD|P$i*x1DR>DkQJ{tunw^Fm#gj#wSZCpB(xxWv7&!Sg?F
zkdW)@(2;rP=Y%|;t$n5(!)RVBUdX4NI5GXkp3fF{@#zLpn~uv
z%RR>~jAK?;9>tVwA4XZDo;BJa^p3Am4FA4IL&e9;A%bR08Yc=;9?R=!_j!a)TW^xvi-npm>pLLoCn=Y&|pfw3d%b1Z#JzQO4v2|B-#47W{PkpGy_?KW?1*{@9ZW9-a)o@w1)Jm|b{r8~9M7WX?G5h~f4`3T
zbgkEq>qL1h1WX_R`TTb&>4N=2Z7Zm%^w2>0ckw1$PP&(~%x<#0KdCI#P&tS?L-3%9
z5Qhu9%7e)-QreF3m|q>i1Lq^0!6x*a)X(2Qmwv0n+4a7HSMRwtN9V_NJ+<5t27Zgj
zy-#q$?4GTD5Q?V6IoSMeS;5@~i6(Jcdw5-e8tTNWgxhTFuGlGrm&=mQw{gb6JJv_hc{e;-*|ACP{#f1qbrJq@d%ku%|SC2SvO*>M}h
z6i;TtvOYOhWN4Y`jfBcQ$;QSzVd%NtF}5rbJt)
z6Bj{m+j~ibZCc8#W?flu(OPfCKMimv#>iw#q%W$>`g5=sKjnw;ch8^jItQN98QH|b
zA!VUq;!dAerJfN-H|B?D7;*sY*@sP9V3vL!HFx+@VYrkGz&(UQce%#ASVMrN2D@3%T7IOv6qL&-xju5k2&Nnui{K
z2F(_8!YZl0#}U*0Ua-OellzQ&!=PD|+MYe6**sLCYhUB=K%1<#KLhQMP{Uu>JqlUtsLgvjuKddjLE
z>lFKr6S8BDVScd{TP2yT$W6$2fD0+5WG3ge=AbX2&`}Zdp|`$FkV1Rl_K25kJ)O-r
z)FIu`&+q=k_Vm3lQRBILYr!Sp_7G1>f$($mrx&Q9PW2)fpME|#>v0SwIYxo=Qe$hzOdp75V`Kk^(h;sE^SNY)w~@wK`Szts>Qc;J7ULYl4LR}%ktNaf$WBU^14DIykhFUJF8u%pHO
z{pzB#sf$yf%Z2wk8goI1^dVL8mXDm#yq1t&4=d+f_l)%$fk?seRJ@zO&aRF7%KR?-
zzPfOQ`?ZhMr7o@;!$>hGX6#Bhc;n^2$sAVV
zK4kRpLd4Us;PP4B+NOu!H!+iklgf~dw(GUG-g=7h@;;LmG!hK4$mY*us`AqzbZ(FP
zszyege|)~-eX96ZPm#kNd}RU%28rg!0yne%w%{8Bd)WhNxq$ctw^az%EJs|K0Bs(?
ziuYN+r-lKtOPF-ZFh;`N;uc)^6INEjYLFEgd>2j_Rya!Fiyj`B32iib#WiLFt#vT*
z9EyF%U~QW{b>QVIZYHnQMEYXs_CiM}hmiOq?LM{Yojb;s7>1eY*Jmw8Kv-OET
z3|ngKh6cE8<_Nl-?%!R@k@sk@@!8pu!c4yB>yR%*gu$Fu32f|T2xXHTsyVQ4_sO|7
zeL@0}iZnNs^`*FbTQi&*M3lZ4DVBw9{-mkUBXeIIE1#&Q4!WEHuG}BswhdhQeE)!6
z@kYqao3yBV)0u1{A@G-3a@NrE(`JqM?V)jPh^LroX#dMM>XYo}PVGR_49-MleHSI5G
zz2eg_BtIr2TF`;;mY?(f{wQUzSX
z143ekIsf{~I9LpOgQ8|5e*a@&6JttW%s^pz`$X{xDnk^Qmb
zu|?g*X9^*~ej++tDioG{wyy`Kcr4&dt$W?vcLsCEucYmC`)dII=7GF2`5fzWZTVP-
z7iF}K@HlD%M`h}|F1DHI;+B2T>v@+A@!_XCz0p6qr(QqhnTaomTY7Z)JU){jP
z@!qYzQhwRd*uX%sU3lOqqQRCGsjHOR@Ig>z^AE?2zMHJJFMhtqs}j_UdXj!ATWy^{UWHl??Ic1>}OAV-;&V4snKY04Csj0XQmGfRVK&TybV<_nrZ*E=cprz##&9x~(f~rz=pHBbw1h<8HpK
z{Dt{)N>o&oMM_iFZs*F17M#S0`QB#DTAAr31rr2+{~c1vaPAKxx%Hbx;goz6)|tCp
zn^<3hN>jziG3vJ|yeT0jt5-@?f2;J2Ikhp-;N)LPonVHJPGsI!NzXNmobt&
zlm8_JC#+`EVz2uKmgQNE@Wf6T9=X4j-@jXFJSR|=BtV+qHFl(dLXg8r9;b_Jqd8A~w4*QISX^`^8%&=WhD4*}RdQ
z#{ASA7}NesDdUciS%QxVG$rlF9Epb^_-$q6PSXzWIlHh5R&i64TJPB4u7PMWb6VOy
zcm)^>3@VcQ&|4M^p|xD&UWS?dPR?%XWL0xdvN==06UpC7NJ71VZ@Ifblw2aB&WAezu@=>zo&*F!
zPo}Utt`P6_W~Ia0xiEPDIaaijO6zUqd7mc`M>^yo++UUsC_hZz<$e77cbdA%eNoI|
z@sh_C#*h)`Iv_X`TIWWfPXB=2VD~vSr)VIRKfEV10Yc-OnSZwP^hu(Nu3%N(b^{q*
ztnI_WQe0h#6u9687CkiaO?;Q%CqMEhyoO;R$2E!g$%CIRh>GCH-|YpD@Y&k-Ly7pq
zVBC8PCPB3j5_b*SaJ)ZJxuWemc5pmO-{k=atv^zdQ}SPaL`nCPijnuz3s5(2oE&0J
z^Cs%w#Ns^UFesNPYQgf2WWvU(|J~ABe{x|siyOXa!oj!8qk)Asf^J5X23TTHRZc(D
z#g`@sj!Pz9&lnkSooYMAR%6YJXG~w*=}zlV5qR;7(?563qTNo|lk0{_@>*GXEf|8%
zUuxfXBtFv9hOk_XNZL3D%c0~>9`x1h>D{~cm0+^Y%I~+>6}ociiTbfC_152(
zQi&Sy@V9ExJ*Er|SzkaBSz*c;o#s8cE8HQGt)>JY#%fEQ6Q7y>h?4H|x{PX889*>1
zFHAuD(4gpvu-oRNGjoBA%HX(&tX{<-b|27G&wUE!V@0jQT;U^5?NB9e(Css*SgnaK
zWWINV(}1x5!2N1=_JpVuDu1*{pxt>G%y+)K)$BF3_Q2}e`8;5}m&vDU7gV@kE>+_D
ztK~*qW7+#zIA}tY|Eu^>Z?^wmpHYrjn*Mv^wLu4`;e6A9FkPo?uT}b2RrtXSffplt
z33}C8%jzQUTN>e5cWI|ax|07PPxhP?E@!yC!7
z-JvK9(HAW}5lf4jyCp3k00bfwih>LGht?93Usrbnifqp<0D$UGg%u$v?+m)JwS=*;
zJ;(LG!5eqK8b7IlmapjcGgrn-)t*&?cW$4yVBd#A5_8Su=F0gWYm2lxFI@S~ZMSIl
zzVv!soPW7%#{Fl0LH^JD0hQH>1<0>~l}`4row*ap&lm?BiUy`7R$#)
z9{RaI;wl7hcR;SPMhhEhl0V|N4PC#k^87-qa>nR)bQrwTp&Y(kHZVcN$*Q~tqRM(%%3=I|AiJK|VVuHgczKWl5{~>2_aVpa33zMSo
zr-22!WW&!4`zn+9vi^#qOph2q=aLIwblwDMEb>YJG!mf?=cNV!8Kz8L-&dTehbMhO<1v@jHx74Qlg9`DEHZF{okSEVYs@l$!TwPmFD;tkAC&$!@%^%
zJcJC%>`0M6(yea4Cl7Qokd)ooBI(c9+X}H3fG&ZF*t&6j_9>vDXCXmZk~;_O{5t{N
z%Sva_2*Iqa#+KQO4HND(O&B~Su~CwQAc*FDp}x959N}$Nm3Q#RkBo!x*
z?;XBbz0SGy{14EM4zCYXCYjzy5bTb;Ko?v6uacoBb6P!_b?3lb4mPg^A3^2&(
z-lT+00~JW5c}J=FD41mUo76ekq)CDaJ#GauBoepl_(Q8i2;;on6Q^tqqeRwn>^TtM
z!}VDW3If>_drO+R>_tDwpHYS_P%zeh;Doam9nLhJ_#I)E(#Z%+Ej6Yx#5lW9dz
zTvqyb+|qZhf-RgkYMFg}&m}nA^uSeqE{|eQN;#K3=?A%ZssWP4SoN3QM^h@P8$mf>
zp7UCAtdeq{LqUW@UtY3=ycY@F1=<{_zK-(Pm8ww7U~R4#{VxK#iIbHcD?F5i#aKRhG$woTi_=M5c<0fp9hgv0P>Gyic6ylFLAWrZzR
zNpCO5cSY#JK~L4zL}}>f(&N!Dn)pm@NM!uG-tctcOC8V`yYv*@M&^GDrQiN}yj>Jj
zPECsMGJGp_-z!JhxPO7Ld}9_b`Ek;@nS|GB=-J{87_T7!wSX~gvt#mI(?wLHU880H
z?`SXzI0*b>=XG}LAE|J2@VRIDL_3+BzmQ}@UbW71+QkH4d?wN7Z^aWeCm~(SsitbS
zPjEJ8+`UDLH!ScOMZ|7GCK1pgOs0-Mo7YH{=gSU==cxJli|<{=O&3>wD}JL|CXdx^
z!xSYa=AD3)n?WSOB2PBbE1)oRjh*x4o+Byq?`Zj4O^%G@$e16nqH1X_)=s7nQ-GA%
zho%g*l$^`fn}p>R^D-wxRnG#?i1o)jPF;pO5%Xc#b7zX0Q8haW18hsfCr97sZ;zL5
zT<(@uD=asJU)6WAZX-65g4KpsD*;GR7_$u#t#>};bQJGA4O#>im;iQ^^EevyZF^zp
zgAOd}4(4VD#Q7{)NZv!WCi@MUCa`Bl+f9>t^iSGW9wD4&oX~GTI4ABREmMupSNCA<
zZ+`B&7cOl@?<1|eDfm{0Tb1Vz^GuzjFL4_9$HrH#GM#$^b@K5z>>AE8d1^gDXRI*fkF{=!zAm#et70{Pk6azuX0-t-ina1je
z@c|}Q;w2n6=g38Uz2~QfM!oJ(ITa)*2
z+)#ZfTJG&dzGE>=cGZ1LkLw+roe%wHD%p_st4^vCPz;O_-6;7Ts%6%C(^I*Zy6q{=
zTnV8>rK3FV<@2BSi&bJt_Cqt2vA{K1I=1R)5WPv5-+IwSo2$GX&xbcAgVIY&@wha7
zM$Hsz$G9L#qb4GlGMguNFqO{D>q0G7+HiFU-3=RP$O|Sf-aGfN=JT+GJSt17OVc)W(974M!nL4<3|&(g(Yk!lwzL@P7*S)^o1
z@Iu!Uc9S}`Hr(-Nx*neawStN)A~^Mky-c~nC!+DFIt?7fgu6W-WT>SgnZiPSG>17SW?@%
z?`2*w3Kgx1g@!v#Q}ey5zsL23~-A5)!!Q~y^3}dmcJSUPJI>aS1u{SX%S2+l6*M-_-&wBJlP&VqtOkQ
z=Qx(O#A+Q^6x7_d=TJcYr2jTbm|cK=oE!!TAOb0j*UZLtgCa@_O`DGcQ7h}h1$2|H1CNj=|sN2JMoeI+P#1Kx5BP^pB$TG}K4N$j9!7m*}
zdz3cWO%=#5f9yQ{HOuNI-c`0+7nw`3<&d7E9AP&kVl;jigcZgx18a-{1nrjB(tlKQ
z+T`=>0vVXj---;}ElQG{7=3s6O+MM;BaFJK%H%|lxgihGMz(AJIw>jb`|R1%GqhG0
z7HVU)B&>D&x9AzuvobP5`_gE^QO&XFe6bq+ynjY4?rkSTy{t72(fd-mHIb7|yF}`t
z>(q*=Fw$W~3t!UI97FtSii{Qlp%l}`bjsJka+j%{GKBVj{H5ws>ZgoVgOw357oPhX
zM|AKi1}ZR{d^p6PH60ZS_NAW#C9`Vd5;wf_LuH?zuHJm=l>{5KiOsapw>8nLobi6#
z4(Cz9D*F+AIKy(&^&ilMfJk6w=*nMmkOik6F_2GS{U6(&3m5F!Wy!0^Jn>s@4swEA
zX~NaDo-p>?S$dzj0tg~60v$6Sk}2)hqC}mjl<;dygg-VkBqq}S=WeGN3g6i49Zh;wWu#(0ZVaIdEDXK!`Pg}P>bLTN
zikLnit%c~*!b-@8_R7M&@#BPzGe6qHz}q;A_=R^1Z?gS)bI@>jjbZ`U{Lks87yN?N
zBypAEwlsGf?i57bV27I45<4OL?4htws>5qo^Nm2L@o{MKCFV<4C3;1*7os|u5w2b)
zSFYY&ff8ZGIEw_SqelGzvI;l{C6^qVrb8b%qgL-liOkM8phH_{Fhp#J@2h`*qM$Od
zcYQwlu(nt?-@p=25ks|1i-}hNekpp7?g3S_Q7!93b9#!-Q_NIsoPQZh_hY_DNiR8sX%Z87X951&mh&0SFJqSx
z*jl;G)D|epuO}X@;U;T0VsSSU@XZL<7Xg
zs`TUW5~d}U4dD9fkYODqk^i@=)lTY_g3y@FwC|K*L4GNJ?35_!^{o39n{h266YDUw
z1bMLy1NNFE7y%~m4jL?kxecfC7c3S%gsU#vFFhHD7c>OE=hh;Zf1dJu3}F}5
z#rQjrEE`Ti3ss>AyjCL#-AuR4zIxS5Z>g}lr&1MW|IbJ44lde7NBFANEXK0acj9qeaAYB(-fOM2-g+$L|
zO#QipcZugW^&&95_E*ZMWfgdBvGAg58HtP?7OGa1BL?>}U5;LUqfaS6zV-D*Kz*3NR0ZbgFGG%j|
z?dVlObi>7~?now
zEdTlmYE|;y#{3O913m9OuDn$Q)W~_rftnm%JJW{syJr{~qQRx{lJz?YK#K<)o90AT
zeCV#H3?0O
From d7f88623e1304667c67da17dfd278b5099522ef9 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Sun, 15 Dec 2024 13:35:39 +0000
Subject: [PATCH 096/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 5f1b95d85..623a68303 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -41,6 +41,7 @@ hide:
### Internal
+* 🔧 Update sponsors: rename CryptAPI to BlockBee. PR [#13078](https://github.com/fastapi/fastapi/pull/13078) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump pypa/gh-action-pypi-publish from 1.12.2 to 1.12.3. PR [#13055](https://github.com/fastapi/fastapi/pull/13055) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump types-ujson from 5.7.0.1 to 5.10.0.20240515. PR [#13018](https://github.com/fastapi/fastapi/pull/13018) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump black from 24.3.0 to 24.10.0. PR [#13014](https://github.com/fastapi/fastapi/pull/13014) by [@dependabot[bot]](https://github.com/apps/dependabot).
From 97206ee28f015806d851c7eff5cd4761d1a62a81 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8F=B2=E9=9B=B2=E6=98=94=20=28Vincy=20SHI=29?=
Date: Mon, 16 Dec 2024 00:39:22 +0800
Subject: [PATCH 097/242] =?UTF-8?q?=F0=9F=8C=90=20Update=20Chinese=20trans?=
=?UTF-8?q?lation=20for=20`docs/zh/docs/tutorial/first-steps.md`=20(#12923?=
=?UTF-8?q?)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh/docs/tutorial/first-steps.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/zh/docs/tutorial/first-steps.md b/docs/zh/docs/tutorial/first-steps.md
index 038e17888..c4ff460e0 100644
--- a/docs/zh/docs/tutorial/first-steps.md
+++ b/docs/zh/docs/tutorial/first-steps.md
@@ -313,7 +313,7 @@ https://example.com/items/foo
/// note
-如果你不知道两者的区别,请查阅 [Async: *"In a hurry?"*](https://fastapi.tiangolo.com/async/#in-a-hurry){.internal-link target=_blank}。
+如果你不知道两者的区别,请查阅 [并发: *赶时间吗?*](../async.md#_1){.internal-link target=_blank}。
///
From f5f0d20af0aba9fb74dc255a5e469f95a1c332da Mon Sep 17 00:00:00 2001
From: github-actions
Date: Sun, 15 Dec 2024 16:39:45 +0000
Subject: [PATCH 098/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 623a68303..1507c62c0 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/first-steps.md`. PR [#12923](https://github.com/fastapi/fastapi/pull/12923) by [@Vincy1230](https://github.com/Vincy1230).
* 🌐 Update Russian translation for `docs/ru/docs/deployment/docker.md`. PR [#13048](https://github.com/fastapi/fastapi/pull/13048) by [@anklav24](https://github.com/anklav24).
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/generate-clients.md`. PR [#13030](https://github.com/fastapi/fastapi/pull/13030) by [@vitumenezes](https://github.com/vitumenezes).
* 🌐 Add Indonesian translation for `docs/id/docs/tutorial/first-steps.md`. PR [#13042](https://github.com/fastapi/fastapi/pull/13042) by [@gerry-sabar](https://github.com/gerry-sabar).
From 0e5f5d2e93b8d466762fa86a437ec2fae94f4fd6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8F=B2=E9=9B=B2=E6=98=94=20=28Vincy=20SHI=29?=
Date: Mon, 16 Dec 2024 00:43:19 +0800
Subject: [PATCH 099/242] =?UTF-8?q?=F0=9F=8C=90=20Update=20Chinese=20trans?=
=?UTF-8?q?lation=20for=20`docs/zh/docs/tutorial/path-params.md`=20(#12926?=
=?UTF-8?q?)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh/docs/tutorial/path-params.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/zh/docs/tutorial/path-params.md b/docs/zh/docs/tutorial/path-params.md
index 692214a4b..ac9df0831 100644
--- a/docs/zh/docs/tutorial/path-params.md
+++ b/docs/zh/docs/tutorial/path-params.md
@@ -137,7 +137,7 @@ FastAPI 充分地利用了 枚举(即 enums)。
+Python 3.4 及之后版本支持枚举(即 enums)。
///
From 488763e9f7cd760b035fc20ab0de746a5e3ce8b0 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Sun, 15 Dec 2024 16:43:41 +0000
Subject: [PATCH 100/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 1507c62c0..5d6d307fe 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/path-params.md`. PR [#12926](https://github.com/fastapi/fastapi/pull/12926) by [@Vincy1230](https://github.com/Vincy1230).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/first-steps.md`. PR [#12923](https://github.com/fastapi/fastapi/pull/12923) by [@Vincy1230](https://github.com/Vincy1230).
* 🌐 Update Russian translation for `docs/ru/docs/deployment/docker.md`. PR [#13048](https://github.com/fastapi/fastapi/pull/13048) by [@anklav24](https://github.com/anklav24).
* 🌐 Add Portuguese translation for `docs/pt/docs/advanced/generate-clients.md`. PR [#13030](https://github.com/fastapi/fastapi/pull/13030) by [@vitumenezes](https://github.com/vitumenezes).
From c1220535cc95e27b2ef45c64c0d967227b2038b7 Mon Sep 17 00:00:00 2001
From: Zhongheng Cheng
Date: Sun, 15 Dec 2024 11:44:11 -0500
Subject: [PATCH 101/242] =?UTF-8?q?=F0=9F=8C=90=20Add=20Chinese=20translat?=
=?UTF-8?q?ion=20for=20`docs/zh/docs/tutorial/header-param-models.md`=20(#?=
=?UTF-8?q?13040)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh/docs/tutorial/header-param-models.md | 56 ++++++++++++++++++++
1 file changed, 56 insertions(+)
create mode 100644 docs/zh/docs/tutorial/header-param-models.md
diff --git a/docs/zh/docs/tutorial/header-param-models.md b/docs/zh/docs/tutorial/header-param-models.md
new file mode 100644
index 000000000..13366aebc
--- /dev/null
+++ b/docs/zh/docs/tutorial/header-param-models.md
@@ -0,0 +1,56 @@
+# Header 参数模型
+
+如果您有一组相关的 **header 参数**,您可以创建一个 **Pydantic 模型**来声明它们。
+
+这将允许您在**多个地方**能够**重用模型**,并且可以一次性声明所有参数的验证和元数据。😎
+
+/// note
+
+自 FastAPI 版本 `0.115.0` 起支持此功能。🤓
+
+///
+
+## 使用 Pydantic 模型的 Header 参数
+
+在 **Pydantic 模型**中声明所需的 **header 参数**,然后将参数声明为 `Header` :
+
+{* ../../docs_src/header_param_models/tutorial001_an_py310.py hl[9:14,18] *}
+
+**FastAPI** 将从请求中接收到的 **headers** 中**提取**出**每个字段**的数据,并提供您定义的 Pydantic 模型。
+
+## 查看文档
+
+您可以在文档 UI 的 `/docs` 中查看所需的 headers:
+
+
+

+
+
+## 禁止额外的 Headers
+
+在某些特殊使用情况下(可能并不常见),您可能希望**限制**您想要接收的 headers。
+
+您可以使用 Pydantic 的模型配置来禁止( `forbid` )任何额外( `extra` )字段:
+
+{* ../../docs_src/header_param_models/tutorial002_an_py310.py hl[10] *}
+
+如果客户尝试发送一些**额外的 headers**,他们将收到**错误**响应。
+
+例如,如果客户端尝试发送一个值为 `plumbus` 的 `tool` header,客户端将收到一个**错误**响应,告知他们 header 参数 `tool` 是不允许的:
+
+```json
+{
+ "detail": [
+ {
+ "type": "extra_forbidden",
+ "loc": ["header", "tool"],
+ "msg": "Extra inputs are not permitted",
+ "input": "plumbus",
+ }
+ ]
+}
+```
+
+## 总结
+
+您可以使用 **Pydantic 模型**在 **FastAPI** 中声明 **headers**。😎
From 940c0fb9fb7db850fa12f13d28cd8dbea0e6b5e8 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Sun, 15 Dec 2024 16:45:42 +0000
Subject: [PATCH 102/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 5d6d307fe..4b9c9c053 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/header-param-models.md`. PR [#13040](https://github.com/fastapi/fastapi/pull/13040) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/path-params.md`. PR [#12926](https://github.com/fastapi/fastapi/pull/12926) by [@Vincy1230](https://github.com/Vincy1230).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/first-steps.md`. PR [#12923](https://github.com/fastapi/fastapi/pull/12923) by [@Vincy1230](https://github.com/Vincy1230).
* 🌐 Update Russian translation for `docs/ru/docs/deployment/docker.md`. PR [#13048](https://github.com/fastapi/fastapi/pull/13048) by [@anklav24](https://github.com/anklav24).
From d3360406c4287f2814b7ffdca6a84fc83e8f74ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8F=B2=E9=9B=B2=E6=98=94=20=28Vincy=20SHI=29?=
Date: Mon, 16 Dec 2024 01:10:14 +0800
Subject: [PATCH 103/242] =?UTF-8?q?=F0=9F=8C=90=20Update=20Chinese=20trans?=
=?UTF-8?q?lation=20for=20`docs/zh/docs/tutorial/query-params-str-validati?=
=?UTF-8?q?ons.md`=20(#12928)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh/docs/tutorial/query-params-str-validations.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/zh/docs/tutorial/query-params-str-validations.md b/docs/zh/docs/tutorial/query-params-str-validations.md
index 9b9d1f5fd..2fba671f7 100644
--- a/docs/zh/docs/tutorial/query-params-str-validations.md
+++ b/docs/zh/docs/tutorial/query-params-str-validations.md
@@ -116,7 +116,7 @@ q: Union[str, None] = Query(default=None, min_length=3)
/// info
-如果你之前没见过 `...` 这种用法:它是一个特殊的单独值,它是 Python 的一部分并且被称为「省略号」。
+如果你之前没见过 `...` 这种用法:它是一个特殊的单独值,它是 Python 的一部分并且被称为“Ellipsis”(意为省略号 —— 译者注)。
Pydantic 和 FastAPI 使用它来显式的声明需要一个值。
///
From cfc17e5510c07b78fd627f6f3b2b962ccd0d31f2 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Sun, 15 Dec 2024 17:10:40 +0000
Subject: [PATCH 104/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 4b9c9c053..8b3e4bc1b 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/query-params-str-validations.md`. PR [#12928](https://github.com/fastapi/fastapi/pull/12928) by [@Vincy1230](https://github.com/Vincy1230).
* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/header-param-models.md`. PR [#13040](https://github.com/fastapi/fastapi/pull/13040) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/path-params.md`. PR [#12926](https://github.com/fastapi/fastapi/pull/12926) by [@Vincy1230](https://github.com/Vincy1230).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/first-steps.md`. PR [#12923](https://github.com/fastapi/fastapi/pull/12923) by [@Vincy1230](https://github.com/Vincy1230).
From 929e844754aa18f7ed05976cd011c73b3c91a63c Mon Sep 17 00:00:00 2001
From: Zhongheng Cheng
Date: Sun, 15 Dec 2024 12:11:14 -0500
Subject: [PATCH 105/242] =?UTF-8?q?=F0=9F=8C=90=20Add=20Chinese=20translat?=
=?UTF-8?q?ion=20for=20`docs/zh/docs/tutorial/sql-databases.md`=20(#13051)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh/docs/tutorial/sql-databases.md | 360 +++++++++++++++++++++++++
1 file changed, 360 insertions(+)
create mode 100644 docs/zh/docs/tutorial/sql-databases.md
diff --git a/docs/zh/docs/tutorial/sql-databases.md b/docs/zh/docs/tutorial/sql-databases.md
new file mode 100644
index 000000000..fbdf3be6c
--- /dev/null
+++ b/docs/zh/docs/tutorial/sql-databases.md
@@ -0,0 +1,360 @@
+# SQL(关系型)数据库
+
+**FastAPI** 并不要求您使用 SQL(关系型)数据库。您可以使用**任何**想用的数据库。
+
+这里,我们来看一个使用 SQLModel 的示例。
+
+**SQLModel** 是基于 SQLAlchemy 和 Pydantic 构建的。它由 **FastAPI** 的同一作者制作,旨在完美匹配需要使用 **SQL 数据库**的 FastAPI 应用程序。
+
+/// tip
+
+您可以使用任何其他您想要的 SQL 或 NoSQL 数据库(在某些情况下称为 “ORM”),FastAPI 不会强迫您使用任何东西。😎
+
+///
+
+由于 SQLModel 基于 SQLAlchemy,因此您可以轻松使用任何由 SQLAlchemy **支持的数据库**(这也让它们被 SQLModel 支持),例如:
+
+* PostgreSQL
+* MySQL
+* SQLite
+* Oracle
+* Microsoft SQL Server 等.
+
+在这个例子中,我们将使用 **SQLite**,因为它使用单个文件,并且 Python 对其有集成支持。因此,您可以直接复制这个例子并运行。
+
+之后,对于您的生产应用程序,您可能会想要使用像 PostgreSQL 这样的数据库服务器。
+
+/// tip
+
+有一个使用 **FastAPI** 和 **PostgreSQL** 的官方的项目生成器,其中包括了前端和更多工具: https://github.com/fastapi/full-stack-fastapi-template
+
+///
+
+这是一个非常简单和简短的教程。如果您想了解一般的数据库、SQL 或更高级的功能,请查看 SQLModel 文档。
+
+## 安装 `SQLModel`
+
+首先,确保您创建并激活了[虚拟环境](../virtual-environments.md){.internal-link target=_blank},然后安装了 `sqlmodel` :
+
+
+
+```console
+$ pip install sqlmodel
+---> 100%
+```
+
+
+
+## 创建含有单一模型的应用程序
+
+我们首先创建应用程序的最简单的第一个版本,只有一个 **SQLModel** 模型。
+
+稍后我们将通过下面的**多个模型**提高其安全性和多功能性。🤓
+
+### 创建模型
+
+导入 `SQLModel` 并创建一个数据库模型:
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *}
+
+`Hero` 类与 Pydantic 模型非常相似(实际上,从底层来看,它确实*就是一个 Pydantic 模型*)。
+
+有一些区别:
+
+* `table=True` 会告诉 SQLModel 这是一个*表模型*,它应该表示 SQL 数据库中的一个*表*,而不仅仅是一个*数据模型*(就像其他常规的 Pydantic 类一样)。
+
+* `Field(primary_key=True)` 会告诉 SQLModel `id` 是 SQL 数据库中的**主键**(您可以在 SQLModel 文档中了解更多关于 SQL 主键的信息)。
+
+ 把类型设置为 `int | None` ,SQLModel 就能知道该列在 SQL 数据库中应该是 `INTEGER` 类型,并且应该是 `NULLABLE` 。
+
+* `Field(index=True)` 会告诉 SQLModel 应该为此列创建一个 **SQL 索引**,这样在读取按此列过滤的数据时,程序能在数据库中进行更快的查找。
+
+ SQLModel 会知道声明为 `str` 的内容将是类型为 `TEXT` (或 `VARCHAR` ,具体取决于数据库)的 SQL 列。
+
+### 创建引擎(Engine)
+
+SQLModel 的引擎 `engine`(实际上它是一个 SQLAlchemy `engine` )是用来与数据库**保持连接**的。
+
+您只需构建**一个 `engine`**,来让您的所有代码连接到同一个数据库。
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *}
+
+使用 `check_same_thread=False` 可以让 FastAPI 在不同线程中使用同一个 SQLite 数据库。这很有必要,因为**单个请求**可能会使用**多个线程**(例如在依赖项中)。
+
+不用担心,我们会按照代码结构确保**每个请求使用一个单独的 SQLModel *会话***,这实际上就是 `check_same_thread` 想要实现的。
+
+### 创建表
+
+然后,我们来添加一个函数,使用 `SQLModel.metadata.create_all(engine)` 为所有*表模型***创建表**。
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *}
+
+### 创建会话(Session)依赖项
+
+**`Session`** 会存储**内存中的对象**并跟踪数据中所需更改的内容,然后它**使用 `engine`** 与数据库进行通信。
+
+我们会使用 `yield` 创建一个 FastAPI **依赖项**,为每个请求提供一个新的 `Session` 。这确保我们每个请求使用一个单独的会话。🤓
+
+然后我们创建一个 `Annotated` 的依赖项 `SessionDep` 来简化其他也会用到此依赖的代码。
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[25:30] hl[25:27,30] *}
+
+### 在启动时创建数据库表
+
+我们会在应用程序启动时创建数据库表。
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *}
+
+此处,在应用程序启动事件中,我们创建了表。
+
+而对于生产环境,您可能会用一个能够在启动应用程序之前运行的迁移脚本。🤓
+
+/// tip
+
+SQLModel 将会拥有封装 Alembic 的迁移工具,但目前您可以直接使用 Alembic。
+
+///
+
+### 创建 Hero 类
+
+因为每个 SQLModel 模型同时也是一个 Pydantic 模型,所以您可以在与 Pydantic 模型相同的**类型注释**中使用它。
+
+例如,如果您声明一个类型为 `Hero` 的参数,它将从 **JSON 主体**中读取数据。
+
+同样,您可以将其声明为函数的**返回类型**,然后数据的结构就会显示在自动生成的 API 文档界面中。
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *}
+
+
+
+这里,我们使用 `SessionDep` 依赖项(一个 `Session` )将新的 `Hero` 添加到 `Session` 实例中,提交更改到数据库,刷新 hero 中的数据,并返回它。
+
+### 读取 Hero 类
+
+我们可以使用 `select()` 从数据库中**读取** `Hero` 类,并利用 `limit` 和 `offset` 来对结果进行分页。
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[48:55] hl[51:52,54] *}
+
+### 读取单个 Hero
+
+我们可以**读取**单个 `Hero` 。
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[58:63] hl[60] *}
+
+### 删除单个 Hero
+
+我们也可以**删除**单个 `Hero` 。
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[66:73] hl[71] *}
+
+### 运行应用程序
+
+您可以运行这个应用程序:
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+然后在 `/docs` UI 中,您能够看到 **FastAPI** 会用这些**模型**来**记录** API,并且还会用它们来**序列化**和**验证**数据。
+
+
+

+
+
+## 更新应用程序以支持多个模型
+
+现在让我们稍微**重构**一下这个应用,以提高**安全性**和**多功能性**。
+
+如果您查看之前的应用程序,您可以在 UI 界面中看到,到目前为止,由客户端决定要创建的 `Hero` 的 `id` 值。😱
+
+我们不应该允许这样做,因为他们可能会覆盖我们在数据库中已经分配的 `id` 。决定 `id` 的行为应该由**后端**或**数据库**来完成,**而非客户端**。
+
+此外,我们为 hero 创建了一个 `secret_name` ,但到目前为止,我们在各处都返回了它,这就不太**秘密**了……😅
+
+我们将通过添加一些**额外的模型**来解决这些问题,而 SQLModel 将在这里大放异彩。✨
+
+### 创建多个模型
+
+在 **SQLModel** 中,任何含有 `table=True` 属性的模型类都是一个**表模型**。
+
+任何不含有 `table=True` 属性的模型类都是**数据模型**,这些实际上只是 Pydantic 模型(附带一些小的额外功能)。🤓
+
+有了 SQLModel,我们就可以利用**继承**来在所有情况下**避免重复**所有字段。
+
+#### `HeroBase` - 基类
+
+我们从一个 `HeroBase` 模型开始,该模型具有所有模型**共享的字段**:
+
+* `name`
+* `age`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *}
+
+#### `Hero` - *表模型*
+
+接下来,我们创建 `Hero` ,实际的*表模型*,并添加那些不总是在其他模型中的**额外字段**:
+
+* `id`
+* `secret_name`
+
+因为 `Hero` 继承自 HeroBase ,所以它**也**包含了在 `HeroBase` 中声明过的**字段**。因此 `Hero` 的所有字段为:
+
+* `id`
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *}
+
+#### `HeroPublic` - 公共*数据模型*
+
+接下来,我们创建一个 `HeroPublic` 模型,这是将**返回**给 API 客户端的模型。
+
+它包含与 `HeroBase` 相同的字段,因此不会包括 `secret_name` 。
+
+终于,我们英雄(hero)的身份得到了保护! 🥷
+
+它还重新声明了 `id: int` 。这样我们便与 API 客户端建立了一种**约定**,使他们始终可以期待 `id` 存在并且是一个整数 `int`(永远不会是 `None` )。
+
+/// tip
+
+确保返回模型始终提供一个值并且始终是 `int` (而不是 `None` )对 API 客户端非常有用,他们可以在这种确定性下编写更简单的代码。
+
+此外,**自动生成的客户端**将拥有更简洁的接口,这样与您的 API 交互的开发者就能更轻松地使用您的 API。😎
+
+///
+
+`HeroPublic` 中的所有字段都与 `HeroBase` 中的相同,其中 `id` 声明为 `int` (不是 `None` ):
+
+* `id`
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *}
+
+#### `HeroCreate` - 用于创建 hero 的*数据模型*
+
+现在我们创建一个 `HeroCreate` 模型,这是用于**验证**客户数据的模型。
+
+它不仅拥有与 `HeroBase` 相同的字段,还有 `secret_name` 。
+
+现在,当客户端**创建一个新的 hero** 时,他们会发送 `secret_name` ,它会被存储到数据库中,但这些 `secret_name` 不会通过 API 返回给客户端。
+
+/// tip
+
+这应当是**密码**被处理的方式:接收密码,但不要通过 API 返回它们。
+
+在存储密码之前,您还应该对密码的值进行**哈希**处理,**绝不要以明文形式存储它们**。
+
+///
+
+`HeroCreate` 的字段包括:
+
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *}
+
+#### `HeroUpdate` - 用于更新 hero 的*数据模型*
+
+在之前的应用程序中,我们没有办法**更新 hero**,但现在有了**多个模型**,我们便能做到这一点了。🎉
+
+`HeroUpdate` *数据模型*有些特殊,它包含创建新 hero 所需的**所有相同字段**,但所有字段都是**可选的**(它们都有默认值)。这样,当您更新一个 hero 时,您可以只发送您想要更新的字段。
+
+因为所有**字段实际上**都发生了**变化**(类型现在包括 `None` ,并且它们现在有一个默认值 `None` ),我们需要**重新声明**它们。
+
+我们会重新声明所有字段,因此我们并不是真的需要从 `HeroBase` 继承。我会让它继承只是为了保持一致,但这并不必要。这更多是个人喜好的问题。🤷
+
+`HeroUpdate` 的字段包括:
+
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *}
+
+### 使用 `HeroCreate` 创建并返回 `HeroPublic`
+
+既然我们有了**多个模型**,我们就可以对使用它们的应用程序部分进行更新。
+
+我们在请求中接收到一个 `HeroCreate` *数据模型*,然后从中创建一个 `Hero` *表模型*。
+
+这个新的*表模型* `Hero` 会包含客户端发送的字段,以及一个由数据库生成的 `id` 。
+
+然后我们将与函数中相同的*表模型* `Hero` 原样返回。但是由于我们使用 `HeroPublic` *数据模型*声明了 `response_model` ,**FastAPI** 会使用 `HeroPublic` 来验证和序列化数据。
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *}
+
+/// tip
+
+现在我们使用 `response_model=HeroPublic` 来代替**返回类型注释** `-> HeroPublic` ,因为我们返回的值实际上**并不是** `HeroPublic` 类型。
+
+如果我们声明了 `-> HeroPublic` ,您的编辑器和代码检查工具会抱怨(但也确实理所应当)您返回了一个 `Hero` 而不是一个 `HeroPublic` 。
+
+通过 `response_model` 的声明,我们让 **FastAPI** 按照它自己的方式处理,而不会干扰类型注解以及编辑器和其他工具提供的帮助。
+
+///
+
+### 用 `HeroPublic` 读取 Hero
+
+我们可以像之前一样**读取** `Hero` 。同样,使用 `response_model=list[HeroPublic]` 确保正确地验证和序列化数据。
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *}
+
+### 用 `HeroPublic` 读取单个 Hero
+
+我们可以**读取**单个 `hero` 。
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *}
+
+### 用 `HeroUpdate` 更新单个 Hero
+
+我们可以**更新**单个 `hero` 。为此,我们会使用 HTTP 的 `PATCH` 操作。
+
+在代码中,我们会得到一个 `dict` ,其中包含客户端发送的所有数据,**只有客户端发送的数据**,并排除了任何一个仅仅作为默认值存在的值。为此,我们使用 `exclude_unset=True` 。这是最主要的技巧。🪄
+
+然后我们会使用 `hero_db.sqlmodel_update(hero_data)` ,来利用 `hero_data` 的数据更新 `hero_db` 。
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *}
+
+### (又一次)删除单个 Hero
+
+**删除**一个 hero 基本保持不变。
+
+我们不会满足在这一部分中重构一切的愿望。😅
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *}
+
+### (又一次)运行应用程序
+
+您可以再运行一次应用程序:
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+您会在 `/docs` API UI 看到它现在已经更新,并且在进行创建 hero 等操作时,它不会再期望从客户端接收 `id` 数据。
+
+
+

+
+
+## 总结
+
+您可以使用 **SQLModel** 与 SQL 数据库进行交互,并通过*数据模型*和*表模型*简化代码。
+
+您可以在 SQLModel 的文档中学习到更多内容,其中有一个更详细的关于如何将 SQLModel 与 FastAPI 一起使用的教程。🚀
From 5fc3e9102039290d918465d6409f731d7679cc02 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Sun, 15 Dec 2024 17:12:47 +0000
Subject: [PATCH 106/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 8b3e4bc1b..1d0777803 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/sql-databases.md`. PR [#13051](https://github.com/fastapi/fastapi/pull/13051) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/query-params-str-validations.md`. PR [#12928](https://github.com/fastapi/fastapi/pull/12928) by [@Vincy1230](https://github.com/Vincy1230).
* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/header-param-models.md`. PR [#13040](https://github.com/fastapi/fastapi/pull/13040) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/path-params.md`. PR [#12926](https://github.com/fastapi/fastapi/pull/12926) by [@Vincy1230](https://github.com/Vincy1230).
From d03ef24c9205dde9f215cb401e3b22e53279b3da Mon Sep 17 00:00:00 2001
From: YungYueh ChanLee
Date: Wed, 18 Dec 2024 05:16:46 +0800
Subject: [PATCH 107/242] =?UTF-8?q?=F0=9F=8C=90=20Update=20Traditional=20C?=
=?UTF-8?q?hinese=20translation=20for=20`docs/zh-hant/docs/tutorial/index.?=
=?UTF-8?q?md`=20(#13075)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh-hant/docs/tutorial/index.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/zh-hant/docs/tutorial/index.md b/docs/zh-hant/docs/tutorial/index.md
index 2aaa78b22..ae0056f52 100644
--- a/docs/zh-hant/docs/tutorial/index.md
+++ b/docs/zh-hant/docs/tutorial/index.md
@@ -85,9 +85,9 @@ $ pip install "fastapi[standard]"
/// note
-當你使用 `pip install "fastapi[standard]"` 安裝時,會包含一些預設的可選標準相依項。
+當你使用 `pip install "fastapi[standard]"` 安裝時,會包含一些預設的可選標準依賴項。
-如果你不想包含那些可選的相依項,你可以使用 `pip install fastapi` 來安裝。
+如果你不想包含那些可選的依賴項,你可以使用 `pip install fastapi` 來安裝。
///
From b19af36826ea9e7e64ba847fc90283c4f5a67dd0 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 17 Dec 2024 21:18:25 +0000
Subject: [PATCH 108/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 1d0777803..468e76ab5 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Update Traditional Chinese translation for `docs/zh-hant/docs/tutorial/index.md`. PR [#13075](https://github.com/fastapi/fastapi/pull/13075) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/sql-databases.md`. PR [#13051](https://github.com/fastapi/fastapi/pull/13051) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/query-params-str-validations.md`. PR [#12928](https://github.com/fastapi/fastapi/pull/12928) by [@Vincy1230](https://github.com/Vincy1230).
* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/header-param-models.md`. PR [#13040](https://github.com/fastapi/fastapi/pull/13040) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
From a0f64948034269f76a7f59025f03a4030d172ac7 Mon Sep 17 00:00:00 2001
From: Zhongheng Cheng
Date: Tue, 17 Dec 2024 16:18:42 -0500
Subject: [PATCH 109/242] =?UTF-8?q?=F0=9F=8C=90=20Update=20Chinese=20trans?=
=?UTF-8?q?lation=20for=20`docs/zh/docs/advanced/testing-dependencies.md`?=
=?UTF-8?q?=20(#13066)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh/docs/advanced/testing-dependencies.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/zh/docs/advanced/testing-dependencies.md b/docs/zh/docs/advanced/testing-dependencies.md
index 620539fd1..8d53a6d49 100644
--- a/docs/zh/docs/advanced/testing-dependencies.md
+++ b/docs/zh/docs/advanced/testing-dependencies.md
@@ -28,7 +28,7 @@
这样一来,**FastAPI** 就会调用覆盖依赖项,不再调用原依赖项。
-{* ../../docs_src/dependency_testing/tutorial001.py hl[26:27,30] *}
+{* ../../docs_src/dependency_testing/tutorial001_an_py310.py hl[26:27,30] *}
/// tip | 提示
From dae2b957ba0382f44c206e074e0b2e2dbd3c53f6 Mon Sep 17 00:00:00 2001
From: alv2017
Date: Tue, 17 Dec 2024 23:20:20 +0200
Subject: [PATCH 110/242] =?UTF-8?q?=F0=9F=8C=90=20Add=20Russian=20translat?=
=?UTF-8?q?ion=20for=20`/docs/ru/docs/tutorial/sql-databases.md`=20(#13079?=
=?UTF-8?q?)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/ru/docs/tutorial/sql-databases.md | 358 +++++++++++++++++++++++++
1 file changed, 358 insertions(+)
create mode 100644 docs/ru/docs/tutorial/sql-databases.md
diff --git a/docs/ru/docs/tutorial/sql-databases.md b/docs/ru/docs/tutorial/sql-databases.md
new file mode 100644
index 000000000..b127e44d5
--- /dev/null
+++ b/docs/ru/docs/tutorial/sql-databases.md
@@ -0,0 +1,358 @@
+# SQL (реляционные) базы данных
+
+**FastAPI** не требует использования реляционной базы данных. Вы можете воспользоваться любой базой данных, которой хотите.
+
+В этом разделе мы продемонстрируем, как работать с SQLModel.
+
+Библиотека **SQLModel** построена на основе SQLAlchemy и Pydantic. Она была разработана автором **FastAPI** специально для приложений на основе FastAPI, которые используют **реляционные базы данных**.
+
+/// tip | Подсказка
+
+Вы можете воспользоваться любой библиотекой для работы с реляционными (SQL) или нереляционными (NoSQL) базами данных. (Их ещё называют **ORM** библиотеками). FastAPI не принуждает вас к использованию чего-либо конкретного. 😎
+
+///
+
+В основе SQLModel лежит SQLAlchemy, поэтому вы спокойно можете использовать любую базу данных, поддерживаемую SQLAlchemy (и, соответственно, поддерживаемую SQLModel), например:
+
+* PostgreSQL
+* MySQL
+* SQLite
+* Oracle
+* Microsoft SQL Server, и т.д.
+
+В данном примере мы будем использовать базу данных **SQLite**, т.к. она состоит из единственного файла и поддерживается встроенными библиотеками Python. Таким образом, вы сможете скопировать данный пример и запустить его как он есть.
+
+В дальнейшем, для продакшн-версии вашего приложения, возможно, вам стоит использовать серверную базу данных, например, **PostgreSQL**.
+
+/// tip | Подсказка
+
+Существует официальный генератор проектов на **FastAPI** и **PostgreSQL**, который также включает frontend и дополнительные инструменты https://github.com/fastapi/full-stack-fastapi-template
+
+///
+
+Это очень простое и короткое руководство, поэтому, если вы хотите узнать о базах данных в целом, об SQL, разобраться с более продвинутым функционалом, то воспользуйтесь документацией SQLModel.
+
+## Установка `SQLModel`
+
+Создайте виртуальное окружение [virtual environment](../virtual-environments.md){.internal-link target=_blank}, активируйте его и установите `sqlmodel`:
+
+
+
+```console
+$ pip install sqlmodel
+---> 100%
+```
+
+
+
+## Создание приложения с единственной моделью
+
+Мы начнем с создания наиболее простой первой версии нашего приложения с одной единственной моделью **SQLModel**.
+
+В дальнейшем с помощью **дополнительных моделей** мы его улучшим и сделаем более безопасным и универсальным. 🤓
+
+### Создание моделей
+
+Импортируйте `SQLModel` и создайте модель базы данных:
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *}
+
+Класс `Hero` очень напоминает модель Pydantic (фактически, под капотом, *это и есть модель Pydantic*).
+
+Но есть и некоторые различия
+
+* `table=True` для SQLModel означает, что это *модель-таблица*, которая должна представлять **таблицу** в реляционной базе данных. Это не просто *модель данных* (в отличие от обычного класса в Pydantic).
+
+* `Field(primary_key=True)` для SQLModel означает, что поле `id` является первичным ключом в таблице базы данных (вы можете подробнее узнать о первичных ключах баз данных в документации по SQLModel).
+
+ Тип `int | None` сигнализирует для SQLModel, что столбец таблицы базы данных должен иметь тип `INTEGER`, или иметь пустое значение `NULL`.
+
+* `Field(index=True)` для SQLModel означает, что нужно создать **SQL индекс** для данного столбца. Это обеспечит более быстрый поиск при чтении данных, отфильтрованных по данному столбцу.
+
+ SQLModel будет знать, что данные типа `str`, будут представлены в базе данных как `TEXT` (или `VARCHAR`, в зависимости от типа базы данных).
+
+### Создание соединения с базой данных (Engine)
+
+В SQLModel объект соединения `engine` (по сути это `Engine` из SQLAlchemy) **содержит пул соединений** к базе данных.
+
+Для обеспечения всех подключений приложения к одной базе данных нужен только один объект соединения `engine`.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *}
+
+Использование настройки `check_same_thread=False` позволяет FastAPI использовать одну и ту же SQLite базу данных в различных потоках (threads). Это необходимо, когда **один запрос** использует **более одного потока** (например, в зависимостях).
+
+Не беспокойтесь, учитывая структуру кода, мы позже позаботимся о том, чтобы использовать **отдельную SQLModel-сессию на каждый отдельный запрос**, это как раз то, что пытается обеспечить `check_same_thread`.
+
+### Создание таблиц
+
+Далее мы добавляем функцию, использующую `SQLModel.metadata.create_all(engine)`, для того, чтобы создать **таблицы** для каждой из **моделей таблицы**.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *}
+
+### Создание зависимости Session
+
+Сессия базы данных (**`Session`**) хранит **объекты в памяти** и отслеживает любые необходимые изменения в данных, а затем **использует `engine`** для коммуникации с базой данных.
+
+Мы создадим FastAPI-**зависимость** с помощью `yield`, которая будет создавать новую сессию (Session) для каждого запроса. Это как раз и обеспечит использование отдельной сессии на каждый отдельный запрос. 🤓
+
+Затем мы создадим объявленную (`Annotated`) зависимость `SessionDep`. Мы сделаем это для того, чтобы упростить остальной код, который будет использовать эту зависимость.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[25:30] hl[25:27,30] *}
+
+### Создание таблиц базы данных при запуске приложения
+
+Мы будем создавать таблицы базы данных при запуске приложения.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *}
+
+В данном примере мы создаем таблицы при наступлении события запуска приложения.
+
+В продуктовом приложении вы, скорее всего, будете использовать скрипт для миграции базы данных, который выполняется перед запуском приложения. 🤓
+
+/// tip | Подсказка
+
+В SQLModel будут включены утилиты миграции, входящие в состав Alembic, но на данный момент вы просто можете использовать
+Alembic напрямую.
+
+///
+
+### Создание героя (Hero)
+
+Каждая модель в SQLModel является также моделью Pydantic, поэтому вы можете использовать её при **объявлении типов**, точно также, как и модели Pydantic.
+
+Например, при объявлении параметра типа `Hero`, она будет считана из **тела JSON**.
+
+Точно также, вы можете использовать её при объявлении типа значения, возвращаемого функцией, и тогда структурированные данные будут отображены через пользовательский интерфейс автоматически сгенерированной документации FastAPI.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *}
+
+Мы используем зависимость `SessionDep` (сессию базы данных) для того, чтобы добавить нового героя `Hero` в объект сессии (`Session`), сохранить изменения в базе данных, обновить данные героя и затем вернуть их.
+
+### Чтение данных о героях
+
+Мы можем **читать** данные героев из базы данных с помощью `select()`. Мы можем включить `limit` и `offset` для постраничного считывания результатов.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[48:55] hl[51:52,54] *}
+
+### Чтение данных отдельного героя
+
+Мы можем прочитать данные отдельного героя (`Hero`).
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[58:63] hl[60] *}
+
+### Удаление данных героя
+
+Мы также можем удалить героя `Hero` из базы данных.
+
+{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[66:73] hl[71] *}
+
+### Запуск приложения
+
+Вы можете запустить приложение следующим образом:
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Далее перейдите в пользовательский интерфейс API `/docs`. Вы увидите, что **FastAPI** использует модели для создания документации API. Эти же модели используются для сериализации и проверки данных.
+
+
+

+
+
+## Добавление в приложение дополнительных (вспомогательных) моделей
+
+Теперь давайте проведём **рефакторинг** нашего приложения, чтобы сделать его более безопасным и более универсальным.
+
+Обратите внимание, что на данном этапе наше приложение позволяет на уровне клиента определять `id` создаваемого героя (`Hero`). 😱
+
+Мы не можем этого допустить, т.к. существует риск переписать уже присвоенные `id` в базе данных. Присвоение `id` должно происходить **на уровне бэкэнда (backend)** или **на уровне базы данных**, но никак **не на уровне клиента**.
+
+Кроме того, мы создаем секретное имя `secret_name` для героя, но пока что, мы возвращаем его повсеместно, и это слабо напоминает **секретность**... 😅
+
+Мы поправим это с помощью нескольких дополнительных (вспомогательных) моделей. Вот где SQLModel по-настоящему покажет себя. ✨
+
+### Создание дополнительных моделей
+
+В **SQLModel**, любая модель с параметром `table=True` является **моделью таблицы**.
+
+Любая модель, не содержащая `table=True` является **моделью данных**, это по сути обычные модели Pydantic (с несколько расширенным функционалом). 🤓
+
+С помощью SQLModel мы можем использовать **наследование**, что поможет нам **избежать дублирования** всех полей.
+
+#### Базовый класс `HeroBase`
+
+Давайте начнём с модели `HeroBase`, которая содержит поля, общие для всех моделей:
+
+* `name`
+* `age`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *}
+
+#### Модель таблицы `Hero`
+
+Далее давайте создадим **модель таблицы** `Hero` с дополнительными полями, которых может не быть в других моделях:
+
+* `id`
+* `secret_name`
+
+Модель `Hero` наследует от `HeroBase`, и поэтому включает также поля из `HeroBase`. Таким образом, все поля, содержащиеся в `Hero`, будут следующими:
+
+* `id`
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *}
+
+#### Публичная модель данных `HeroPublic`
+
+Далее мы создадим модель `HeroPublic`. Мы будем возвращать её клиентам API.
+
+Она включает в себя те же поля, что и `HeroBase`, и, соответственно, поле `secret_name` в ней отсутствует.
+
+Наконец-то личность наших героев защищена! 🥷
+
+В модели `HeroPublic` также объявляется поле `id: int`. Мы как бы заключаем договоренность с API клиентом, на то, что передаваемые данные всегда должны содержать поле `id`, и это поле должно содержать целое число (и никогда не содержать `None`).
+
+/// tip | Подсказка
+
+Модель ответа, гарантирующая наличие поля со значением типа `int` (не `None`), очень полезна при разработке API клиентов. Определенность в передаваемых данных может обеспечить написание более простого кода.
+
+Также **автоматически генерируемые клиенты** будут иметь более простой интерфейс. И в результате жизнь разработчиков, использующих ваш API, станет значительно легче. 😎
+
+///
+
+`HeroPublic` содержит все поля `HeroBase`, а также поле `id`, объявленное как `int` (не `None`):
+
+* `id`
+* `name`
+* `age`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *}
+
+#### Модель для создания героя `HeroCreate`
+
+Сейчас мы создадим модель `HeroCreate`. Эта модель будет использоваться для проверки данных, переданных клиентом.
+
+Она содержит те же поля, что и `HeroBase`, а также поле `secret_name`.
+
+Теперь, при создании нового героя, клиенты будут передавать секретное имя `secret_name`, которое будет сохранено в базе данных, но не будет возвращено в ответе API клиентам.
+
+/// tip | Подсказка
+
+Вот как нужно работать с **паролями**: получайте их, но не возвращайте их через API.
+
+Также хэшируйте значения паролей перед тем, как их сохранить. Ни в коем случае не храните пароли в открытом виде, как обычный текст.
+
+///
+
+Поля модели `HeroCreate`:
+
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *}
+
+#### Модель для обновления данных героя `HeroUpdate`
+
+В предыдущих версиях нашей программы мы не могли обновить данные героя, теперь, воспользовавшись дополнительными моделями, мы сможем это сделать. 🎉
+
+Модель данных `HeroUpdate` в некотором смысле особенная. Она содержит все те же поля, что и модель создания героя, но все поля модели являются **необязательными**. (Все они имеют значение по умолчанию.) Таким образом, при обновлении данных героя, вам достаточно передать только те поля, которые требуют изменения.
+
+Поскольку **все поля по сути меняются** (теперь тип каждого поля допускает значение `None` и значение по умолчанию `None`), мы должны их **объявить заново**.
+
+Фактически, нам не нужно наследоваться от `HeroBase`, потому что мы будем заново объявлять все поля. Я оставлю наследование просто для поддержания общего стиля, но оно (наследование) здесь необязательно. 🤷
+
+Поля `HeroUpdate`:
+
+* `name`
+* `age`
+* `secret_name`
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *}
+
+### Создание героя с помощью `HeroCreate` и возвращение результатов с помощью `HeroPublic`
+
+Теперь, когда у нас есть дополнительные модели, мы можем обновить те части приложения, которые их используют.
+
+Вместе c запросом на создание героя мы получаем объект данных `HeroCreate`, и создаем на его основе объект модели таблицы `Hero`.
+
+Созданный объект *модели таблицы* `Hero` будет иметь все поля, переданные клиентом, а также поле `id`, сгенерированное базой данных.
+
+Далее функция вернёт объект *модели таблицы* `Hero`. Но поскольку, мы объявили `HeroPublic` как модель ответа, то **FastAPI** будет использовать именно её для проверки и сериализации данных.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *}
+
+/// tip | Подсказка
+
+Теперь мы используем модель ответа `response_model=HeroPublic`, вместо того, чтобы объявить тип возвращаемого значения как `-> HeroPublic`. Мы это делаем потому, что тип возвращаемого значения не относится к `HeroPublic`.
+
+Если бы мы объявили тип возвращаемого значения как `-> HeroPublic`, то редактор и линтер начали бы ругаться (и вполне справедливо), что возвращаемое значение принадлежит типу `Hero`, а совсем не `HeroPublic`.
+
+Объявляя модель ответа в `response_model`, мы как бы говорим **FastAPI**: делай свое дело, не вмешиваясь в аннотацию типов и не полагаясь на помощь редактора или других инструментов.
+
+///
+
+### Чтение данных героев с помощью `HeroPublic`
+
+Мы можем проделать то же самое **для чтения данных** героев. Мы применим модель ответа `response_model=list[HeroPublic]`, и тем самым обеспечим правильную проверку и сериализацию данных.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *}
+
+### Чтение данных отдельного героя с помощью `HeroPublic`
+
+Мы можем **прочитать** данные отдельного героя:
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *}
+
+### Обновление данных героя с помощью `HeroUpdate`
+
+Мы можем **обновить данные героя**. Для этого мы воспользуемся HTTP методом `PATCH`.
+
+В коде мы получаем объект словаря `dict` с данными, переданными клиентом (т.е. **только c данными, переданными клиентом**, исключая любые значения, которые могли бы быть там только потому, что они являются значениями по умолчанию). Для того чтобы сделать это, мы воспользуемся опцией `exclude_unset=True`. В этом главная хитрость. 🪄
+
+Затем мы применим `hero_db.sqlmodel_update(hero_data)`, и обновим `hero_db`, использовав данные `hero_data`.
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *}
+
+### Удалим героя ещё раз
+
+Операция **удаления** героя практически не меняется.
+
+В данном случае желание *`отрефакторить всё`* остаётся неудовлетворенным. 😅
+
+{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *}
+
+### Снова запустим приложение
+
+Вы можете снова запустить приложение:
+
+
+
+```console
+$ fastapi dev main.py
+
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+
+
+Если вы перейдете в пользовательский интерфейс API `/docs`, то вы увидите, что он был обновлен, и больше не принимает параметра `id` от клиента при создании нового героя, и т.д.
+
+
+

+
+
+## Резюме
+
+Вы можете использовать **SQLModel** для взаимодействия с реляционными базами данных, а также для упрощения работы с **моделями данных** и **моделями таблиц**.
+
+Вы можете узнать гораздо больше информации в документации по **SQLModel**. Там вы найдете более подробное мини-руководство по использованию SQLModel с **FastAPI**. 🚀
From 52d8ad8bfaf839bb6f0784ec44912d9d49ea842b Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 17 Dec 2024 21:21:10 +0000
Subject: [PATCH 111/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 468e76ab5..3b288f0a2 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Update Chinese translation for `docs/zh/docs/advanced/testing-dependencies.md`. PR [#13066](https://github.com/fastapi/fastapi/pull/13066) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Update Traditional Chinese translation for `docs/zh-hant/docs/tutorial/index.md`. PR [#13075](https://github.com/fastapi/fastapi/pull/13075) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/sql-databases.md`. PR [#13051](https://github.com/fastapi/fastapi/pull/13051) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Update Chinese translation for `docs/zh/docs/tutorial/query-params-str-validations.md`. PR [#12928](https://github.com/fastapi/fastapi/pull/12928) by [@Vincy1230](https://github.com/Vincy1230).
From 0d8e9663d818686c2bcec9d4e2cea0a495d588e6 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 17 Dec 2024 21:21:39 +0000
Subject: [PATCH 112/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 3b288f0a2..2ddf8686c 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Add Russian translation for `/docs/ru/docs/tutorial/sql-databases.md`. PR [#13079](https://github.com/fastapi/fastapi/pull/13079) by [@alv2017](https://github.com/alv2017).
* 🌐 Update Chinese translation for `docs/zh/docs/advanced/testing-dependencies.md`. PR [#13066](https://github.com/fastapi/fastapi/pull/13066) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Update Traditional Chinese translation for `docs/zh-hant/docs/tutorial/index.md`. PR [#13075](https://github.com/fastapi/fastapi/pull/13075) by [@codingjenny](https://github.com/codingjenny).
* 🌐 Add Chinese translation for `docs/zh/docs/tutorial/sql-databases.md`. PR [#13051](https://github.com/fastapi/fastapi/pull/13051) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
From a559f8f3971ca27f284dc031f3f4510bbbf5c6e0 Mon Sep 17 00:00:00 2001
From: Zhibang Yue
Date: Wed, 18 Dec 2024 05:28:37 +0800
Subject: [PATCH 113/242] =?UTF-8?q?=F0=9F=8C=90=20Add=20Chinese=20translat?=
=?UTF-8?q?ion=20for=20`docs/zh/docs/advanced/events.md`=20(#12512)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh/docs/advanced/events.md | 132 ++++++++++++++++++++++++++++++--
1 file changed, 125 insertions(+), 7 deletions(-)
diff --git a/docs/zh/docs/advanced/events.md b/docs/zh/docs/advanced/events.md
index 66f5af2e3..5ade0f0ff 100644
--- a/docs/zh/docs/advanced/events.md
+++ b/docs/zh/docs/advanced/events.md
@@ -1,16 +1,114 @@
-# 事件:启动 - 关闭
+# 生命周期事件
-**FastAPI** 支持定义在应用启动前,或应用关闭后执行的事件处理器(函数)。
+你可以定义在应用**启动**前执行的逻辑(代码)。这意味着在应用**开始接收请求**之前,这些代码只会被执行**一次**。
-事件函数既可以声明为异步函数(`async def`),也可以声明为普通函数(`def`)。
+同样地,你可以定义在应用**关闭**时应执行的逻辑。在这种情况下,这段代码将在**处理可能的多次请求后**执行**一次**。
+
+因为这段代码在应用开始接收请求**之前**执行,也会在处理可能的若干请求**之后**执行,它覆盖了整个应用程序的**生命周期**("生命周期"这个词很重要😉)。
+
+这对于设置你需要在整个应用中使用的**资源**非常有用,这些资源在请求之间**共享**,你可能需要在之后进行**释放**。例如,数据库连接池,或加载一个共享的机器学习模型。
+
+## 用例
+
+让我们从一个示例用例开始,看看如何解决它。
+
+假设你有几个**机器学习的模型**,你想要用它们来处理请求。
+
+相同的模型在请求之间是共享的,因此并非每个请求或每个用户各自拥有一个模型。
+
+假设加载模型可能**需要相当长的时间**,因为它必须从**磁盘**读取大量数据。因此你不希望每个请求都加载它。
+
+你可以在模块/文件的顶部加载它,但这也意味着即使你只是在运行一个简单的自动化测试,它也会**加载模型**,这样测试将**变慢**,因为它必须在能够独立运行代码的其他部分之前等待模型加载完成。
+
+这就是我们要解决的问题——在处理请求前加载模型,但只是在应用开始接收请求前,而不是代码执行时。
+
+## 生命周期 lifespan
+
+你可以使用`FastAPI()`应用的`lifespan`参数和一个上下文管理器(稍后我将为你展示)来定义**启动**和**关闭**的逻辑。
+
+让我们从一个例子开始,然后详细介绍。
+
+我们使用`yield`创建了一个异步函数`lifespan()`像这样:
+
+```Python hl_lines="16 19"
+{!../../docs_src/events/tutorial003.py!}
+```
+
+在这里,我们在 `yield` 之前将(虚拟的)模型函数放入机器学习模型的字典中,以此模拟加载模型的耗时**启动**操作。这段代码将在应用程序**开始处理请求之前**执行,即**启动**期间。
+
+然后,在 `yield` 之后,我们卸载模型。这段代码将会在应用程序**完成处理请求后**执行,即在**关闭**之前。这可以释放诸如内存或 GPU 之类的资源。
+
+/// tip | 提示
+
+**关闭**事件只会在你停止应用时触发。
+
+可能你需要启动一个新版本,或者你只是你厌倦了运行它。 🤷
+
+///
+
+## 生命周期函数
+
+首先要注意的是,我们定义了一个带有 `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!}
+```
+
+在 Python 中, **上下文管理器**是一个你可以在 `with` 语句中使用的东西,例如,`open()` 可以作为上下文管理器使用。
+
+```Python
+with open("file.txt") as file:
+ file.read()
+```
+
+Python 的最近几个版本也有了一个**异步上下文管理器**,你可以通过 `async with` 来使用:
+
+```Python
+async with lifespan(app):
+ await do_stuff()
+```
+
+你可以像上面一样创建了一个上下文管理器或者异步上下文管理器,它的作用是在进入 `with` 块时,执行 `yield` 之前的代码,并且在离开 `with` 块时,执行 `yield` 后面的代码。
+
+但在我们上面的例子里,我们并不是直接使用,而是传递给 FastAPI 来供其使用。
+
+`FastAPI()` 的 `lifespan` 参数接受一个**异步上下文管理器**,所以我们可以把我们新定义的上下文管理器 `lifespan` 传给它。
+
+```Python hl_lines="22"
+{!../../docs_src/events/tutorial003.py!}
+```
+
+## 替代事件(弃用)
/// warning | 警告
-**FastAPI** 只执行主应用中的事件处理器,不执行[子应用 - 挂载](sub-applications.md){.internal-link target=_blank}中的事件处理器。
+配置**启动**和**关闭**事件的推荐方法是使用 `FastAPI()` 应用的 `lifespan` 参数,如前所示。如果你提供了一个 `lifespan` 参数,启动(`startup`)和关闭(`shutdown`)事件处理器将不再生效。要么使用 `lifespan`,要么配置所有事件,两者不能共用。
+
+你可以跳过这一部分。
///
-## `startup` 事件
+有一种替代方法可以定义在**启动**和**关闭**期间执行的逻辑。
+
+**FastAPI** 支持定义在应用启动前,或应用关闭时执行的事件处理器(函数)。
+
+事件函数既可以声明为异步函数(`async def`),也可以声明为普通函数(`def`)。
+
+### `startup` 事件
使用 `startup` 事件声明 `app` 启动前运行的函数:
@@ -22,7 +120,7 @@
只有所有 `startup` 事件处理器运行完毕,**FastAPI** 应用才开始接收请求。
-## `shutdown` 事件
+### `shutdown` 事件
使用 `shutdown` 事件声明 `app` 关闭时运行的函数:
@@ -48,8 +146,28 @@
///
+### `startup` 和 `shutdown` 一起使用
+
+启动和关闭的逻辑很可能是连接在一起的,你可能希望启动某个东西然后结束它,获取一个资源然后释放它等等。
+
+在不共享逻辑或变量的不同函数中处理这些逻辑比较困难,因为你需要在全局变量中存储值或使用类似的方式。
+
+因此,推荐使用 `lifespan` 。
+
+## 技术细节
+
+只是为好奇者提供的技术细节。🤓
+
+在底层,这部分是生命周期协议的一部分,参见 ASGI 技术规范,定义了称为启动(`startup`)和关闭(`shutdown`)的事件。
+
/// info | 说明
-有关事件处理器的详情,请参阅 Starlette 官档 - 事件。
+有关事件处理器的详情,请参阅 Starlette 官档 - 事件。
+
+包括如何处理生命周期状态,这可以用于程序的其他部分。
///
+
+## 子应用
+
+🚨 **FastAPI** 只会触发主应用中的生命周期事件,不包括[子应用 - 挂载](sub-applications.md){.internal-link target=_blank}中的。
From 334c9bc7ad1a7c15db633352495a2a72f3d73b04 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 17 Dec 2024 21:29:01 +0000
Subject: [PATCH 114/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index 2ddf8686c..aab6c6334 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Add Chinese translation for `docs/zh/docs/advanced/events.md`. PR [#12512](https://github.com/fastapi/fastapi/pull/12512) by [@ZhibangYue](https://github.com/ZhibangYue).
* 🌐 Add Russian translation for `/docs/ru/docs/tutorial/sql-databases.md`. PR [#13079](https://github.com/fastapi/fastapi/pull/13079) by [@alv2017](https://github.com/alv2017).
* 🌐 Update Chinese translation for `docs/zh/docs/advanced/testing-dependencies.md`. PR [#13066](https://github.com/fastapi/fastapi/pull/13066) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Update Traditional Chinese translation for `docs/zh-hant/docs/tutorial/index.md`. PR [#13075](https://github.com/fastapi/fastapi/pull/13075) by [@codingjenny](https://github.com/codingjenny).
From 2b788666628475b708df990552beeca201f9b9f6 Mon Sep 17 00:00:00 2001
From: Yarema Kertytsky <83857001+ykertytsky@users.noreply.github.com>
Date: Tue, 17 Dec 2024 23:33:34 +0200
Subject: [PATCH 115/242] =?UTF-8?q?=F0=9F=8C=90=20Add=20Ukrainian=20transl?=
=?UTF-8?q?ation=20for=20`docs/uk/docs/fastapi-cli.md`=20(#13020)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/uk/docs/fastapi-cli.md | 83 +++++++++++++++++++++++++++++++++++++
1 file changed, 83 insertions(+)
create mode 100644 docs/uk/docs/fastapi-cli.md
diff --git a/docs/uk/docs/fastapi-cli.md b/docs/uk/docs/fastapi-cli.md
new file mode 100644
index 000000000..6bbbbc326
--- /dev/null
+++ b/docs/uk/docs/fastapi-cli.md
@@ -0,0 +1,83 @@
+# FastAPI CLI
+
+**FastAPI CLI** це програма командного рядка, яку Ви можете використовувати, щоб обслуговувати Ваш додаток FastAPI, керувати Вашими FastApi проектами, тощо.
+
+Коли Ви встановлюєте FastApi (тобто виконуєте `pip install "fastapi[standard]"`), Ви також встановлюєте пакунок `fastapi-cli`, цей пакунок надає команду `fastapi` в терміналі.
+
+Для запуску Вашого FastAPI проекту для розробки, Ви можете скористатись командою `fastapi dev`:
+
+
+
+```console
+$ fastapi dev main.py
+INFO Using path main.py
+INFO Resolved absolute path /home/user/code/awesomeapp/main.py
+INFO Searching for package file structure from directories with __init__.py files
+INFO Importing from /home/user/code/awesomeapp
+
+ ╭─ Python module file ─╮
+ │ │
+ │ 🐍 main.py │
+ │ │
+ ╰──────────────────────╯
+
+INFO Importing module main
+INFO Found importable FastAPI app
+
+ ╭─ Importable FastAPI app ─╮
+ │ │
+ │ from main import app │
+ │ │
+ ╰──────────────────────────╯
+
+INFO Using import string main:app
+
+ ╭────────── FastAPI CLI - Development mode ───────────╮
+ │ │
+ │ Serving at: http://127.0.0.1:8000 │
+ │ │
+ │ API docs: http://127.0.0.1:8000/docs │
+ │ │
+ │ Running in development mode, for production use: │
+ │ │
+ │ fastapi run │
+ │ │
+ ╰─────────────────────────────────────────────────────╯
+
+INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [2265862] using WatchFiles
+INFO: Started server process [2265873]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+Програма командного рядка `fastapi` це **FastAPI CLI**.
+
+FastAPI CLI приймає шлях до Вашої Python програми (напр. `main.py`) і автоматично виявляє екземпляр `FastAPI` (зазвичай названий `app`), обирає коректний процес імпорту, а потім обслуговує його.
+
+Натомість, для запуску у продакшн використовуйте `fastapi run`. 🚀
+
+Всередині **FastAPI CLI** використовує Uvicorn, високопродуктивний, production-ready, ASGI cервер. 😎
+
+## `fastapi dev`
+
+Використання `fastapi dev` ініціює режим розробки.
+
+За замовчуванням, **автоматичне перезавантаження** увімкнене, автоматично перезавантажуючи сервер кожного разу, коли Ви змінюєте Ваш код. Це ресурсо-затратно, та може бути менш стабільним, ніж коли воно вимкнене. Ви повинні використовувати його тільки під час розробки. Воно також слухає IP-адресу `127.0.0.1`, що є IP Вашого девайсу для самостійної комунікації з самим собою (`localhost`).
+
+## `fastapi run`
+
+Виконання `fastapi run` запустить FastAPI у продакшн-режимі за замовчуванням.
+
+За замовчуванням, **автоматичне перезавантаження** вимкнене. Воно також прослуховує IP-адресу `0.0.0.0`, що означає всі доступні IP адреси, тим самим даючи змогу будь-кому комунікувати з девайсом. Так Ви зазвичай будете запускати його у продакшн, наприклад у контейнері.
+
+В більшості випадків Ви можете (і маєте) мати "termination proxy", який обробляє HTTPS для Вас, це залежить від способу розгортання вашого додатку, Ваш провайдер може зробити це для Вас, або Вам потрібно налаштувати його самостійно.
+
+/// tip
+
+Ви можете дізнатись більше про це у [документації про розгортування](deployment/index.md){.internal-link target=_blank}.
+
+///
From 3ca5fe1709cd899f3f0f69b72e62681f075a3969 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 17 Dec 2024 21:34:01 +0000
Subject: [PATCH 116/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index aab6c6334..c3bacaf12 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Add Ukrainian translation for `docs/uk/docs/fastapi-cli.md`. PR [#13020](https://github.com/fastapi/fastapi/pull/13020) by [@ykertytsky](https://github.com/ykertytsky).
* 🌐 Add Chinese translation for `docs/zh/docs/advanced/events.md`. PR [#12512](https://github.com/fastapi/fastapi/pull/12512) by [@ZhibangYue](https://github.com/ZhibangYue).
* 🌐 Add Russian translation for `/docs/ru/docs/tutorial/sql-databases.md`. PR [#13079](https://github.com/fastapi/fastapi/pull/13079) by [@alv2017](https://github.com/alv2017).
* 🌐 Update Chinese translation for `docs/zh/docs/advanced/testing-dependencies.md`. PR [#13066](https://github.com/fastapi/fastapi/pull/13066) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
From a9f63e5d222795cdd7ab853997916fb662551761 Mon Sep 17 00:00:00 2001
From: Zhongheng Cheng
Date: Tue, 17 Dec 2024 16:49:06 -0500
Subject: [PATCH 117/242] =?UTF-8?q?=F0=9F=8C=90=20Add=20Chinese=20translat?=
=?UTF-8?q?ion=20for=20`docs/zh/docs/advanced/async-tests.md`=20(#13074)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh/docs/advanced/async-tests.md | 99 ++++++++++++++++++++++++++++
1 file changed, 99 insertions(+)
create mode 100644 docs/zh/docs/advanced/async-tests.md
diff --git a/docs/zh/docs/advanced/async-tests.md b/docs/zh/docs/advanced/async-tests.md
new file mode 100644
index 000000000..b5ac15b5b
--- /dev/null
+++ b/docs/zh/docs/advanced/async-tests.md
@@ -0,0 +1,99 @@
+# 异步测试
+
+您已经了解了如何使用 `TestClient` 测试 **FastAPI** 应用程序。但是到目前为止,您只了解了如何编写同步测试,而没有使用 `async` 异步函数。
+
+在测试中能够使用异步函数可能会很有用,比如当您需要异步查询数据库的时候。想象一下,您想要测试向 FastAPI 应用程序发送请求,然后验证您的后端是否成功在数据库中写入了正确的数据,与此同时您使用了异步的数据库的库。
+
+让我们看看如何才能实现这一点。
+
+## pytest.mark.anyio
+
+如果我们想在测试中调用异步函数,那么我们的测试函数必须是异步的。 AnyIO 为此提供了一个简洁的插件,它允许我们指定一些测试函数要异步调用。
+
+## HTTPX
+
+即使您的 **FastAPI** 应用程序使用普通的 `def` 函数而不是 `async def` ,它本质上仍是一个 `async` 异步应用程序。
+
+`TestClient` 在内部通过一些“魔法”操作,使得您可以在普通的 `def` 测试函数中调用异步的 FastAPI 应用程序,并使用标准的 pytest。但当我们在异步函数中使用它时,这种“魔法”就不再生效了。由于测试以异步方式运行,我们无法在测试函数中继续使用 `TestClient`。
+
+`TestClient` 是基于 HTTPX 的。幸运的是,我们可以直接使用它来测试API。
+
+## 示例
+
+举个简单的例子,让我们来看一个[更大的应用](../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` 将包含:
+
+{* ../../docs_src/async_tests/main.py *}
+
+文件 `test_main.py` 将包含针对 `main.py` 的测试,现在它可能看起来如下:
+
+{* ../../docs_src/async_tests/test_main.py *}
+
+## 运行测试
+
+您可以通过以下方式照常运行测试:
+
+
+
+```console
+$ pytest
+
+---> 100%
+```
+
+
+
+## 详细说明
+
+这个标记 `@pytest.mark.anyio` 会告诉 pytest 该测试函数应该被异步调用:
+
+{* ../../docs_src/async_tests/test_main.py hl[7] *}
+
+/// tip
+
+请注意,测试函数现在用的是 `async def`,而不是像以前使用 `TestClient` 时那样只是 `def` 。
+
+///
+
+我们现在可以使用应用程序创建一个 `AsyncClient` ,并使用 `await` 向其发送异步请求。
+
+{* ../../docs_src/async_tests/test_main.py hl[9:12] *}
+
+这相当于:
+
+```Python
+response = client.get('/')
+```
+
+我们曾经通过它向 `TestClient` 发出请求。
+
+/// tip
+
+请注意,我们正在将 async/await 与新的 `AsyncClient` 一起使用——请求是异步的。
+
+///
+
+/// warning
+
+如果您的应用程序依赖于生命周期事件, `AsyncClient` 将不会触发这些事件。为了确保它们被触发,请使用 florimondmanca/asgi-lifespan 中的 `LifespanManager` 。
+
+///
+
+## 其他异步函数调用
+
+由于测试函数现在是异步的,因此除了在测试中向 FastAPI 应用程序发送请求之外,您现在还可以调用(和使用 `await` 等待)其他 `async` 异步函数,就和您在代码中的其他任何地方调用它们的方法一样。
+
+/// tip
+
+如果您在测试程序中集成异步函数调用的时候遇到一个 `RuntimeError: Task attached to a different loop` 的报错(例如,使用 MongoDB 的 MotorClient 时),请记住,只能在异步函数中实例化需要事件循环的对象,例如通过 `'@app.on_event("startup")` 回调函数进行初始化。
+
+///
From 986d363a3810f0b7c19228b58f2389a02eae477c Mon Sep 17 00:00:00 2001
From: github-actions
Date: Tue, 17 Dec 2024 21:49:28 +0000
Subject: [PATCH 118/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index c3bacaf12..e8cb60b40 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Add Chinese translation for `docs/zh/docs/advanced/async-tests.md`. PR [#13074](https://github.com/fastapi/fastapi/pull/13074) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Add Ukrainian translation for `docs/uk/docs/fastapi-cli.md`. PR [#13020](https://github.com/fastapi/fastapi/pull/13020) by [@ykertytsky](https://github.com/ykertytsky).
* 🌐 Add Chinese translation for `docs/zh/docs/advanced/events.md`. PR [#12512](https://github.com/fastapi/fastapi/pull/12512) by [@ZhibangYue](https://github.com/ZhibangYue).
* 🌐 Add Russian translation for `/docs/ru/docs/tutorial/sql-databases.md`. PR [#13079](https://github.com/fastapi/fastapi/pull/13079) by [@alv2017](https://github.com/alv2017).
From c015245676b84685922fd2969d670ec472347c60 Mon Sep 17 00:00:00 2001
From: Zhongheng Cheng
Date: Thu, 19 Dec 2024 10:30:38 -0500
Subject: [PATCH 119/242] =?UTF-8?q?=F0=9F=8C=90=20Add=20Chinese=20translat?=
=?UTF-8?q?ion=20for=20`docs/zh/docs/advanced/openapi-webhooks.md`=20(#130?=
=?UTF-8?q?91)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh/docs/advanced/openapi-webhooks.md | 55 +++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 docs/zh/docs/advanced/openapi-webhooks.md
diff --git a/docs/zh/docs/advanced/openapi-webhooks.md b/docs/zh/docs/advanced/openapi-webhooks.md
new file mode 100644
index 000000000..92ae8db15
--- /dev/null
+++ b/docs/zh/docs/advanced/openapi-webhooks.md
@@ -0,0 +1,55 @@
+# OpenAPI 网络钩子
+
+有些情况下,您可能想告诉您的 API **用户**,您的应用程序可以携带一些数据调用*他们的*应用程序(给它们发送请求),通常是为了**通知**某种**事件**。
+
+这意味着,除了您的用户向您的 API 发送请求的一般情况,**您的 API**(或您的应用)也可以向**他们的系统**(他们的 API、他们的应用)**发送请求**。
+
+这通常被称为**网络钩子**(Webhook)。
+
+## 使用网络钩子的步骤
+
+通常的过程是**您**在代码中**定义**要发送的消息,即**请求的主体**。
+
+您还需要以某种方式定义您的应用程序将在**何时**发送这些请求或事件。
+
+**用户**会以某种方式(例如在某个网页仪表板上)定义您的应用程序发送这些请求应该使用的 **URL**。
+
+所有关于注册网络钩子的 URL 的**逻辑**以及发送这些请求的实际代码都由您决定。您可以在**自己的代码**中以任何想要的方式来编写它。
+
+## 使用 `FastAPI` 和 OpenAPI 文档化网络钩子
+
+使用 **FastAPI**,您可以利用 OpenAPI 来自定义这些网络钩子的名称、您的应用可以发送的 HTTP 操作类型(例如 `POST`、`PUT` 等)以及您的应用将发送的**请求体**。
+
+这能让您的用户更轻松地**实现他们的 API** 来接收您的**网络钩子**请求,他们甚至可能能够自动生成一些自己的 API 代码。
+
+/// info
+
+网络钩子在 OpenAPI 3.1.0 及以上版本中可用,FastAPI `0.99.0` 及以上版本支持。
+
+///
+
+## 带有网络钩子的应用程序
+
+当您创建一个 **FastAPI** 应用程序时,有一个 `webhooks` 属性可以用来定义网络钩子,方式与您定义*路径操作*的时候相同,例如使用 `@app.webhooks.post()` 。
+
+{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *}
+
+您定义的网络钩子将被包含在 `OpenAPI` 的架构中,并出现在自动生成的**文档 UI** 中。
+
+/// info
+
+`app.webhooks` 对象实际上只是一个 `APIRouter` ,与您在使用多个文件来构建应用程序时所使用的类型相同。
+
+///
+
+请注意,使用网络钩子时,您实际上并没有声明一个*路径*(比如 `/items/` ),您传递的文本只是这个网络钩子的**标识符**(事件的名称)。例如在 `@app.webhooks.post("new-subscription")` 中,网络钩子的名称是 `new-subscription` 。
+
+这是因为我们预计**您的用户**会以其他方式(例如通过网页仪表板)来定义他们希望接收网络钩子的请求的实际 **URL 路径**。
+
+### 查看文档
+
+现在您可以启动您的应用程序并访问 http://127.0.0.1:8000/docs.
+
+您会看到您的文档不仅有正常的*路径操作*显示,现在还多了一些**网络钩子**:
+
+
From d041f12331081110a2098d7ba9ecac4de55b1661 Mon Sep 17 00:00:00 2001
From: github-actions
Date: Thu, 19 Dec 2024 15:31:03 +0000
Subject: [PATCH 120/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index e8cb60b40..d9b43c725 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -15,6 +15,7 @@ hide:
### Translations
+* 🌐 Add Chinese translation for `docs/zh/docs/advanced/openapi-webhooks.md`. PR [#13091](https://github.com/fastapi/fastapi/pull/13091) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Add Chinese translation for `docs/zh/docs/advanced/async-tests.md`. PR [#13074](https://github.com/fastapi/fastapi/pull/13074) by [@Zhongheng-Cheng](https://github.com/Zhongheng-Cheng).
* 🌐 Add Ukrainian translation for `docs/uk/docs/fastapi-cli.md`. PR [#13020](https://github.com/fastapi/fastapi/pull/13020) by [@ykertytsky](https://github.com/ykertytsky).
* 🌐 Add Chinese translation for `docs/zh/docs/advanced/events.md`. PR [#12512](https://github.com/fastapi/fastapi/pull/12512) by [@ZhibangYue](https://github.com/ZhibangYue).
From e779069c92da8b3dafd8d1c9aeef2cc3317e3f57 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 20 Dec 2024 21:15:54 +0000
Subject: [PATCH 121/242] =?UTF-8?q?=E2=AC=86=20Bump=20astral-sh/setup-uv?=
=?UTF-8?q?=20from=204=20to=205=20(#13096)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 4 to 5.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](https://github.com/astral-sh/setup-uv/compare/v4...v5)
---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/build-docs.yml | 4 ++--
.github/workflows/deploy-docs.yml | 2 +-
.github/workflows/label-approved.yml | 2 +-
.github/workflows/notify-translations.yml | 2 +-
.github/workflows/smokeshow.yml | 2 +-
.github/workflows/test.yml | 6 +++---
6 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
index 36d3780ac..6ecdf487c 100644
--- a/.github/workflows/build-docs.yml
+++ b/.github/workflows/build-docs.yml
@@ -53,7 +53,7 @@ jobs:
with:
python-version: "3.11"
- name: Setup uv
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v5
with:
version: "0.4.15"
enable-cache: true
@@ -95,7 +95,7 @@ jobs:
with:
python-version: "3.11"
- name: Setup uv
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v5
with:
version: "0.4.15"
enable-cache: true
diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml
index 648539d47..d9ed61910 100644
--- a/.github/workflows/deploy-docs.yml
+++ b/.github/workflows/deploy-docs.yml
@@ -29,7 +29,7 @@ jobs:
with:
python-version: "3.11"
- name: Setup uv
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v5
with:
version: "0.4.15"
enable-cache: true
diff --git a/.github/workflows/label-approved.yml b/.github/workflows/label-approved.yml
index 7ecb65547..02070146c 100644
--- a/.github/workflows/label-approved.yml
+++ b/.github/workflows/label-approved.yml
@@ -26,7 +26,7 @@ jobs:
with:
python-version: "3.11"
- name: Setup uv
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v5
with:
version: "0.4.15"
enable-cache: true
diff --git a/.github/workflows/notify-translations.yml b/.github/workflows/notify-translations.yml
index edf3e838f..187322bca 100644
--- a/.github/workflows/notify-translations.yml
+++ b/.github/workflows/notify-translations.yml
@@ -35,7 +35,7 @@ jobs:
with:
python-version: "3.11"
- name: Setup uv
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v5
with:
version: "0.4.15"
enable-cache: true
diff --git a/.github/workflows/smokeshow.yml b/.github/workflows/smokeshow.yml
index 51e5f56fd..ba505985d 100644
--- a/.github/workflows/smokeshow.yml
+++ b/.github/workflows/smokeshow.yml
@@ -26,7 +26,7 @@ jobs:
with:
python-version: '3.9'
- name: Setup uv
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v5
with:
version: "0.4.15"
enable-cache: true
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 0c87d8ed3..e0daf7472 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -29,7 +29,7 @@ jobs:
with:
python-version: "3.11"
- name: Setup uv
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v5
with:
version: "0.4.15"
enable-cache: true
@@ -66,7 +66,7 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Setup uv
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v5
with:
version: "0.4.15"
enable-cache: true
@@ -107,7 +107,7 @@ jobs:
with:
python-version: '3.8'
- name: Setup uv
- uses: astral-sh/setup-uv@v4
+ uses: astral-sh/setup-uv@v5
with:
version: "0.4.15"
enable-cache: true
From dd0b335052619ab5f28749d720aa00a061d6dcce Mon Sep 17 00:00:00 2001
From: github-actions
Date: Fri, 20 Dec 2024 21:16:17 +0000
Subject: [PATCH 122/242] =?UTF-8?q?=F0=9F=93=9D=20Update=20release=20notes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[skip ci]
---
docs/en/docs/release-notes.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md
index d9b43c725..b28ee5685 100644
--- a/docs/en/docs/release-notes.md
+++ b/docs/en/docs/release-notes.md
@@ -53,6 +53,7 @@ hide:
### Internal
+* ⬆ Bump astral-sh/setup-uv from 4 to 5. PR [#13096](https://github.com/fastapi/fastapi/pull/13096) by [@dependabot[bot]](https://github.com/apps/dependabot).
* 🔧 Update sponsors: rename CryptAPI to BlockBee. PR [#13078](https://github.com/fastapi/fastapi/pull/13078) by [@tiangolo](https://github.com/tiangolo).
* ⬆ Bump pypa/gh-action-pypi-publish from 1.12.2 to 1.12.3. PR [#13055](https://github.com/fastapi/fastapi/pull/13055) by [@dependabot[bot]](https://github.com/apps/dependabot).
* ⬆ Bump types-ujson from 5.7.0.1 to 5.10.0.20240515. PR [#13018](https://github.com/fastapi/fastapi/pull/13018) by [@dependabot[bot]](https://github.com/apps/dependabot).
From f2986a1d53543b4a229f00930cd5f074f2ff33ad Mon Sep 17 00:00:00 2001
From: Zhongheng Cheng
Date: Mon, 23 Dec 2024 16:53:06 -0500
Subject: [PATCH 123/242] =?UTF-8?q?=F0=9F=8C=90=20Update=20Chinese=20trans?=
=?UTF-8?q?lation=20for=20`docs/zh/docs/async.md`=20(#13095)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/zh/docs/async.md | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/docs/zh/docs/async.md b/docs/zh/docs/async.md
index 822ceeee4..9e6962eb1 100644
--- a/docs/zh/docs/async.md
+++ b/docs/zh/docs/async.md
@@ -251,7 +251,7 @@ Python 的现代版本支持通过一种叫**"协程"**——使用 `async` 和
这与 **FastAPI** 的性能水平相同。
-您可以同时拥有并行性和异步性,您可以获得比大多数经过测试的 NodeJS 框架更高的性能,并且与 Go 不相上下, Go 是一种更接近于 C 的编译语言(全部归功于 Starlette)。
+你可以同时拥有并行性和异步性,你可以获得比大多数经过测试的 NodeJS 框架更高的性能,并且与 Go 不相上下, Go 是一种更接近于 C 的编译语言(全部归功于 Starlette)。
### 并发比并行好吗?
@@ -275,7 +275,7 @@ Python 的现代版本支持通过一种叫**"协程"**——使用 `async` 和
但在这种情况下,如果你能带上 8 名前收银员/厨师,现在是清洁工一起清扫,他们中的每一个人(加上你)都能占据房子的一个区域来清扫,你就可以在额外的帮助下并行的更快地完成所有工作。
-在这个场景中,每个清洁工(包括您)都将是一个处理器,完成这个工作的一部分。
+在这个场景中,每个清洁工(包括你)都将是一个处理器,完成这个工作的一部分。
由于大多数执行时间是由实际工作(而不是等待)占用的,并且计算机中的工作是由 CPU 完成的,所以他们称这些问题为"CPU 密集型"。
@@ -292,9 +292,9 @@ CPU 密集型操作的常见示例是需要复杂的数学处理。
### 并发 + 并行: Web + 机器学习
-使用 **FastAPI**,您可以利用 Web 开发中常见的并发机制的优势(NodeJS 的主要吸引力)。
+使用 **FastAPI**,你可以利用 Web 开发中常见的并发机制的优势(NodeJS 的主要吸引力)。
-并且,您也可以利用并行和多进程(让多个进程并行运行)的优点来处理与机器学习系统中类似的 **CPU 密集型** 工作。
+并且,你也可以利用并行和多进程(让多个进程并行运行)的优点来处理与机器学习系统中类似的 **CPU 密集型** 工作。
这一点,再加上 Python 是**数据科学**、机器学习(尤其是深度学习)的主要语言这一简单事实,使得 **FastAPI** 与数据科学/机器学习 Web API 和应用程序(以及其他许多应用程序)非常匹配。
@@ -304,7 +304,7 @@ CPU 密集型操作的常见示例是需要复杂的数学处理。
现代版本的 Python 有一种非常直观的方式来定义异步代码。这使它看起来就像正常的"顺序"代码,并在适当的时候"等待"。
-当有一个操作需要等待才能给出结果,且支持这个新的 Python 特性时,您可以编写如下代码:
+当有一个操作需要等待才能给出结果,且支持这个新的 Python 特性时,你可以编写如下代码:
```Python
burgers = await get_burgers(2)
@@ -340,7 +340,7 @@ burgers = get_burgers(2)
---
-因此,如果您使用的库告诉您可以使用 `await` 调用它,则需要使用 `async def` 创建路径操作函数 ,如:
+因此,如果你使用的库告诉你可以使用 `await` 调用它,则需要使用 `async def` 创建路径操作函数 ,如:
```Python hl_lines="2-3"
@app.get('/burgers')
@@ -351,15 +351,15 @@ async def read_burgers():
### 更多技术细节
-您可能已经注意到,`await` 只能在 `async def` 定义的函数内部使用。
+你可能已经注意到,`await` 只能在 `async def` 定义的函数内部使用。
但与此同时,必须"等待"通过 `async def` 定义的函数。因此,带 `async def` 的函数也只能在 `async def` 定义的函数内部调用。
那么,这关于先有鸡还是先有蛋的问题,如何调用第一个 `async` 函数?
-如果您使用 **FastAPI**,你不必担心这一点,因为"第一个"函数将是你的路径操作函数,FastAPI 将知道如何做正确的事情。
+如果你使用 **FastAPI**,你不必担心这一点,因为"第一个"函数将是你的路径操作函数,FastAPI 将知道如何做正确的事情。
-但如果您想在没有 FastAPI 的情况下使用 `async` / `await`,则可以这样做。
+但如果你想在没有 FastAPI 的情况下使用 `async` / `await`,则可以这样做。
### 编写自己的异步代码
@@ -367,7 +367,9 @@ Starlette (和 **FastAPI**) 是基于 AnyIO 来处理高级的并发用例,这些用例需要在自己的代码中使用更高级的模式。
-即使您没有使用 **FastAPI**,您也可以使用 AnyIO 编写自己的异步程序,使其拥有较高的兼容性并获得一些好处(例如, 结构化并发)。
+即使你没有使用 **FastAPI**,你也可以使用 AnyIO 编写自己的异步程序,使其拥有较高的兼容性并获得一些好处(例如, 结构化并发)。
+
+我(指原作者 —— 译者注)基于 AnyIO 新建了一个库,作为一个轻量级的封装层,用来优化类型注解,同时提供了更好的**自动补全**、**内联错误提示**等功能。这个库还附带了一个友好的入门指南和教程,能帮助你**理解**并编写**自己的异步代码**:Asyncer。如果你有**结合使用异步代码和常规**(阻塞/同步)代码的需求,这个库会特别有用。
### 其他形式的异步代码
@@ -407,7 +409,7 @@ Starlette (和 **FastAPI**) 是基于 I/O 的代码。
+如果你使用过另一个不以上述方式工作的异步框架,并且你习惯于用普通的 `def` 定义普通的仅计算路径操作函数,以获得微小的性能增益(大约100纳秒),请注意,在 FastAPI 中,效果将完全相反。在这些情况下,最好使用 `async def`,除非路径操作函数内使用执行阻塞