From 41ca767a3b36a9914e66804268c976516e281ec2 Mon Sep 17 00:00:00 2001 From: David Esner Date: Fri, 31 May 2024 11:24:31 +0200 Subject: [PATCH] Detection of path when missing to match generic ex behaviour --- .../__pycache__/configuration.cpython-310.pyc | Bin 9227 -> 0 bytes .../placeholders_utils.cpython-310.pyc | Bin 3847 -> 0 bytes .../user_functions.cpython-310.pyc | Bin 4017 -> 0 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 191 -> 0 bytes .../actions/__pycache__/curl.cpython-310.pyc | Bin 5267 -> 0 bytes .../__pycache__/mapping.cpython-310.pyc | Bin 3693 -> 0 bytes python-sync-actions/src/component.py | 35 ++++++++++++++- python-sync-actions/src/configuration.py | 6 ++- .../__pycache__/__init__.cpython-310.pyc | Bin 196 -> 0 bytes .../__pycache__/auth.cpython-310.pyc | Bin 4833 -> 0 bytes .../__pycache__/client.cpython-310.pyc | Bin 3081 -> 0 bytes .../test_009_empty_datafield/config.json | 42 ++++++++++++++++++ .../test_009_empty_datafield/response.json | 13 ++++++ python-sync-actions/tests/test_component.py | 33 ++++++++++++++ 14 files changed, 127 insertions(+), 2 deletions(-) delete mode 100644 python-sync-actions/src/__pycache__/configuration.cpython-310.pyc delete mode 100644 python-sync-actions/src/__pycache__/placeholders_utils.cpython-310.pyc delete mode 100644 python-sync-actions/src/__pycache__/user_functions.cpython-310.pyc delete mode 100644 python-sync-actions/src/actions/__pycache__/__init__.cpython-310.pyc delete mode 100644 python-sync-actions/src/actions/__pycache__/curl.cpython-310.pyc delete mode 100644 python-sync-actions/src/actions/__pycache__/mapping.cpython-310.pyc delete mode 100644 python-sync-actions/src/http_generic/__pycache__/__init__.cpython-310.pyc delete mode 100644 python-sync-actions/src/http_generic/__pycache__/auth.cpython-310.pyc delete mode 100644 python-sync-actions/src/http_generic/__pycache__/client.cpython-310.pyc create mode 100644 python-sync-actions/tests/data_tests/test_009_empty_datafield/config.json create mode 100644 python-sync-actions/tests/data_tests/test_009_empty_datafield/response.json diff --git a/python-sync-actions/src/__pycache__/configuration.cpython-310.pyc b/python-sync-actions/src/__pycache__/configuration.cpython-310.pyc deleted file mode 100644 index f48f724d6e62126ff8520d5836756f358b7a429f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9227 zcmcIq+iw(EdaqkoS68>&ZDYVNWYP=lhMs^u%jB{l3=77FVPrfm&M0bl<=XhX+jfvQ}dF)x~JpYXlgCP zGg_u+>I65NRx9IWxNSA48!uG09YY~6&W@oihvbU*et_lMG3G{3M*lUIWZ5&yquGnCzdzQ zqmGCLz!uU`M;LZg90TlF3R}R;<6;qzMa(n3qvC`-CQizQh9%w*r=D8g@f1=3vH)~-SXBvTQii#dvYwcdEV#d~oK^VoE^<@eSdMJVQYe9C;?5 zyWVLxg3X?)(Lq*fp^P)zwPsJ&!8)TKwdq9HQNjYMf%Y71C5$}-tC-ckar#W(KHUvJ z6+Z5oRkGWx)#VFafyMCcor*nqOp{g&}Cy&0=-HDI+0BuVZ`CS!k z*COfjRcQ0jKvgjM=MLO=>F`Mh?w`Q|eE%{U15FhZ9PH`b(g_>F+%xZ^4>+-^UWU=} zNFdB@Y5iAs7QcSo+>(BQq7s8PCmu!7XbmGcX2B_Gh?e#q9r!TTXws+Cdc5 znn7QdqldCQwN-f}4du?pmaIqRhU&D+B4AS1)XvgqnQLk@yfpfvwWn6PR9+oTDmObd zAw{y*R@iAz4_$Ic%iNPuPqne`2(n($y}4ks-BHr-wdH4B97>9c9b2?eoDscNH&hM~ zp^B(thi?FGi!-!q2r)M6%}^adr+MRUef#J>y!LT zqPH|XA+{AC{QxVHC=$)WMO1&LHJJIHIz+V}X?yyr_Js72+5f@l#t9C}P3WF-r%_h& zaW7E7Ubm)dEg3;7%Nsa=CIro!Qg>(s&GQ!$=0H zvgt|U{OGJQjI+0I-M@dUdNZC)yZr_kX(ULg0k(xt9q; z^-imM!k8Tq3F_(Qz4b#O#ccnbU*TlcN+EW9pHSlavFrP-j_5V1UGV+Ky;?Kv zDL`#SK^<)Jup?p<#AT^SFq&sGm-bo2=IR99hG?wlgcCx+nvO2VqD8n3i7Jj}7$w~> zQEZf%MVWsWRGp)0iB>g(b`;P0ey!c^5DsCud|xe7SEd13kJLLfmQ?zo zXu5z7l97;9kqh%x(19F+z8*QW`xrSAs1f>QTwmJ4c&2+w0Y^H9PjsjwOsYtv{g5O3|Ul?XQ1<5CzleK;yXV~F=` z6trZg7ggrI3Yy==dDIoEzD*S&lG#FCrPei6u|=MgTA}aXqiXDCjK%N|(LqavBm*vp zGOy3;1ui9BQSa-?^C##%ggnG=5JV=5IpQ}EWdupclmWtR_@?kni72DqJQLADZw};e zV;AJO2WutaG~20~nUQVL?Lf9b1GrL5oNS8vxU`=-H{v7p4j8=MlRgY}qZTxKO2%#* zOG@EybvB>~zY5ZC;>PMds%}wrovQb#It;a|=%BG7IS_>q;iIG~pG0y&R|I|iO^FE)y=fwfslta{ zbc6+w%twA#Ad73op4CU#)7yq8ZJI>^cP>Z_#v*s2v_QRSV8?ZRkYs3Eyf#p z=;)v@K@(xObORx;q8<*q)Je3aa7NxF2^FLHuhEDIy*lCw1Vus*v^`_j7#L_%ly2-I zs72c%IR0k1-u^V}XF=t4UiIRyRK+|BMf zySXSgum{rt4w-;DN>faStmUXv-o98SEm@0r*mO8tpA^bV)6ru& zXqUIYIh@OrlaLP~*%Y04;Aj&b$eiqD$=P|JnlTjh!zk)1GIw4v^?8y!RT$gs5h4Iq zm(iWLAml;7=rD~xBItLhV#y_;g%Llx(F>Zw->(-;ggESF#Pi93NhgV2nfM5~r?)xs zNO2}roCPKbeeC?ibIDxjC=S1%qFC^uktxRHb9fH*Qk=f;*q%!r31YqcYq^|N?saGFqEV=#Xf)&WxWEisUISDgTQJ+lMtB{S%kksVLQ5zE9fqW!q6!aP?$Q> z&J?_CBA)yi)JC8|U1&fzli|6(r>$zA6h4OH*tMVt^le?8ggSsyxU4-c4mb_ke>Oo3 zV)n`O%CD6WlvkbDEFl5}Z^rkpJy?IwzrD8p-knv?_WkO$+iS08&-nhz+O>OY_x$xc zAFRQLffpQl1;iiSUbNDyKavp=WbL|=l%cIP?{EhaV{)UniHCt&w;QxK!@gTSL-(Xa z!K>VvE)w3Kc9e+igyBFaB3hh*U)ljQT$qup> zUO|w|x}j?kjKr1=W8}2Y0h$N&J1I2Fa|$HtV&<8F5ywRl{SBVu9O!j&8qP2~$o{?d z57-|kq1{W^J;$v%v|Jb-H*%jC>dyx*dglSla|c4+y1rHR}YOMQJ^%!iS+Nk;~?}OvZsq!czJp z!xdmh4Pu{eAvv^xxS6zbP7-+ z+;(6LRZhk3Um0ijr+w7%lg&f`SUyL2;mY`7Cy~P@PFIB|`F;FVpHuaxsQM=+C56&x zBXNNoNQ{V!#9r)!F{Y4V9epR5Dvbc-(veXaU>>F~(k@SEjXbUFrwOHO@;5|^q6eeL zp$J#(N<75)U!a7?P%UJM7cG-&`+r^ALSmKR287?Ad1h0IqL;ce;oGI*|j=aD`vBl2N7As=l{=4KAkZCS= z$T>)C^FdX&Lfl5jpY|NR9Cy429}7z6FR&o5`od7(qBi+TFU-U#Bjj=pvSN)f%u`}# zxbJ?XKE<3l*k*oWDIxz)_8d{=>BA5?A}7;(3ZDkn!7>Rx3AqB1vicYe-VsM1(R}|A zeuzOQ=?Jt2o>R|$>DDPHO>J({L=-0Gc{C0X6M_c9;eSUk;aH3UUD)irXH$FB!o>c~ z6=q$;fRAMR5F#bL>)cD{gbq$q$NR{ZPZr{leftcrr+$nr)K5@B+(!6_GfC$@cK-o} zy-8>xAF9Oawq*3rd?|7g4OPkSOYM1c_aEH7d*>e6;lu^KpTz!zt0Zep!lj5A6p=&G z<`Z<{qp=W@Zu~h)xPZ#h;QPS`G>$LmhJ#|_S%kIcDSlW>vWY}iP9?>b#Q(ieM5)+D z`VOvZ@;*fhKS{-rXeST87pTPvbkX%s|Wy=@YZL%@a%8DbYcciIeII){PBoU0pZVMs-yWSZ}8!vb1 z*`Z?*s~1y+otFT8E06?`3gp2*rhi~x`;_Ot8EDk+%<4i}R@)_JIM*{X=X~coGuiaC zZ{ged$7=5{vzGNws!V=UsN6ux|AtIhf+bd;br_>EPk7(%*rseJPT%dgeXry7Yn@uZ z-l;R|cb0I3yKM1hpSMIC^;tP1&Y`S4CgG8cM8>mbSBfaR9 z&WCZXOXpS`>C(NM##vh0@1~m(&71rfDmRe+)kG$(4ii>~3x+j#Iej;m>bH*~InbED z_RKEp-7YQI?UsJG+s9f7m7Cq}gJGCdJTgz^RI($DHrsC+7iturCgsL<{ZGekq zI@<@ea_aWchM=CQiT#ysFP4cY-G^Z^lqWVr>b`-LUx5V<^e%0|q$6GF8T)ftJE{Q> z_EAkZ$NPG9;RG>jxj9hSE)>{5rDO+Oi94$J(`SS)WdS z!nd3)SF;^nIE7oVUAwRgXVrS(#a6+;Wrh7M+p^J*_FeKBwg%U8V=eo+x&U$I%(~Rw ziCvZ#O@rA{cOX?a+K3a;{Vcn;=&6gCq2?*OM034r<7$pt&QW&gSc(8y&QHkdWfQXU zv*^wVtB&1fbFAt3&gj|+{Vkt5|7gwA)wK=rf)&<7raZw@Ut3Td6Kt0Wkk^S&# zMi4dK7+Vi5wOY7am|w605dYeS(i>~f+1rYU>^sUzXAtU*(WN^ZGN4ib)dUkJ2o^@~ zF9iKzu7i6r2!mX!I9(5nn_^^`2HCyOWTb;AOLZ8h)VV-{7SJbxh2AhVjI^*^@?NS) z)r)><$0>+5A0)9Z{Wy=)T!(2SOB>=19hFX$4K_=AkPRwmoO=NpU9*GIOR^|Ta=_up z?u3cbP2@wFsMk?e=P5gm2K7UsbHXd`hs?u3EMn4G0um*cZsmFzi>>H(;j6 z3}7I`5j;4I=>F0A*m5jwZ@$AU`eB}1*aVHk*|l$6L9w@9u$YaV$Lw=5xUu%g`;ase zC_43MDM&L7TZ7DlIECej3xa(vcrExSd=&SG{lF;k?O=3vEvrnvKZQUtx_n~ha&UEj z#&foa_-dr)aB@45X=T?lWJiHO((S3N-zB7&Pyq`Xr!@{u8Z`zj8~yN6*T^g#n)RX? zuVExHQBG{Yc@svw$Xd3?o1DXyedc`6_eKl<(})$E)T@vZky{*m90f8h(O~`uWS~5F z@jm6f`U(GneE~x}g>TPWnvb~(o>)&u`H&p1X z8I+z_o1kRq=?5sRgEKz$w;%~}t$Bb$u&?dE@&}wQAeH`Tuu&31HeddUk@}1qWp>&V zer;|hl{O7K`l|`9KvC8oT&H8^6!kr5w6*8$jjo@fzn2j6@@nOg*HJhSxaca{zFI(5 zI@DbGbR!CtmU$ee*gdJf)959k*0|Y-YHPowY34fd3QD(;a=K0sPq$c;!OY(`UEdzP z@&9iS0Vf>{^)XG8bq`Yh1}YUh?^<74urMtC#OguUf^XM}p}$198?!AqE%a`$9TP=> zIW!t^i!oXQG;Lr44&Y-}ne4z!j-YF&J&FfV!!IzUGX*=`i_?&N46-FgK6Ak@zT!?gs~vGtgPklRDZ6hya5jqUCxJ z1|ri-`#Y4P3f-V|1DWOE_i{i1D)>A`M8}f=?~NetPLm&D(||DDCz z5?D_XTp;Mxq6pAs12;mY@y^K=fwT1V<^X4|fMLL5fI(m>8;4I36JE@ID~u2d45~_p m-b`lQiJcnE80M?5R!_6*#QSE?O{uszKsz8 diff --git a/python-sync-actions/src/__pycache__/user_functions.cpython-310.pyc b/python-sync-actions/src/__pycache__/user_functions.cpython-310.pyc deleted file mode 100644 index 1e148ca5f43e7b9f36940f0976d8944cd5e4245c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4017 zcma)9&2JmW72nxilFJn-%eE}papKS)YRWc};vi0w)^*d`jolU%g1SlJZH?_}XGE>d z-KA%Twnb2vNJuFZCWRAOzQ@&X)8h1w6)X=>dd-p zahp5)7I*gSz~}6~)pq|4n$|{4_0ez2^KY0H7V!ZO2Kt6V;ED=&d1c?)W8hKcwS6n7 z@hiN}{e2dAe2zCTQ|C=SkJjg>_yXEFewv>_+u&#UBHAWD$CuE~^JRV>?J0hhzrinp z!UBJjzlE98n7PE?#>^Ss;+HXVmS2F}*L3sqLdZ}1S*(&gD+V|G7QWm4Lgi^|Ydqaj zd23U&`i0=FBx}Wawv}{bKcXXMe{3JQG~Ky^avP<17uC=jSqIjxJ!EC?DU*weaW-UM z0m-5LmGyUbkNpYQKq6;jaN&MW#K~3yZeS@7#rXZ;-G{BDXl1!-75!c>mrC%*>Mbzz!pG%p`wxiubbhmVKvK(enDuQ`BcX;H5C2P3M zw|`tG#ENxMWJ0dr$>V-1GF7a9CZkxa|LSMA*B^_`Jnu$p;`wSvU{eyWK7D_^x1+Z6 zY_-_Q;?<}`d%ckHI$iOQ%UW+oFFlRA36GSRP8)$12v4d!)?haCP~4aF8(braraD}E z_3@bD=;Wh5>4{3QgzC@M7Bs@`eNS0m!W!?O7;VfPBQ;l1&eE~>P<5c(hl{&RS&DsW z4cVT($0QUzf+HQU0zJ;4ZnS^3pV%O1YdZ|vj;!ObB<^}aJQs2Q$Yr4qFOIt1XtOJH z4GN5ulG-m+BvtV&QQJgh?L9r03Lwf2HZPcV;%;FyBt0VQ-|QxZiu1I0>jK8bJSxuu za4!Me%c|}FckuBnY_BnuwVT}>;uN>gnNVzl9Z#e@4WcDa(<8>_Qp?1Vz*@2gEB_al z6COm^+$AzCROB~9cEA{5RseI)9$FnXwEw|=WBmnQ^MY+mFl}PHB-WT9FO;OO!0knH zj1C#Gfk@7w_ZCXwqVm}i8(f-|^|)rf^;RCNuB59gJSOobAF&}4w^52WP$_E!=Z3)c zAM9Oc*Bv?|xcLDLN}j_qDfsawbe?pJV3{NnA(^{MQV}MZ5)u}yy+X+?nrc_fMG*DK zB`}+0o$+8RmuaMe(l!i@z!Moay;3jJ+v@r9WTr_XsANFkMbmI+eT{bMzV7pd0j;ajU)9P9RG%N1ql{sB`7z{SOsk)s13~I zvn9-MHCV<08#&a%7VM2drLVSDKWe+Wx)~MX!w+ZIj@#xKTlvJ*l! z%d=s*zYT_^NwdMlSy^ZHy;kIJ7GELq0gP9+umD+W+flLIO*XZY@*DChCUt#VJm*PA zKp!g@A5*FP9_HwQF&Hkg!RcAKK<2g5$nO%p7OJ)@>27!fwxjEYt^7W%y^7%~7S?Hz zxDL+DvZM1eenDnJ#VCwS1#!_D9{Pd2h`F(w>N*$QBu!xax(f5}ixc{&C26koe&q>k$PzC^d6U-$th6AmBNO*)GNG!?0J; z-XzQ+*N}NieDJKLJpi0PljlKKU+8W3C`Og(f(cb&8RjM^H_PET66*St3i3sYkoo4L zeus>-{Iyq z<$8Clhdx5TyITPgZ0HUv2Y3jcEDs%+*WAXyUU`7BgOZ|flzS+@K>0PweUx5%Ub6?9 z?P!*2mTAT{d!*St&F*TptyxF2L{j|JEYj?!NC_(NowU$3DSBOGV(n`AYWRfb_?>8s z*G$3|G{+E+7aeR2s^#1<{N#_p=qD&9{c6|^=CbO4+{yx*M{n@Xtl_>^fhR1Alwt6t ze53SS{(`r8{k_^U|#X>uXukweGL6VI~%3gvdr9-`_P{sr$d5a_nCRSK2 z-^id&(LW>`l%LR^Sx?h-Y*RTc{}QVv3v+>*Z_hKrv0)!~`|17}Yjkj!-oLv@X|MbDR{Cq+^! zEq_22MWzx+vN=hz%HL6Scp1|(sU}^5lDOg;D$jD6=h`)&c@@9nxt??Q^BvFi=NgSN zF`Sc^iK0=siQ(62NSyU4iUVXWYo)cw&oCP_C;wg`kf(2)7(m?cM5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;x_gerR!OQL%n% zab9YXzDs^`X>Mv>NwI!FQDSnczPFRJes*e7etu4(UTTGIdMZ#+X0mRXk$ypCNk)F2 zZgFK^vTkB>NoIatv3_w;vObI*AD@|*SrQ+wS5SG2!zMRBr8Fni4rF&R6OdqG004M| BF^T{H diff --git a/python-sync-actions/src/actions/__pycache__/curl.cpython-310.pyc b/python-sync-actions/src/actions/__pycache__/curl.cpython-310.pyc deleted file mode 100644 index 98a665467b69d623b760a1ca0378f016090e4916..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5267 zcmb7I-EZ6073bxbC|R-<*>U2o>$n!1pf0w$Zry{CrOjuzv~{xD=}@j6LGxbQawt-{ zq>@;bfT7MFi*3(s0sCb@|0TZessF$*N=j& zEqi6vXGWFooHwUvE2?&DUX5wOd{^T(FFn(E=}#*0?wRRb;8oSL zfSwwkM^9s>XMxwzvpDWq!ki1dfu4(e5vz*57ItjD#4n`r@K;+N5LiT_Zo zrP(iuI>zRA9R36T@-xf3%-N>adgWWlu5GmRyv&0v2%{iPb8Dv~BHl7`^Zibm<;L~+ zAUAJy!mPz|r!S*kAX5Rl_8=AV_R~=GvQ83*wA1Wm;NczI>0i+Zjdbei51?ny5T>xW zepM5;C~@Np<~gD)Dk~a#&8r%>yg4<)23_*1igpxTQ*>FaoL4IsL>+yV9bK)i%#2(( zH8O|wRbG3hLBsQqd?BB^n{021ZZ8Tlk!!glV%|$SF-f_=#ZJ(VGJhusvqT=`PPo^J zxD;`2ynA~qx4R$nZvCTIpeJct3T@hz#`@Rf9 z(SGm7&GtjFog`7PCZ4YD3QX#RtB>Do_YRF#4K^Xqz#%gmRK9JxOO#4!XQeoftajmIiBtN8`nR$E$4{m8Z`^lT%e{w z%_23VgjVVQnZ$B47153ozi5at3B1rqBPs1^>L#0K=JaR(Yp{3@#~ZE1-0}T5=nCJ@ zE56@Nct0Y#>iduSK~#(=u5u&IWWM10K^!Mppfu+Dl0qgoN!~&>vZ}PGIW1*wk`)VC zZ5k$l71J|jp7D zB?hUH^r^%cf*5K?V36y_`bf*z5rXX)A`KZgRy1xtG~~t1;MO7goN;>uA#Z7)zC1F9 z#>gBRMFGr0=Nno!)~S>^VQhCl? zNpO>!G<|S+Bgx#reH=s`?#}KnDN{aY&2MS)x8LC!{B$E3PgGnb{g}I*_yx{drMx5s zFf zIAyYm10b!!D)Mb~y!xG?AO#F#QUOoMTylciWOSdOVVu8 zJ1$Mo{aG^zsfeQ)K@Y(jD%RWkX%f?mZzgdDc~+^)Id{%z{GvyF6a*qwTM`#E`GlJh zwxVK54L=kIG+OXE8Wk#;2)_%Q=x>wUZSuIO9nL)cub^`-BgHASa|={iJB^y( z--5CYHyxPGPnykvEyBITZ4O>*xNY3)hLK}`@yboNu%!SR?8%;6v%{TCZ1-< zhZ#@$#lMhJLH1xtL8tONa!P{hb+=jQ$2-oGtxfGbI1 zlvl>tJV6ag89XgG!CdhHcoaqR-=&?-47`c904}ija!H$wjn*TcN-!AgF|;#4Kw=sy0w{ za7IaX6C;RTeejj?f_Fux>^G_5p|))AB$rYOBZ#FWJ9+Op-ZL3mSDr&pl#h zN_lWuigPzZoS*1!j1%XmYdms(^-&$~wo1FH`T~aztCI;Fi{OAyglri~oZJ8wv*s`=iXEoA z&Z$ucyHzQz@!Hphsx7CyPT#6{#S>QS8%I?>f6Vy8iiV!r(0~`z2iepMCbQ zb3mwwV-{6LZUA)08Ol8=n|2cE(r!q_Se9m~ONFPavh%Eu4}LuRwx_F4o;+E_+U_a> zUBn?!lY8c!dmnxvsel~v(yEmVVmTk`ST07%IDpo){9QXb)Yas2xwQFIW-$(L&C z0&TWHc~yjjkI+-!I=ndr(*@vrweiFFi^e2uRj{26$HnbFzJgGE`E*QCK!1e&)mIF= zjB;CV0N|_o604)oBfzH+tsCiG3|A-cu^c_PT zL5kv-3R3whHI$wT1CY`SHm9FR3YDnCsB^VA;9sLdlRAMo8i`p~XOF6`8+F!LZa59M MvAFzNqwd!K1GL3RnE(I) diff --git a/python-sync-actions/src/actions/__pycache__/mapping.cpython-310.pyc b/python-sync-actions/src/actions/__pycache__/mapping.cpython-310.pyc deleted file mode 100644 index 4c7161db7c743a21e896a0cd89a10f8162362fd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3693 zcmcInTW=e=6(%{H(dcT&n`Gndb}?PFXw=qHvF)ObVH9zbV6ivtVx9J3&|)wdQua8~ zj6#mw$QS_ylAqAWeXt+%C;HUa{sF!gD3HIU7O+-yn=ry(p^y{+T_e4W9pSodF_y?rD@f=Pi zZD#y0Mn#%u@xVCy*`!U4zYl}SsZ{u}mkW7+GLnX4FTp*lWdjDcq3SLDGsy7j~7;wuW4kau~lbw?fx}!;PlxI77k|jHFf-cZqt&;AdKa5ACG&}5!CdQAV zG)s#ps-lvpZG)a}U%XalvC23q|3iYy7R7~*2i0EkN6D4e_Z}DEb2vMg`!49Kd>DwhhyxuDM+4be zO4(P3dUrWO(W{r)4e~iDgFy=C zi(Y^h3YHc^Q6MKsv!FPV3!T@bEKRrzpC6~g@o;`+*xDb&MIp05Nj)AEy0+Z-l{Gfp zZaHK8#~h+D8}G`CuWR*Q6@W~_~r1W4)hL|X8fRtAA6I!dLARdO_G z^BMTAfeY1jY~IEOskwr+=GqBY;G;(8Z?-t1?Y)Z{b=HG^ zA;FlwD5wI`#ggvN&?!AZe?g{R>1sbEQ+G+gFM)uSsbBg6BIUGNI%l-39kmq=u9 z(i_%!=N=`Q4|3{ja;jBwaqdy0bb$x_^zTcL{=Z1D?%UltZ7hYBXa8@=vJ`h2uFuim z5V`D2$OcD#_v1VF)jN2=m42=gX{FAWw(B!=Bly$>h<_L7-ot$k&|e{_%`*C; z@}X}-B7R(_LwNJsQto{asyop5EzU4H`?NthR3GAWgZT`{3}zVhUT(RJZZh^qPET)L zV$`=ivF-HKTX3Md3QgNx8T2d<+f959(Q;8_YEd-I#dv`IMif07$Aj4y)r8%Ki!>>W z1EEAYC~^xM`*d&&tHw#QLcNQVX#N!=S##m5q>#{9^&T`n@!55U!8PHcub};gG4_f% zwU=xQ=V10lZ8^(cG6yPWFBosVu#yrGvQ`i~x1s7^LbJ%9q$4QgGfcXDE*!z1@+UO( z)@EJd+1ZMy05g5{eb{d5Gk96!D16c`B|7-%*>HqUwV)*=nZo&+r4;GiGnIK%yAPRP zT}WM|S&WHESet|R(>au$QS|{xSh1Kj)(>FrbEq2A0k}LEgujCL`u+t{bS`t^->V9# zGpH(9Nm7c|_}T$w-JbDgw^cuf@Au(d;g*a)gHc$uJi@efrs0P$c~RG!F!x)ib6q(D zXFA?LPrr9j*Gru2fxUl>5`Tit4m75r3oukNl#tR1)x~)vjY5McJZa_h*Vsa*eFoL4 z;1fo#Qs&>F)|ov3FGQFb=dCXhw~KSF`fH>zAayS?Ikm-%K z4hcLbyu^ftp8mx~zyCgnuV*o+@S8*Siof-LmfKi`*F$yNv7DN*8d(f^=q>n}*$iJ^ zn~`GnhZ)L>3oKZ1M-0_k->YFDYe9&c#RHr4wu}duf*jn&3>!kicNfY0vCgxo$fHD` zbQXUN>_3I@#+#Pd#{}J`Fz=Wtj{a9a#m0ig!p26U*U@?j7US>DBHgd>ak76@Hc5kR M(w5V@ck|l600X<4!2kdN diff --git a/python-sync-actions/src/component.py b/python-sync-actions/src/component.py index 07d72f3..c304cca 100644 --- a/python-sync-actions/src/component.py +++ b/python-sync-actions/src/component.py @@ -235,7 +235,38 @@ def _parse_data(self, data, path) -> list: """ - if path.path == '.': + def find_array_property_path(response_data: dict, result_arrays: list = None) -> list[dict] | None: + """ + Travers all object and find the first array property, return None if there are two array properties + Args: + response_data: + result_arrays + + Returns: + + """ + result_arrays = [] + if isinstance(response_data, list): + return response_data + + for k, data_value in response_data.items(): + if isinstance(data_value, list): + result_arrays.append(data_value) + if isinstance(data_value, dict): + res = find_array_property_path(data_value) + if res is not None: + result_arrays.extend(res) + + if len(result_arrays) == 1: + return result_arrays[0] + else: + return None + + if not path: + # find array property in data, if there is only one + result = find_array_property_path(data) + + elif path.path == '.': result = data else: keys = path.path.split(path.delimiter) @@ -248,6 +279,8 @@ def _parse_data(self, data, path) -> list: return [f"Path {path.path} not found in the response data"] # TODO: check if the result is list + if result is None: + return [f"No suitable array element found in the response data, please define the Data Selector path."] if not isinstance(result, list): element_name = 'root' if path.path == '.' else path.path return [f"The {element_name} element of the response is not a list, " diff --git a/python-sync-actions/src/configuration.py b/python-sync-actions/src/configuration.py index c7d7335..4d0bdab 100644 --- a/python-sync-actions/src/configuration.py +++ b/python-sync-actions/src/configuration.py @@ -288,9 +288,13 @@ def build_api_request(configuration: dict) -> List[Tuple[ApiRequest, RequestCont if isinstance(data_field, dict): path = data_field.get('path') delimiter = data_field.get("delimiter", ".") + data_path = DataPath(path=path, delimiter=delimiter) + elif data_field is None: + data_path = None else: path = data_field or '.' delimiter = "." + data_path = DataPath(path=path, delimiter=delimiter) result_requests.append( (ApiRequest(method=method, @@ -299,7 +303,7 @@ def build_api_request(configuration: dict) -> List[Tuple[ApiRequest, RequestCont headers=endpoint_config.get('headers', {}), query_parameters=endpoint_config.get('params', {}), ), request_content, - DataPath(path=path, delimiter=delimiter))) + data_path)) return result_requests diff --git a/python-sync-actions/src/http_generic/__pycache__/__init__.cpython-310.pyc b/python-sync-actions/src/http_generic/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index b5532ee836a9cd02c32709be691e4ecf52902252..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196 zcmYk0!3x4K5JXeyK?FaR)&=0YL}m4YSN) zX}Mg8Ae{0t<}2b~NhrHuP6H}&5vwGB3K!2mylc2JItFBm4vwUU4y|W6yFw$J_6N9O zNz@h@K4gtyWVF1mp&xxiR`O`IEVMUd8Q5uPyzkX_2TB=hyi!>|PV-Gi)zIQLKEShp GRD1w<@H2V< diff --git a/python-sync-actions/src/http_generic/__pycache__/auth.cpython-310.pyc b/python-sync-actions/src/http_generic/__pycache__/auth.cpython-310.pyc deleted file mode 100644 index 9c1d80570d8a587533be938cf806662d631f81b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4833 zcmb7I%WvDr8J{63iIOE*cD>G{-InbZyQ^&?Zx?;7>!yyA#V)X@5H#5ySOf%3j%C`E zC=aP57G$8Pb8XR{7XfTwFZl<0>pwEro_gw`w;Y=OzM-DBgGFe}Xy%*Y%=h?x4?3yU zDh$s*D?i=)PmQsE(PaK9V6u&t{taEoLLM`hevO!S4cF+JuE}X`##XoB7P>{Z*e$sw zO|xRVTXxIcid*6Aa~2lD;&T=j#nP$iRxvMyHs-c4Ft1@=4l9^fP7Sw?*-}`=tSV|) zUB6)SHoi)QOgBW@6LRBz z5)8Vcm!%sIAc)xba_8R0q1a85*l&qvw>tuxqTu$EPd56;kg<0=J?;g!Au@zZH&PjF z>}Ofu8}HljAyTV4&FActyM@q#<_oG$ z!v9Vyn)EpQrsCkCp%cV@nmSqHMBRQYNE|2I7Y;FlaTNH(t&F|~VWS~0mQjfR(8S;YPf8nOa%H(h9f4JqJTFWF&y!?UNhi#mtpP|E$Ypf2KP7^QvJ@V+}q}UanT=B+lJUE#>ghz7~*TCJ!OJi1sB~D$$MD89Qeu=7?u}WS$x4 zK=BhUZ)Tu;jfgg*VrIMmcYo$1c3_RL4$gSQM#eY%ul&RSwQ!NjSxyP9$v*Oq;Xh{P zy(>HE=G52(t2x#e7e4xEhWJe9r=4UX2iWYbv7cb)dvKFD zc6Q;8N$-h}8E9}xxXqN8-{%HP5(f1IPZSyW3Mk$Jg@sj}iI&6IU0j#C|S)J<>9j+gs89CYI2Si_-F=x1X5zURwM z9uAw9GJ`mk@4%p{GWX8Plu>US1?NDXJJ2pc=3RnA1D(CpFl=7omDlUWI$t%0*Disp zrQcA+T!@93LC7khX>`RHgoG8Qkz<}9MuygNmhm&fih0fttouOQiP>Q%z|(#9c=@C- zDvSt!?~klAjL(WA_{q6(&N(}}HnQZ;vQk(apII7NU$Y#MAp@@Lw&I>LJa2&~9TvdK zL$vfdx(+b^*goMSB&$PH8YBL9 z*>L-^j^1pm)>fPZew^OHU~tP_r$Zj`1`ue0eiZ5_*0 zDe9$t5oD^IMxCCIh$|?+=D}W)NmbGB_eC#MB`NwbGNwiuVxdEe7A{NOs?JAVoDNa@KhI z7=wr*&Tt@Qg(B9-yn*P0s0Eybgei(x<_q)O*kVW42sUk6ZTUXllRu>HN9dY{{0WUI z8#FDg2(2o&-V;yf-0ezPZ{nrjpy^~_!BHGYd!>ADcH?568yB+21fx3FI=BFGvW%Va za|T&Ugw+un@dJ_z=zqvwauicK3#q#2rGs5sRM4b0V0?qSCe#|yg>vmscO2wj(Uf#nZ>Aa zT-4?!oivQ$2UoLp>7917elf!@X{F?6DidXs`~l8X)igti6^!Y{WcL6*q+u+{zLJ8N zB;@7X6Sn8ro>c~fcLIO9j?QL=(cs1!S_Q3m9SwB??OCui=8VqXMoa1FNu59le$HGo zL^UZ;BaHLD6&9XbE@EC-!m1tGz;s!abw&OKYT1BnF?ncAYMa`IVB?XCFb~0QY@3&; z?f# zpY+`yVvygRA*Mk8?9@EenMu!$eBLom>08Qd&-kEhiwaf~R0#<7GhmB2d}(MUszQQV zR$fq;Dtewc^1R2`sNK)t4g3}VH*Cy!&bPFi8&|Hjv2ImONz?#s;h7?G2jsU!WLO3=@pXy{mARF$3T@TY(vCpRl8=%@(Ys`V zDMl$)E{CF3NnxZ3NsNKGTng5kkntt7!4kRVFrSsVO{8>cAK9 zv;#!CEnKa=YFNs-c2vzrC7sA-p`$!!k;RC_AC&6`qa_In@;*VuV`1+H(kY?vbXYouiPPo XrxYq|*5GTrVKmH!RbOs=y59IdXfimW diff --git a/python-sync-actions/src/http_generic/__pycache__/client.cpython-310.pyc b/python-sync-actions/src/http_generic/__pycache__/client.cpython-310.pyc deleted file mode 100644 index f3940bde2f0a8cb4137d676a9fc1478b42dd9710..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3081 zcmZ`*TaO$^6|Snj&ULTxC4tbG2N;Q+39-zBxyDXNAY!q+3z7Pz)!S9G+v~nes(QSh zQ4fk@OA!y|4}?fwi5LG7{s3?F%0rZQ6oCPob82SR<6Wp$ojz4vRei4Csj|~)5@>(f zetYgd;^Ix6|CScwFs zS#2AOfs()o5>ie=)}ZEL4Xa`E%iIwbcZJP8=)Q1xL%66TZwVi`_K;mA!|rEfNO^~M zA9cb8U*qeKNZ8~Xd=uU+zQwoU-R4*LYy8q98g@P-HVM06pR0P~eNhORCNI_B{R+MN z<#p5k`m?82`gcl5`Zbb&0MY&ds1l83rnk5l#^bDtj=*@)k%+mFy1Sel#WK#7ZpC1O zC^tsXtvr4ZNw7{Tl0(aS7Q|oOPPo)RaHOnSFD9Rb_=??2Babn z$uX^I?bL4V)vUHSee6rHTnS@~k1xpx=hBUI$W>VK)_jmJb?QYMKSK(;wnAM?UOx&Xq|0lnB zM&3m3TR@OeE)dsUr}m5K<%`OglM)PvWyA1jLH`iC+6KL*Tc`zZLy&+Doc+nFtv}O0 z(wSY`s2c{$M-V7Bso3NWB{M*y=?`k>*gA$FI(F_8d4pRu{hV;SWWLGb{|5xehR@kbAIofQ24JuDJaMRXtw$v{|jg4*4C2-Z=BN6k>Q%B zbmrk1wfB&HihG-rKP+Tke`R;8c0ew7=3e~c3F&oqe*sbNE>f~13O*{+qKZawbri0r zDvA$OnT;!9W~Pn1;^VPURd8*}ZU)odwO|;hnc&|KsQ=$h%_0AASsLckc^N_eQo2cwvSa=Ouw`I$y_Yl zGc2>LJV}egxmY&?6QI3T*aqw}wuoeWqSs}d0un+FM04bl9>ksYjKe_i#VtJ^vjmK#!w3iE|;zJ=3`_83|ZYyx( zQo8TL0`)^6j9#HWb!pc;F65C*{TE$p&bcp|%>SfKH|aKO!ir0@N&QdQ^XZ!xb8Yqb zS5gks54!;mL?K8u5&>vDfs{K1$aqS3d(41m*o+RwX~wa3034XiH`t8&o>!=Gw)7|P zRiVjTkZ=0NMcK|)CWvCohC9%*MzDQgYC3W%gJ?5aG01LfrJHPrv5P42*qbrP9LBB3 zbOu@Z#E0y+PT}@qcxTB29=ecAo_4CTiZgUo%(VxRh8KdD)kd$y7*K*Q%AnF~^Ux`a zMdSbwVkwz=2=O-ugQ<^<0CY7(c^&5vF}0JIW4OoI#>CoF z^G(_@>88DSez7@k@ypBbQKmvqqQ$;jaHRSMkT%8A^73KS{b#e$rfry;_AdJ6|C|Rl z+ufBNl(vgx4M`tJZw+g35$6JGa5IYXl8-aw+fnrKIL;PdELBN~Atw>)wFS_nogsii zCDH$;9GVg$cW^jB@*`Z?S=45@Tx3zSqW&AW#8e)*&Jq+#y#>T4%wnMP{PCZ``vqg{ zIn4ft+3erUVgG8n-DiH+Z}^us9f`YpTiOM@0q~ehV+6ecAN0nu*e7KUm;Dul2MRAr>%?d1>o(m+%C_zQ0_ma~)Bpeg diff --git a/python-sync-actions/tests/data_tests/test_009_empty_datafield/config.json b/python-sync-actions/tests/data_tests/test_009_empty_datafield/config.json new file mode 100644 index 0000000..8cb4e9d --- /dev/null +++ b/python-sync-actions/tests/data_tests/test_009_empty_datafield/config.json @@ -0,0 +1,42 @@ +{ + "storage": {}, + "parameters": { + "__SELECTED_JOB": "0", + + "config": { + "jobs": [ + { + "__NAME": "users", + "endpoint": "scroll", + "method": "GET", + "dataType": "users" + } + ], + "test": "test-value", + + "debug": false, + "outputBucket": "somebucket", + "incrementalOutput": false + }, + "api": { + "baseUrl": "https://private-834388-extractormock.apiary-mock.com/" + }, + "http": { + "maxRetries": 10, + "codes": [ + 500, + 502, + 503, + 504, + 408, + 420, + 429 + ] + } +}, + "action": "test-request", + "image_parameters": { + }, + "authorization": { + } +} diff --git a/python-sync-actions/tests/data_tests/test_009_empty_datafield/response.json b/python-sync-actions/tests/data_tests/test_009_empty_datafield/response.json new file mode 100644 index 0000000..6e06289 --- /dev/null +++ b/python-sync-actions/tests/data_tests/test_009_empty_datafield/response.json @@ -0,0 +1,13 @@ +{ + "data": [ + { + "id": "1.0", + "status": "first" + }, + { + "id": "1.1", + "status": "page" + } + ], + "next": "/scroll/next" +} \ No newline at end of file diff --git a/python-sync-actions/tests/test_component.py b/python-sync-actions/tests/test_component.py index b24d6c0..377e330 100644 --- a/python-sync-actions/tests/test_component.py +++ b/python-sync-actions/tests/test_component.py @@ -79,6 +79,39 @@ def test_006_post_fail(self): expected_request_data = '{"parameter": "value"}' self.assertEqual(output['request']['data'], expected_request_data) + def test_009_empty_datafield(self): + component = self._get_test_component(self._testMethodName) + results, response, log, error_message = component.make_call() + expected_data = [ + { + "id": "1.0", + "status": "first" + }, + { + "id": "1.1", + "status": "page" + } + ] + self.assertEqual(results, expected_data) + + def test_parse_data_null_datafield(self): + component = self._get_test_component('test_009_empty_datafield') + # test array of primitives + data = {"some_property": "asd", + "some_object": {"some_property": "asd"}, + "data": [1, 2, 3] + } + results = component._parse_data(data, None) + self.assertEqual(results, data['data']) + + # test array of arrays + data = {"some_property": "asd", + "some_object": {"some_property": "asd"}, + "data": [[{"col": "a"}], [{"col": "b"}]] + } + results = component._parse_data(data, None) + self.assertEqual(results, data['data']) + if __name__ == '__main__': unittest.main()