From d692c28f52a5390468bad0f321c24dc0173c08ed Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebasti=C3=A1n=20Ram=C3=ADrez?= Date: Mon, 14 Jan 2019 19:23:38 +0400 Subject: [PATCH] :memo: Add docs for bigger applications and APIRouter and update tests to match docs --- .../tutorial/bigger-applications/image01.png | Bin 0 -> 61037 bytes .../app/{tutorial003.py => main.py} | 4 +- .../app/routers/{tutorial002.py => items.py} | 4 +- .../app/routers/{tutorial001.py => users.py} | 6 +- docs/tutorial/bigger-applications.md | 279 +++++++++++++++++- .../{test_tutorial003.py => test_main.py} | 31 +- 6 files changed, 300 insertions(+), 24 deletions(-) create mode 100644 docs/img/tutorial/bigger-applications/image01.png rename docs/src/bigger_applications/app/{tutorial003.py => main.py} (53%) rename docs/src/bigger_applications/app/routers/{tutorial002.py => items.py} (75%) rename docs/src/bigger_applications/app/routers/{tutorial001.py => users.py} (68%) rename tests/test_tutorial/test_bigger_applications/{test_tutorial003.py => test_main.py} (96%) diff --git a/docs/img/tutorial/bigger-applications/image01.png b/docs/img/tutorial/bigger-applications/image01.png new file mode 100644 index 0000000000000000000000000000000000000000..78544b4034199b100cf5431b16b367fc85d135f2 GIT binary patch literal 61037 zc-rK=bx>Sg5HE-mJOm3K5+no-?vOwrc!1#UK?ipWPH=Y!2@>3W7$A6XcZLB5cN=6F zmXPn&Zf(_W?b~|)Z0)HU?%|w!`}Xbb)2I7)dnV$Ok_;X;1vU~A5}xcwDODsS)D9#h zG=V1=4)#gJ1E&} zajR}sMbp$HlPW=xtDF#)ef?G9+52bDRGB9I{L$XON1@M`IKC4hAQ)gbLj62%WgC46l0B_j|APMaCl^?lQI+haUz{9fo~oC_CLh|#|jig)+jgxM|G z*;6AKbsL@+rt>yn{Ug`A!q6&4m2w5B~S?&<>8#!-XPs&_m(B{?MOQViN`cL44>rR5r zTRGm(xhFCZ*p!6V#%sO)XgYqy&qEPL&k`EQcv4hcz2faH^2{w)EZbItJFCUt!{gVAC zLl;L!+S{LLBA#;OwT0;eiA9_iL$68MGID7HM?(z*9tMmWGUS1yTyz^r<$72Zy!lk(0FYVnwZ9tw6cqcL~($w%7)Cd4o*c}wx2xE z9R2a(%yTg$_?z5bp9)-E4#jy#&~&!ol3zbb2XY|etON6%V; zE0#YrE>=4;akO1IrDGJ8D4=5kQBGSWa@&~Z6wuwjHr#mZ?LI3G1lp!vuUuqZn$$ULXh5Yjwohgv8^FO z51$OS><;j|ViQ=Mp8r~X*m`8ZsGOs^rm;Hlz}{=5NH{x+gC~Z@Pn63?J#PgT&wplK z&KS19d9b9m4PqH{yagnU(&Pu-ZYaCD@NJOdc3L*FIOee3k!kySlN5i$RbxK%_|?xo zh~4>@0`>v}>!3vg39Z?1ifSwpo_QLEtW?ECx88@xJDds=Ke!d<+m@L>#Z%2ue%GEV z)q_Qfxt;vrktuanC*EJ%q&leeD1RlL)LFgWhlPVz@L=`OmeI3pG2aZYi(PdO!DLsl zWSRhE4197OdSWoom!}=-q=CN0lMO_Q&X+ZOLLZK}uJ2x(b5isBq0op7Wn9xvXa7|l zI(IrNl{o3(iD@-S%~9a}N+SRek}YYTJ4%An(R00i=D&8=2yOvBwMCn_E(dtl`i`p& z7+mr9`ZVP%4GJ(8m6P+g!=K%yz|$4SnNyc!D*P>TGT{`awJ9g(cSlvzP-fynT?Cj6 zI9W@|hkLw{ke<*{Evl<^3_5%eIP=!%e@%j!w{||bSrwzTrQuI=35vtoK%zNLXTU7P(BtmRQ1;DJ`z5UL zR1!aqu%l@IRYrNn0p8ZPdH%0;Q)yU^&B5Pt{W+)c@4YskmwU`ce21kGirgCrTZ>(? za;zEe3H#r#v+GXTCVeX8DFM(th|BR!y$#42$yp z@W;)we&cYQFiYoLc?I7)L)H{fIGmt7@4He>EY=&%I-eqStf}lYST*AV(>^z!*4Iho z)7whzX=q&8NW9pwOsTLKNMBvvE+AL1sZSPH_Q}L!C$LvjJG_F?+k>xl{PsL_O2e)o zLGQXj9%PlaBTZ7-$kH$H`b0a3x>_e*=2NU(Dk$~z)z~d8!cCV?o&nb1T2EXaVtVEq z%20%QtjEmvO<2($U$+Q2MN8<2o?FuFjYoxA=Fr}*Q;G<9$`{=Ia^wwPBKy#IsE>Rq zdE8IbHi^ehwkGy}^>%Pe(7@WO)hI{c0`Eqs6hNuLQeH6%S; z)=+`O{sFC)`>&dJUW@s+U^WOEo^DO|4V+dg2Awy(N8X#7An@=!e1}w{)J?2wZylRS z4ka3{qvfyuG2(>pH7fJdOP1i1bnyvl%Dirf5oN;P6!er)<^+8ZylXqe8 zY-Io*o!24H%EB{ci~1NiWXG}2>KW2rOsYqwjxz9%u&)tx3Uh#_K{04Mx8b-i`eqxaA%2Wi29Rmjp6K|^Ij@O3PamN-pu+^uLC8pt}J zx9YAjnH6EoKKLVX0KMd3X~@2>tIl4R=-IQ6fZ6nhOFb@1sWIk`?sykUeIfoH8(5?5 z@MQpUPUMvKH-EB2TEcfTKQujeCNIp8@G~RqW1|`1LuyX)Rncua1T+*>()*hJ8@V{A zenxYo(8B4ccCPQrY9It7N0cy8L#@gB3|Rk|?aN_$3OI&Z*a&H{!EV%0W4<>!*P+wf zFV_(86B)PmZ2I{QGVe+Pn9v2=_hKn5{IdeP903rJ2a^I0`f`u7QT@ z)p{@vB?hlMe5j6E|N4w2_jJ0~bx2nrHMfzPO?^(ziYu*}O}W+7g665`l1JX zfDX5;I_;jZmHqjIzU=Mw#j<;P-45~duVmlar@S4p6TLB@*{NGkCl9>>$+0Yjt%Uov zZU|#5uVP4jLpeP@iRWCI5fi2O{gFSqR~U*oU=`e6E6B+{Hf%|v$<9o;9*iwJbR$|` zKs&yhVLZ1o-&{QhkGKpsJe#{6!I{yPPHd>V95gvv&^Oat4VSM`v{)zQsrMp8^cTTT zKSEsRJEu=x${&pciq~ZgN74|en?K=@#M1oh$A|-1LYYP5`}MuCmr=8p&hbIllWbF3 zywS3`hl~S|zKdAU?=H)kOlN|stLw12r8aR>>FCWof4sGk0@~9J-FDTQx5Z^rxCb&U zl}~ki1;XBKmA9FHaYpE_=0IxcL^{1kzOks}5dx-q^scK(pycSv@E8n&W5g zS@gT9X{6effj~d@n z*S?C%vh${i+w~Gt4EQlSnFCW;430y4#75<&Nbb0ynh;UtESQaB?=N0rOl)n}cy(>M z`eIq-qVk{?2De{qpnlOVd=6w8!-lt~gNe1>8lbQ?e~@2#vB6_pjodVZ&u{;pd(Y8A zDYvf$jmfA-017d_57ae}2l^o!Ru~S|-L7nIiAUwblAu1BIgz5XLGA6}koC-R(MA|9 zwEK6X$63)FoOADO*;M8gcI74Q`yv3WcG?#bXYhoi9#e zW`bm&iubD+5!aUu?|@2ohT3_6@FnK$Nm@M??<;>3bs$cZ{A{}N{yP(DKOP(K^U7i2 zNW5c)<;{RDxxPYVD#NCtZ9ax4(xFVz%S;K5Zo3~F18B887F-JvHe5hw)FD~ja3xpu z9UG7S=%CXsK&SoagQt1H-)De;A+scX`|Fia9Hxm$DF;=4;si0pY^?rxoj|3rfI;q1 zsLsg^WP-U>IjlNx2}-;Erkw3aqLG&_#B@F+Y@k)#Iy7iJ8B?0u#{C}SOMB)ooY8(i zxr{kcdE=NeqTN&RGbEFOpJSmvvC;*a660sPtm?RxHsgnK6#K*kyxB%2JKO=)%)}1@ z6x0eQLo?3~%kjeRqK^nxdceK--SumBd>c*04W1;WIX5is=Z;QaCahz!u%M|W+__1v z3i_G-8@f5`Bz^p>OWC2tcZzyj?(DqDE}1)#vE%-8YQTdhkT5ox{*w}=k9K5>mgQ>> z5%1H2g1{UWGO@y*H`%Gh{N8N0Sr)&&SAGYxgQR@bY^BLyN{hQVOc_idg6zSjG-Il^1?NV zw1^8V9OoqoQeCn8C~c0V(J?YatjeVtmG(K^;Demp4ND38n%;{(y5m!m%W2*XxB9@;}hhiIVMKdo$1T z$%xMzLzq+&EQf}N(bamm{Wis*C>oIm87y%!3_aC5Iph7u9%WD(f{kx6rK*9|}cV zvg|f?O)6)?G~2yXyl6%GP34K$y(x=5tOf?4pi#$lCZrxPE$d$o?Nt9|s>%=Ah?Huc zW7sS-bs(B?m?98EZxIJI%w+$0WNzd}oY;`VI?d;l{08dVkxJs@T3P*9F?z_!6amvU z-fYJV-z5R|J2cYK6bO$+ZrP}np$$!tnGzyNnPFbKLPr`M^K*#d-;||U)zFot7N;&; zPn+Qor5x#zgV{7`ygk!5>NcD>!57D4eWKS6dQSl$-rn;jC$JfOAZtmwX%U_D>Y)F(C8kvpO3i;S)Em^RtPG}>B zH@1l3V;ot6W<*O1P_S4=WmPQzA6pQufIz7*v!4>b*sj7NSv8MI9>ECGfME?B12Iqu zTf9xca37|;_Td))$gOiR^yT9{7?2i$zQ+VlJ}XA(Ny1T3syuIhy?jIo+zUQ(#|?0D zvXTxlavShbT9iurkv4Cp;R5e`sy#d*{q^fk%?_xFA{vQ;g@?Q%7zjun?^V|#{Nvu3+f5^4@X+%6k zD0UwAn+-W`TvSxl#QETPvtBce+kBKNJ<`~|puvOR5QjjN%D)Wst6yg?2Vpi&MiVhT z$Iyr*ubmGxeqQnd-G~{hXfk9F(jDFUe(eKvR{kQOWE5nGl;b?AQ#VR1_E^@8;dTAN>F)Njl=zbR1g_xJCOp?RhNvIXgJ`>kkjzV0#gpk}7vpQxc+nG(TF5)uR$EN=+3X&Sn`2Zm4^59=(nb#(J zo6a6*+P{3ooyfa4WBeRLwAH;xM}l{gL+clkUdpj96Mb;-RWOTNf<`1dt)ZdU@>s3v zdxuo^Y){Db){`=Ww&T;0?45~b?pL9B>j&=OpRT1EQSApaT$o0wi|V`HeyAntrsvz^ zQarKWwQDVqq-11>$VmnWoHreA&aHe^)#=2By~Y-(2R4HSLQ-1oF1~pBiaPPzK^$WI z1d0C&=9!TDPGH}<@p4Oj>V*$1o!o$R^E4VjbOa2d;I&Ce$-tH{y4cOn&;RU&1hQE} zV^m7(hyozG>UOx_)RkfHq3CnMb3T4t9S|3D?qP3o-Q$l-%+96_Y_nS-(a>lYYx6v# ztt5K-yniSi?6`L&{G9X46I2X5$jpiRG5Dyx4?LPXYj`KT4rr|(f_jcb5o@*t_=&0& zDwzL1aF0vR?#ZIv;@s*JG_$aL3%L|d6Ec6Z+~PXPq)q~92%aoHa^-0tIY5si8VgrC z&`}*MtT_3r2u(RK$aiP9(lGrJ;vjIGw0>SVoWWNhJ)Cjf3A0_-cW~ge)2XkRx*_Lv zGFt)j$Ce$}yvavzaw}i(IX=|AhQK0c zwMYs#S8AKXxrSeSRh_sD{dhxeAP|?Ml{URUF3oxc8C#9Yxnl5(p42&zGiI*eDRY8Q0;cJC5ba;(1pT8*6Hjs$V0k@iC{%MB@9lXfv6&791;=;az*5?y<|0?l^7sZ=$G;(uK1_w z)Z6HjKpMFukGIDgAF`=xpPp|oA+WNd93SA)Z;pUP{nLukY1GoQBFkLUBSf1B41RV! z=&ub#3-}s@>G*n+b5!(RBvA|=ATD}KCER$l@p+**f#g#Wp5&o#AX8|=i+<<8W%Rvv zX?~ivTG0yg$?HDLVvmdF?5!ie^wgh>r+vHwby0|Tf6)fQBkuGmyHcfC8N-d4A;tYa zm!Aa4bc^r0_ki=$0hA>WbD^9NO?N+kr5A5ltk7RD!1w-3GgQ_Ae?MXb!ggL zm6ttTs+Ac98ggz9vANyd!B)EZAzg#8e7O^vCTL3L+jIrsNpEKA(q-;FoJ==`Wf z(N;}E+mxVy@2lr-w@B6i#Mer9@5!1NvOYf@#m_&e1qRmihdpateFH_~scJ(f>&;yg zX8gMT^s7nWicev0jVnaXj=B346^+i|+O~=++kdyfuRy}gJNVtNOKWrQ0Y%tT1Dufw}E@I)lf|@YP;M(Qad0uYrnj`@{{T7*RNXTGr;fZY5hgHJ_^=4 z*3Et}@!a-y@x~a+t~8aO)t-xT$5EH(N3*%}&VH+l>GurWETzA9E4VN_A9R?NnW?+G z)ugA{fL<&T_DuXXD9X45xRbn0L%<*!bYpC6y8xN-r6~v~hk_Sh3S{Xg79!rldA!911G+ZD+LjNu(T0I>b}xhSvoohn;hPHbRbhjL_;G-#pp_dAvLT) zM&@Q_oSwV03OP3y>YDE8n4Kl6$XCtc?G7JWB`WpmcM}#p7J)milFB|lz5^qFOqLg1 zp&EYg-=ipI@a3s=VeBur-~U*|z{EU**N#^CTw|xePvr}yV!I%()mQn`6`H7^!tGUk zzm&SU@7EG9v4Hnisavk^Ms)pW6_<}!;N)j(>|!mhEh?u30TZ^ms+$2iXmdp23zYKq z9j1==06DZ#2Zu z#*0d(*0zoShjCHgQp+TDKb4~{X!;nxh z@HQs6KDdp^CO}6^xd_W3RV%kjZ1O;Pd`^7`*?sMD0Eu zcI7_mBIdtIV$o+#HqXf2L@6nxGgs?!hfYZzG?^&N3qRFy82yM<@y>OWc}>-s-FtDu z;YOPCm*$g!!L1tWEj~WhtdXQ>tKiE6N$$k2(>b!Ckjz;f?@PGv-SNqs?BGR`r>KO* zN9T;&!e=DeWKGfB+05)PO}5c=<)Af_@&VVt1F*8i!s%4spxT98s6O8S2d0=EL3xFW=(2H+4LThY-2WZZaiKh%VL7 zbP6laF0-Lb*U*n`!%8w|W1X&Qwer4iC~d9PlWNC7bb0AkyYc$>D`iaTxz37niG_MG zZyF6RcUz_5b2F>jb+SxiXT4ZuvZ+G!H|tx|V<#IJ7@()mdC`|6sih@g zYz%qGdp;@%$*QWVuDBEy-~puP*B5z-F%Z~uOp*JDmZ z5L1&r0z0NF_eRfP%g(dBumuty4#@wg1^C=QT%xJ_U^yZTPPDY?H0y!0qf* zp2OgL_Ei_B$8`ajW9#zJUA0dOT~joMh^GvJ&kVa!F-tHho6gve4>&q}6R zpnU}vAApC~G99qx3o`f7PJsK3G)T)WLC9Tn&=BJ?e{yci!~LTj{#{kTu+peGz?)eK z`~(Ah|JvQ{NhcHZwM?z`M4r1P#cc71PhYq(TmVWJb!aBsOKDlvwo9pU7l)GD^ZCfG zi}+?9nb!37%hFlz(r3M+gzD^8m3I-6`Pt=dLtkd33y3CQ78vz5N_S(QC_-jBEZCdG zBC9}M+eG7WalLlWIe|>Z#kX_M6C-(@#clA-31?syH;p!OcVjm^U&ezM3@~E8OV`DI zdEX{PH&q6Xb1-Ca^Jd>gWBcoyfsBe74yRHtO?#uD^Om{m>6SU>=iAj;AH$0r*QHZo z%k5M;0X7)3s~&nHaqi01jj3cRm;{8b$4@P~`j0NNlCl(rS1FQJHUB2HmGXX@hY{`? z9@-=`0nU7A%3k;SyTQT7D~kZfSznl8d}O6%?4if))#oo)qBhrm)Hmi1MDB-Z$;Au}rVFa0r?{%qVxWt|DiR4QRW?_xC+vSn<5I6T7}5!tbGC=ebf} z4~_QNKk55II375=awRjcg#<$Lu4m+_*b6cYD!Ml7Xoec}ZJzaKA8mkfs7RkF*q=I@ zuzQVG1a-$6Y?8E-U9B6g7*&aWy*mT1797FU>fQl)7E^w#9E54}`D2|Q%C%SXugc>W zJF39z%y=U(0wS|`&(imJ!zsg}^0Lo(nA};7>=9HTbKP8$iKrChVksK-ITexAse=1; z?^~oBeetw-KMg%Wa3yPw|-rm&$J zU5(M5@68fe+Ox0sMnh-K2U!Y051R$+|Bml~k94TQV@0;QxKf zQn^S{HqR@FOn6Mp+Cv~bm@D6CQLYn3DI60XPU>?r&?oglCK-O4Yy1Xs{vmay9bo8n zu{!`sdu}nDA*tcEau5L$14U5_f0K@;sP>wsNGaD+VZKn0pL|ikkZZ$fJyqq`gK1Rk z!CsWOq>8Z{5P&2dOYuSK>`4YM0AIr8GjY61Je<=KzeqV(qsO2?M4Gyy_110S=q{$1 za$TM75iCfzUv5oIj~}Se7mm~iH`odL+`;FXjC~_uJLdH!4PVewYA}qZS9v>ZtBssm zxec}W?O*B@$Vq+@lu?e0Y z{I+bb`2mi9m7_Q4PFtb=;Ss-6@|Z6x33f73CDD7ukv|Zest&+?MC@!r`qn!KcSDR{ zH!vf~6Iw)~bChbDgI=lcJO&tSOk*rMz{cUwd6SvF??|j<_?;HEd;o>y;|YoY%zt%H z%^0;DG*K*{8?cD@GVv0%A&tNtnpK;)0kc);LC7Gq8{(oq$Dv8n)nr18{RmBx40Lp; z%^SMmp_Wbu&YSgeo-67iYssCgysgqI(_+*8g|J3<7t+GM0nsv@I{q5g? z-Yv4nY=wRa$$#kNX@*Q4>$#Tx_YeOnsodWoYyB(5A`bZQzohd&=>4zi{IBBc|1S*Y z=d+feG^ao}=H_cm3A}&e$HzG&Py`;}4EzjWJY`H8yxok+jYId`vSX>9a zI^B5ljBBmmQE2e~ik0*|e2-A2l%INcIdu5huSm(iWc}Qu@+8B&sMrbKh7q7XC23Z! ze>od0`L-`j)E}$ZYA0F8{-VP=iu`SOFJ2dWv)xcJ@6h6{P_bZovb)cUUzF_y7haJ4 z*oViJF7UU;OLkD&?r8~5I=&^EuPDDC?VG=DL|kpxw^a=%HeYbyL~vtsxDhFU zW5u>;*;q*~TRd4wOE9N@xOt$yY&kc(ileE!_zFYDx}g*GdZ`6wyHWY3?a61R>( zX?s^4QJeB&#G4~-)9;tL+{`_(?M(6QdbU-3cZ`I4_hDPr)5D&7!cL37_N+Dman%4` z?#)Ap)LZl6oc3TQnx>y~hhqR*of!js_u-c8$A>1G6u!ckiVT^kOE z@S2LZa4Q=3HybaMPn;WG9l6%><^xJocXUKiXw~qwi&Cq_PDN*OMi>P4WueCEehuCD6j z#DmExSMN3S4YN+2+D!Sx3G0HD4u$|)EqjiBN^%TMowrNVzx)uDpAS3ycI#g9 zzr$ClCa%(avWjC?4n>2vUBvo7r6z8;*!d>}II6JOuEc&Wxy=E%2Y-{ps|n z@#hWWj)`9%>CDOWjbDHI@2yhGx0Jewg4SA=qB6EUE%ycA&S^1b-SpO1rKfvF%fvJ} zRNCyVasnzoskX86VMyZr)r-jdJC{_)u%9|#-M=z3g>*TRftY3w4#FzuKg29Yykoa= zJBD4dT~yPX^^$oIONat!`{z2|!RBXsdrs6;jBMoeOR-{$8QE-jx^rrh3={pj^zB}h z+md#4oix!3KwOFVVOd?1vv<+)#^q1=pu8u-%QPh)d^#g%+uzR>H>Oeg@4oDN3LmUQRsfxLBgueCuD!S7wqpi7NdeHEHm&hfarQxcaXHnBO~l?u-Ss{ zv?y~!g{>$I5e*4^ytm`|(gYcN8B&V@n%6$J9Q12+2mOOX0-{lf;rs6GF;O2XO83tH zp%l>jDC>Hw&y6Fzh-djV#shv%(Q>cfSd!s1kRIwC_};OJ3^C7e2>7vY*clA!^j+ZA zQKa6r@Y+5#*l)oY))~u#8TGPzgn5f=X}*rqb$XRv&lhphWs|zYW5>s_--D*ym8|H* z=&@)UfCb3pH#19EW4{Islc(o551}oxdK~8!;&E};vU{=iu=DFywT^_2PIj9Yyq93g zNaK6DDv0 zd9{>k4b>bTjs{rbJtcp>_9!T-t@~FudclD~7e^$2m7hQEcm&fxzeuaNxOK?vPshQL zb6SyrcZ#UrL||i!1kSSw-6k-~2GcjDfUFEM>FTlbf?|ceJt#h!Z&HZgx$`k-HgpRV^T-jkL4ta4iSD{bZ!mnJo@O>7_eOC>O?Ri>o!E z^SQ@3Ne(VPwQ?Y7`Od_j%rVC4{w41usryh|nhA=*O$Js0i##tparhmZ(aEZ2En_{m zGQ?^*7gE2bRd@WvTe*pRxsa&* z#V0ko8doa>nU?GTr4uVZ7o`A7>C+O?&*mkzW8I#ths4xZ`0M*(|0_&6u4hOt&-L#p zt#u={cI@uQ(H|)@i`iG&>_23K!-rw#-iT4)c3NpNZeiy#3gGnISM_ zf28eAg>bV<uac-aX=^DL2H7w-tjhv-b1s?-Jcr^ z3q%V)m{aZs`^%?ObdUCwg18q6Jdg3c>@xZk+Bq{qJ&xZV8Q-q))=^If3EOiCG~1v@ z;%^w7Ykeb9Y2|-wbwA*5t8|?~?u{$WL(vy)chqegyLk-h({{OfE$D|Daa>E}zQOcE zxd?if=6KHZO!Bb6JT4P(2@i?W@Xz<%D|X?A#-&%sM8|`lB_Gu&@-D{ioM4LxDlwXhwCGKYcxbo$BV zv*lWwReHM~;zN=6&U1G_LG%T7$m*o9mX`s{QaKgmQbQqugQ2e(bdA2bcrgzQG*9Q} z9I9N4nQiwPZ*47aZZ=;zay`(ky=*+lC*dYZVBUJpVxeICp_8k&fg5^pfHZd%&0%<7 zp4LXQSx|c`0E)c#0q!OA5kA+7-dkv7che8^TA%lD!7sk7T`m&MXHbA<1{e3}CAM=y zXAQAu)ouuU5PJlcGb`2vPCZg-%Pbt({3^2vgPmOT*#-l zAZ~kccPGcYt?dYGvx}mB8$JLY0{xg>nIjB3zGO$(+NMZIHy~IZB0-0q7=YPcyGbqD zuG*)6K|m#5aoM%KYo5bS=lkdg4zBA4>FYrZ{4X*ccN|>Yov!RvjJ8HMF}FKQ%@QP@ zF`NKj+q`Er8St;^xnSwDGda+DXXZ7cnCxoXNC{D+=1f|()4;TYf~LnGzF2{ZPYD+R zkPV>cWKvD!EcQl!R}!4*Dq(2FxqA{vv=kG6faBr-s=$0$NX%1sUbo-M^DhsSL!^w9 zsdV|6h_$Jn(&(^5dF`L~`V#eW+8`24bOTvbjf{AEW1dT`hZ>VDR~V1sDeRvsZytD- zOUOI)l-i$}KRn?C=Qf5f%72c4x63anyO=K!Wi+~buO@`M&@kxt;(W&23U2}Kt?mtu zhi!8ORVL55(_3INTv-IrzgjpP`4IN`@~sjOz`yF_m_EVAFR=G``mXchmp{WUofXd6 zPbX|PE+JUHW#^2Y?zsI}gW{le%6#lNbOlc+mFWKNTk%Q7`{jO7w6Ri|L?@O4$1cts zpH=*Z{kg7{e#!1!0qy^XG{RqUv3-h*d*X$>osY&)^OeoRTxS4*RrMB}?onB=AzW-6uaP})ZF-{=bG2Xm59g-Tf9{!m%ohhl`cgYdI zab7&bXnM1NCj`*>!6QxZMnAKxD@RTb9`SPUY!f-gco_I^Hm$fe!Cd++ogc>5hEAEj78;%p^;%NMl)nJPN zdcd~e9e#fNUzmhbZCAU$(-rK-P&cia+Uq+;M30ox@OLhq_iHWeiayr%yln47((|hk zXfWm#XEo?*=r^U$l6%$Vx${Zmv#WhmIT^2kw(2&>1eK}iW#h5h2C3hT*pb+JKviMg z-crcdJFoFt_2F-sO53VyeB2yDlnUrEF!EAe(JexO|Kg;F8c>EwJ)f6C>dj8uAQ6SYJ1y?+xTaF zZFbb8@wg#8{6hX|rzp3@nxu7Puwq3X(es^w!5bt9dr>>X_}0(k09#PZ`x9DMu2-NY zJKs^wf5^pg!GtcZ-PFBOMNC;?CK% ztM0hB_UM*SUA%IxXvb#i%IaNC{hK4Ws3WVsSCv95r-PHj0EQAStv35lRc}^OpFnHE zg?#chua*9AMES1+^X=@{|0H{al*M~x-XP+B9Yj_zlHR#5;GI`7jNks`@aDEwWCCOX zi6(0w2x#DA29#=fPRa(G#A zEA)71T>Ws4q>H3e;+DPyxRHhS5WeIaMqfx@m@>sUIe)C{%ztc<+tv;XeBAwX#p&$YU z7UCQN4(;Li@y2n9Bl7?1-9R_wW{Cz%T3TWL#tRK~FC!0{LyoXUVitNcP^;-_qUhf6 z#iM?`^E@g*kOBE;O4Z0-4zYwgd&{|IiIJzH7g2yjR7$l7A7YU^!Foq`jIdihF9T?3 zHo4wC zz%_&FE(Gb!5m~Q~1+Hhwfj0;qvE0T$^To?&wQIU7dfumjGI7n;Y{L3mzbi3uqBFC| zQrmEWBZGZkt23{!gIg6W{kONk;ewU7&gJaXRt7%|v3JKCowf2lSSYie&CrYsOaH6) zEVF4upZg`VNZJ|qN#MJVhEI3-N$ECtE_eSY=9L}HaRRRjvmVl$fvH8}TX9go64MO# z)!-!h-G*g56F>7RY{K)<(pHSfS~0(B2cYbH>#Dy!(?FNkiI{U(Rft(%9TA1M@D`3e z8E-~pKleuHHBMWrPMS!3)i9Aiq$?CbSjL=xQLvKr7Deu-av z0_g=Q$^#>HP%DZc1aCv$yR0QZrIu%!%;zaI@+i5DZOtm~jI4n*$I4{r0 zRvFW1M#VeTZdc6JT|Ofk7**#kdRpNTNGJvXnd+6v34N8x0CJnnKd?-$WfQX#o93K&GQ-{SaOj$K z-ZSkdQ*D(l8`_kW#2LG9y2q`e3%1aiu*C2o@OY%_%7-sgJw75|nC)t+LMAe0xtSTh z4?s7VYCBP3gwgbk7?ReS-T7To2`T+9X64HA46@K>6GNLRmhnima5#TobvlLgcyq5wGKDbS9WN3CkVhS)2)lF$Rq=4;x zZ0m6h`F&pOIyis+5l#Pm{n2;LR+ z|4d*5_y4+j_5WSx!R35S?5T}8wGP~SQ^`&i=`S+Web>yO$NuPRUuxnEPRIKnz%z`E zzm%7@y<1Rd&-}e(-;m_c{BIL@jYLMA*|VSn0$T9(N6D`PSd^-{$vUKFY3e=dn+duZ zxSi6oJM*eU2L{F!wx=ucIryuPmH5gPHlk78YKAbT_b`roJ6>d@IeVBoJxkfM?WU8VRvq_=upf6@n`!>zPfmY_BbD~VwdxZ*X$VJ1wsQfdV z4H={f4ZV(MvMjM13)@*{8}9>ykTj*yw|X%o1vZct`aD-Eou#n>CC09)9}!?f33C4 zgPuQIrol3M-j{u_*4M*QL4dn&=KIWwOUj1Vi&u&6d~@V3&c1%2N@Q9zVGl=rAvdJR zcbkrwiU3^mn=1?-o!OqjQl+i(*5G|qE0L{Z(;MIDt80)$&e^EBaUfB`muhk7lBE( zeiw7km+32Ar&YUhA=A{X;?97o!NE*pV+|yqF5jIbsF8O|&C8hndmOuG^RLs>=Y)WpS+SVfUimNPxobyT4anYWYFy-Vj z64kGru4v0YHc!ov&HBT z`|XIJrIM3@#Pk`;LN%l8!7N$Dl&bxw@EExS+z_&Ij{9aGnsPnAN{ih8Q45e>0)u%b z*~m4Bv=h^)oR_>|SNm|!W%upU17`+CX-RCYIl<%^#%u3dvvMu;J;U|o`I2jVNgRZu zS*f-7_2dL7&;m+P$R?goX3LHA(7s2ZuXZ48?Y`lwn94fM6R#1xUIxe((hXEjiO3UH zz^kjIzt1^?0%C6Pcpc`6H*1(HT+Mx_S+APvx4z6U{~2C((juVZ;i-pxu(qYBX`r`W zXfPdR+PqF?f`&~10}`_NLgX!<2HKU3bINh>MNLF{HfJEz0};()9}R=kc9w-2E!oyI7A2l-Mg<6;&*Haivd9NuhmXqkLU+#>hJXPzOG@hec+4D{ z+zp#=de=1}Qqp+OYI&HtIGDdHE;=U>QkS(b%&bnP*vZt>ExtL~M$}{N-nK`R(dWV!f6@>xi7*0|wG{GP>{4Hc|?uM`hzGrrE#rYwDn2NfD@IaEj==?opY)*Q$ zW+J`kGP~%4ppK*Jc$4X0fp_HgZ7+9<{=zp*0{ zBjvQcKg}|>)}P#jbL;)Cth7839XS8^_v(NN)%JHkf85sF=(~vNp|`Levv3b44CV_V zKTNLrd@#9P24-;I1<+ie?=4dcgK$0VBi2>pV)YXWbpz zER-|KEBWj-O>`PgiOY^DT&LFnq8AdCnq&!m0L#ZOghhOvb}L_<-I?ZE0b!u zcgl;CLDO#M9&HO#h}H(ozw9|VIVHu%=cT2kIqQfC3To%&dv<@Rx&+6D*a$A1Q3Q z)@Pf;mTmi+!9es%2JEM#i34$O-i{1x=8EuR{K@h!;-lF&38NNh*?>g^#&v({$*7u&Z&RS=k zf2^4```OQa?tAb1-q-cqt}T(wz&xEe1J5_QjGh5wnHr9|CDyfv;*F^d^4De=oTRG8 z;NCu)OEME%i5&Pv$6Ftdt`_%_uX_1thO4umca;6ol;HKRa1Ez){Rz;jS<^o~Gu`6d zBt-bf%){i^oA<>28ibIThW}kmOw9UlVeCkWfoEG+i2+I_P1Hj}N$Cp#=@VV}dbbhR zOrD2Yil@ap2(Byz(8Y<{BaDwI-M(O1pxIo>h&!N_FdXin8I}9q`>@OE8p9lLRWz84 z1tMm^0DsRFHVThPBD~6)ofn)P$hb1+gymW9Fh@}0CfvT_5zq zv>e~eBA$3Qz#wYYzbJ}M4Cc1dt6%#5gMOv;Udk`j?{DE@VFN+2B zaJ9V3&NFaxKgfH^5@&xg31n*7sd2pV(i0YDX6W0ySL;Ox_p_zMj6^R0}XFShIM(u|RGXgzxA&dF1xtkb1_j=7GPJy5`Y!cfPfS|6CKBQY|VoS6NI zvAu0}*-!ZGsGnCjhFxwC9R02x|Ggpz=&F|{WeNUs$2tC|)qWSpwZB4W`RztHfZj{- zOhy&1OA6EOL(1V%QCz5BI&5-OO)%$nG8(Xx0fsl?j!p*e@pX2_vLAeu-cL7xmR}_z z`u2Xtq1WPG+8KTUZ?t*(;=qGoZFels`r!JzN?%jS>X0FrEfRyls{)rH&vKSa3qE>p=_n;?P#0~m z%Li_Yfi2ZWaTVO!WJ_@R$QSGJj_o1wNjt;W6%@3`1E7`$q66du<&NTW>-o1%_kX8V zf20OUN7WIyqZw8T8#qE z4F4{s-dB+{0+n8SrZO@ztZZxw5memFmz33+`hi=C{F)9WLxS>9q-utgm_iJmXp#Is z>WWZbnD^DoV7;|Y;l{GzB-jr6Qnm=2Pz?>x;D;`dfsgTr{l-TO8O-L^AH8e=FN`XgDQzoVZC^;)v zDkc65&w2T&*HN+nB=_^KGuz@D;_ooOGy>46{>KF7caUyu(cx7o0PYM z#fmLwZpqt7(e<&0mYjsxuH5v&xvGLd)cT5z+0l>6g%O8$MxJ!og#k&JvDQqakIOEX z1g~Wh=pq_eQd3?3Q}J-e#B)QVUGMgs+cf>35eQ4)o+XmF#s0P@lyr21O1b~e!HBJ# zYZdOcLT$k~#X8p6$wM&Fwk)23-eJbxTO9J_Oi>mD*3ew%#>2>p=35DyK<>lAH9#<#j~M&sJ+(HzH%|%zCq>HvI4A z|Nk2~_S9}%5sa6BFl;rt>CQECI=-aK^A^_@;Z3u+`|clZZWKq9H-l@hHzL1tb9*k| z5R=qH{~E&Y!6u{S#bk~*SC>EZkC;^uyPIfBRBEBOe}UaU^TiLqG6nJ61e<2!#^8W0 zkS5fo(-GCh-=pDx&lP{maBOhnAP(b|Oj=Msz8sRp&s^5MpE zIrSzSku;SgsNS>ZiD$PA9|!qKW@xzL(jYN;(3p^`@nPtg8oUet=BlQv?m%s(Wvj-g zk^AIk2OX9b@o298V9xJ~v8lE+HmeD>peWKmEni5RN;`y?*u_5F8Jd3^>R7VGj`;=8 z8=TS~!=G3=u+xJK*AkXA{%NYF4Kx~uQiOiV-jIyfzRQJN)H{VPRJ=u5-E`FQr=vcN z!oExC{oDTrA0Y`N1coWvjg|g&cW)Tm51U9_;7K;9whp^$u3oyCO$fP_9@VKRtv!<*ji)n znw(Hx&gr0V*Loj>7Nk;&1nUuL=9sDirW0limN6cq!hoGPCcWf}sUn@B5?;fUaeW?# zvUwoY#tiL7{J5u0*Cfn_55>j_M-fyK#&Af={T(*$UG#klt<;F}aAC8fMs$ zC+H$55Lvlaw$m_SF2BFr7n2g7P{f(Uw9+MTnLxUHio6O`mE({vXXO%n7f-I{`v$Io zJ;U(=r{^e*=DVE;C6_N3*aLlFcDd>xv#ZhHF{>qSIoe%ox`G%jmoHU>R-Mq;m)^Xq zlSeta+WWzC4JK7R^Jtbj*S`_Hks`+>wVlMzNzbdcQ|bMh&j-V`*WEix-+#+kiW7VY z(z;NM*s#%J2~iW1C3MzEfkj|Y?omTF~0lz+#;IN2w*xmO=UH`YP`(g|)77J*{s#aSni7QvFVwbFH=(Sxzd zL5jtrmGehSMU#u30QEF|kNA{&xkC9QD}bd-W9v1hSu2HRY8;!3b7pwjVq19Ok+?d& zS4Ymxsy{Bei@ESITb9l1d}=%pqpWTLM%5!>nY#?V*KHjAkiPlWfNy5C$~Z*wvZsxQ<30X{(+n}J6Y3O`@XA;<7qxaZbQ1J#G4sj z?OX9B(DpVp#P?i)rSipMRk7KSGQ|{|63N;{dl}fNNJm3 zSGzxh629AS`EK!G!7f3|%6d?63W#eU$o6OctH}>O2YaOWChP`b@*nuPDui1^3%vQX zSql}!NNlLEp_uffGHE_4`@xuVzu}({dnw=I_D13CNh2Q}3Db{p*lDnj*C{w0yUPPi zsgQL-*C>5xHy&No{>59RG$P$skKi_F$d(*H+jjn>p1@pK_zl)1Z?awwDMoh#j+a)d zfFT}gijt=qb&d>q_r+wp54G zb<=@y;~ zf(uOXQw9^c2g=vChU-l{JZSdcUUhtQy3UV}pRiV%e9-}^2O!i=LShdO_q_^@{B^=R zw?x@`pX!Mo`9vkgC*?iyd^;dd+%i$vN6=V2&RTP}Q`m{5IkpT~$(}E$ z1Mw1$E%i0N7K+9s#5u^9A8yS{oOd$jjYbaE7B!pSzJx@1cuS5yevjbOdJW$UOty#~YWE zOJ@-8J|$|OZl6bYqWkJ$xM-_zKOgJC*u7ZtlGDvQbj4#Ds-DHib?fXEO^(VOjc0~u1K6}1g)%=EbI2!v`cB_5AT9xNBz45>avhS2iSNoS za$mIERo7iDTbhb-3_k7MulU6&zQ|tC6Wh1;!G;fM-L2M;?zo;^bg_DUHDEL#SHASl zu=t@Ln!PGjPOfF}IUvDY=bgF9?1mGC4&1K{U!!K?EGP)C&tem=$hU_fjOvqzETPbSud(h6i-wNrTJ#6+2mx@zMk` zk|fpG@vrx~bS9XKFfLY>$H&;n$Kacsze^}@QPD0ppkPc>kosC|h~WZREb(uN#1#@M z@3&8!|Bn6Gz$RO%SA@^)`$PL0v#pj#hZcW6Sj*n_+3uNCt$$R7T=_Jpf=r+H;E=~4 ztl_l>iFQ|wwC+}~op9x>bJ-LK2|X0{J0J&@9=V1$Q?rwepgN7cMQgv8SXud4-Z6!~ zrY%bq;cjgx7HWy@$&2wwh4kfQkP;|-*@_JFukq~c~Vl3#Zl+N7k^r7ZRK={ht*>XK~%{Ld}ycBT+V6{AHt z^c@BjWnA|r5l%YK$vIF;ZdJ>vejgw~ct?BT?|ghHbEB9q-koDjdswM=b}B5-_P za6Ko0WQYa5%%V_X>(MH+n4x^vc0^l;sklE5b2i=Q;0>;{9$w8JO*n;!_V}p$gj0Er ze%BsPKAyU(JRYZ83bau;b%`?aF)P%t8`eB@8dmqe+o$a+NXGvg>%<9E-nu6B4>cfb zlpl<;d{~d$EgbMlj`!fu?@hw8eeVFuQU;%*$ilO_Q2SRqq5~43^J;~kr8n63 zn8_(eGN}e&;L`pki}8Z;Sux+9oGI^y8hZ=(-uqB15pt7$QTusjgk_e zRaTCDDmI%=Y|w(bsWw+W?b4$r88%C&jNHc_bsFx5p9j#wzulD3`pzL!xP)Y5v+Yu`E~T`#S%LbS(E6y z+QAbJn1y||^G>(@1>SzsKv`1K!RkJ_)uz$?{Le78YmMpS!L(YQHfUfn%<2R{gT0hK zuTzDX=y=5%`9Kvtyy-AUyRmYI$Dz@Mvy%zL8PXJ!Q&~@4UTe%%yBg*j^@Xt&ob~^r z5m?al+aFQu5&i}hm%9@GPIYpLVs>|cS}PK!LZdEi3yym>ea@0D4xMMMj(Q`Jr{%w$ z^@8!g!t3*VDw?~u7Z1+jl9KY$*`*IH^2rR`e7N=vA5%Qum9I(K2k(>LJzYvv=A|na z`DpG|V?kM2CRPrKi{FsK=r0l>U|)mwz6i3*jl?i^@&uU|sj2r86}X(5U+inSTA?%j z8SFKC@@EHDNAl^h8}Cky5Dmhw6;CXGsy7t+pzaTJt2VOp+%IMP#iIP}G=9W>79suH zZ-?U)lt9f$pQ*gp5?ow@Rl))EbN7aHtcTLg>GtHSzAC`RGt2a6eeAjB<_~UBW!P0O zg3{!Z#`UFqGeh7d**FWK8_VyO=O6NhSSis7+9veU%hi+7(L>8NNLV z_jri&IFBrl#4ewC2AeBMxR&kNetg}s{6k_^*t2hRE+A@joiy66mobrwmYwJZHeRpa zQlhesBkU?Ds$=%cs>|h_KA6-jiZDvY1k?RN&8c^)?^6EH$cNn>D%)~5F8{W zp~_ko^KG^pXw9yYh;vPNsE7YAtfmYkY58jMINVL~f)8)=-c6gFV=Dsk70Cp=F2F4= z-yu+4At*i%5cU@mzbNuoB3xa6tO%;pgFUU*G6+;2(hBXQcM!I>v8<0y_}fVOcNhG8 zGxN&6&sgqX@nE;3(1I&HyFP&NEqer@g+}= z7ED25A3N>H9e`84OOgU*%^xa!oT7>v*)OyzHcqgR*BCIqp_qg7ULH`8`Uxo4ZGyn+ zM9wzBa~c^09sJ7U_JVo|0QVbmB`)$G-^&vIcw4H~g&i{gKR7;fGk7j`np+3w)VKJ? z=&!~tatQzT-s=QvmM0z)=q7j!Ufg^o$}oA%(qIh7bv7A8a%_B}y{ZrGCP5B>YVg_lLIR>_F=#Ie-*#6=F*!&)sOCMYxHYF4w5DEB&(%~ zbRLpLt6%j2<%Ldob|>8=3x)a zL(2cC1t=KP1fcRx61+X81ynF%7V-(p94G4-_afp^%PMUpgJQ4I*4mRcAB$t)#D10S zM0bfo#6}5D$(!d9eGhLQq48GpjXIsiN2vs8 zW0@T^d)jA44RqwH6PKREYa~haxaC$3w^eH zR_}HI)V_(7(*UG}Baf2;%yIH4ELj^0qM%NmuXvuc zU)Qq4QIR&%pnu(A=-`G?M;oND7R;%qAY~DUPqHYk{=rZSsv}U9>|R^K(^s2sm?mio zuH$~ywx(swm23A5jr zmMm(PqhVUNdM5Y~!bCknuUrHE+;&H3v_$;^xw~Qrs4GMHJW0*JC&k2;Z=x!3ak*vt zOZZ?*Y9Uq_uIN77eyxrQ66N0?JlyCOIy?=S(ds_UT3;0GY_$@}4Klb`MyR>gIfhpe zo?z%X^&!Qd@2-fH@Ohu#mEe_-E@7a_7MdIe#PJ!hN+AYUcItD$v7E|&hio#JZKC^v z-6OPih-ZI7;e$X$67SP^Br^Toxd?hT+-)OVuJ8_JB>f>V}A z_xfD)B`m=*eT3ZAT5L3t8=skKNG#wfc_=Bv%pSdjRM}6q$2F?a#yYC6A;l7kN5^&< z8|~!L=3`5a7z62R%xeLTj`Z@^3}2oUwcdj^=M)uowLNk2524 z+1g7FWCXS|ufa7nJ~R~J%{zr7dI4MQG%p>IPZ}N8r4|E2zBFQUSpYYY=W0k#_LV>o zvAiTUnM|MD)nKG-4NB-JzkT^V{z3ohCo^EWoe=3@`2s|J+aK*{xT0xPQ=*KRm&zy- z_&~FcxhS8trw~i}FH{tH{a-4|$gFD;#?6etm@w*M80hu-!&6Gq5E9S;Zk7Ie)-HFa zpB&$A2RiUf_-3EB=@)WEKyBRStax4X}im<$Q4TIujA_ z#~Ml0jpWdrL=P7*=6GD(*+5zuL+pFp`u=z_CJ|aPL}{zoT3ee{t{fF-;p6Z_Jdea* zKBF=W!f29Y1O0_5V3Ks z=@f0B^|Kx?`Fc##XFVc0d8(+&P$i$V#5f!$AlNG5M2 zXht93b2G=*Z6B}HgihQ+gh}P+reRLx6+vx9PuTQNJd+rh(dIYdBhj7Veid4GIek^X zqgB8ciaUQ&P$IqbRnTlsNUC58VL+O!4zGuDyqQ#atQ(#y(-VVjbF)A`J`xDmL zjRlLaPDgC1W3&WHa%Q^|qt&X0k!sdQ;2=!%mAC`F z3zVqIos)K6EO^dpKH3+qV?_}S#mNbGTy;|}qilQtDD+*nNcenKWNF=IB+YYj!m--x zJ0(vM3N*=539d@q_02owNF6P9sQydv{7Ja&fc6OqZRQ9m zt7pq~Ww{1zqzx^T9t5>cu|DGrNjIYB#vl+;+>t{RDyX36XDzfFu;heBMNy6xg%MRT zSFMArk?^YAz@pj-Px}IOzFw?wSn-p>ey0SRz4aHsX?_(X_*(Hg#$5FqqV>XbcuA^< zJnOPt)Wb1XrxBR%hg!ZfbQrRQS>l%<;%Lc=sH@Wc@hw;%d?Mwp*DK38_8_Yl57v3f zhHej$aA~pWVr}e`(9=^Oid3r}dO--6LW`<#BUEB_AhRAZK2bjEp69A)mBvh*Kf8?; zxm%>V6Dc*NdX`*OR@Sd=s>=PMZ8OHCCerpqRr(jI*cKgU~Su^1|H zo4A^t_XK8x3EOT>?t@lyK5$#FQAl7!1Ov!HBQf?OkErb4&hA7tP$A^xTJ{x1FBdo> z)5>J;_?@wG3$g0hCZQws#zDa~(R5>3F^(dA`=XBY(M(-GjbGG{zHeAR*BFxY1{iO4 z#1+ZQO^fYv0aIeK?fZ;+uFzlswDTprp74HzR(bAS`EA1OY?r0{;p&{)y7W;hyK>Ct zPYu7>RncjKfjo=gqYK)l;TKhG`C@Mg{ot_kg}BpP*`ma+vj>=M2`z>xNFG+oX=GVIQNXGP#$@NYO%mr5C{t^&YzvJ?g#UaemLd&@pb?iE7V=xKP_wOFIcFLb0WxBE(>h;5buU)2h z24bgoVmNmK{U0Ae(tS`+{VPU=r@g|{qQ_(S1L31`mr4H6NZZ=wiN_5mJ%pUf(W5d# zk_C4+##n=2jjeUDKAfTz(qW&}=+R5h-ljW1Nj_NDmZ`C*coQM}=6Xbw>=gDJQJzYV z7X-PPe^Z!A$|~%T>~I)j92GuXizkh=Tj?)G*YKA|Y3_R;4mG_BD{J5>BaN(?@^5x{ zC6i;Qy$};zfqW*Uq;p(*Om3!=<|?+|KF`cdm+*Y+!UM${UBm^R2Voy%uyw6zA1#-7 zU;~?cN&)_0*XAqfvxl{od;)~1j!J(_J-0UdxG*JLbCi2{>`bh8dvky~E{R*Y3$2?i zVZ!OIny9~Gs1tB_obhF0UDBuYTqW}ClqFA*@IR4U#eYdIYrlOv_?K=DI)OLjIxPHB zxrmfJ1li@jg|`K@0H)Z#^w_sTp+ok{)s1pf+@fat7&y$jBGzzx6)pPJM!r*f-ZPfp zb>JazaKRQ+I(WFS`_$($}^^meJQ%T;{!8o&!)@^ayMRUMidSyO(<|?*~ zJkM?itvAHLfbbL*8qg$x545P#4@@#hLj9c#czsC$_HLmeKkz%ukV9!(+N;QG@T)Gi zw=j+08>rnAZJOhO7ZUp5YNMU&OrLsQm5+`o*}LD8YqO-?WcuP=Rgd)u(OTEOYp?wd zo3td3PIyE)>ZZy(JjTDT9PVPyI13VIK@Hjs2ld-2t1*fYib(}&f-0SA`}N}=ujqWY z{IGS#R}(#=4o4@wR#F~ch1PjJqEZUt%hHA?)b|-}s4=~;)X!Yfhn8bcl)qg;>A@^| zN#*SPP$&(uRz4?vJvYQrIza{9YpY`j>k9SD1ru!cGnz4s2#|i{Hu{ZRXPf?O?Qeij z)`wTGBr{Z#lJwSVc;6a>M9ZRW`ef3Ha&Yk^S%ozHRnu{C(3j=%P-#J{ul8K1?jS*s zoHnG~6`QXg;rk0fq4833&~oXgsOwu1*{}8#Y@OaX*ky_FM)CNmaqfcIJCj-mYo7eI zM}>0NqK_I!?S5~}1{IdC4A|B76?(g=>7|GYKtqRwH+9cQ#ITr#g z*wFZ6@PfHOdWY2f)-ckBMxM-54$?Lt-{;l%KEg8=5e;6V^n&(6O78T>>dfEdd zH_s>-w7Z8I)PeysqtU9T_&4QGR6(jBv?2c7K^gCjwJj1O+5R_cw^TZeCTQRP|Mgb? zpQ^XoBulTzx9`uFW*7jXX0zz0od)t$d(_LD%3R=^vr*azN7QOtI;yA-Pg-C-^fudX z>t@zp3FZ>|GoYnw8ygFa0QTW-OCj0X49w7OX&;PMEgVag8(xjj&hj3?`reLza#JeM2V_Yl>%dD8+^R zsL{&EJ4=NRet$43X7iw7>z=Ow^&SCHCEL|CL67{;G8)IvBO3jkYT>qG?;Hv=Z|u;^ zbtySK0+)OUT|BWfwuSSW7q~JdPW%`j<{yN%H=fwWGIgX#$vJB4!>h~_Qn^QW4Me{! zjGp63(v>~$fL4$F1JHQ2cdtg_Xywk_mUk2{Fr#;R*19t}r`%($5FTTJ>fpQBSkwRd zOXEOJ6t;cuX?KzIov3$^H$LJ8PaA9xUSFh%3n0`GS2{mqG!$7q8;US;kKF$mf=pQj ze5t8Y9l?IIvT-Vt!8?90GvWx_xZVpq7rc8djgnXlMGgBwH2Wg4p)?Gh#ku~wPSce| zvCH+tdJkI@^>}3Im_?78KYg%0V+rvEuY-E7SIK$|(25s>6nf|+I65EgDDlzf zWn8uZ(MdtuQ3-iZ$K4xB_Zm}TH^li6>dtS#NC~wCrL$_{EZt7>$&!vs_QHkHnp$g) zlo@+=fGhaDDo{UsI8vmm-iIb|iopVN1AE{DsM_I?Lz|{>V&y$Oh|<~gFV}=|l?|hk zYjb#2&3eIXNe{W!Zb6TJj*d@MKViVvb>ftQQG*GJdQhrk04NLMKr$TA={&9R!2JK3 z|J$AWZ}Wdr=OzD{|6{4VQZQPgm?FAQBC%b=&q==@I5V~kn2BtuoNH86(U*dlcTMKx znXy=}t4>x*O|$bof1{4sScf#8Y+UQpfip&;;?J!I`8g*cxs2uH`ZZa}N9T3))o{l$ zwfK^F>2te9L4-Zs&geq#&QZsp!$gW%2fZ7TKINs_7N}?B`-j-dX>Dn`9UEB7H84A4 zNP^IIOfOp855>hjCTH13%K7c3bi|0$D8goK|8$cu0$y0ng|h8;NMxOW_|uOYNBdF1 z?GQwxAxx9;lZS#>;~``Iwb)2e!?G|R60nBnkBO)frz!IueKhc5kP}}j;%{JjA$b*DOTpo^n71~X{qzp&MAn#BGb()2?%GbE28A>HG~r5uD79!l zPBi}{+j+Q>|Ga{DG>`EYtuip}*-ktbBe1-w+30p+PeRY5Cx!(9iZO2;*iPf?15j00 z)hb|*k2F;ETz*$Cup4O@QTs6p?X736-Wrv5U4(vu?xCRj40$Xmw-Yb3oLV=!bWj~T zuxwG}I-8Jpv_>p%AFO-cH{!Y|xKL1_y5d3}&$X$@-^#(#ZmS@X|2&lZYzi=(>-{B& zSF;j4O5;~|=B$1Tw4IJ%VW2}C`F9kk0g%%53gc)!_SwfUP8;sk1*0QX;(#vZRi+HB zGHp(Q(m|xqQ)L^bb-Rp4thm9E9Y8bhFil}XTrOJG7JhagsrL0bpGVO$_qlxCR6IGb zE(WHzHc`fCv>`>GCueAOI39_K7^%3-hlP8b##J3_Hq;kF=Glbf+^tL6dS)`k=xv`G z%#ix=o{IRTe`5)F$Al?d8yvs`BiD*hhu@pTl^=r|Y%lRSBNB>&)~EYlljJL7;EZQY z6EVB7GXW0elq`##HlA#i0B#cMVIzU!%UCiZIdooMfMl__d@qfId!O0K8tk3)@eR$Y z%c=5`f*z<0l|sc~)9D zef>`RWFu!PU*QXu%#%^yS-Z*xN3QlV^adxCJR6oL{Npmjla@%Tq ztq(Hf?VR2jjok2+;S5-c*4fMG!z8~VIa>GA3)@b$V)NV}XuZhGDI48bLS0Z@zBpN5 z9r07(_KM_mDr)>zuN@ls9uVMV{+ivf3e1JUYUg_&*|}m zw1;vrg3gsFD;d709TU;o)h7(PKe-}k;0>+zF^zURzdXSgRFFL5Vl*IUT95S?m$-hs zEdds`9cCW9Z9J#!?qx?V;K-T=?Awbqf{rdWJTYtxVcZf+H&C55A&#bfjp7!JaRocc zqGo#z{PN2-t)E!kT1X62ik4?78>Xw5s=t4fN^ty5hIkXpYBzHI{nIq3cM0UEKGU|{ zF{o9%2~NiR>59(^5tIJCw~%Pe=miAa%=vhkXSx2GCxTs~tG&gRESbKi9tW|%UdgMp zX&6OD*0wuSDC>JQ8>Pj+ptrXkL7eK$9+6(ymf&J`_Vm=h@obK?c_{nr2s!%BU8s85 zZ&J!aJT^k|N2STpJ?7w#u~G|@N9z1GzfOnz4&8)>8~1K8h59z7DhAo$8dSAC8mn|7 zjT8pGX(6(>?ko4f#e=3nH^62#4C;Y#vyypzbs3NLmTsM&G^Wiq?)G0-1b7xy{ndVv z+RLMIT3!XOFjbD?qQil2$Fnu+)KK*S#c(C!AAou4pJ18Hv^z~RQU4h@guA$w$5v4M)cVs%C zlw(BECu^dzP06!s6`s-6LVEWGk91fs#TXKN}*_RTR);E!$a&5&fPJo z=oq|ZtIHV=0-^V+lHCb8lG_}fzp6hjcuW9a_F=R+HiHQ8GSpLRgD%XgmIEuX18un(%ly3dt>+NGa2~RUH`zA z_&3j3e-ujwPToT2`gK1!B;ez#`Yzw{qnWj8Cp=hzsc#a+#$TlKjj3p1{IZvw*vXe~ ziDpJR{~)B%_@3RlV59%4e`7C9CpzsJl6LpUWJ7_|9fNL5N``w2+bG*d#HW`EgD?+@ z5Uz=zF;IlJ(^0nwPnTxP#l_ty?dr2CR|gN1eFAVa zHr!X1?wC>Ydf>U-5h^{LBS=uWZLkEd-vjB`ijZ)~TfMtYtPwU@7h4@MV&al#_%fC1 zyWC3|F24K&g(`1&)AMwSSZ%jrH98|F^?8Vg9^`nht2<-dB(U${+odWxYxf>1T%uoa zs&v!Ye#E!B>*wHrl%APc%LOD=&Uyucr`YD+mqT+1pQ^OyAs6VaaewVc6R7iu-&!)> z8@%!rE90nzaz@bflNA2XR4iNnu!c%kR0FHa@ti>iKk=jK#!V(=G&I^sMIS|#GX5Go z%BwS^!nS3w0g2MzuKhUK)m>Nk@kZ-Fy|{!^&#!U$6vffOYm;PzU2)%n}ti%mfNTw>93Wls#NM z6hqXf3B&g%Jh>9XY|QIl6dWA*&I!d9&iZ|?EO>qiL(T0qM)zNGAM-qR4iR=Mwj0`Q zr#AhiHD&YDp361fp(Bt7^$Yh=K3X;UHq{)nNK^1NoJYKVyZ$6-QqI|RKN!INSE0|3 zudIC2nnohx)XmL;osLY&^7%)W(%T@SDTC(k_uti@dWdx6R4p&KR;FV=vJzzrYhu;Y zi|u=UWvi_;$Hq|nG-OV+80Z2+>+hCwH)_!5!9k*ERPefBBl1QANX+@wiJe*;3Dfzr-_q>AVYS{d%a)v zHq%}vN83f!y}!GIzm%YNOSV>QWsq&=D~p^^uFmFb!JVl#h68`o?Oxp~U(px~5(4MY z46=MWB}8N?P6l6NN4$W<>2>6=>9>nhmtHOiv9r!jr&!;V^z`m6--DT~mN8|W8o@g_ zIH2z>VF}!2>q$O3rPvpi#Mlr3OT#JBKP*Odn6Y{9q}MpZScZPng@~x#zqRkkI7hkQ z19$1&t0+QuYR_$4hZUOM>~8{xZrc3b5d+a$&%S+mI!9M!5eFZVivO|b{+%H(cj#XA zl!=JrBsKk;x#SnwBzGlu>LbORzf^veO&Z|;MCib<5MLE-A|Gvew0q*^VNbn&xw3!p z`QF8K_J=&#w7Y{k93~5R@w{?;WA|Rf@j$0m_=Q2!*~}NaOvM}CQ?d`@+6>p6SvUsIf4AxT7C}qvNf^j@hZH#Y(K=$fWgW}HL#LuJ z0_y`dr0081e^H}yJM@x$!J!$;_L{PI8OJ~U_zue#w_oRrQ2Z|`sFQX5X!!dS>PNbg z4)@eQAiX!Y%LB?~#j=hjhpH+`i1I&+Lfqx`Zj16x6sx34Hc@|{s!8*sKY+9aNpDoS z4&#rQE)}@R8JtT_ro)(ZWBZ(W@A=B&JC^9)!n?07)$@MHTZc_Ga^gp{W@6b6gCrB@ z8f!H#ip_*|hzr3kd6E2q#y~gL1iWmxOHQgn-)exS$JO|( zh#-RaA@uS1(d z+PkO6C@1QwU4G1jP*z;h_X*F7gF!_5J3L>1lQ?dwZ{x4_tu9VSn#V4q?x%Oc z7{hXLwtrZIdahD`Ny%zL4P~tnW0jOmMJv2JUTu~4jl0>}?w^MsJD7!ui9LD4xRn1$ z1;t#`9o@PnF{+D2_(z&K^}OHa27LYbp8esea9Uh1?3?+ry`n`7@&SG?yM@))_}av& zXG1^0{p}g<0n0rjiHDrNLS`)YC~Aj_-~myg85G0*HAKQW zdr9$fc3S75@9$Z0%OAYVXQ9Z}dwgOsE4s4(WQ-3iIK8bHx~mP>q`yemA~(P?AsQ?1 zW}iF+cd*5Z2)n#w3_aD%How;_P5kKo_Cg>|2NPpW;a41}6iRX;m<^A))a~TSjFkcd7^z}BoxO}$*QvSyGt=rw6DN;DS0o&C|;r*8#QJ1@e zUXnJzG#&QDxtYWZSNq|W`du~Im#74%?=2-=?`a6O=o^D0GbH5tc7j-S8(FdE?n~dn zvj@#A4}C`}gtkKcWzq21dxY#Q5}w1^tA_8o3dKJ<{u)2=IXI%y^g8+#liD1@_Y7ii zL7J-?`{ioZ2e@O}!}8HNr={`>FBuPN-S~9IS?H9`EZa)GZs?hinqNx9^LP7*aSbkfO7`te-vE zn0?%I5MO+r^G9!p@cSs=kZJqweUsLa=LvAB;J%gC2>fCYM-;B^Ww_cu714e}$+|Qg z2S%341nHUcr&dv1$kY1z{pqI~k+`~V2!H*|No!$6U;dbXD`hJ&6!f#pG9ZBF7#yzs z5pBBm%ZoI<@b!sf-nYGJroSU z*A>`t{vg8>=$9$U{i(+g70SpmABLoQUTTi-2pbAN&$_<6m3XLdpAY1tf_7>zNZRU^ z*_ub~kChsDbA)<)Li&fOa@FDvXYOow_+Kur8hG#5uS|H>`%ZpShd!0KBb2+c1gbV= zKaX^bU(gJwil!j=Vs>Sm5FnE*c|f3i?amsYQ013k;^5}vr<{Ij`bc$E^^XSP<$Y?0 ziAtVnqgd%X_i;@Sa^u2L%ool)0 zp<`yt1J_}D_GMbomBlB^jeo>cf1+V6Z>aca^Bz2y`(asOQg(U4=gJO%L$K9`@AH_ULzP*Sld0Uy zkos=OJHn%I-uMAL`L8Mw8Ttz3%J1`K>RRY&Ci-Wfur<@_f0Wh_-uEvrU

