From e2e046459d3ace120d6be91ec469e97092162c12 Mon Sep 17 00:00:00 2001 From: smulyono Date: Sun, 28 Oct 2012 10:34:20 -0700 Subject: [PATCH 1/9] - added video demo - Updated readme --- Readme | 2 +- delete_csv.txt | 7 +++---- pybulk/__init__.pyc | Bin 12936 -> 13103 bytes pyrest.zip | Bin 0 -> 56021 bytes update_csv.txt | 4 ++-- 5 files changed, 6 insertions(+), 7 deletions(-) create mode 100644 pyrest.zip diff --git a/Readme b/Readme index 0f88668..5de023e 100644 --- a/Readme +++ b/Readme @@ -1,4 +1,4 @@ -Bulk API implementation in Python +Salesforce Bulk API Demo with Python Cloudspokes Challenge : http://www.cloudspokes.com/challenges/1857 diff --git a/delete_csv.txt b/delete_csv.txt index 05bca5f..f8f702a 100644 --- a/delete_csv.txt +++ b/delete_csv.txt @@ -1,5 +1,4 @@ id -001E000000Q1aT3IAJ -001E000000Q1aT4IAJ -001E000000Q1aT5IAJ -001E000000Q1aT6IAJ \ No newline at end of file +001E000000Q1art +001E000000Q1as3 +001E000000Q1as4 diff --git a/pybulk/__init__.pyc b/pybulk/__init__.pyc index f881b8d178cc02fe85fe16d75755b2968f30f2e4..f215618535731aa33b9b2f748c41c3536204f739 100644 GIT binary patch delta 2291 zcmZ`)ZERCj7(S=ny0z=p?yKFpxs@@tTSoVVY)ppxEHWTtoNfpc9bNC;R_NBzdpB4j z429^_K-6Ob#)N3_58;O-)nCTM5dZkYA0$R&NK8l!hQvf8i4hZx?{nG>V&a^<*$ z&U@bPvu1oUQ)7Qv?0U#Ajm25+&q4qD=`*L^srhBKfF;Y=d^wveXI$q@&tu67Hd(>+ zLS|I58R9tEMaC{Lc68Fmbk{n!XoKr#x_g~lyuqzvdI=Vj)lBy=BfxYoyJ%yRHMkc^GNG&9Eft6^MQ?5vU9+6t+hU-nv z3#6yIKOZt(uDD0NVeEnm%?7GKe(!#XCo)~dEjCA|lF3<56A#GCo}u&det@7)+|Z^Gx$a+2g(CXa}Q1{^}ju*$r|hpa(DnP%bW2?0n^HHsgSV9AY09ygL!h(xr zE$+131iCT3G&_|xOv->z-tH!D)Zb-|<%H`;@+{JKV|L>m&E3vR-Yzl_MLCs4t5hbvS2nNPRrVd9$ zbmZWu7y}cwnnrrrNKa5rdgM2LZ6rWEG5T1lYH&ms%27C=YS>&cEtH~hCSfVvGbsJ2 zl};?oYH*Kgrm8Az6HO@6EtACgl0K8du5#?NmD}7D8v5Dnywdg*1xbEXH5$yulQv~7 zMBtOD+0>GyI*qiV=BJ7KtsJku!y~dO(8~v9Jg~bmf>V14G*~9kZ&Yia1&-z;vv)J) zH39BWn}+1}+Qva-K*RwQP9~IO7?c5+0n7sas}j69KtdUVBM&k^*0yneQkK+(*00!I z*Vd-atCl!MyHpvOmTsies>4pF6I77@rvU$Fq-ce7BRYNZW`mE{W^Olh=c3cIiVY(K8V1i3@!z;c87v~v zi38)=agx1J9&4-(6yOY^@#IBVqR#r{oyH2jEpxxI2-ETREi3u3vtKSYeN}~4P%~#V zr5gtlrX}9Mx!2`^=3eg_$kzyRr6aF42l-`{UhF!U`KP&(hg2d}OW_d^l>h-yMXQQV zC9_%fhMLI$J=Eu|gM2ff5iqB8BDOL4XXtvT8bRkFQ6mV)pR8V5secC%w^~p8 z@%CJzr`dE6!Dz}<^8}4-`E1+00D2?=c7itKVu!ILPRpM5A^w&;+diAWM2z?3gZ8ka z7NV`PwxhQQJuK9VxgDXnyDeo<`47F7v&LIh0AK7^_;mdNg5xv#T~ WZJ-$Dj1^)tv7oyn! delta 2145 zcmZ`)U2Icj7(QRS9cVY&j&0q#vL6_1r)*tW6&Pl)Zmi-E$N0t&W@Kx74qHjbnLTG9 z{(#CvP>H~YL}D+yb-!%=JDw)aiOR52ItQKdB_J}e&$wBsI}Xf8;q_^13Jn=Bk$ z(dJS+rA@r!Zy5-YXd_I{JZ9wWWh9N6>BC0G=8xdkqp*7kQq$AM5qr_dKyi6k&{gRwXY$`w?GpW=!6v5wGCLu`&zw17&e$4*vPigtB!4gd4Bck^;#OTZ z>lJEvYjr~S>vW#)^SS?&$4wRpOu+;>&z?8uf8WU*TmH|p84!QS<}$B*c@5M6ghETq$802FG(JSb)iEE zv8%b7)fUptn~M$F@)9mQL7;gd{YMy?Fi#GT?Ap6DqWEj=s=9@4EDZ!d>u4SckzZHI zw8H6iW!O&_TaK3^&u$TD{ifDWl8yQYP2Jd)wQPPG&&`Vat=)mwA)X?b=WUnP#NKj7 zjB8I8KG3RJ1jFQT!~=jTz#f34E~e~Evqk(8X{8KG*7pSJpMxDZ~ez{ zxei{2Nv;F1VJU~{C1j;ZRk8IEB&;snwHV z7Y4sCiiszF6*aJ$b($a$;ZLZSLAB$iGuEF_9L5~@plU}4tQ>GoX9Gs9Q*pMII-Oji ztW!y}_W7wPfeCb;NGhyf;S52lc^4`*)Pp;=wnuLtym~A@&;;J-5eH7#w{Rd6a5c^s z=fO`Be78A4CDxXCR9l85W7?|kl>)uL9D&N8@hsyc_ z#i9d~Az%U40U-pu^26Z6Nd^G`EC0hpaENY!aD2+YX3GD)|9fs~G4+3m6~sScWovI^ zZe-y24~zf&4O2r?_&+T+isgs%r$-Q4v4`r{F6Tl6MIxb%3UddrBvS>pT0kXiae+z- zt>(OWnfaWY-Ctt0gCB+>X)w&Njz=d}&>ZEIuwFTEPeFDQY?71Ftp=HhoQ0cmYs{}V zCs+vpydcK_6e?avEu5fuQzQ@ezOcB5eUWDV%=aSz;ndY2X+!%H$mmoK{vwNn2j}IE zD}MU24Pz`V>|%62EwTEm^KdY^E7?AA3@wfzqa z+AOEnyZ`!c3i$uR0QR34xEUHb|6hQ}nw7EWr$+|3_23n9bvbCBa5hy4o|wg1M>^VCPP zPjlj?j7s>k%cMrjI3`5k8rr*kEAiFHldY}rvYw+!jphb+$t;+C`tZ|uzmf5|rgcok zaA0&tc|s4Mmjt?^$L8rZnm@rs`OrihlqK5v9j)A?C zp`($5Bdx95e=U-H;Q#zTt8Q3tvLbk`s7N+~Qs+SrIpadv?B$NN^WzXZ?Mukz(twEX zt4or|6O>iH+;9;)=?vKc^SbL$o6%-Yq!q-$!@+en6$&oEfP_RS4&2E|u=8+pK6f^e zOY}35qnGfNm+Ml@!7McbNF{+~DU>>kX?;d;h7sGNxuKyXDNCr~JW3D;JsnM9gerq% zzhtapvOPu@Hx*OefIAjCAQ#n76JrW5O+R=Ou<#^O$p$`XsiAT81-bb0+Z2*-G^nXT zmhoF@A8a8(@z=AFYwLX71*15wL2QQ~X4(X-=c|cz7(j_r z&1e9OF-}@%^14EzG9kLy2|2=*xJnvU6ULK2u-#^L!>J?Y9y~j@vZ>C;Wt z<*464O~Gqt{x;MTOj3T`q=)KKSv-pfsOew`nl*#c__V5ku62Da8RKP`6dcPiliK?6x|G5>l*27v zM!Bg@TCgt!mMMk1r+^rpM6IIx*0~m-`U{I*Myg)(y~DbhE0q$Buq7ij_%xG@`pU}` zM{B4UXDxZ0`%4ESCrfK{KbG5Q4*_q?ryc>_zHID+oF-7n2Q8+$Jvx?%DYZqlMnZbc zXc3?t8U)vZV~&{$@p26n(me#n!5%)%A9>lS;0FY}oP#^_*A9C+AwQccm7trp*z66z zIuc>{_e9j96lw-f`t$6}4T$e1>vh?pyHu|9?|dWOQ)DWc4Q{h4nZJ zs{-&x{1o+pdY2DKq$oc8(L*FkY+9x&t_LPTxv`?Y+Itr)V=|p~F2LaSx)eUU964o* z=(0;6=gJ;`>Uw{HOES6c`-&X<{+5A$AfQ9Yu{sIgy3GM3ha?@m!~4gs>$px?Km!T@ zP>cLOa}vV8aVWUIyRM;;rIDkNj)8+St)uJz&d$A%|FQ8-NbWJx(>t;N1n>rnKI};Tl8*|%RDwYk!azVe zTNp@4e@1@JV*m!;bR^-xR#$uPYHfXfe(7>;QFEa%3vGLEabs;xSw`kTsg?fq+10_( z+0FTWkbhdfAHy|c@Ym{!f3aMyQR81&%RkUDvvx4Dcl>vB&Icm@$z7c0HJ}3M5rXz! zs{26;&xy_BuZJgQq0A#NMxQ10kfBCafOi(&TD*-C+(a8{F^-MWT1?`z)U5l(-t9UQ z+`>F@m69B2oeJ$eYlb-~y#?lE7N#k(27&aGR3)+TrNaga0So2kb?1TRDa{zp0L~H} zQ(gHwkz&LEh{+*S1^M#hLm`(=C*Ii`x@Bv9nfxNaAcXitKp%7Z(EhOqU>DVIGyb|5 z0`xx@!N0rtZvpy$d;I@Xfc}FCJEQ$8X#oElAX_(mCrgWe@?f67tP&pR-+8dH28p+62s%WV1?7OJ<559oYVRb=$-p92{uhxS{l*C9J3rt{c~F zju$>okV^^P5KakYZi|H7CLr__DN)Qz9zS}LmotVJ;1wKdCt^`#OY~?K;R#_^+4Js% zIb~Z96;n6tubrKFDO#5=k&CvJ2!Wz6Ge*lSMQYpB#kC>xe12q!s_>5HQVS-6*rALg zbOXGXB3zIschL>C;f;ub`$$WFle02{MG}U7R8?oYsTDUTWMuPES8BO{91eyfdDDeX_H^Ha$IMX=0 z6Q1>^epJU2;Pd$cABJ7z)e3|w>P|uj{XD? zp}A^?)wZ|7BU{9W4$D~jT?qL`Fm>HInnmW-4odkAFp~DHTGAgm1}kvO#n!qIZ`@OU zPH(3$?C@(m9{@4tk4Npd4Ec(Fn;=z(<})-#O$Zdc@6Y2y?y|e?^gLLFMK0*Qb$pK{Q%^sp#)@~80&1m4d1g|Aw z?QcUg6?x<(bF8HC>)4$xue;$P3}JpVxE8+5@Do&Jhj_hkjeUnfDR`DMf#NVBUDMh- zn~Ov?-FO2|Pa|#NQ%gFxMqYZ`T}dQxOC=$@*2BH-e#Y9M5J-TP81=A75zu;rJH25duh*#( z9pH`4S@7BvJo5aTBWosPywBG74E42eImL18Z>xy!+%7Jmc?i$`c(O+;ZkqKuB)X); zNTEv`l|1-7m>Be3#+^0^{?0^SHGw!>Dl_!GobEpwHAKAmA1;Ssm&dX^{&Ji#t2NIN zj5iXFIt1>atU3;A%5M4u^0n)PTz2{`T0AYlBGGVLxrmcv)hyD8#3AX{ujCOnsoY_G z#_h+u5d$%?`iJ?F4$%<}*hG!?WZXcv<`1P|T=VpZf+EcO>QDKC(B`m#_DWlH4r%~$ z&#jOjSA8T*gShc{{PRe>+9Hf_ziua=1q}Z<@az8Oy4QVyaxA(l1p)5?AhB^HJQj6m zJW8iFBSR}F`Fd=)60cr(^h)w0PAN@;83?Su0!=a~c3HRf?}0Ll)ALd^E)Q4P9hDU* zxNogZE`<_!#oU+r6)t|HhGM@`agM?u&(LA7Bmn9B^;(twc#Zf`M2eBEPMxod=CUEm zgDt0HNvJY9W(G=uZ4*}{1`!e#E)S5c%35+@ee6vQjSgA37cSf_mXu@Gy~i8unVoyb*Wj8dMR$hnw4XZw4&7IIiNuhe za56e>Y0;djE@fFjnGCtLF{sX|osaZ%#CSV`;+zW3(8OXLHD`}qym4JJ!NT= zX1D#gIYO%ZzBmcXz>FM`Eifq6Z7e$MhKxxMtP4FGn|ZL3ln z@S#pt-w5QAwT|{y=)>A0Xr%*7TeiTclQ&138wX0nL`7R`YgQOriwlz-mj_2%+xvzg zAT;{9HEB(;=>0_ps6blZ#F^zdNN4usiBHfG4m%Tjn;XIL!b8W}(tecc=C_;s!P+6< z%Spu8ls{yjL%Oz%4q(}SI7D}A`ZRoEZEa?7NbVa- z5Rsio3QxTn=XLTh5D{{y&%0T0{_#jao+u#EIKilFP?|4;qcBF#UV;jX88RzAi&6>@ zi#(notV%-BrE)OLJ)VASzDb1)&ia{NI^=UX@`!8{C0%>WG z>}c#NMBt004)7wkb7yomm<0wHN|Hc}X6fB2VWL^qd&}llw);koh*Yo`rtvCh96Jnt zH`eyALp>w<%?n)=YPh%UHf4J)|C-x)#MQ(iHI$133uUHfWcpytjv>&>Xwx-*7hA~j zfj1UGwSljfj`xCrOZTEazy|O8X^tSSyhdqm10Z$3<6m~4Q4p-&a2OM>)^>LH9|jef zUWIf;WzW%b0NWCP4b9$2h#r<{!ny6Oq8CP?=*xP3*FcBYF?+{35d*R74(H z&^+}KXJzPujlGlVJ3yd`V=OcTK1`b5oQ)Udy1GIVO(@XkVSOeqf$JJLL}?L6?b`l2 z39Ti)`a$~KiPJqf%^2lS^Koe%-LUUP*K5@H)~KS5aGY9xsUw&9KBW&j zqXcqFzJF4xMCWmajo^3IiM}5Ce5P9wI9CiS5JXi>Z22_20xE63Ip3_+t{b4@B%H%& z&3&L9M*td`1Kz%Q>dH_oHS5$%Z$7$LEpi z%{gGbV=Wx74J00zX@tD8;*cp_yrmdo!~Q_tB{&9rdC*{kSND6xEGfFW;SrD!0}-Rr zFcsB#6NZv$1udv0OjX_r?!9ag@UThmq{ZqDm(gP8zw>+V3C{E{%jUbD-gw8;YXTT} zW?vUJ3Q=}Z2NLSj0|SJ}{bo90s{EKIzX70&7*ai#T6p&JSnO{ny0VMMQU>DM*NrN! zgWy4)gyk!|ZInRw4C^FbxqZ%}F?*smlB}f|vP!5&h#9)8GbQGFZYSQ<@^VfG(w|LL zEqHeDyV5ZJ<;rV=psu8|$k5-1&c}isNh|b7&iJ^RyxdgB>^7S%Q7PZF-`&4V`D-Qi zHwh`FoyA+lpB6;i{X`xKTa86LZcIp21O5nEy^c?_{GPB+qI756%G1Swq+c%(u@s7z|h(dBTLKy#$` zt-NAJZu_bIY-Q={gRow2w@(A~>czhvI>?++jSlXu+mk)T_Tcv|_Fo+xCHQ>Z9dYVO zUqiJ*GoekQpNB7QuSsEuWwO>OC5wEFYCBgnB@(HEzCFi&VJ%n&`wU8X7MehuE06=4 zX;qOq3w9V;D-t$$*jx};Je!6bR;A-moV|kf#Pt5`OdDF15o4=g&Ytoc0A``J#e46l zMd;XCO7$argF893pI?K(>kP6lHEDqzA|+hX2={#2xNE+$C&rhUb=?^it{j zdhRo0fb``jp&x}agY)~ClEFhhf61%K@fDB-YnM^WiB`bz{V4PlZb0r6X#}m_LK3vG z|8j8DFb9vTX`Pj+jeO5&Y?}=ujFtHCXL#_Ja{!>Roa(u9q=ffu%K$1b%$?3)%9Jtf zX+`&D(^6?cUJp%&AsX{oOxNM;(pL`7;%m2zvp!~Jpc{yeO)3p z>${3s2ewXPh%*M)ohkB@xHuA`qa6eAw)qw1_#?k-w5#2R;y*`#C&lC*0`y3wH_ zEKn$GXat_SGyDs+k?Y_KsP=2O7eGmX(p);KB)LWmhQHBN-K=BGAsrVOIa_9yGk}zt zkU*ZDO2C}5vvFOR%@-*m`K=$o^baF-)a7t2htHiLOgGwD-$54*!@=n(w=+y!cXB4_ zv@>%i*B(EK^$`VQqxTAlCwiavsnqKF+|B3nv7{s?&wVMmmt&tn(UHIBqYevcW-u zaWMf~=x+-M(o)ZuZP8A{tZRA{s!Lz-sGM0mtfVB#ksS#+53@qWJ(pGZ%0LjT4w;hA z1?AYc9IVN7igZ%B(1q2c__Z5zknS_{EaTh|kRI2Lx+D2Y4TfIagkcc36Rqtl3HlbK zC;VGis%ab3BazmM3wDkRPW@N0sY+wY z0ei&hChe=A761rD)Hheuj9LP55J5G(xlCpP$gfB=OjEW&!tc-II*c>epl<`yM4B3q zEKMf6;aWIKhrOs0k966%7&xB1owXQA(kFCVq30NjiOLZIUi^#4*6$7p`FIkD-e>0- z$Ct;>nH`U<(J$lrd#r;Kwv9hu$Y&35Uh&BUfmDN}Nx`;Ki0JtSp;7|qrYC~B;iTqn zh=+s5(xvX&md8$A_^igu|OuVXwSOUN7wJ^EBsXfq!^Cg)OITy8_)!lr5*n zR|-7H29F{4=GUdet=i>LV?eS$=8iLMsou|Bot?B>f4!d@IzJ`a#^lwt;crsxWuaa- zx*CR0ncRjB@7p1`laUD)*|(u>HYi(bH+)L7-EwNDa+cu*DIbX=Yw$a+z|)X9%0;-B zp*VG=-sH5nm*KtsJ!#OQ+PbTp$WE{p`cU4r8ItzYwHlEdSr=Qdz87wCUy*Tf*O<5} zRgiLL9%x1bQDVuLH@kMNGvRoAi$<}!a=&7(`>e%z)SM}TlDZ*VZpL#>a#$|^1)>`A zsiy9}v3>`XK4%Ut9j|I82>iL|B0uBavfNm{JoO~J(7tZD-N>ok{;MrasDXIH_2MPJ z%3{xXu)%P^CExdbH|msCsu^bp$9vDH;<(YJa?6yeZe7~6i6}o2k5st?t&k^fdfk5h zS$fEQT!!e}HP;5YL^{=&%5A{i+~zZr%cRMGFg8R<*RPS;&2Rbe9p1C$1VnWbO$JdA zawc~>PW{uInYO_HIvN+pJr9tAxaKI7hJ-|C?`iw>KBWUDT+6Spl9lHWi#Tovx1xXJm4GG@@`mIwD|RsUa$B`+tKOpG;#vJ50(I`9-5n7& z{#`qNH1<-^V~jrQ4RD}eSBbLX6YR6~$=O`1({a1qbuTF*$t4q)hQ@n9Jd>Uqe~&%1 zzjXfx?~6L#=obZyRtwg`xDnP+TRS{fYI5mnygPvnZb3dG#}*Zwm>NxV*x+fwB0f`g z;n+T-0)44pxR^~{=20&E`}w7!>38T964l1UFyg!e5r1@mX~A&H`!eP z@I+Mbk~rhKy?b53`U8`tvX{qp5V|wA( zyfE^PM7#8cMEO?0s)YQzf2fKE&1#IYMVm)#^c=)iw=cylfSx4!6_A&K9;nd!Au$al zivEi4({F0qE#xmC%>g~RM+es;4>a30v|I#hHt=AMH!JJTd8zSyz=s0TY_+Me`TIA(W|tlj zi32Y0^P$HxV(O;oi{?UG`-ke3=EI8nNmpw4{&LkFD^?h4qcTl+3|tq)eUp?&8u!+y zHF;4(sHp>`(G%kOYVEqx?0jw73#=Lu!a#wu&YBd z-U-G0bBJ{}4+EG%qk^0r56V%6~-Ba>;F#wj9$(ASnr!n`ZF_mdj;~pub|qnfdT2 zNAynlBMxmE^K@{)c#yUt{j_z1k!1;+exq zsxOB5(9isyxLsVcN5o?E$T5v@feVS5$bScN(PIarx@Z3hH#jT(3^Z*;H)pKLe$<&! z0Hl(1maB#4sycVH%kw*er9mvPr1lq*W0hD(xT~*e6S-IDh1dvGX2d@Llq43?{!C=B zX5`Q#g?b0oPW*yxgk#v)XAdJLdfN7B(GZN@7Igg>vx?^C;yJ*#j3gLg!YS8hEylXEzEQC zU2UD_IriYz2+Sy;h2Te)U53^jsRwG4hRI@(#SRL`gkCuq--o18k}UV?ES&om<-!JnEQ#8l-Jx|- zCWryZi&prOA1IZ(7NIDo8GH{Rg@FFLJ>mN-$hURR<;KllVBu_Xp8&)&tNJ|w`bVLp ziAAy^IXSxF21JzrXBQDnuE^QCJ(2sGq+zvj#GI-$(3KZfPuI<-YKInuz23aPS{NvP ze?H4Y(HViIczL3LW>$5Pc0=0uWD9%d7FDQ{r(fQL_)O)i(I!e9DOBzv0UB20`43nB zwCppi*x0g8V1rl^3j+hl8Uo1b1JDlxSr1=^al*~_<*wK9%;$=J8D(`|BeyNb6ya8@{mQ8uUK-v?+vChVWl|p=cX?Vmi#TS!v+tL8S?i> z#8-4+J=JBN_KS|7C(zi#`ImA?@zW;rUaE?p=H6*G+Lub#o|3RwF3hK@8Jef8w=~U| zS(mR^EQ-2~S{yb5t5*S3mADK>qr|xd-g%XOfuG0HosPH z&e_4Ql-(D?6riZjVV8FWh4%))Mw2HQ}^)TgeYq4IyEk36R%Lbl=}O zK#L)WX}Fn@Z&>?N$W3#0L%(u@>{8LdI2?S_u}vU~2Row|)26TwNl!vRqOrx^Q(Kk# z=+8jLfzeaH z#PxSX1W8`sMrs4G3)90y(Wd2gkvqFZdge9~_P8jLHHZ;?qX@|80o`Xf98(YVe_9+z zCLF6FO^^)~KBVzc%GQ?(k%2$4Y2y3|B9cSi_R0;7-xYcjm!ta%&M&9Iyu;Hcr%y|a zL&4Qvq`N)11T9l5GG~<$cRJIHM#RvXpi*@j<&ctx6f_LUbetF~)F-e& zxBO8BANvL@!H{iqv#)=+(Oy#26CCb7kgDi97z9b}@u_e#I%@(cHc|4wA<4DrAXQ|A zHhTv7Q)$0Z-4uye!6>TYOROTMr+U1t(KA^}Je0chl$dg$7?7 zoJi5^Zbt_rMj9t=`!@HCVoO|uG1x0b5*AMzL1M22#fcN!--cSIK?ec#Mz4HcAg@^P8Ex$~^+AaQE z??k-Xh_A9+e>W%q$#WL~sx&cRnNpYis0N~?CGDu>Ja^q4_{$Jpe}0v`owm5n|}{a>DOK34=Pk$@5mJI@Z^|Z&BW@P3{i1V=3B%%pcNav})|q?_Eg>LA$RQndCHw~tzIcCp{RLsq=f^EOJC z9=Uxgi6FDl35?2&)AjglX{UOSh6VAAzsMM)8}7dHSi8l}-R&m3E#cn`KE4q9_OMb^ z(koPQ8u2Tl;EVA2S;62W)xjYMO0p1sdov-CI3NYkbp4>LJN#91-5);)OGB=T9aJ(H zHxsNF=tGDT@XH9YPhL#LGk~aiHNUKqa+F9ygo%wJ5{Aj8EA#_#EAD>9_^Wn25Zbhf zj_B$N0Jo?qBKW1KD&FWIVtsXP=hPxTHZ0*8{t13Y;NS>g$I?g=+@SK_t%EI@9gt@3 zF`O0%-U2o+SoV(9#Y&*qv3oYCft{3{^Sq5uz8S9qUpm}g^IDs%5Bi>~4`M2)l&^7| z9HsV<%ZJ%tEMzdi_6etWEkbviw+^;GabhVcZ)LXJnwt)jD13l_P(O;0QFxnaG@sBM z+m)Boc}JqUyt!TlIC2{u#Ym33p}-is``!q*oHG$8 zBhrYj%tS75+@71`LCg;3<~lNJUnms*Fn-Luw#_83 z@G#K$!$bh4C{twPsdUL3L1p1`+$hC@0h(do;lnTAWD|M62M;c0h5;H^+|9CX7s=(F zU&8FWwpdw!NNfRM3-Jrjvh|v*?5m{pQ-S7uYTarmpniWgWL0PRkVIKmcetA~XpJ>~ zKtv?j1v!lbldPvF*gO41l!ABDhcX4%*0r=)nlgsgt7s}9MEGuDK z75B(~jk=k|egkzf`Mx*_X~4$t0*aR9CC~#*O$GE~2ijah56al1e4%b*UmqOdHwwF*0#zm({2g;?XfQ{<(FYc&K%7em+%dwJtsPNPer*qGU3NDk$v4g z(p5)~9i8OtTsd9SByA|JVt(jQhDX_Y0UXLE0p1>Ec1BiCWdsT_G8?hFG7W??+<(4p z5DAi%ult$O)Vop(M4hWUC88})5dhJ1kprX7;@&<3w|~O&q?;jtKv4<|CDWa@JKa1l zq94%s*zZ9UuL3lhgcpQ`W&HJrg?&oY%!uBbYzkf>K(XF=(J;9ig7{DqAA$qExT0Gw z@r)>MWlaT#x`X*wck*AUkbO7^iFH=!cL6Yr#cR#p7jb$r-;qm5i>3e4OM|0>qhG&9 z#utu$9hKcrPD;9UX4+V&jUS#FnQ_1CoBFKz*0_!WsHR(P)3b`$H%aOqeH}{EKD%+4 zkqdMbx6E`WE=72FjH~>ie^W%;_+=S_6UMyC|J@cx;$){D!8U;2+Usr-e7_R}bIXx0 zLf*^JF>yll@&U|Pxdo}zC>?#PbO_8&@p?}1A(#Yf%U2HRnMAKW4Vt5}D^LXLE9oYe zFQ0yu_X!RpnK~kwsxC0y$vXOzZ(aU=t2&vzkU^43zf087X+ZXbIK8kfz%=nnXn(Q= zgz}!yc2-tZ73#Tp%ilW)`8)dY*M~yYtskCy0Al@vQ#+{(mFbHTKI$Z?U4+j49t^R!U@b%+=mxF%md z`QBsl6xL5?Rp`qp=NX(rgdp24*f56%uwQYK>rHivy*fz4r~uQMGmN+c zt`KgX^&N;%8w4Sfjn=qU4ny00Vz8stAqa_g-#27M2RCM)ZSjlLDuNrn60WRghD@)2 z_-zJClJ(xsCd}L?3J|u#Vmc`VO7SLWX!?}?2e&pmpzN4dGj4G#^y3R_{q}Vh{P58KVCMtgkeA0X>!B@)94yO>4|{ zKgSs3VWp)S$j87Yi3G$KjFJYcSE&6HLy^r3rAQnO0Hwnv5h)A97BX0Hnm1wpL?(wv zS`@M_(<)hF6_&%}6+aoeE|~mjo)#mHWHe0ms2nqg+ml`twcnZy02DYdBR}@Yl)6}f zLGV)`5GS!72%5Q$U=R|VZ4aatu5^JF9U4zfM?}mRXq8*aP&q7rvZm#hME-ma_?<+1 z9wy$;QcIIq4Jgm5(6Aj}80?iIQ)tQ4Dcv(E_w|Q^r}=>TZpO&G^N*iKA;&1?W5EmJ zA5z_F5mP>qi~^ILkP*M306UfmfUytm1a|YYFr)K0V1Fl-Pc*tb3N$5l83z&(1I!S- z7!WxYyGxL=XvWZ2*YLx&j8qut>2Ob2KqENeIut4ZQ6p|dYEPaNh+pVOq*e5^R>$-t zG-J#XAPEJ@r>(!_d@F128I4KjkyO1VOh*?*x|z9Df^DIcCK368M=26`fGCB{+>Twn zP1`u}WCTw-w=X=ooh|8U=6v}yO~H{hi*jvojs9qpmG8G&5I>{sEp)CH0x>(1gy4^- z3GOnl8|r@6wMr5qhP?^<`3j{Q>O>A|3X58z{uBz|pc{03HG(-wjtBKoNaKI*ce`%~A&xDS`@?-z_i`2n*>u{^DxSC)1~KCKev!--AnwUrP5 zq=dFG0QJXynK!;o9{zpcC`gakjoWC(`6mq`a>?LoECwLkto#5XkPsqhNjahD0Kqmg z1W%A!*B)-WCGm+^d?y~s%D7fUgUCa zneT&pYtR-(LKYC6yPSmbq~Z{%JMk?EN=sa)@QjVvnGmQ!Vpi(4mjrC6v@Gw&=7FQw z)2bZd_Bzq6^ z5Y@x6vpK?=UjlwRixcSF+pwS=$H{%JC4YJzoGUr3lbN(p)DW`*teIFD*RAK2<>S{% zL~{fu92ZO(zOr%Z{O=(}YX1T7fgX-|qP*Qq@w;v}F-W593sh+bh!?@x20E{toD>i{ z3%MVW(w*3(>-_AiSH8uJTpy};Hc(5ICkNk#bYM3vJ?F&kupNc)#R0_X)tmzDLMu3M z((8b`s}XEGNUzDeO5^G?vde*whq?g*IFUQj4Y3E4-(EiDUJ8Fwb~3zKLMEIufaB=s zi&Qn%m@>OTE1Z3;$_GMv6fC#;DkK&x+W)jPG@xPW;tz0*SNVJF9$ZaBV-j~pHIwo` zvY#eG0`G_sen1{7Fe`+hf$Lu(1W)N@B>!0(Im5nRfj5F#c?#DN9{@MXE+F_s!cE3r2j4cm@uw$MTai7r|hsUn_u~5cv#az<;m9g@; z(D7@wz2(KkImeE_c@*A61a4lN%tug7DjP8VyecvhKNB(BLse3pc*WK0WS%p4MrWn0 z3QEQ?O0X~O_5+NzF}A3$X+)V5kVwZTY0iE#o#Do^^byH=x`R);pj3;cgP|DpHUrPGz#@bz*uY|Lfv3ueywpU1Hyy>EU4#`jsDwBn#D-@5MM!&GlEbazzfMRA`8& zJ*6~0B>K+}gxLAgB+{`t)pr1!E1|?h)w$iJRDR#ziHzN&i$k20i5deAwg!0|3S==$ z%&wLGd9IS7nUs=P38~=?4lWmn4Yn9X2uyKc`lKMA7A%-ARxlbo%B_2)0Zn3GyA1lB z2X-Zv-we#4c3NW;tR$_4g54l}zVJhBgPTUdMU0R1TH*>z#&rmD)FF%Cbg>VX57f_{ zGq1>zUwC<(80<|7JMi}_e^aW`?vP~zfLxkNksLx~(;8Eyiegdtdm_{YfpoXHJcs&8 zT_#+Ou|Q{L5o695Yn9vsiky-K<$xM7dw8?=e0H!9jz)SseUvtxULln~0AZ+ShWXuL zP2VaY{8+uuQwL`?#d#Ei{NZk7er@P$@BcuNsBGFvC zT;PF!B5TF}Z~vUiY^T0=oFBa$N2w8x8Cvq0b){6KYBmcx_44lBoy%Rq$jHpA2wxu0 z=AUQS%RmeE-zu*J(al~Sq-sXd@P$azKuh55q7S85tK|JCWhIJOUFKDs;|~T{mt6J- zCEoa0E&hK+oF3cac=T`~u>$c^QIBUNH7E7G#Nj#cV-$B)8q|cX+8ZZ=o?9M4M7&8P zf=4-%<=utR$~}Pwf3QGIY%tU**$GdTB6An^B#hWmw$TqHZ-~>&>e{V zIOGlFe+}!sAU0G(afD1-SI?N$rgYA}G2{$aE4msQp0tzXKd1pON*ZUWJgz%(!sYOR z{?f}iaOp*XIC%!X^qoRnz5+XiGVi3o9^yU24ekA_enM}+nhOL7Sh&#gMdd%hX&9PT zLusAKZtB%QhFkrPU@UPaqHhFUikDnNf$d|a#$NLVK5Sj?iW7?Y#qPr4iCoYDg+}nU z^)1B>>p1NYSbX-#;Wm^1dnTLtf&dKSrXz^)1JL))6c{nfi&udvChSe6i3A?XoYGd$ zXY}Ao$~RRJ>#P;k&&}+LxpEX&z#zV{ehVM-lM9+tMcpH0iLQY8i;qAYV>eo0TcbZ7 z@^NTmRE+K!{#ZNQl2H$Iy$&~;E_-{3NBk{%vIVw)AKRifgR!Ifcf>VUK+*NsJa-v6 z!=XjY^|o4a2F!h5=O^P{h@~D@=Oc8RGZR-=v2tIiy1sgXsj+jGHBi4X!F4E6?3?&> z4|5FT?+~{ENCAZ2_Xo#UM{?y#TG&J9pu|`rE#Wk;zSs%Mml2-u`)pfUf{V-Bj!uS3Dz=UOfU#$eXQaZrAAJ`vo z=WCK>@cMH|R9!pN2v8AQ8ZYU!toWtG8-;zDEVb4x)l6B_@#)~z2xUbXNk1c3xIs8X z@6#$09G2v177QE<@b@@7zA-461Xn?0>GLb(@wJ==u=TI}+UN`~il$AsAbs{S1 zLJ5u@cTo;B+!9EQzn~>y^cUir_vCKx2F^-)ZIytfBfriXBr={7ReKYsVC*jQf>4Ji zgI1%>5`?&*Dlpzkt76A&M}J!sA}7biY}P=h>ig2ru=gI+$pDPiqIPVw4rRqiR}fgt z2@UINc-cJE^Gnv6t)-o*!!TrLt>{q5{XY4WUV7Wgo#q&-x|?JOgHehjT{3lL#C|9W zJ52H|#C)@pd6!Uu5YHOwIZWnD6X4-0b6}w88z-;S9T(#Vt6u5p_YwZ9XQW4$`dd{W zX@7=zv0Zda)NPRka^59oZyW;InPI=lbB43#Q3pORq^B>MY!uJPgF!1{#A0ADxP!k_ z+=v|;u=~6`-0WfaXb_~z#>!N7+j6juUUFGj-O?O+@&=b;dT>q#U)(>zK14$UBLc(v znoDEp=&gKP&7epdpNvuqT^l(hU_taKW(ZEi^h*jhBO21^bl4%v5=b32;J(ifpVqXb ziP+@f4!-g1Xf4XlWP|0EXp3rgzt6}f?f=$Xp)BT2S=5U3{^Op2d3ntLKvKd~;0S5i zt+pZs{fjb>U}T{;5;Q72Wru}ds3!CL!M#)KrGCRt@d78^soERRjjEOv*eyg=XwkN7 zlB3WJTT8w{MJ5)L7S`N*CYYU`8&5+SHElxTRmj?^D94-_`W)xj$oTWv3oWhTgmB@b zsll60n!{#aOWO`hL|43{_VO0s#Vi(!2l#4Fl91*3jB7RzA`7DAs%F6LX8KPIZwJo# zbAy80>C36KJZGQHy^l)lM|)4vQfm*+X`AdluZV-N5srCh!*FZR;;*MfEO95~vsFvp zr>FEF2W@+na&$MF?6?Xo@>+ED@f~z3j(8c>&oAO2*4XXSdD_EY`|jeIvLV- zCT`}Quzr|u8O`TxSKGYZi&}jz5Fwi;o5|Q1IpTOctu2MFA^(fAa|jkJXq)u4ZQHip z*S2ljwr$(CZQHhO_MQG_HvceUb|-3ami1O;KAFY0^dz!;OU~z?-pTE$HLJre0KP{d zq^Hf%obP{SM+cKA-bVNSvz-A@Xn^6%#~%#HowcUv@U`$N{3mXTfDjxK?xq9B%5c~4 zx&?2&Ff2*5Ijci!)DfXe|D(nJuIyb`3;GhwRhGAU;!CIVjs0z>X5cLxW!wK+1j>(| zMb<9g=Do7j(*=UK_3P&yO6zFPt4%O3UDRMr<^-F?6TEN_&9~mXSo0u^d%4f!yrTr{ zHF>SyN#z$FkOwkW?z7X$H7aW2L4IeF_+lk+oT<(sRK2h3`!AI2VXJKi`uElan%8Do z`;(w-=rCotzFOxIOiZn-oNF5z^3u`4x*QzIVZZY}_~zek;lhtL*0;5*TmFjO{q zu456^U0A*6iy>Mi2rKw72Jk|FsPq;U28AzE2zFAexi?m+mFB6`MQ*IpyE>0H)-PR8 z*K(^B*$S93e7FLZ(PK4H7v37zv)J3)KN3|M>b+~QCUzA!m27@W8M{@hJPd95n~7h4 zM^E$H3ckW>PxIhFaUsEfM-tI1mI-ZB*o9MK@8^HSxWG{_21q7ZUMHGx-+zJI27bZ+ z6AP7?vwjr($G#Pb|5x@6LjQl(Ww8EVy3Bt^;Qk}b^zHl)VP-_z!y0GJtr@w+wygOTAmEHQKqJtLXp4*w;6Jt z?cAWuHK6nyF`wP@TY*Jz6HFwqRXh?*X0zEM0Pg~y*3)P2EjD8ZSFzD`+;gVP!>;zN z=k06utw-WVOK&cg-uqe-^VpB_+Y9pd+w6WEEPZs*-vZbgxm2cJi6IAw8+OT}o>|{) zV5Z+WG_I?EMu-)9NrRz$7uFVCxl6xOYWZQ)HvLxh?L?oeEY?fEGc3-@S^FmBLf1hK zzTKnzb-+2V{LRq^TG|frg{NJsU=x1nM}2InH6Vt(EvN^z6ukc;3~K(@t^Nt#e+d|x zyMF`BExu4tWoLGUPz87YQr14yz!N>KYrq4c^v!<<9)AFE1DdV(1Z91z!V`QSc7(99z%XpMJYS3m?b}Bl~B&Q>u**=GC@-&i^OhmJ8w) z&mQhE#LMN1SpQC`hPd-Zq5duCiJ}c}zNSc@zgQE0wI(jW2O)c`{RMHy6XIG-<*MA) z2j_Zh85!9rhsiU=+9S+^!v&+^%iUH zfWLw*c`LN?2szM2=a9g8<3^&DpiD2N#zg5-Y`Ol5Gu%bLlde6OUFmLM(yvt!hfI;z zMrXG>8Vpl@pt^Y!E7NiJ>SZ|OIPk~Faq#@TM(hKJhf1;RVRKw{(DB1prBAs=^y}@# z*jKtb9QdA35XH4~`wn}^Tu_ROk;dcmcD8=JPf8*_03H>amC?cGbUQg5KXyOyd+4iB z0H%lUY*2sR7M*y?sV_lrPubiKnJOd=5*cy(5m0_o@AkYn~TLus|TCxiWf@xfCd~_(`o!7juSUvP18zftyD?Dkk&@RHre_ z)`V=G=#E3BZY91_vIosNMJA*^1|Q$J!cRDHh(5FKs6Q$DbP#{Yuy7ZG?7JVoOZUz8 zGX`nUtgzvl)0cs8q3kcN9nDi$Rrts~F9=GWF7T*q(cC_Jt|PT9?Yv|F**%HQYn?hr z|0RGrMkb5Ab375KAh^XMqH{bUt01^W;oTvEnk|6zrH`jPl zeOVA+;-hmtsQlp4fGX0X^Sqp6E?g_+L3d6tGcJtyN3d?O|)|D*{QMq(jm z32)@Tk5t2dE0M-r>#(W@&gh9cY{vrWP^`lt;=Dqo5W>8;_xKx zr4MO}zznU=ODXXPt^6ZzB)gM$I+OWVfh(8Zww~y2J8s%Xh-3hwlo?vFOg!mTm@2o> zgAovr05rToy|NO0bY&d8B14@>MS8Ty2N|FO>TT_DVPS!>Q5{P|+p@Ky)@7`+ zGSN|11O*y>7TlmnUKEhz`@Z|3Ju8j|Pzmo#p&VB~GNIXq0>Q<`t%Lv61QP{P#U$SK zslHwNlMTOcVew+&j9xC-FS=oe4WBE-H7+b@DNNTFrV}!x2(#}0(ZCvAVW~FNM~&;! zZ^4e&#;HwVfyLQLj1>ynwY?!EY7=XyX|Pl9tEPn#DB@(L@J5Dj5(%<e_yN76YtTltFHtL@SN(7 zK@hU3V{jHo;;cS5!>aX+l4y`smFDYxX5sBO&TM{M_GaFcjoC+4OtM%_Q=frI!7PX{ zJw?U(a!vfqIyV%d=${>|_MN&hPlY?gJu{+MRQL79jg;Ttn`lNLz4o^aDM7BCLeUH> zZ|7E7J;I$$79sjL6rEP+%Pf*|ne%{uN>(#+XwWsSsz=5-T^=e&PBR*pt{YMp)~7nI zfe64HQ3owMPB~jMsAdEB#08XJcRnmZv|LO?f*op?Flq@#N@8e7lOcJV^4~wr{Ya$zh#X1@51UdYm@lT;JK6xnylY zo&^U(#&of|GR593I=SJ~Ho61cwxpav+yu&Qbxqy9u!#Og@v{18xGMLDM^7a*Vic`X zX--qa)yIS}J=&S~!PC4zvMfDh(-<;#i8=r`W==&{(Sw;#ivn#sjx^q_2evpGrqDk2 zP@0-nG7t^HCTL>HsCEVlZS+nKoFa(gcfd?D&{!Pp8s!G?5=*0GkhB&roliUvOh4#n zoe6oZe(qiI)TMMAoIS|eafJCE2}#w;awU3a)8izlmqNQ=ifW@k9yBSPE=a@X;UIS^ z=r_^AR*~vArG`4CfI(Ts_e*^BIMBT$pmWswZqX$9teU9)HO+Ww2)`xwG5AoFXr_6Q z>@=Z>5uz`a5yKW+`cCy0@mQ_mxSAhj`Rb`cjbnGHFajDw`6x7{>NkZ48q{Ve(;i{a z8Ul5*at<+25g6J?&HBZLT6w|5m=l1eFqfQ2czMPh;oF}@=~hHgE$>BI4dS!`J+`$R zsU!Llzl(ADm2YTsAlXA;xz#k?noiG^DxZ?zz*NNHtB$0+k02Xo#2DO z*vh3118&eikJIu2xT_UVyv>8uXv#RqAdiUvn0h0Rg=Y%SZP6qJY70n-gu|}ZgNuzA z9hCe~T&p{Fu3080Jy!64apj?LphL9*69+f^2@^G>z)Nhoe2maVx`(1RBAoN;Xdc_+t2g&JICsunmvgnJ9J-0UnwJ! zD~06cr_%C7c}@Eol_fBT#W4OESB=zG$5-4QYSw5G7M_OfJ`zLmmme;6)UoEvZ*G@8 z!ia=YiimvMiz>Hg>aMk%cdR5%RfW}6m?=kHsn%4uNu;i%(1BPr87bC$tA)BSWKJ9w zf-Ri%QmA#=%04wJdogUMR5cCW)MPDa)yW++>e$X8V+JZo&QYM|)bW-8mh229g_1++v$KeuK@*+5@bpN?A1W9=_c>ov{Rs~?S?iIlONeq= zi9NaOa=vl}yHX{#x@LVOqs6mf{}fu1nA#{Pe@~bkuvUYUBB&uPy^TDZR!yZ#!Gc`` zo*8C&#~Dg)PxjhIlmMxp6YQ#-ml}p|j-NL?5BVwMbhdPLy8DCw;KgOK27iRxhjvjB zxoRon-Rx7Za6D;FTWL&~JR%v%u_h#?xiAPc>Zt?EwJ2op!hj`H3qK`wWg4a&u`VWz z^_T2CWQ>YS(NO#Bl3upKEgcRe!bH2T0Lp!76N_U z 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