*F- 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�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 J-Pvom{{tDV4Ltw= literal 0 Hc-jL100001 diff --git a/docs/src/bigger_applications/app/tutorial003.py b/docs/src/bigger_applications/app/main.py similarity index 53% rename from docs/src/bigger_applications/app/tutorial003.py rename to docs/src/bigger_applications/app/main.py index 4c2a348db3..4e614a0073 100644 --- a/docs/src/bigger_applications/app/tutorial003.py +++ b/docs/src/bigger_applications/app/main.py @@ -1,7 +1,7 @@ from fastapi import FastAPI -from .routers.tutorial001 import router as users_router -from .routers.tutorial002 import router as items_router +from .routers.items import router as items_router +from .routers.users import router as users_router app = FastAPI() diff --git a/docs/src/bigger_applications/app/routers/tutorial002.py b/docs/src/bigger_applications/app/routers/items.py similarity index 75% rename from docs/src/bigger_applications/app/routers/tutorial002.py rename to docs/src/bigger_applications/app/routers/items.py index 46a241902b..2297e2d27e 100644 --- a/docs/src/bigger_applications/app/routers/tutorial002.py +++ b/docs/src/bigger_applications/app/routers/items.py @@ -3,11 +3,11 @@ from fastapi import APIRouter router = APIRouter() -@router.get("/") +@router.get("/", tags=["items"]) async def read_items(): return [{"name": "Item Foo"}, {"name": "item Bar"}] -@router.get("/{item_id}") +@router.get("/{item_id}", tags=["items"]) async def read_item(item_id: str): return {"name": "Fake Specific Item", "item_id": item_id} diff --git a/docs/src/bigger_applications/app/routers/tutorial001.py b/docs/src/bigger_applications/app/routers/users.py similarity index 68% rename from docs/src/bigger_applications/app/routers/tutorial001.py rename to docs/src/bigger_applications/app/routers/users.py index 37e3fbc4a3..e88b20cd1b 100644 --- a/docs/src/bigger_applications/app/routers/tutorial001.py +++ b/docs/src/bigger_applications/app/routers/users.py @@ -3,16 +3,16 @@ from fastapi import APIRouter router = APIRouter() -@router.get("/users/") +@router.get("/users/", tags=["users"]) async def read_users(): return [{"username": "Foo"}, {"username": "Bar"}] -@router.get("/users/me") +@router.get("/users/me", tags=["users"]) async def read_user_me(): return {"username": "fakecurrentuser"} -@router.get("/users/{username}") +@router.get("/users/{username}", tags=["users"]) async def read_user(username: str): return {"username": username} diff --git a/docs/tutorial/bigger-applications.md b/docs/tutorial/bigger-applications.md index 056dcbbbf3..81ebb04403 100644 --- a/docs/tutorial/bigger-applications.md +++ b/docs/tutorial/bigger-applications.md @@ -1,13 +1,284 @@ -Coming soon... +If you are building an application or a web API, it's rarely the case that you can put everything on a single file. + +**FastAPI** provides a convenience tool to structure your application while keeping all the flexibility. + + +## An example file structure + +Let's say you have a file structure like this: + +``` +. +├── app +│   ├── __init__.py +│   ├── main.py +│   └── routers +│   ├── __init__.py +│   ├── items.py +│   └── users.py +``` + +!!! tip + There are two `__init__.py` files: one in each directory or subdirectory. + + This is what allows importing code from one file into another. + + For example, in `app/main.py` you could have a line like: + + ``` + from app.routers import items + ``` + + +* The `app` directory contains everything. +* This `app` directory has an empty file `app/__init__.py`. + * So, the `app` directory is a "Python package" (a collection of "Python modules"). +* The `app` directory also has a `app/main.py` file. + * As it is inside a Python package directory (because there's a file `__init__.py`), it is a "module" of that package: `app.main`. +* There's a subdirectory `app/routers/`. +* The subdirectory `app/routers` also has an empty file `__init__.py`. + * So, it is a "Python subpackage". +* The file `app/routers/items.py` is beside the `app/routers/__init__.py`. + * So, it's a submodule: `app.routers.items`. +* The file `app/routers/users.py` is beside the `app/routers/__init__.py`. + * So, it's a submodule: `app.routers.users`. + + +## `APIRouter` + +Let's say the file dedicated to handling just users is the submodule at `/app/routers/users.py`. + +You want to have the *path operations* related to your users separated from the rest of the code, to keep it organized. + +But it's still part of the same **FastAPI** application/web API (it's part of the same "Python Package"). + +You can create the *path operations* for that module using `APIRouter`. + + +### Import `APIRouter` + +You import it and create an "instance" the same way you would with the class `FastAPI`: + +```Python hl_lines="1 3" +{!./src/bigger_applications/app/routers/users.py!} +``` + + +### Path operations with `APIRouter` + +And then you use it to declare your *path operations*. + +Use it the same way you would use the `FastAPI` class: + +```Python hl_lines="6 11 16" +{!./src/bigger_applications/app/routers/users.py!} +``` + +You can think of `APIRouter` as a "mini `FastAPI`" class. + +All the same options are supported. + +All the same parameters, responses, dependencies, tags, etc. + +!!! tip + In this example, the variable is called `router`, but you can name it however you want. + +We are going to include this `APIrouter` in the main `FastAPI` app, but first, let's add another `APIRouter`. + + +## Another module with `APIRouter` + +Let's say you also have the endpoints dedicated to handling "Items" from your application in the module at `app/routers/items.py`. + +You have path operations for: + +* `/items/` +* `/items/{item_id}` + +It's all the same structure as with `app/routers/users.py`. + +But let's say that this time we are more lazy. + +And we don't want to have to explicitly type `/items/` in every path operation, we can do it later: + +```Python hl_lines="6 11 16" +{!./src/bigger_applications/app/routers/items.py!} +``` + + +## The main `FastAPI` + +Now, let's see the module at `app/main.py`. + +Here's where you import and use the class `FastAPI`. + +This will be the main file in your application that ties everything together. + +### Import `FastAPI` + +You import and create a `FastAPI` class as normally: + +```Python hl_lines="1 6" +{!./src/bigger_applications/app/main.py!} +``` + +### Import the `APIRouter` + +But this time we are not adding path operations directly with the `FastAPI` `app`. + +We import the `APIRouter`s from the other files: + +```Python hl_lines="3 4" +{!./src/bigger_applications/app/main.py!} +``` + +As the file `app/routers/items.py` is part of the same Python package, we can import it using "dot notation". + + +### How the importing works + +The section: ```Python -{!./src/bigger_applications/app/routers/tutorial001.py!} +from .routers.items import router ``` +Means: + +* Starting in the same package that this module (the file `app/main.py`) lives in (the directory `app/`)... +* look for the subpackage `routers` (the directory at `app/routers/`)... +* and from it, the submodule `items` (the file at `app/routers/items.py`)... +* and from that submodule, import the variable `router`. + +The variable `router` is the same one we created in the file `app/routers/items.py`. It's an `APIRouter`. + +We could also import it like: + ```Python -{!./src/bigger_applications/app/routers/tutorial002.py!} +from app.routers.items import router ``` +!!! info + The first version is a "relative import". + + The second version is an "absolute import". + + To learn more about Python Packages and Modules, read the official Python documentation about Modules. + + +### Avoid name collisions + +We are importing a variable named `router` from the submodule `items`. + +But we also have another variable named `router` in the submodule `users`. + +If we import one after the other, like: + ```Python -{!./src/bigger_applications/app/tutorial003.py!} +from .routers.items import router +from .routers.users import router +``` + +The `router` from `users` will overwrite the one form `items` and we won't be able to use them at the same time. + +So, to be able to use both of them in the same file, we rename them while importing them using `as`: + +```Python hl_lines="3 4" +{!./src/bigger_applications/app/main.py!} +``` + + +### Include an `APIRouter` + +Now, let's include the router from the submodule `users`, now in the variable `users_router`: + +```Python hl_lines="8" +{!./src/bigger_applications/app/main.py!} +``` + +With `app.include_router()` we can add an `APIRouter` to the main `FastAPI` application. + +It will include all the routes from that router as part of it. + +!!! note "Technical Details" + It will actually internally create a path operation for each path operation that was declared in the `APIRouter`. + + So, behind the scenes, it will actually work as if everything was the same single app. + + +!!! check + You don't have to worry about performance when including routers. + + This will take microseconds and will only happen at startup. + + So it won't affect performance. + + +### Include an `APIRouter` with a prefix + +Now, let's include the router form the `items` submodule, now in the variable `items_router`. + +But, remember that we were lazy and didn't add `/items/` to all the path operations? + +We can add a prefix to all the path operations using the parameter `prefix` of `app.include_router()`. + +As the path of each path operation has to start with `/`, like in: + +```Python hl_lines="1" +@router.get("/{item_id}", tags=["items"]) +async def read_item(item_id: str): + ... +``` + +...the prefix must not include a final `/`. + +So, the prefix in this case would be `/items`: + +```Python hl_lines="9" +{!./src/bigger_applications/app/main.py!} +``` + +The end result is that the item paths are now: + +* `/items/` +* `/items/{item_id}` + +...as we intended. + +!!! check + The `prefix` parameter is (as in many other cases) just a feature from **FastAPI** to help you avoid code duplication. + + +!!! tip + You could also add path operations directly, for example with: `@app.get(...)`. + + Apart from `app.include_router()`, in the same **FastAPI** app. + + It would still work the same. + + +!!! info "Very Technical Details" + **Note**: this is a very technical detail that you probably can **just skip**. + + --- + + The `APIRouter`s are not "mounted", they are not isolated from the rest of the application. + + This is because we want to include their path operations in the OpenAPI schema and the user interfaces. + + As we cannot just isolate them and "mount" them independently of the rest, the path operations are "cloned" (re-created), not included directly. + + +## Check the automatic API docs + +Now, run `uvicorn`, using the module `app.main` and the variable `app`: + +```bash +uvicorn app.main:app --debug ``` + +And open the docs at http://127.0.0.1:8000/docs. + +You will see the automatic API docs, including the paths from all the submodules: + + diff --git a/tests/test_tutorial/test_bigger_applications/test_tutorial003.py b/tests/test_tutorial/test_bigger_applications/test_main.py similarity index 96% rename from tests/test_tutorial/test_bigger_applications/test_tutorial003.py rename to tests/test_tutorial/test_bigger_applications/test_main.py index 680bc8efea..eb68c44929 100644 --- a/tests/test_tutorial/test_bigger_applications/test_tutorial003.py +++ b/tests/test_tutorial/test_bigger_applications/test_main.py @@ -1,7 +1,7 @@ import pytest from starlette.testclient import TestClient -from bigger_applications.app.tutorial003 import app +from bigger_applications.app.main import app client = TestClient(app) @@ -17,10 +17,24 @@ openapi_schema = { "content": {"application/json": {"schema": {}}}, } }, + "tags": ["users"], "summary": "Read Users Get", "operationId": "read_users_users__get", } }, + "/users/me": { + "get": { + "responses": { + "200": { + "description": "Successful Response", + "content": {"application/json": {"schema": {}}}, + } + }, + "tags": ["users"], + "summary": "Read User Me Get", + "operationId": "read_user_me_users_me_get", + } + }, "/users/{username}": { "get": { "responses": { @@ -39,6 +53,7 @@ openapi_schema = { }, }, }, + "tags": ["users"], "summary": "Read User Get", "operationId": "read_user_users__username__get", "parameters": [ @@ -51,18 +66,6 @@ openapi_schema = { ], } }, - "/users/me": { - "get": { - "responses": { - "200": { - "description": "Successful Response", - "content": {"application/json": {"schema": {}}}, - } - }, - "summary": "Read User Me Get", - "operationId": "read_user_me_users_me_get", - } - }, "/items/": { "get": { "responses": { @@ -71,6 +74,7 @@ openapi_schema = { "content": {"application/json": {"schema": {}}}, } }, + "tags": ["items"], "summary": "Read Items Get", "operationId": "read_items_items__get", } @@ -93,6 +97,7 @@ openapi_schema = { }, }, }, + "tags": ["items"], "summary": "Read Item Get", "operationId": "read_item_items__item_id__get", "parameters": [ -- 2.47.3