bv_9)poX|YcSRgO{qgj#VA19Q~1ZKol>Vnv% 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 literal 0 HcmV?d00001 diff --git a/update_csv.txt b/update_csv.txt index 44d9566..2457fe1 100644 --- a/update_csv.txt +++ b/update_csv.txt @@ -1,3 +1,3 @@ id,Name -001E000000Q1aT4IAJ,testacc-2-updated -001E000000Q1aT6IAJ,testacc-4-updated \ No newline at end of file +001E000000Q1aru,testacc-2-updated +001E000000Q1arw,testacc-4-updated \ No newline at end of file From b0b7d5b1a7e2652ca164eb7498fe9b4679cf3609 Mon Sep 17 00:00:00 2001 From: smulyono Date: Fri, 9 Nov 2012 11:37:47 -0800 Subject: [PATCH 2/9] - Remove video files and put it as link - Updated readme with markdown --- Readme => Readme.md | 41 ++++++++++++++++++++++++++++++----------- pyrest.zip | Bin 56021 -> 0 bytes 2 files changed, 30 insertions(+), 11 deletions(-) rename Readme => Readme.md (77%) delete mode 100644 pyrest.zip diff --git a/Readme b/Readme.md similarity index 77% rename from Readme rename to Readme.md index 5de023e..01830fb 100644 --- a/Readme +++ b/Readme.md @@ -1,18 +1,29 @@ Salesforce Bulk API Demo with Python +==================================== -Cloudspokes Challenge : http://www.cloudspokes.com/challenges/1857 +Cloudspokes Challenge : +----------------------- +http://www.cloudspokes.com/challenges/1857 Requirement: +------------ The application will demonstrate how to create, read, update and delete records in Salesforce.com in bulk using the Bulk API. -For login and logout operation, utilizing the Beatbox library from https://github.com/superfell/Beatbox +###For login and logout operation, utilizing the Beatbox library from https://github.com/superfell/Beatbox + +###How to Run : + $ python crudtest.py + +###Video Instruction : + -- showing how to use CUD operation + -- show how to do bulk query -How to Run : -$ python crudtest.py Instructions to do CRUD Operation +================================= -(C)reate Operation: +##(C)reate Operation: +``` python # initate login obb = sfBulk(); obb.login(username, password) @@ -34,8 +45,10 @@ Instructions to do CRUD Operation obb.closeJob(jobinfo) # logout obb.logout() +``` -(U)pdate Operation: +##(U)pdate Operation: +```python obb = sfBulk(); obb.login(username, password) jobinfo = sfBulkJobInfo() @@ -46,8 +59,10 @@ Instructions to do CRUD Operation batchIds = obb.createBatchFromCSV(jobinfo, "update_csv.txt") obb.closeJob(jobinfo) obb.logout() +``` -(D)elete Operation: +##(D)elete Operation: +```python obb = sfBulk(); obb.login(username, password) jobinfo = sfBulkJobInfo() @@ -58,8 +73,10 @@ Instructions to do CRUD Operation batchIds = obb.createBatchFromCSV(jobinfo, "delete_csv.txt") obb.closeJob(jobinfo) obb.logout() +``` -(R)ead / Query Operation: +##(R)ead / Query Operation: +```python obb = sfBulk(); obb.login(username, password) jobinfo = sfBulkJobInfo() @@ -72,9 +89,11 @@ Instructions to do CRUD Operation # batchId = obb.createBatch(jobInfo, "Select id, name from Account") obb.closeJob(jobinfo) obb.logout() +``` -Another operation included in the library: - * Ability to find batch status, Example during query +##Another operation included in the library: + * Ability to find batch status, Example during query +```python obb = sfBulk(); obb.login(username, password) jobinfo = sfBulkJobInfo() @@ -95,5 +114,5 @@ Another operation included in the library: obb.closeJob(jobinfo) obb.logout() - +``` \ No newline at end of file diff --git a/pyrest.zip b/pyrest.zip deleted file mode 100644 index c9f6591038156325905b0dcca4eece7fd9e0779a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56021 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 z z4-aMJLbs5@NZoQgwxvk|zTkp`{stxFRB`0#DNmF~S2GQo zJVHJS)BaMEZ4U~>?OzBM&J`93+!36Q06!Q>`t+@tno(CL{7di$tGO-@Hmb_-v*Inv zMEl(MX{rweICApFZAgzMDd2iF0C@|ME7thec2;pvN;^E+XRVNr)M%|w$nK-6d?kv{ z_(fl%WUeL4=7dCp58Cck&74MPA2ht_-e^ZW5nuDOQrwW%iRU*7$^wft@;HXPiL?2r z?LjmOQrjF_+Rg#YxhN;72{YZP#U_yCmd>>$$)TNGjio|bkzK-`Pm~SCo=P$hD-xtf z2`avo3;B5vZ{TLdi4l^H>kx5(W4JGgKaI0oj^d#F=e3BpgiX0;EZyStNz*`2z|E(< zpa#>#xWHBTav;?Fp>E$XSOmk8nWTsZMI+Gea_i>U$5jXs$RLAo%L)qwxHVZ!r&X7f zOn;PnqUc(e3UDWMi$reu=H!B=xSTdIGsLJ1%UoFPiNZz5TBFAs(gdMO&zEiGAYpZr zA-gN7o;=Gyw#Z0?%GrN~+g|@kJX3mI{oa7d{mP4r@v;e(=?jqz7CEQUa;G(LRQVduyb3u1Afvf_I1P!gXbg`AiZV!hA&qVwA$r;r620fI-ICHLM; zk!EATghEXYZNdi5wjM#_V$zN#h;PFk)zHSvHbPnFo>-K%TXY0!?un76TD6pBdWmac zJFgs~Y$b~1Q`rU>GIb~t!FEay86@@}djK*MO_P^QD2&#j!Mvw$tYMcM`nNPiRCRbx zyObN|I$5G!b*^^2jlQ)*3I-!1KAakDY0L?+&6t~dU}&y`ui6G#EC>oNiH4!cj??vr zB*fA=)8dF?)7hxGk%ED78hsb0`RO4nj9GPv^wZT(LY?yaHQC| za-}SzLlsgL%*!-!5)JIe5moMCBp+6WT>*P96C2_fYgwi}N4Z;xm@^727z`>PCUQ}+ zMdRwoBp5!DQErB0+qw-sU|9*=MO#irkjZkw5mf~xhv7^J=*|pK%^`10xc|Z@ISIwm zS^e93B*DA`o70?N_+JI=U2VD%>2FQk*l{x!S9q$A4G8DPe7v{CcpJSg3f2WZl_mv> z91N&!>>xf3O5(WOz+rsQdzfH%3HV*J8aEd#bTQ)9>TCl}EHvM=HiWLOp@SHte_;mh z2W9#CSpOa~C@9 zGbGdHwL1p7m4%lem{F#yS9Z?D$P4$o1)gzIjn95iY9f?_8YLea&?31~2#I%8Nx20()Jk z^Mfvu^JqCXKxul^&kajl4y&!2U2rX0=GG@IALfzclf>*N&LkqrO*e__FVaZP>@!es z8&o&hs{_?3qk6@-pQYN%ZBRmqi^-u@>p^gb$qJt1yJ>OBF8(!DVRjX1KA6Do!5Q#d=)Y8Eo(l?J6J z-~(FJd6TS@KvpEfo^-fSIWx{t3yN@bMOin|hm2q+AjP$?)U?{M6Ng5OrWHkps-S_Q zerVepFVf2V#{d)Hoy6ppc{--aH!#iPfA z{<@@PMan)=iMCCkM0-h1O?R>kld8%Pjoy5q;(t5uE|_T!D9I2l^88gp}7n zEmR>bKTpwu`w;P**fB$$nam_|TsVc3;%XGa`HY@Ed`$cjI}34H~v z6I&g~RQDzl3rHJVYG}u{7|4kn$+AlS#daZn-qcHUy;ijptyhPOODWr)gn_q&A_|0^mD_E4!uC8o@{B#s z^vp>7$VI7##LC_j^sYH^Hdop8t*o5cQTt_`Z<(*vk=^X@@P9o*dMobrr!1H~fk^bBIo+rD+P9tC=RdP$3Fp6_#8$~PiIj=(WM0-xfp(|xd>!_=j2Ba_TH-5x`W@J+e69@hU z>;5aL2$fj_S`qf2D3RSCbi_JZ1aBTjoZ3(hoY(=v2i@)!bOo~GGW)P1EBb5;aHr%Oxc@7f4_j~AFr{GEE4j3TPE?p0CkJe=EE4?h~7j12D=s!DPEBBT9TuvG=SL= z0iC$9XI1IsB2Cp>&$U$EiGEU z&JGJKr5>rG$E4^?oh3zzJh&9=%Uw^DzqJy-LLDA(RDE#DmpTzSeUxS0rAH(qVBtz0 zh0iYb|Hk(y5 z!R+OMy!WnlpdsQ~ED-v&0lI&DmYyRBjjCl4Dc9|?t0q1&T@XXo=#rHLplV+j< z5;aRvX^v6WK8)0orCg3hR;MKatoD%*G{y>ajemy0`p@*)MUE4Ne>)|OcYgnZW>Pce zdr&}Smf8ig3X-8Q=J=9Dd)?<@2dCTF0T})@Q$qOj{vJnRsENlZiD>-d^5WT{emt!D zF_XV&$e{NYDU!je^NQ1j^sat~{KD1S#>5`iWc9$_brC>RlhKsTFA91yiC&@J%+;mr zGWN5G^g|1Vx`v+DThRM(hP7<*y@p)jfXNG?I%Dt$F{vOw^d4nm#Sl7027VP_dVxm*SB|x;92Y&$!!w|bc8lf2 zbanqxfo@2yMz0Ryr;Ymb)zj`#S&qqrR{GnLgMQ&hO`aJNoYo zjO&peKAyqN?|<)f<&n5D^~C}J@G<|duGarb8>9X2uGSwpc?}6!vHz4h{8!XCM_bEj zYrMfXPmi$#T}p+;?I!!!SgoR_kYv)3NJ%rXv8c`eSY8+g2nH-Z_4n`d+72*``@?Mn zHMSNB!_v}P9X+uX{I53_|AySqgFRDwTb!KQTalI2FYMS-0p}yjUvGyJxu|X5>y5s( zjwXEH&x;_&*Ut6Z$!8Otji)Q<&-*(5mv?F}EiSXNkxEY~Ni(}BEdns`!am~^|Fip^@A#E zH&BHH&n}mLcqdg`vx)(_aIDN@iB4%R)slw}r_|i6#T9I?bPju~`i7;9o$1Bk$?k?p zLpeKL+0TVXmpb`}RA%3L^WdY0!UoAyBzxO+meTYAe_V+a+tc(x#l~jHNskU{$n)Y~YqTTa>R%26FA>B-5djk#I`)J*V2N&X!2zl-2s_xA>gNF)PZg{OZ zeQMd1PKNPoL+;Y*sji%unfTM>iPXkriEQ{4DkQkp#+^;bopk=kkC&%0Fqe-^oWas5 zM>A;dNf1(9xTu|#9MlpxxuRWX@rHnAz!9aWMWxA@%?nihKXCB#vTWh|X zWEX8z8q>yln@d2-m8DK{ZhJG~Nj|yEjYz5R;z#p3htExNrYl?z=2>BD6vLG zrvCb9xI|rZi;SB3W^akF&w^EJVH1t^XQarbV?aq7NqQpY>*4rcDr8-foD%#ZwTEab zOEJs~mqp%x&s+pc(j;ze_dxap+@%%%G3c=Kcv!9OqNy((n;bTqTg*UpZ*h#0qzUWE zHLEzLJ2biIuK-ORpL!gQ_UL3OuCmwAFP++0bV1gD4E|H}!~Rj}uPnK4GXb7l_GwCX z=j=)t^{S!xa0soY3W=MZyS|uq!85Z+rNSPZ5>j+pE^H+GDv;3Vr$n=ax}2urAf?y7 zmpH>#6!siZH1*-x&?=$N`CxgY?-J@;smRCJ1=Ho&jBuxvgzYY&@+;1*s7XbB+F#SG zt=~HsP2=1`uR3~nTfyAZXas!4T8UPH?qfwXQ{)0xj0B78D?=qXXC25SUmO5^s3Kx; zu4iEpXs$nWo1PlKtE64ED_)wi^_h3`5e6Nrg2dIOP2R$ChEE^vXM9#krqJxERW_`A zKmL@K;YG-NMsdz5WQB1(f>g@tw@)!_82x5c37$a?Cx}KDFud-S*tJrmuYv)MD~^&| z!${Fhm2D8(g^*!IQCoM;x)(0gZJ|5=MH)CC+jhLI6}vkRu+eewM|9~JS=*=`%No9gBvG*vLP6=UppSgr zHxVHWmaA)Uh^nIw)>!0zSA8X@6X`tuNxP3N$xc61lLrS8WttUE-vyDyA(~0MutJyL+w}bjqD>Y&9r<4$`yg zQ&Ee(&>G?&paKZu4)p7TFEtmMG^fOkvA2E|_Aq14=7}M9b2Aj|>+Ovf!~b$UW6qTo zU7LH4%K!dxVCu}>iMJ1I{b7`+u*|q#+&Ph5b_7xCK|N`AN#>6v5xPsVj|}v{CZ+6A zKv)B>iH=DWBj+0F!yYUu0aAmkk=Y3;Iyetd9A^~MJHCIdaL!HaeiI(WI|NWlm}eyH z3?@G(8;|lF9mga$-0X2ypSi&S<+)noeSD5x9pDnN{G2i@HaS`a@o*E+bbMpRc%N)h zkhIkLSluY&($&I!tPx#%L3HjA!+(Co;H9fq= z3`JsAybJvJQWuB@bwVw_N=bZylbAp%ZyuE@!mW%;H?qehTt%JN_@l&8vJzBDVxL2; zwE6*fwekmi{V0_;#I75QQ{@qIgv@tDxW8vSphvBn(0B?kz{gV4!Mzzg(sXe4>==0m zjf3V4CS)5uJc}FX>U!inTa2RjJgY9y)w;;o1ok?ng~t_Au$=R_(H;qn?-_J~q>Dds z0c^i?s{4ttJiy(k7#1ey)S3_*3X-*eiHYy=qZV`sta_s~s{f5Vww3d6aD~NAELr>3|SH_ ze2CoX&T$hoAZB)z#^xS|c#=&mT3#^Cr5M6Hd4Js*Kgk$WLQO#XizT8mA+eY@+8A{? zzDnng2UD!nlXeuxk$ppAepgma0)+)l>xF^CDJX@AAr#_UYkUzn&~)Zw-7+?iS64w+ z1y3z~pK+xL^TGOAct+5X_&C>jgcr8Du#EB2cx~4u_;UXyL7r)4$cJGf`}#FpH_;N| zbC-i$lBn#S4(gI$DqNOsGg?1kS$8o4OrUmAdhjgJeJZ+yd9YjM#2psCZ;}lcN%pku z9Y=%EJ)cyOUWLa)vS9GrA8u8KAzy>-5S>wsR_aOn@k0GHCXm^0%DlQdvwk+u1JZ?K zEf-pO;1TN^&*4$+Z(a~K|W9@itofjA<0cJMLviDTV(8LqX>`w0Q5O%DPo=z zfR2>8$G;!zN1hsiD-)e=^Ac2TbN!GwnjQV7t?j~1t^Di2Ygo3QJVPAlZoC?0TOREl8LLEMf-FrA(>sC(!!m!lyT9IA{{ z7~;2LN%4}g@o?Ah2YP8){(T_^1*4s>Y@k>{ZMU%nPF7k5ib7zIJQ+#zt{GzJThMZ% z4g!tKB7+xBs{GHipx9wlw(3zOUA)2sKtl+w`#LuhUpXe*J=7c9@S)nVF)9opn;;?$ z0KAqtJS%POzq&gbibmGsCeoV^;#waPUpuSiysJu&f$NKGIW|PKbDLM5Y`e&?glUqO zoOHuiBdD(x3_Hu|L{_1|ayw9R<4&A-O?xe@glstmf&Rf{q3_Vk_Q+j<<`P?E2Gf}V zAxYwAK=MMz>ct+ClSD(nsXX0AyYNLtimZjGp7Iy~$qp1f*1w7$!wnGa6qTS%vM(tS zQ{vC*ByOZ!cpyOO>XcCPPHCyd&8OW3JCRM;N4`!a#e)UmWG+O>%#B6Uv5#eiBrItK zjfjnuekhRh8DgAFQOaDr*c_e5C!pF;Qxkw8pOmXkTJ~@3{qzf%wT^TgEMy z-_(+yKPxFH>lD*=bLH~wu7XcZ?EMg34p}wI5{hwP9sNG}6!-WC`Ci5eNK?U{pB{h+ zE7O0mUsB}Z$uDRxBY$84HWKcwN(T=47+~>fgUXdKBC`P}%`BA^cM0H{?=9-{V*+0XfX&+BQm&3&|I_nU*8)`7|BJqd%dzwC~CyIrzW`7wxf}sZFUqNm&#TJtB7uPLtAUl*L`S`}j0vi{&rx4H@jxwn4PJ}~ zIOGlQ@skBDeWxXTqcf>zFV?bvLk}wnQ&JBp!A{cm2~Rv?Rk2_GD4BqGvwyfce1 zZmy$$RbcUfb4 zGJ`uWoHa|tC{x-bp-EmhZaNtzy6e#_%EJ>Qi|4=FrkqwR>m-<7JROEjIaAM=fLJ3R zqK8YhNRQTouRPL78Sc;LhRb@01^R(51>8jMaiz9HtGBw@=dNqF?}U{XoNze5wkxbF zdtymr_qoPa>r{qxGCi2jLWT!q(`ibrll+>3)Dy;-I(yQQgN*En$LNsF4-duYokPNo zlq))__C28rvez;WJh;xq2}iVRo<(b=pPEt^mGde|4QT za>);d7Ycdo*l8s@aQZBY<9B-mE6=YBdqgA~YGH0aMR8c8)uBd0Q&{xcknO2t5&EpG7F96ltcj_0%$5DT5CEOgcH(k31){f zwBn>9HDb3P3ILP@oqH_&s=AQHl1d><;%Yeip)G`5)6KFLBy3s!qi8546AR>KGK-SX zudT9$5G&rc1cJ~NZ+njFL-K-B-baHDsasarnn|=taiyr1>eSehhS%)c7)) zDUqIs>z0wBnWSo$13F#4ObJ%SB$%D#d->($^(=!GjY)0g@!_pPKdwvV?N*lwyle4^ z7!oBb@6){D%OXLPJvf#8X}QYIr9(`$tHJ5q)XQSqcvbEjP|RABsid@>nY9Qq77iU@ zgY$x6Z7qQ{M4=)*ym121xcO=LMEzDVn&AyXB9t_hPv(zH$^AA_9 zv2Oj!plQwSSlcDzLp$^RwC#Z5{5?PkTZ_QfrmMx|U~uG>JoJv`E?#cgTuTjMN-ZJ% z2))i_EXy97%pM-Om!ZaS5df)3J}Eq=lM3pqwQ6R7Ae>$9mcYRmjJi~7JVE%y*f@`-A=>iharQREQitW2d5Ogn2XYtw^cb)K#J27n84N) z$PBc^!%oY(?DkT^!`fW`^8A5T$B~dn=*Io#@$Ro@h!Mu8#mNQTTd+-Df`Rr zZ-l${N=f1C!-$f?b}q3UJ%CVE(tqDwDW=5q(!j3ldIsIy-- zNn(jzG3L#s&J;eHqsoSY)z9I<3L}}KVVql`fNag4^Wjdzxp1<3Y|J2#UB}ex*NC=Q zfoVkiKMqifOUEiWT{-`prutrkUt^Ri5MSw++cS6%2H79_9(gF&?R3S0-Wgafu-GCD z4QsRWVC0m7d)gseh=j@@n0F>LWPRbz-r2ZK>e7EOi8VMdFxhe7u#k%GP4iuazz#E< za;GtjKZ>8E(b8hz`B5fD*JRn$dBa+gm-}nW(gyWB`)UF2#|^6F&4OZSRIH=OOvX|R zFs;{GGTsYb&4c(Hcl@yLX^y0SONC56c)4VZCf zhH`FTdvRmJ-3-aPcEmafZg<(hM-SCSZ zW#!_=x)&Vq{~kX7t%6Hd2?sRSU~4;;6a?M$-Mz{4KE!(7;p*8fYTI6jBc-na{=@$|X`RH%(N)*^OOxWtB z>3@5%4lgF`rN0fGu(b8~WyYKDL3Rl&OXZBMix{Ct_PecTiY8?0$xoYlaHDVY$iTTo zx%m;G8%VA+iR1H)m!j~l{Bd^{RoC38c()oh&Ah}4+p!jng0kp|-SIZY;%TMDCX>K* z1V7v-w-ziuZis>Z?y%n)r(5=GR4E&p!JwQEnYo`b77)RP;ni6}=qQ5BM$(Engvi`9 zn>drontiZT_THx;>S0c*6lbe`k;zLym1l4&LZjfeyY`4u5uJ;d9&oCcq+Ec(LZ;5( z;!o4NMCLD?ER>evOhz9d=}_#bsubo_p#5Pb?gKQG>YV`QU{z_T){Cia~py0^wqmtcRp}~Bs)eN{DJ;lwu zRasEg#SkxH;@265j9#N^xzM_$7}a0;-uutj+C8k%UNQ3`_%Pr!1N?iJIl+4<&!b98 zmXPfmrd`_yIEk2A}Sy*&;mAt_gTB@g2-%oh>I zOmDHJEVWxLD&4Pzvl?D`qy+KKCXU;+Z;lgBvS%B}(OTBbP}n@yBXAA8sQ|4A`Y0}got(7Kb>ee-1qq`?A;vMfwt!w$z_jUU59l&4F>GJl ze@JMi9>BX!PiU($62QpS++lU9~a03PEPJ8wKdGXH9h%sbyHlf*Boq#~{b( z7b3Tkg&;pv@qnV-qN(nCG4&Wb-OJe`l-!}0iVw)%6A5(M&79u97^ffh;vCdLe)#_r z;wpF+mCgERcU6o2f7)HfCN_5ehi07-4UK=zItae50RMupUj&p2C}XmVs^P#KvPux* zxNEKp;93afq@+z6v}+`5u}H^#Ztiq%@$k*&{{8cgrsElQaB$@OL_%sjX_ERQ?y>Jc zDTyai#dMUOQVpI{{6*0-plDXb9Fh*Hn3>x435w44JR82vKjAe{bSQ~dn7(s@?z8-1 zcXL%Ra2luv0s11SS_-uE=;nJ;(WaLe&?!m|&QQr$EJV1b(WjOC>%PZose0-TLUoc< zD}TMRC7N_H4Jdm)@A~^6UW;gj&?%0jQr}2t(EijXMdH+*BcS&C41r>rx6;bsevoo( z{VuZ*`w5w3Q0DvF5_cJm>1OsI(5O))NZ%#plSA0wig{&Ejfg8!0)9Ydj1sZ4NPR@w zA}yZDJc8zZ#=V)O;syYjBAZ<&Rw_}|R&W3(mjGSIoUBT^&5G=vHiiY-;9?7JAyX+0 zoc@EP=NwjBTylsPSQ?$%S&L(C5ER7;Q;8c{#_vD&SX3N&ShqTTSh2u@w$q_2$PWZEn%Lo-Di3yLq5t(G>*P@|Er!~8oA69}zTf8@|v~A-K7J?JInnoXi0k1exo1xhk^nwSH+m|i&Ddy*9cD7>g z*51V|u&1q?f~R37`X`N0alxfDhMqRlBy%w24CwnJ%Rh#c83}1kvlmtR_XW$=x6Wbf zQH}rSdrFodY4MerMz5h;Ss7?5DlK<2MiL>mVV+$N8vdtf(D>ckuDuQT7wiu;f5KRx zjupY!cryuD^A`~qXcaV_PGd5K!Cbq(pwR;4K3a&8Rkkuj_%&CPMp9{*|CUb5V?44O zZZx~25IMm^;wsPvh=dt|RV1XbHoS4#Lr(#GKV*POu=L}cX>_)O79mhjt$M=P?%_vg zA|I8S6V>~mveA84vjX4+gXhCz%7~uoJGM_lOFu9jK2*Cm#Qx*1e;WsJKOn)el|I!u z*fQ;j?J{t&*fSWbxZgsDFI$)fkUnhn3S^jo&4^awEg%(%pqTM z;B62*7bxYm8yhgYj;c9N6@7pE5$(TJIyK|5bu<(!@CZzcPwBf}AkaZ)B=#7GV;Wpd z+_0-DTM^L52Jx5${aH6MhmWm3&|EDMEZcE zWz64qdfD+*xH@L-|8Q|u29Zn>)4%$iB`DDWgHN!$xV#dRekic^f;F>V}r$LXQPLK{~^v%W6=~+rtQ!!LE=K z6-7F`fxfiOa>f%VSsA;tP5F45b7{^mRv1AF%D(1Wb5T_g#}2i`L|l9ptotV_fOrEF!Xt`3z39! zSa;|QBuqtI6rE#@89u2T^7A^0Ll9+Vn0nO~*`C3Z>XH=xeP$Zfu^~BG>=_+CXKQO1 z)1UAiW3^1*ME_!6Gj-VzjZ=}K;Z^U|Pjw&vgmQD$)k>$!*X`)I4qUnc4;npHr;dB@ z$qVb!gRGfno4jdL>gmS~8q6#R#}(Du0&?W3E5J_!{F{*h-ODKqMvK34`pVS{R{U$e zLH{25V@zRER+xcY7cFwtGMI+5-MpRU_T$4Xyl>#Hd1sr>0B+Fjp0@1aQn}JGI>9RN zGSoDxFzs=X$m6$3gf5HJ2e(~m^LkW+zO6uUivJXPW(kL9$xAV&ZOZ=ji-@nB*bKGIpB+2)y7C zzYL_{)}RF>HxrI;H8nu5kYRJGqe9VnA>IoUO`1M#X-}8^S5*Y&dX_4(3%r+>7TM>)N&* zhoDKDX)QNjYG^Z+4s5tk;7R>mpwfn~is~hE{M76X@}7Tkbdjqd1uLa#eZ?b@PUadB zLDNT2gqJ*N=z_g{f+pS3p+#i!x_8i&7<@i632;OeCKuKN`yCwSF_vOip>^hodNE4P zNpBQS5RePOJp!6NZa`gk=8!uRnt<1FOOW&=tDCwMbX094mS`|2dnlqdYs+_rh7wzX zZMAC`?$g<=w8Fox;7Sx)P~Aj5UEsb_QR$1>C*_=l<`FcpvIpRaC^TwJX-j+?lyb znGfQYBQSMRfa>|DdJr~f?f4%^>*%1;a}QtE)!54mJz>Z!=em9=q} zu}|yOO3te0R{tfo3SX4Odu|Myywa~0;v!OFTO}e7pN2IB4|)8th?5dSysEBD@6TOw z7gC3jdG2+&O)`$z0r!~$w)2B@4ApJ2haV^&aYc*88Fz^J6qeO*cthkI-;#2*IVi`i z6CEyM*tK)_SGp_!n^t9^)uun;Jpym<7?5G{kBLV-mEOb+57;O%ayf@=eC;)SWPO1C zSM?Ltu)dZ4q*GV?M3w)atN%Y(5tw-BIhi=S*#C$6pVG97*%(Istk&zJP#5<%q1%DS zbc`dT(7J)X{ZPJ zW#vZ*MBPzn;vkv%BJu-~7q?T?R?gij_urh7j{|4mBoq#Z)<>bQaN{vas)Xa>B%LGZ zlB=JJVJiOECbs>a5q0OnTX2f!ol2}b{6lkZ6j!?PPyprsJaBNZ>OUgp#P%-HCh?wh z7L_DyfI|MEOQob9htuRPquiAIbF|~u2S+9ereWCqs4dg`;aX1b^W#dcqo?zIZ{)@I zYkC#SX#ytIW~M`o|NFM;zQUui=I507*Vi9DGSe(=Q(c}db_s>;ourr7nvE+T+s!ha z$>AP+w(9|F*WIt^gm8h~9_K-{6n0%BC(9nbY}^Ibp@juQBbxkC2aLEn6YlOIV)}ds zoLPA;K4{_IQA2N`@D<5C18Jgtjp|#kiMT}3ZiMPaqZv4zoHW ziDP$F^SD&4JY+7OXgjGh=R18sSS#+}W*!lQwS;!auYR{ca$>V_BDYfLqUtG{F+uid ziQRt&I3aw*Jjr}@z})SWMGHew;)C`n;QkIH4xRGr1~fvl{shT^GU9i^?Z2Xr-Ujb} zy#&%yKnqdQu#*iU`@sbHDvb}(M{*5Ddz~UW^cNPwwdBPdDW8E6tT{vuML5QlLI4kYb7qK<(&xM>P>*VBO{u!wkm}Q;KmX3 zzDAn31DSzGz&GuPGl`oGui7x=viXQT5E-N>jzbNGdobGXAi390dCipbC`LPIF>JjB z?k9R>g3~~G_c?{o6Xu&&m< zoG)S`A*`Q8rEv@r!42eoG(6u#TX+kWMB;8XQHW-6So}o-Ij!@H@3xX66@j@Q(?Y{f z%tRnmNXYg#?Vn{KL#;SmCNnB|;!McP-e_FH)C(zkl+bis20Vlx3m)>!c&496!~hh3 z=~Ki}_g@(!2u0R;3JpleXTziHMb-U7bP+gdqKT<2Amqf*>Q@9Og*>TNuNlMxp)A1T zoiL8yyRSsDrv!J=V+uHKO9~@r!!=o&but(Pbw>P||2pM8@*IOu2x@I7&T9mc#H}*# zW*5$jh$vus0yXSXEs#wi4fd)DWCLqsYLcoJ8mLJ9+qS&v70YKmx z1q$a~5jwPDD-O3#c=HjGVrT~X|0t;AY{2#NDeeWqiF#AJ(F+<&{xW0KVLyNnea80p zoZ`vD`hg1Z%!v5C8AD3*x;LlCKCbwl0BBAQ%ZI7Pox`wg?Y^3z4uAusa02l5u{6MVTd{NYGe)8-}a6VE}>r zz?%`gtIN=n`a^|}ibdvHTbIcvaQK6yUao>R1TFrkg*jsHFDls)^*breR2;S!K~}O8 z-&yjmI)k>o$$Sie3x++tPqMJW(wqLQ>aiaPVs*@r$jn|v;M&sWEzk|{w6ZM%YS+y{ zkSrQsmL^xD!JmX&?tV3h1UdW;o25_pyp!@qf6(cGaZFFrv*xD6*PMe#cR%mn46?Yr z(qhd@L`4TZZa>lwYCj$?9QHTm>l{E4WeC2bhcSBd)=h?#@jSp6<@)e`9kBEvy{u+- zx;1Bgl{zE#kti=x+M!3-BwDyG$K}F;d&)QMT#pWJb17Mlj#sqy1lht$*oP}PXQP*K zrMlJ1lHP*WEC;Nd^rqcc6EZ%z zN@g)t>md#w^diOtV_Brkya!%wY=JhaiXk`g7&-K)r^(kp&ljvKj-BBeU5YSr5V*@S zI4ww#L3E3XE<;wUOgp|3)Bf5!iTJmA&~;f>vQ^z;HBHu-T0W;JRUlX~&mo+nUdwY} za+RSPMf^LTqNJa=yfU8Z_i25}w!0|q-S8I=@;{zDKJ2|FU3<%HD*Wz0eEE&maM;4c z(m6*cZ;;$!nn~@`p$-Tp64}Duy$+P^BVt+fpc0Y>AAjhm9sayT+^eaA6ETYic|MJS zBRFDZ9OT|b#>VAu#@z)TrU*zbQp4Jk&v@dMVcCyEferYSp~MP z9*ce3g*J@3b&ylDz>cfp6~G~S`I1@fV|`wM``zf9{w}(SKb(4m_?b6IR3Clh-)&rd zs2r3pWr(`!1?BziS)}fnW=JfQ=lY5tXmOFgEzk06Lc4^vNuH_s5 zNQDLRofdB{RhDoe1)h{2acdV%Kj2cKEuj&j${2nr69{gcs5vadQY?Z2Ak`Kv$&-md zie*Zwz(I?1wB)htes3!I7(^d>Px6^g)X0edS^Ry_?A2l1uR>M7h@a>u8B%)d^JtyY z;PSDc3}zI_haYIWR$C8I$l@zi>ke$f8helfQJ_ECbzb&L$R$DYP=xu?(fyd-~Dj(U$lpU&JJ>NFilhCwZ>Jr|yjK!hEG2`l^z%>%5+gRixVK^3`VH+`Nj zpZcv`bRc!T=#**RxcAtLitV~o3)<#zC(cBw4WQML(`rFkq%7}` z`%^l!%YDIFZ#OSPm9MWT6q=~eS=CiUQPtM)orFo|77&EfYq^Y9^MU=TrppS)@lRwQ zUzW1?Vo@(jcR)?q>p1V1d`SDzCcnKs-MB5~#Ip3R6S%)AChwdj%I9R#44K81@#{|` zj!!=m@s@YrcxTykZ5K$PvXE1KFPU*m9ff037}x-GOwX5rjxr%RkZN+_R8F7+(Pp4x zAcxoL7wuj+1&CWYt(t#1v-3`yh?P!mShJZmkP1j!Cx$eof*5!%+1_a{4mOJY$rFCc zM9)c=SsAV~P03U(eAAXC3=$3NaAZ@W0ETDSYPtZ8^(q@Ic7&R%RoMYJJ$Z^EO4M~r zrs19HvMO^;ESINO>k5hGB{WGc8n3a)mLZI=KgArCzF?V}K@X&(Pqb|t4toA1Xn8T* zG4qF8yEk1*9e}fZzRZXy0(l`Ay{ffr^xn!@Js@qRH2U*`6#SbN z#da9sFD#n}dh&6RdUZ8HekGfx`M3LkDXsbMKIPB({^d*lHWXj{*fS{>nw%A-NbkMP zmli&jC7gG-DwT$E($JLjv$>GD7OpdoKc}_-B==3Gu7HH(&X--J*l>u!lmesEsG_zn zd+!H;g3|-=>UpOLrv#RDWg;6RlTTY z7Q2rTXt+#L0sOSw4Z*Nx^LCq4Th({Vwr19hNSeha>k;1`!mrc--GGYp2#d55;3h6c ztQHym(L&qH8mxbUIQKJHb}l66H$1117?TP>9t%6YTM8w7Yw_$NPca4!^BJB0wx*vL zUh!d^U)>A7@nmc=&aA(4lO6;Ock~sWjC8PUKlgiD{HHu!4Q@3PehJlW)WU@ zPN5~bo&*rCr>0}};##h$6Mo$$kq4Iu3a7uj31s<#xZgyOb0j)Q9$)^QL-*i~N)OK) zoX2-OnS3WtFSgY^>4w#4Q+3C62PLk7l=QbB4L+8oNO>hBRk|xDg9vYh!5s~PhdyZN zQy&E$RnOXO$es?N*KPD$P5+dt)OFh}X$y}8Wzr-3>F8$KjZB}eg`9+GwG_SYQZ-$T z)nfj#iuk5h@Lz|+epUIQV&JFCHrS4?M@h%t*I>B>Q|O1$6( zKxs*HM-eSCTm05P9voNlNy-H@6ky_;1omyQ5DPw@O z%`4G>Qmp-S{9?TD#XmJ_{SbP+S082}+N&sM8J@9yf9`nC$3&NaXR0JIeUKSyDi-?9>-B1+117PkLW!!$7|HBBiap#tIP;(X_FG#=>K z^aw?@hodLPFUP*Ji_kU6L-*g}DVWZgOHu#;!0>bZpXYGY{~d)=6!|SIBl17rD-*+L zJHP-V;+C_IpIhq}y%k>sF-xeHYr=*`rQk0<@_Z#lF0dX&z`sL0Bh8i!tMGeN!LT?m zjCx`a$#rq-m`L2gdePM@1q{khrC?K^S%|XEgWDcoa(J9Laf80VugLhGfHx5MUO9ItXGTnytM>F6>p!IH>uVbO$a6Suf&T{Ck1f=1pA8H zNe?ebJ5~!0vdfhfB)_$0DIP!U0WyPg&woJ_fB zDY5#v%@Y}shqDU6_D&`iL=C6x7ySeCRPYR({c_#awuyl}k3jVFbo9=A><|6Kbay;0 z>fB0L`JO}z9|zJyy>wqNzMa53j>I(H(M7h2czdAk=d=Z4L<^qW8J{k5tE_wD0@CZcdhGIWL z*S6bCQW#CR(r)_I~*ebUqf}!SjWgfy&Y3^&c!f89&2iqSGuSlg(rA@xS5ckqU=afU0lIYxfZHb>}s#< zzT_M=V86~`1Km(A(k62=8R%aEP^1_<@vyN;6!hPoi|J&Y@Yd%)<^GK0FW^6Sl2#!5C&Xd&beDSZ(t3@98lY4xR``%=9MhJ z$bik&DfZosi}It}`ss3546K>;xfMc@`kxf;V30GQCH{Fzqb1au25L(w2crAsLGKiF z_oTBuRoA337XDFOy4XaCLjEPHc+9qh2^zXxl#57QNaGO8Dq{8|8lf~iZ?*CZ@OXhIaHX742h&$9;mCnw zXf+5Iz`oh+D>Drul^^Z124?YP6O!!ih+F&LEV_7t`G@z<7d89AApg(*z5lei?HqnA zubu5|{=?>uQnzy2Xhr>``GTTpsVWoAi+Ao|URq4M<8sZ%9C4-T7^}RnBtVL<4Tb;% z*jTyU?|9M)oEu1Jn8e2dUqin*T!Z?4Zfq|8VhjOL|M#*N>GW9N3W8 zqW{8<42#n;97o9V5rVl5FzJ7Av6VAwwq?`dEM!h>=#P?-)vSiTp%UijCM45oB;sz> z`M*_&Z&aV?3&B5LB3BfKkvejq*iw0p6aU;pV2_u>*2J>ladMInQX7mwOyhb6d?T?x zD)a$vOb3!vm@`hNuEwPh?MJDowPJ^7irsZ|<_7h*iK-NFoW&$;qC^YK7!ntSBv<3t3)sL0jvA{lL4&9ANf zHOH%7Ycw z$dGg&=a=S1)Om?XFV*Uw4=yJ?MlHF$kli>pUz6O$u_Spm(&yz$7U3zSrS|($f-w%1 zN42t2C$9LL^lWFt*B~NaVuG`Sm-FM^apB*#-goZMHezOZ)W??RmDb6^ZmE;&$<=8C zr7wi5f}>-yEba^fM5{1Wow)k1#3PF0NsC0ZdTW_3dkx7T9Fc*&00uP8U?JC0LlnzM z*6XK`BEQTt|178?bMl3w&C#*NpsB;wsqIdWCuS|hqRY=WSWjQ~;q5|s0<$8v=(RQ* z-HUTuA5-ME`*YE`RRCkQDOJ-4<

bv_9)poX|YcSRgO{qgj#VA19Q~1ZKol>Vnv% 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 From 9a5df557157fc22ce7047a9d648336826fc153fc Mon Sep 17 00:00:00 2001 From: smulyono Date: Fri, 9 Nov 2012 11:51:14 -0800 Subject: [PATCH 3/9] - fix some new lines problem in Readme --- Readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 01830fb..b898961 100644 --- a/Readme.md +++ b/Readme.md @@ -9,13 +9,15 @@ Requirement: ------------ The application will demonstrate how to create, read, update and delete records in Salesforce.com in bulk using the Bulk API. -###For login and logout operation, utilizing the Beatbox library from https://github.com/superfell/Beatbox +###For login and logout operation, utilizing the Beatbox library from + ###How to Run : $ python crudtest.py ###Video Instruction : -- showing how to use CUD operation + -- show how to do bulk query From 784ba326af71f820127ef1ab39178a818e62d157 Mon Sep 17 00:00:00 2001 From: Jim Clouse Date: Mon, 25 Feb 2013 16:55:36 -0600 Subject: [PATCH 4/9] code is now PEP8 compliant. method level comments were converted to docstring. I also noticed that xmlTramp was imported but not used and commented it out --- pybulk/__init__.py | 374 ++++++++++++++++++++++++--------------------- 1 file changed, 196 insertions(+), 178 deletions(-) diff --git a/pybulk/__init__.py b/pybulk/__init__.py index e9f1288..0edb77e 100644 --- a/pybulk/__init__.py +++ b/pybulk/__init__.py @@ -1,22 +1,21 @@ -''' - -Bulk API implementation +""" +Bulk API implementation For login and logout operation, utilizing the Beatbox library from https://github.com/superfell/Beatbox There are 3 objects included in this file -* Callout --> helper class to initiate GET / POST HTTP methods +* Callout --> helper class to initiate GET / POST HTTP methods * sfBulkJobInfo --> class to holds the Job information. Each jobs can contains multiple batch - Some important methods : - ** createJob --> to create individual job + Some important methods : + ** createJob --> to create individual job ** closeJob --> close the job * sfBulk --> main class to operate the bulk API Some important methods: ** createBatchFrom CSV --> will accepts CSV file as input and divide those into batches based on MAX_RECORDS - ** updateBatchStatus --> shows individual batch information + ** updateBatchStatus --> shows individual batch information Created on Oct 26, 2012 @author: sannymulyono -''' +""" from pprint import pprint from xml.dom.minidom import * import httplib @@ -26,16 +25,16 @@ import urllib import urllib2 -# added beatbox library -beatbox_path = os.path.realpath(os.path.abspath( \ - os.path.join( \ - os.path.split(inspect.getfile(inspect.currentframe()))[0],"beatbox") \ - )) +# added beatbox library +beatbox_path = os.path.realpath(os.path.abspath(os.path.join( + os.path.split(inspect.getfile( + inspect.currentframe()))[0], "beatbox"))) if beatbox_path not in sys.path: - sys.path.insert(0,beatbox_path) + sys.path.insert(0, beatbox_path) import beatbox from beatbox import SoapFaultError -import xmltramp +#import xmltramp + class Callout(object): """ @@ -43,48 +42,48 @@ class Callout(object): """ headerAuth = None sessionid = None - - - def __init__(self, header = {}): - if 'Authorization' in header : - self.headerAuth=header['Authorization'] - - # initiate http call (get / post) along with the data - # @param String url , server url information for the callout destination - # @param String method , "GET" or "POST" - # @param String tdata , data information which will be submitted on the BODY - # @param dict headers , header information - def docall(self,url , method ,tdata = None, headers = None): + + def __init__(self, header={}): + if 'Authorization' in header: + self.headerAuth = header['Authorization'] + + def docall(self, url, method, tdata=None, headers=None): + """ initiate http call (get / post) along with the data + @param String url , server url information for the callout destination + @param String method , "GET" or "POST" + @param String tdata , data information which will be submitted on the BODY + @param dict headers , header information + """ handler = urllib2.HTTPHandler() opener = urllib2.build_opener(handler) if tdata is not None: - if type(tdata) == dict : + if type(tdata) == dict: data = urllib.urlencode(tdata) - else : + else: data = tdata else: data = urllib.urlencode({}) request = urllib2.Request(url, data) - + if headers is not None: for keyh, valueh in headers.iteritems(): request.add_header(keyh, valueh) - request.get_method = lambda : method + request.get_method = lambda: method try: connection = opener.open(request) - except urllib2.HTTPError,e: + except urllib2.HTTPError, e: connection = e pprint(str(e.read())) - + return connection.read() + class sfBulkJobInfo(object): """ - Class to hold jobs information. Every jobs information can holds multiple batches; + Class to hold jobs information. Every jobs information can holds multiple batches each of the batch id are stored in property "batch" - """ - # properties + # properties id = None state = None debug_result = None @@ -94,27 +93,29 @@ class sfBulkJobInfo(object): jobstate = None concurrencyMode = None contentType = None - batch = None - + def __init__(self): self.batch = {} - - # Lookup latest batch state which is stored - # @param String batchId , batch id which is inspected for it's batch status + def findBatchState(self, batchId): + """ Lookup latest batch state which is stored + @param String batchId , batch id which is inspected for it's batch status + """ if batchId in self.batch: return self.batch[batchId] else: return None - - # Creating individual job information. This information will correspondent to single job information in Salesforce + def createJob(self): + """ Creating individual job information. This information will correspondent + to single job information in Salesforce + """ # header root = Document() - jobinfo = root.createElement("jobInfo"); + jobinfo = root.createElement("jobInfo") jobinfo.setAttribute("xmlns", "http://www.force.com/2009/06/asyncapi/dataload") - + # iterate the property ( order is important ) if self.operation is not None: # operation must be in lower case @@ -127,57 +128,59 @@ def createJob(self): jobinfo.appendChid(createxmlNode("externalfieldname", self.externalfieldname)) if self.contentType is not None: jobinfo.appendChild(createxmlNode("contentType", self.contentType)) - + # finally put them all to root document root.appendChild(jobinfo) return root.toxml("utf-8") - - # Close the individual job information + def closeJob(self): + """ Close the individual job information + """ # header root = Document() - jobinfo = root.createElement("jobInfo"); + jobinfo = root.createElement("jobInfo") jobinfo.setAttribute("xmlns", "http://www.force.com/2009/06/asyncapi/dataload") - + # iterate the property ( order is important ) if self.state is not None: # operation must be in lower case jobinfo.appendChild(createxmlNode("state", self.state)) - + # finally put them all to root document root.appendChild(jobinfo) return root.toxml("utf-8") - + + class sfBulk(object): """ Salesforce Bulk API Implementation - Main class to intiate bulk operation. """ # constants CONTENT_TYPE_XML = "application/xml" CONTENT_TYPE_CSV = "text/csv" REQUEST = "request" - RESULT = "result" - BATCH = "batch" - JOB = "job" - USERAGENT= "Python-BulkApiClient/26.0.0" - API_VERSION= "26.0" + RESULT = "result" + BATCH = "batch" + JOB = "job" + USERAGENT = "Python-BulkApiClient/26.0.0" + API_VERSION = "26.0" MAX_RECORDS = 10000 - + # LOGIN CREDENTIALS , CHANGE THIS FOR YOUR ORGANIZATION USERNAME = "PUT YOUR USERNAME HERE" PASSWORD = "PUT YOUR PASSWORD AND SECURITY TOKEN" - + # CONSTANTS FOR XML ELEMENT IDENTIFIER ELEMENT_NODE = 1 TEXT_NODE = 3 - - # standard constructor - # @param String url_instance, url to connect for the bulk operation - # @param String newsession, sessionid which can be use for initial. This property will ALWAYS be overriden - # when you use the login method - def __init__(self, url_instance="https://na9.my.salesforce.com", newsession = None): + + def __init__(self, url_instance="https://na9.my.salesforce.com", newsession=None): + """ standard constructor + @param String url_instance, url to connect for the bulk operation + @param String newsession, sessionid which can be use for initial. This property will ALWAYS be overriden + when you use the login method + """ beatbox.gzipRequest = False self.sf = beatbox._tPartnerNS self.svc = beatbox.Client() @@ -185,13 +188,15 @@ def __init__(self, url_instance="https://na9.my.salesforce.com", newsession = No self.sessionid = newsession self.callClient = None self.sandboxmode = False - - # initiate login to get the session id. Utilize beatbox library - # @param String username (optional), other than using constant USERNAME; the library can also accept username as parameter - # @param String password (optional), other than using constant PASSWORD; the library can also accept username as parameter - def login (self, username=None, password=None): + + def login(self, username=None, password=None): + """ initiate login to get the session id. Utilize beatbox library + @param String username (optional), other than using constant USERNAME; the library can also accept username as parameter + @param String password (optional), other than using constant PASSWORD; the library can also accept username as parameter + """ + # override beatbox server url - if self.sandboxmode : + if self.sandboxmode: self.svc.serverUrl = "https://test.salesforce.com/services/Soap/u/" + self.API_VERSION else: self.svc.serverUrl = "https://login.salesforce.com/services/Soap/u/" + self.API_VERSION @@ -200,41 +205,43 @@ def login (self, username=None, password=None): username = self.USERNAME if password is None: password = self.PASSWORD - - try : - loginResult = self.svc.login(username,password) + + try: + loginResult = self.svc.login(username, password) # update the session self.sessionid = str(loginResult[self.sf.sessionId]) except SoapFaultError, e: sys.exit("unable to continue! -- " + e.faultString) - - # logout user completely + def logout(self): + """ logout user completely """ if self.sessionid is not None: self.svc.logout() self.sessionid = None - - # creating new job - # @param sfBulkJobInfo jobinfo, this parameter will be used to populate the job information + def createJob(self, jobinfo): - resp = self.bulkHttp(self.JOB, - jobinfo.createJob(), - {"Content-Type" : self.CONTENT_TYPE_XML + '; charset=UTF-8'}) + """ creating new job + @param sfBulkJobInfo jobinfo, this parameter will be used to populate the job information + """ + resp = self.bulkHttp(self.JOB, + jobinfo.createJob(), + {"Content-Type": self.CONTENT_TYPE_XML + '; charset=UTF-8'}) # create dict for easier manipulation dict_result = self.parseXMLResult(resp) if "id" in dict_result: self.runningJobId = dict_result["id"] jobinfo.id = dict_result["id"] jobinfo.debug_result = dict_result - print "Job "+ jobinfo.id + " created ..... \n" - - # closing job - # @param sfBulkJobInfo jobinfo, indicate job information which needs to be closed + print "Job " + jobinfo.id + " created ..... \n" + def closeJob(self, jobinfo): - jobinfo.state="Closed" - resp = self.bulkHttp(self.JOB + "/" + jobinfo.id, - jobinfo.closeJob(), - {"Content-Type" : self.CONTENT_TYPE_XML + '; charset=UTF-8'}) + """ closing job + @param sfBulkJobInfo jobinfo, indicate job information which needs to be closed + """ + jobinfo.state = "Closed" + resp = self.bulkHttp(self.JOB + "/" + jobinfo.id, + jobinfo.closeJob(), + {"Content-Type": self.CONTENT_TYPE_XML + '; charset=UTF-8'}) # create dict for easier manipulation dict_result = self.parseXMLResult(resp) if "id" in dict_result: @@ -242,19 +249,20 @@ def closeJob(self, jobinfo): jobinfo.id = dict_result["id"] jobinfo.debug_result = dict_result jobinfo.state = dict_result["state"] - print "Job "+ jobinfo.id + " " + jobinfo.state + "..... \n" - - # create individual batch operation with batchdata (as string) - # @param sfBulkJobInfo jobinfo, job information - # @param String batchdata , information which will be sent (e.g SOQL, CSV lines in string) + print "Job " + jobinfo.id + " " + jobinfo.state + "..... \n" + def createBatch(self, jobinfo, batchdata): + """ create individual batch operation with batchdata (as string) + @param sfBulkJobInfo jobinfo, job information + @param String batchdata , information which will be sent (e.g SOQL, CSV lines in string) + """ if self.runningJobId is None: sys.stderr.write("No running job id is found, inituate runJob first!\n") return False # only CSV is supported - resp = self.bulkHttp(self.JOB + "/" + self.runningJobId + "/" + self.BATCH, - batchdata, - {"Content-Type" : self.CONTENT_TYPE_CSV + '; charset=UTF-8'}) + resp = self.bulkHttp(self.JOB + "/" + self.runningJobId + "/" + self.BATCH, + batchdata, + {"Content-Type": self.CONTENT_TYPE_CSV + '; charset=UTF-8'}) # create dict for easier manipulation dict_result = self.parseXMLResult(resp) if "id" in dict_result: @@ -263,112 +271,118 @@ def createBatch(self, jobinfo, batchdata): return dict_result["id"] else: return "" - - # create batch from csv file, also includes the max_record limitation - # @param sfBulkJobInfo jobinfo , job information - # @param String csvfile , CSV file name to load and will be divided based on the max_record limitation - def createBatchFromCSV(self, jobinfo, cvsfile, maxrecord = None): + + def createBatchFromCSV(self, jobinfo, cvsfile, maxrecord=None): + """ create batch from csv file, also includes the max_record limitation + @param sfBulkJobInfo jobinfo , job information + @param String csvfile , CSV file name to load and will be divided based on the max_record limitation + """ batches_id = [] - if maxrecord is None or \ - maxrecord == '' : + if maxrecord is None or maxrecord == '': maxrecord = self.MAX_RECORDS batches_file = loadFromCSVFile(cvsfile, int(maxrecord)) - for batch_file in batches_file : + for batch_file in batches_file: batchid = self.createBatch(jobinfo, batch_file) batches_id.append(batchid) return batches_id - # update individual batch status - # @param sfBulkJobInfo jobinfo , job information - # @param String batchId , batch id def updateBatchStatus(self, jobinfo, batchId): + """ update individual batch status + @param sfBulkJobInfo jobinfo , job information + @param String batchId , batch id + """ # only CSV is supported - resp = self.bulkHttp(self.JOB + "/" + self.runningJobId + "/" + self.BATCH + "/" + batchId, - None, - {"Content-Type" : self.CONTENT_TYPE_CSV + '; charset=UTF-8'}, - "GET") + resp = self.bulkHttp(self.JOB + "/" + self.runningJobId + "/" + self.BATCH + "/" + batchId, + None, + {"Content-Type": self.CONTENT_TYPE_CSV + '; charset=UTF-8'}, + "GET") # create dict for easier manipulation dict_result = self.parseXMLResult(resp) if "id" in dict_result: if dict_result["id"] in jobinfo.batch: jobinfo.batch[dict_result["id"]] = dict_result["state"] print "Batch " + dict_result["id"] + " ... " + dict_result["state"] - - # show the specific batch result - # @param sfBulkJobInfo jobinfo , job information - # @param String batchId , batch id + def showBatchResult(self, jobinfo, batchId): + """ show the specific batch result + @param sfBulkJobInfo jobinfo , job information + @param String batchId , batch id + """ # only CSV is supported - resp = self.bulkHttp(self.JOB + "/" + self.runningJobId + "/" + self.BATCH + "/" + batchId + "/" + self.RESULT, - None, - {"Content-Type" : self.CONTENT_TYPE_CSV + '; charset=UTF-8'}, - "GET") + resp = self.bulkHttp(self.JOB + "/" + self.runningJobId + "/" + self.BATCH + "/" + batchId + "/" + self.RESULT, + None, + {"Content-Type": self.CONTENT_TYPE_CSV + '; charset=UTF-8'}, + "GET") # create dict for easier manipulation - try : + try: dict_result = self.parseXMLResult(resp) if "result" in dict_result: - resp = self.bulkHttp(self.JOB + "/" + self.runningJobId + "/" + self.BATCH + "/" + batchId + "/" + self.RESULT+ "/" + dict_result["result"], - None, - {"Content-Type" : self.CONTENT_TYPE_CSV + '; charset=UTF-8'}, - "GET") + resp = self.bulkHttp(self.JOB + "/" + self.runningJobId + "/" + self.BATCH + "/" + batchId + "/" + self.RESULT + "/" + dict_result["result"], + None, + {"Content-Type": self.CONTENT_TYPE_CSV + '; charset=UTF-8'}, + "GET") pprint(resp) except Exception, e: - pprint (e) - - # helper methods to transform XML to dict - # @param String raw_xml , XML which is represented in string + pprint(e) + def parseXMLResult(self, raw_xml): + """ helper methods to transform XML to dict + @param String raw_xml , XML which is represented in string + """ # parse the job result retval = {} - + parse_resp = parseString(raw_xml) Root = parse_resp.documentElement - + for child in Root.childNodes: - if child.nodeType == self.ELEMENT_NODE : + if child.nodeType == self.ELEMENT_NODE: retval = self._parseElement(child.childNodes, retval) return retval - - # helper methods to parse each XML Element - # @param XMLElement nodeElement - # @param dict dataval + def _parseElement(self, nodeElement, dataval): + """ helper methods to parse each XML Element + @param XMLElement nodeElement + @param dict dataval + """ if type(nodeElement) == NodeList: - for child in nodeElement : + for child in nodeElement: self._parseElement(child, dataval) return dataval - - if nodeElement.nodeType == self.TEXT_NODE : + + if nodeElement.nodeType == self.TEXT_NODE: dataval[nodeElement.parentNode.nodeName] = nodeElement.nodeValue return dataval - else : + else: if nodeElement.nodeType == self.ELEMENT_NODE: self._parseElement(nodeElement.childNodes, dataval) - - # methods to run http callout to salesforce - # @param String bulkmethod , what kind of bulk request (e.g self.JOB, self.BATCH) - # @param String submitdata , data to be submitted - # @param dict pheaders , HTTP header information - # @param String httpmethods , GET / POST methods to be used in bulk request - def bulkHttp(self, bulkmethod, submitdata = None, pheaders = None, httpmethods="POST"): + + def bulkHttp(self, bulkmethod, submitdata=None, pheaders=None, httpmethods="POST"): + """ methods to run http callout to salesforce + @param String bulkmethod , what kind of bulk request (e.g self.JOB, self.BATCH) + @param String submitdata , data to be submitted + @param dict pheaders , HTTP header information + @param String httpmethods , GET / POST methods to be used in bulk request + """ headers = self.__standardHeaders() # add additional headers or override - if headers is not None : - if type(pheaders) == dict : + if headers is not None: + if type(pheaders) == dict: for keyh, valueh in pheaders.iteritems(): headers[keyh] = valueh - - if self.callClient is None : - if self.sessionid is not None : + + if self.callClient is None: + if self.sessionid is not None: self.callClient = Callout() else: return False - resp = self.callClient.docall( self.__constructBulkUrl(bulkmethod) , httpmethods, submitdata, headers) + resp = self.callClient.docall(self.__constructBulkUrl(bulkmethod), httpmethods, submitdata, headers) return resp - - # will check whether all batches in specific jobinfo record is completed - # @param sfBulkJobInfo jobinfo , job information + def is_jobs_completed(self, jobinfo): + """ will check whether all batches in specific jobinfo record is completed + @param sfBulkJobInfo jobinfo , job information + """ completed = True for batchId in jobinfo.batch: self.updateBatchStatus(jobinfo, batchId) @@ -376,34 +390,38 @@ def is_jobs_completed(self, jobinfo): if jobinfo.findBatchState(batchId) != "Completed": completed = False return completed - - # helper method to create valid bulk operation url - # @param String bulkmethod , what kind of bulk request (e.g self.JOB, self.BATCH) + def __constructBulkUrl(self, bulkmethod): + """ helper method to create valid bulk operation url + @param String bulkmethod , what kind of bulk request (e.g self.JOB, self.BATCH) + """ return self.bulk_server + '/services/async/' + self.API_VERSION + "/" + bulkmethod - - # prepare standard headers information + def __standardHeaders(self): - headersValue = { - "X-SFDC-Session" : self.sessionid, - "Accept" : "application/xml", - "User-Agent" : self.USERAGENT - } + """ prepare standard headers information + """ + headersValue = {"X-SFDC-Session": self.sessionid, + "Accept": "application/xml", + "User-Agent": self.USERAGENT} return headersValue - -# utility to create XML Node Element -# @param string element, XML Node tag -# @param string value , XML node tag value + + def createxmlNode(element, value): + """ utility to create XML Node Element + @param string element, XML Node tag + @param string value , XML node tag value + """ xmls = Element(element) xmls.appendChild(Document().createTextNode(value)) return xmls -# simple utility to load from csv file -# Assumption : first line will be the field name + def loadFromCSVFile(filename, max_count=10000, omit_header=False): + """ simple utility to load from csv file + Assumption : first line will be the field name + """ sane_files = [] - retval= "" + retval = "" linecount = 0 headerLines = "" for line in open(filename): @@ -413,11 +431,11 @@ def loadFromCSVFile(filename, max_count=10000, omit_header=False): headerLines = line linecount = 0 if linecount >= max_count: - linecount = 0 + linecount = 0 sane_files.append(retval) retval = "" retval += headerLines - + if retval != "" and retval != headerLines: sane_files.append(retval) - return sane_files \ No newline at end of file + return sane_files From 4a4c6688b86bab8fec0f4f86caf1ca4c1c314518 Mon Sep 17 00:00:00 2001 From: Jim Clouse Date: Mon, 25 Feb 2013 16:59:58 -0600 Subject: [PATCH 5/9] compiled python file removed. Python will rebuild this at runtime --- pybulk/__init__.pyc | Bin 13103 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 pybulk/__init__.pyc diff --git a/pybulk/__init__.pyc b/pybulk/__init__.pyc deleted file mode 100644 index f215618535731aa33b9b2f748c41c3536204f739..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13103 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 Date: Mon, 25 Feb 2013 17:22:06 -0600 Subject: [PATCH 6/9] logout method removed; this makes PyBulk compatible with the current version of beatbox. In the current version of the Salesforce API, logout is no longer necessary and in fact is not recommended as it may kill other open sessions using the same ID. --- pybulk/__init__.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/pybulk/__init__.py b/pybulk/__init__.py index 0edb77e..20eaf87 100644 --- a/pybulk/__init__.py +++ b/pybulk/__init__.py @@ -1,6 +1,6 @@ """ Bulk API implementation -For login and logout operation, utilizing the Beatbox library from https://github.com/superfell/Beatbox +For login operation, utilizing the Beatbox library from https://github.com/superfell/Beatbox There are 3 objects included in this file * Callout --> helper class to initiate GET / POST HTTP methods @@ -15,6 +15,7 @@ Created on Oct 26, 2012 @author: sannymulyono + """ from pprint import pprint from xml.dom.minidom import * @@ -213,12 +214,6 @@ def login(self, username=None, password=None): except SoapFaultError, e: sys.exit("unable to continue! -- " + e.faultString) - def logout(self): - """ logout user completely """ - if self.sessionid is not None: - self.svc.logout() - self.sessionid = None - def createJob(self, jobinfo): """ creating new job @param sfBulkJobInfo jobinfo, this parameter will be used to populate the job information From 7dfeadc647ec236e54798470df72329120230de9 Mon Sep 17 00:00:00 2001 From: Jim Clouse Date: Mon, 25 Feb 2013 18:45:28 -0600 Subject: [PATCH 7/9] removed references to logout in readme --- Readme.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Readme.md b/Readme.md index b898961..353af3a 100644 --- a/Readme.md +++ b/Readme.md @@ -45,8 +45,6 @@ Instructions to do CRUD Operation batchIds = obb.createBatchFromCSV(jobinfo, "insert_csv.txt") # close the job obb.closeJob(jobinfo) - # logout - obb.logout() ``` ##(U)pdate Operation: @@ -60,7 +58,6 @@ Instructions to do CRUD Operation obb.createJob(jobinfo) batchIds = obb.createBatchFromCSV(jobinfo, "update_csv.txt") obb.closeJob(jobinfo) - obb.logout() ``` ##(D)elete Operation: @@ -74,7 +71,6 @@ Instructions to do CRUD Operation obb.createJob(jobinfo) batchIds = obb.createBatchFromCSV(jobinfo, "delete_csv.txt") obb.closeJob(jobinfo) - obb.logout() ``` ##(R)ead / Query Operation: @@ -90,7 +86,6 @@ Instructions to do CRUD Operation # you can also use SOQL directly using # batchId = obb.createBatch(jobInfo, "Select id, name from Account") obb.closeJob(jobinfo) - obb.logout() ``` ##Another operation included in the library: @@ -115,6 +110,5 @@ Instructions to do CRUD Operation pprint(obb.showBatchResult(jobinfo, batchIds[0])) obb.closeJob(jobinfo) - obb.logout() ``` \ No newline at end of file From 6aafec033697674fcd8a21949f37ff23255c13c3 Mon Sep 17 00:00:00 2001 From: Jim Clouse Date: Mon, 25 Feb 2013 18:47:47 -0600 Subject: [PATCH 8/9] logout method removed from testing code crudtest --- crudtest.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crudtest.py b/crudtest.py index 19cdb2b..ad756f0 100644 --- a/crudtest.py +++ b/crudtest.py @@ -161,8 +161,5 @@ pprint(obb.showBatchResult(jobinfo, batchId)) # close the job - obb.closeJob(jobinfo) - # logout completely - obb.logout() - + obb.closeJob(jobinfo) \ No newline at end of file From 09f179d91de7ede78b143ffd5e9a91ee6d8e6ade Mon Sep 17 00:00:00 2001 From: jordam Date: Tue, 20 Aug 2013 17:45:33 -0700 Subject: [PATCH 9/9] Set up session expiration detection and routine to log back in --- pybulk/__init__.py | 43 ++++++++++++++++++++++++++++++++---- pybulk/beatbox/beatbox.pyc | Bin 26749 -> 27397 bytes pybulk/beatbox/xmltramp.pyc | Bin 16035 -> 16239 bytes 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/pybulk/__init__.py b/pybulk/__init__.py index 20eaf87..38ff8b9 100644 --- a/pybulk/__init__.py +++ b/pybulk/__init__.py @@ -169,13 +169,17 @@ class sfBulk(object): MAX_RECORDS = 10000 # LOGIN CREDENTIALS , CHANGE THIS FOR YOUR ORGANIZATION - USERNAME = "PUT YOUR USERNAME HERE" - PASSWORD = "PUT YOUR PASSWORD AND SECURITY TOKEN" + USERNAME = None#"PUT YOUR USERNAME HERE" + PASSWORD = None#"PUT YOUR PASSWORD AND SECURITY TOKEN" # CONSTANTS FOR XML ELEMENT IDENTIFIER ELEMENT_NODE = 1 TEXT_NODE = 3 + # RE-LOGIN SETTINGS + LOG_BACK_IN = True + LOG_BACK_IN_WAIT_TIME = 60*2 + def __init__(self, url_instance="https://na9.my.salesforce.com", newsession=None): """ standard constructor @param String url_instance, url to connect for the bulk operation @@ -202,10 +206,14 @@ def login(self, username=None, password=None): else: self.svc.serverUrl = "https://login.salesforce.com/services/Soap/u/" + self.API_VERSION - if username is None: + if username is None: username = self.USERNAME + else: + self.USERNAME = username if password is None: password = self.PASSWORD + else: + self.PASSWORD = password try: loginResult = self.svc.login(username, password) @@ -228,6 +236,9 @@ def createJob(self, jobinfo): jobinfo.id = dict_result["id"] jobinfo.debug_result = dict_result print "Job " + jobinfo.id + " created ..... \n" + else: + if self.handle_errors(dict_result): + self.createJob(jobinfo) def closeJob(self, jobinfo): """ closing job @@ -245,6 +256,9 @@ def closeJob(self, jobinfo): jobinfo.debug_result = dict_result jobinfo.state = dict_result["state"] print "Job " + jobinfo.id + " " + jobinfo.state + "..... \n" + else: + if self.handle_errors(dict_result): + self.closeJob(jobinfo) def createBatch(self, jobinfo, batchdata): """ create individual batch operation with batchdata (as string) @@ -265,7 +279,10 @@ def createBatch(self, jobinfo, batchdata): print "Batch " + dict_result["id"] + " status is " + dict_result["state"] + "\n" return dict_result["id"] else: - return "" + if self.handle_errors(dict_result): + return self.closeJob(jobinfo) + else: + return "" def createBatchFromCSV(self, jobinfo, cvsfile, maxrecord=None): """ create batch from csv file, also includes the max_record limitation @@ -297,6 +314,9 @@ def updateBatchStatus(self, jobinfo, batchId): if dict_result["id"] in jobinfo.batch: jobinfo.batch[dict_result["id"]] = dict_result["state"] print "Batch " + dict_result["id"] + " ... " + dict_result["state"] + else: + if self.handle_errors(dict_result): + self.updateBatchStatus(jobinfo, batchId) def showBatchResult(self, jobinfo, batchId): """ show the specific batch result @@ -317,8 +337,13 @@ def showBatchResult(self, jobinfo, batchId): {"Content-Type": self.CONTENT_TYPE_CSV + '; charset=UTF-8'}, "GET") pprint(resp) + else: + if self.handle_errors(dict_result): + self.showBatchResult(jobinfo, batchId) except Exception, e: pprint(e) + if self.handle_errors(dict_result): + self.updateBatchStatus(jobinfo, batchId) def parseXMLResult(self, raw_xml): """ helper methods to transform XML to dict @@ -400,6 +425,16 @@ def __standardHeaders(self): "User-Agent": self.USERAGENT} return headersValue + def handle_errors(self, retdic): + if 'exceptionCode' in retdic: + if retdic['exceptionCode'] == 'InvalidSessionId': + if self.LOG_BACK_IN: + print "INVALID SESSION, SLEEPING AND RETRYING" + time.sleep(self.LOG_BACK_IN_WAIT_TIME) + self.login() + return True + return False + def createxmlNode(element, value): """ utility to create XML Node Element diff --git a/pybulk/beatbox/beatbox.pyc b/pybulk/beatbox/beatbox.pyc index 3ecbd258ca80e593fc39886ae25ae0d75e905cc4..38772c24817daca4af32257862dfe5621b634bab 100644 GIT binary patch delta 4871 zcmb7|?MstU7{*;`KIqi7p7dE|sg+BdE>k01zT`{3PS?`8R$1Ga7zG)huIwlbr-IH!_U z|B8#5jFzo0q|vBtxe*Z&#?xM}-{=dt+E1O#@;UwPHlrm_8vgMAJLXJ~`BGHmDvZua zR9L2T0fQ-eQBtd5nr(?$!Qf$?%<5xrVX!knVJYhS7);5()%S3CD()!;hwES?@pn;p z76oP2s(FsXRcl8vn9e$1dk2G;v~UXwn_c$=OQn%u8r_Y%B*&iz@}v-58)brlP6%9hc?H8ugdr#g&9-8 zlEWL%)v1@kXxfbTY0a?pg9BT^SC*vvw%>-6nJv8&hWqs+7)#IhoL&RAL94H1fR8{J z=F1sp1fqvB!TU-cR}Cky5eYVAeZpWm6;pN>2Geo`vx_m9>aZJYz&gldekb^X(uA*a zN^p<#U9y0OFSikkraqQ)9Wcy$^KOD3w5R6XHzKiYDkRawV3>b4tpP>oV3G<4;Apm3 zSb)Rkq7N8M8ui5jH_=dH2PdTRUhgww9;v0{7)ZiOnGu6YAy77t!Ia!r{tkmF`CLU2 z4u>kfV=!qXRG!CR(wL~+gTscZ5C)TmrMd%yN#jqofQGAP0ZS$ge{C-Ylg5rZT!Z)5 zm4nMn9_spO+(T;Ei^ClaZ!wrOycT@>`HUrAU_#mY81tZ}Lso$Y$#F1wuaGPnm!6O3q zL^}Evlcp_7YY}+8rd#lmdEPOtKpox32QX=>W4}}2QoVHkz>=wsk1l~adfa#&Ea?7* ZYeahlG@f~I4X$e)15btitdQE;{{i`jr;Gpq delta 4316 zcma)nq-A*9Xu46S`JNXreh03NoYgd#g3UX<{L z3=bt{RFb5;7Zr3N9Y7L93__zoDk?I)sPHC|_6WOv{`Wur|L6R@-?ewTe`7ks;@`%g z$dQ(!LBkV$oH-yMz*1Z1vA8{Mv%R+Al)J97+U2&?oo{ftJ+eMoQ*(O#B7l?tb|cuF@ez+{axxT9qxgmpwVUAv z`8ez$hCW3w>fDux+YsujVYzk-Ma`lQMYTv+^>bt!q-q*OFz+&;NJ2J8wIga}(GPe` z$ZgB-A($!VIf4bn-r+G#PQ^k68D0UblaQTpFL+a-+Exa$yIy=CN`72*pO^D3iAk@9 z;#*ir-{q1`s~xf+cL2+IZ2{=ze4sV8Bv$qJywKb)b zPePM1sZIb>{i*G&D}BZt?Mql&DzP)u3&_c_qCjcMN<+}DtPu_) zycY=&Sr$4kP2)g0mdvH}2jI8Heooz$ub(qU|z=`Her>5MxzXXk~|w zoJaS*!JIP?%v$`C!^kwJ1esCQR}u>4@MjF4x={wEQ8(?RJZPfPzoVVJ_VogUnkW6sza$z|KFCgQ|I5F@xxoW$`HEq z$QKTy0#;Q(_adwkF;$l;BcOCgtGrxr{&ah)p>Yp8I>RZ(yKZoZ-*nmq&5Hfl4^EM4 deBn4$9H`jj zKqZmM*O(fJR=l}``8*@>sykUP5bu!9-5g&@P`!zJ2MI2j!&^*Iyp-205vy2q@+BJf>x;axrg9M`w hYtACt=*bhb`iWI6vN=%uz5wy6lWfkC;Oay>Cji~|ANK$N delta 1351 zcmaD~x44#r`78?ti_R{VrqzvfS%|bf&1c*_mX?un!*Xh|i0sv&k-PZsB