pax_global_header00006660000000000000000000000064130602111170014502gustar00rootroot0000000000000052 comment=cba1673f95673a22888dc179dc2a16fb1bc6c858 siridb-connector-2.0.5/000077500000000000000000000000001306021111700147525ustar00rootroot00000000000000siridb-connector-2.0.5/.gitignore000066400000000000000000000001411306021111700167360ustar00rootroot00000000000000__pycache__/ *.pyc *.pyo *.module-cache* .project .pydevproject .idea checklist.txt test/ build/ siridb-connector-2.0.5/ChangeLog000066400000000000000000000011761306021111700165310ustar00rootroot000000000000002017.03.09, Version 2.0.5 (BETA) - Raise Authentication Errors on connect. 2017.02.27, Version 2.0.4 (BETA) - Check for correct types using assert in query method. - Changed timeouts for insert and query method. - Changed callback functions 2016.10.22, Version 2.0.3 (BETA) - Fixed handling authentication errors correctly. (issue #2) 2016.10.21, Version 2.0.2 (BETA) - Added is_closed property to client. - New and closed connections logging is set from info to debug. (issue #1) 2016.10.03, Version 2.0.1 (BETA) - Fixed bug in setup.py - Initial version for communication with SiriDB 2.0.x siridb-connector-2.0.5/LICENSE.txt000066400000000000000000000021021306021111700165700ustar00rootroot00000000000000Copyright (c) 2017 Jeroen van der Heijden / Transceptor Technology Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.siridb-connector-2.0.5/README.md000066400000000000000000000021541306021111700162330ustar00rootroot00000000000000SiriDB - Connector ================== This manual describes how to install and configure SiriDB Connector for Python 3, a self-contained Python driver for communicating with SiriDB servers, and how to use it to develop database applications. Installation ------------ From PyPI (recommend) ``` pip install siridb-connector ``` From source code ``` python setup.py install ``` Example ------- ```python import asyncio from siridb.connector import SiriDBClient async def example(siri): # Start connecting to SiriDB. # .connect() returns a list of all connections referring to the supplied # hostlist. The list can contain exceptions in case a connection could not # be made. await siri.connect() try: resp = await siri.query('show') print(resp) finally: # Close all SiriDB connections. siri.close() siri = SiriDBClient( username='iris', password='siri', dbname='dbtest', hostlist=[('localhost', 9000)], # Multiple connections are supported keepalive=True) loop = asyncio.get_event_loop() loop.run_until_complete(example(siri)) ``` siridb-connector-2.0.5/dist/000077500000000000000000000000001306021111700157155ustar00rootroot00000000000000siridb-connector-2.0.5/dist/siridb-connector-2.0.1.tar.gz000066400000000000000000000214561306021111700227540ustar00rootroot00000000000000_Wdist/siridb-connector-2.0.1.tar=sƱŽfހL(Dᄝ*ŖTINq0y Ռ{2$}Ĵ}Anqi'{nlO!8ϳpp?|<4B(pˁNNwz|k? FHoG/?3GAIw71sZ,aL8k{K*˲e:~6V7ix%~N-ӻ(ۇV]O>ф?h$>хc3RwyLiBwޜpvә"؟|9|ss4&2cXm@dJvD4 q( ~"^4 $WR2G2j'ч # 0`NygG3:#GtcJh H LJNr(Z~֊C%~D!肗VgtH_,+?]aw7l\bqѦ%A+w/)ÿ` ׫x UyٞOiZv'!;ۅX9Bv̓ <9z9[z{<~dw @?.^B<=7/i5#`s4vM|Px8>$OXIF҇?!|oK?KTZn붝y/&&h–zpn9saAǟ[ҭ!$4],'XZi2 Łj}׊&-숨W/dD-Fc vSQzДoxaRh "0n'} ?AѠ|, l6O˅i $!´_~tS\RGTGVz'XEiζ?寻!k=0w_s/mn1ێ+A`?w&k83w:sy|r\[/{?8sa'b=|p8{^) W1 npWregX0t,QC3 x _A^4[5PRjN0ާkUu`]l{}7h4S<;77rAp7jP;!-~k`0?:0kaس VYiP7xQ8LǓ˫32!.#Z[&_baFUv]3Z[,0AR kR3Wĵ{5 'nQX%xߢe&\VW y=On~;r6'q.W0fKzLsϕFz7Ju^LvSmTKwa |w6-0ܴh{+9/mKΣorzRczityap_~9OA_ O:7;If Q8wO.ÿ-FD;+¤q{B^yc tg`'A_$]6&^ԩ8CZׅ;\3aק(fv1Q_{[z ',OV@V)Hm5 ,):/-4/ gBx{9\͆wD@C$Qᲄ'I'W̵PsuW/H= żFT.Wܦ`]ni"=D>VjIVW*hߡ֮gT0Zk?,*NckM#mRͮsQ(Hgc`(Xmt֒ZYGv^6t~E" Of!eIKo ͎G~::.O/,\ءIÔuڼV_L>œ9?;;9O_A*f3 % ?yMiΪ>҈R$ÓŹu._x;.|sʡd9Jg!4%$>{$c8 w *&"j?kk_1Qa~i$H: ^VXU$:WKnJaX/yA3r$ S h7~V# UF7̅x#tS.i-PAb0*y *bDf|Nʉ$\b>ź.[ e)91\\2ބqw>H{r fA:cPҭsx36^"N\FH/?Tg+ʄ6)pt0Cj6B)V;}rd7md2aTEbmMa# K ūSYY)Y>7jlX>Li))rg)?zl]P)JoZpQrhTx$njܟ\iTq.PZBbB X%`L0 5 Ha~ aE8t1ut/b'Qdn\mͮ%G0QwOqcoų0jXS+7CԮ]%"\RWU\w}F509hU7d9S܀!^1Ƀ`FٲVd$EUc$) ~kɴ{SU.H}.[gvOl|v`n\Ws;L&Әa:+*t) F0#%oW36>s$8%?:]#&hP|̭U"Z>84Pc=-UvXZR"!cVq+ƘqW 9vpBLԍtٖ/2y(GiBzoCt4A|~Z3Z7 ni ՘W#j9^;(@T~*9oTG09ì4iD⚓hT WҶfdBog")e##2(>?2!-BXrĭP2d 3ɒX}!iOB.!|UU7A |BwDf5| 5΃[@%h'Gwa@(? I/#Bt.%?̛9)/szB2\aBRT,z9QtL4CռG3GH\ZA$$I薶26/ܮFj^ZYl(1ů)DDJW{gO1' 7'-$U:KS޷ΚNu薌"kѫL[~a|c,O/:ML$>n%e);;Mi+VI|6]/a>ov! 4=vdK3`--O` Q /'sW9 h=I̋M<[+z_h݉0G-޷;p ѝ"YCC6iWT0%+;zq^,o8^OA!w#"weSCZ {R S/:uQG4߹#bJkOgެn[.3w/jhs/|]?ʿFLRK3_/pTat~ڶ T d׾+ŗ!0l)Ͳ{D{<7' N!֪b)53oA7,N:){۴,(`~ԩT^a)0`v%R^U4?nfթ^V-Wv@~A;ΜhnLe7nXmePcƠՖ>+>.kVnsFe¶xs Fb9:W?aULQ9B 2mkjVbW||Gt+g~EһF덮 :^HRrȂMڀk%ٸIlSA X(+eW5mlNwD|hk2XMۢb)9f9el  <`[z|aWGUAF!fXl]gˎXHeLTN+?T eօ^R6";r^f4 *Mp.@j*Ƭq_JN&QFW-MӠj]MÂRB (wZYyfjo-W e^ς> &9oX`F!E2*g=`1k,Z4Qh nw2lmayp0).X q`h|q yw:<>.O?փ].Orzu}r' \хxǍC%nZIm9+j䞍۩̷u-OEmKΟ{Hr ]v8Znr56ðmj;4€k=O,Kոmf!60G۶yoY;.mWOi]Ki4DQ˔I]긟4iYn^K5+6)k-/).7DË h" ?* KQJDЋ+SxTwE*%,1e}9Wv= L| |Ύpt?QuHdBOX㟾 uC A2s E 9Z%$<"Š0):QuaKH4gEMM,ɣΐGph?شȿv&e C~]/ ]5"e׻P?z8ui7~vzm~tVq/J[q a70P466ߪ7awlRo=rsnQmVu$呬"4Eצ\=aڣmߘUVZkF6TX9̴,N]UL." ԝVjKN̴::hh+|Nm՘6e-YcakֱzYɼx6y`6+,%R 2(]ͭv}W{p?d}߀z?ҽ\bPK[@%> O%=,i꼸ʼnwv~IPzϿ]bh,ʧ@5)*7$k$5XCۣ7e9fiK0_@ l˘(T8V[@JdK3/k8[1PRD8T8\ s•JjwnU\[AxV5޸rKs?kHV|qk)Z߻u\$vLW'"QBC]dٕU]1zWoOtߘ+1EڕÚ~\^zPwr,6h.C}|CSaίF?=>>y}bbzPxsOg[0k'  r Oe."L*'WM%~=i|^_5:ֈGƍQBS:U[v U0x= r{=ΉZhs~.J-l1ojTꕶfkr+'[z箙$n>g\[1s\[1\l5?­DʭKn[9;bn~ny)n }vLB櫻~^ڙZ߻55I.l[#|se`yґ;|w$X6qr(ACGt$SmU\!.T it6kVsޕGV6XɻvAܩkŜqCbA(y;8 wq@A!+WPUt63;hre)Vu\Ŋ/Z\S%/ȫ̥!Į_ O;*~‘)25f2.nY[!a̛3;3dۑ^[J*]:[egT܏ܛѬ3F܄!կ{$w҉0geMwl,*R2crؠghJ&<yb)RUl/S=O].q]*͏x.3] چ}ZՓ,.K l['g}z剢g{}ewawTˢ.RI 2HMIQD Tϱ@KDF.|QP_XS{v玗ВO.u-/OLn*([d)m9iau=OY poY["eLPXwk=l uZuA2i4r]\1%9Kv~m?a>-J/L9$ r4+Bˌ!Fo|v: _Zߧ/'&hyi̡1PLK[qX2߬ZLdGZBFMYo !7ݏYQycAxl>QEQuk8eK1O,i _2MY[ B-o̾7(H!WVEwX3Xs0W#h^a+ HޡG][͓:^ō¹yRRaX樻lWI%f$"M|[uT6{tLUa~mMo|SLqSFn os Uhryƻ'" =JKjwN@1NYRƁSulݳ{v=gݳ{v=gݳ{vYsiridb-connector-2.0.5/dist/siridb-connector-2.0.2.tar.gz000066400000000000000000000215471306021111700227560ustar00rootroot00000000000000u Xdist/siridb-connector-2.0.2.tar=sƱŽfހL)D*ᄝ*ŖInq0y Ռ{AV>bژvv f7{( 4AydFc ~P|ޣK?X/ Jݼne0ay}g>\DlO3xQ&8X K}NVڙ./b(^慏~"tIR?]'d<&d|d@OA `;R>gtF3Ɣb\d^*CQ9J4oC%/ 5zsG\b~x>"@o =ظpMK0<u 5_yzT g{?z՝o@??Sb>A8_?$ݚ?woMOw`x8z;O\EqJ?!|o+?+TZn붝y-&i̖jpn9saAǟ[ҭ!4Y/RXN{?j3Uif5ZQ' _~Z/&tp+F'A@2K"kM,BN0'yd2!z{6ͩED~ğxz0 +Mi+#[T,|{ąω>@DebynP4($]I:y§´yEw;&/EB?;Z/*5xTG:xTayel[^ ֳX_N4Zy 9t;_n:Lp?bg`c`t;&Ru䪹W/{?8vI_az*zM=x_ GKAPvzUCz&xh\ME5WW89VokĴL뜭woOG;濺lGïϿP mIh oǞINEҝF1{4L˸uȷWbXkQ,@d׌ }sDtT&5̕8qF cƉ[o%1>޷(j Wh^kbEǣN;ἜE\ĕ>LYsڍ΋81Uf>LD Sn{iFKXyih]r|  O{LOq:흮t"@7<߻ߞ,?`;G{H?:A?]Ǔ<¼oK$8ʭ0i"zܞ!Oydw,$G_^{/OOήkjf&# ƀltHCm#wn([KJҸCm,)ƼTE ̎@ն$2܈ry@PBL`(I۷fSˠx{#{N93Jb.e`&5t#)B+/$eB?L ,!e-<]5v[jbaA 'gQhTKIgT*;c;: s_7 G)c@?+9R\Bh; KTO:5Tm@&VwENyV"Q#ķ-mn! ;c1ٯjNS&J>: 3㘤!X8twSi73l[[$oyyZƨ \9?yx;&@\Rvc󻣿L]ϡ7?q]'SLŚ _R?vc}@u;8lOrY} qhw zQxi] r3x!:F1o;?F>?=NQOFYM_0 6jY9_St$^@[h^ ΢6sN ΏHe O8Kak!S=uW/H<,yr\+?MrXz:$}{꡽xSƭv7UοC]Ϩza1ZXT:^Ӎ֚8&+GjM%4͋] QƚP020%RLqa؏[ux]% )0>a%w >8 `:go%i$=tĿ03;^ڻ<}urM>,D,4'v #( 6` $,έuo'Ё§? HI)At$gbLʀ E8dIAA׌|`"c1N}<|;&*amh NbF%70T9MQ h7~V!b UFi@_1RMdx䯢SeSx Si3҈5'39 7mȄ4a=8DRP\Gkd}!_3!-BXrĭPRd 3ɒX}!iOB.!|UU7Ao lBwDf5|5΃[@%h'Gwa@(? Q/#Bt.%g͜A9H,m^:}sԺܐ}  R7ɺ0VzinEqWbpGaP&JJnQm {m]! :VC;X %bzk[Džݬ\!؆ĸەf,TYȓnp>z;kיIJ/V2uӽ~ZyP̺k1\6VsZ)]Ϊvj~SnDN`J[ t[$ZTaPxhEtUєkH *)4,(%<h"< ]:١uhq=.&Tjӄư6o%wPSmklkT+C<8PLJm-T)%*ʏۣ*~6sote#ZEiMC֦0wh Ѷ*+ k4Y!e,fZpR Y.RDo'?(ݫdYC{k_T2Ê&\xgg'GF`Y==Y6"IQ)&YRf瘥G/^=M)w|;,|{}ſ|] >0_ l˘(T8V[ @JdK3/+8[1P RD`^*qO~`dpWn)5;*-kqKHoRJwn=n ݒ/n%E]{.ɚ{A"ҐeW6YveeW㓫+]7&cJLv%ﰢDeO./WW(CG;9P} f4R_P}}q~_~D2G(PTسk)OO#D_`x<W*ayS XUUvr4-n[3Iܒ/}θ dd4j0\[6\[:;tNwnr7n stS &έ6nW~^ʙZ߻%55I.2a<盋, s+O˔Cq : 'nh*@/yȭM\@5AOpy"N.]a_-cpC$=p*r]tݒHDi*bpL);Em{"J~ŧ f5mz`E_&B./20^Z?|, yؘ|'6.H1hF':}KJvi?3An/D)RjE& bTV ōK^5hXB[cuzBz/lf K W}5kSW6erhvPHV#mJUk>UiުzrO6smQs 5oX?h;ԩCa)HtcLq>[]DJy֡k>ۑ^[J]:Uۭ{u*GQMi s}x-nBv@u=\~"geMwl,TPU[ c]64xF6?ț5Ef !+$em$mBɋd+]ɝg4K#B5;XbvYZDvVYzuuJ73#o.zJj p.v}]QN+]el@#DzU>!  [S+qgP?*DFe.liL)]&(O Fp*O % B6QP_XS|%x/1^鐹^fCKvEG@O0-p"L0Čoy@?g7-mmʧrgs7&x8VvH$d=_7GAnH20폼1Sf G`<6"IlCp <la8晕-!Ká)kse>U%g i RUUһW:VH9|M6Ss8WrtfT.yl]%FD߫'5IfcJ+.}s4lzSLk -3n7c] vG`9v⪅.4U.[R?ūD\= _E$~M;`TԷ^^ #N7g oʔMWX!8}yd''%eW\-C~|S❱rt((B2%r0 jNnb^$ELU{%֜ ]0ԘjuKwTsEe s(vd7WH6ore}?m3A,!Y,7Qg{Ӥ8lܔQ<6[*:-xrƿ'" ]RK:*wND1YfցSuK{v=gݳ{v=gݳ{vDsiridb-connector-2.0.5/dist/siridb-connector-2.0.3.tar.gz000066400000000000000000000217141306021111700227530ustar00rootroot00000000000000 Xdist/siridb-connector-2.0.3.tar=ksF_1+YC6)bK$' r(!&.Z֦߯{`,+Qb=====IYtFޠ?{̧F=|`^={g~Lȳ_"<_]y;n٣ρz9 `2(ɶ~wQZI, xA?e^ANr&! '{[@8QȲB |2es:'9tcFh Pd^:>@QJ&kEΠ? rytBsvޜMVXl=;ķ[m]bm py_=2Zw~LUp'4ݬ^`y ;gEdJ._>xA9]orɇЋcR~8vMKi>? ;?]i?`7zS/h%nF{D큗ْSkG\vXaJdLaXZa`uign#_߷#N^~jFt:˜Wnq] yY|RPNynBP?E_ݵ ˟`MԙOn;~D?2 zk|QJMHX[CR20_A1O ,)]Z('X A<2@ =m,h5!ίX.KӇ6TS+=,a 9wS+ k~TIt$uotȯ?{Y4|jw|U,5xPJ?Ԩ;2<G쳗}Sh>Fkok|7>a4ww?w?ng˳7GǗͥz_n9m}p? RS>\2q\g <>ZyڟU.2MJ3Pi+ .fѲ:WW%89VE.5g2'5cMӺl^<6lo{;N濺/vL`7m$ q0)?O0y4X&YSWhQQL˓S2%.#,&]o%ַȪ쏻GUZ40'8uMKgĩk4jN^A*b3 !+?~MIF>ˆb>2H H7Oͺprzxtu1t`s->9AJ%4%8>{8e f(\CUL0Dy0{MVxQk=t|G !0fQ#C|dܲ_ kCHtmsU( E'/]3SwIϺAU"Z>8TPc=42=,Lx1+cB):p&&<OF:o,P#E6%7 8P{,vZ4ZW1ni ՄW#J\;@9T~&)oDGP9QT"qTN}4*+[343MX )PI\kd0&.BXrحR.d 5jg|!iи嫑C.C9HUMm;#K6! 1{ϣ(o 3_C1I 4DTtC$`f' 3wu(l̚9-."9H<T.ްj &e)* (:&h#5A*g\eus$Q mi-4dDt^]JG ļ6nb]SҩxL9 =5f9l>a ]ewjBN;Zo*5DqgjP9sA+q)-Wh򼥳lr5&S^#šQ{ _6\XT3: sEtdesbF,E'`b\$iy S[H])MJ-HHh޵HwY@|[+/V#$_O"@հ`TnPS4D;)fYLn%਷k@ B6&1Kvu -,e906qB=:S@7 Ke;o#v\BJEG.w35Y:ara:zsrşQF7_cCJ5Lϕ2YrbvQ1xiٵqÈ_JYS{稁\ōde$q۟C||*E _`-,ςb fe@ M bW )5ZqIk6vo9lr{S)`T;¢s43vC,f5f nD+&3x4oߘ;2gFEOqeΨ(SV]@&jY?;m8O8w#C;͎cȻ3d󋳫3G7vrzy7jwq:/p~r]I'ׇ˶b?4v,7o6*M,d"V>o2۲΋WP[>Qfr X-A!#ʅz0$wQTkؼnök]L] 뭟i 5ͪqLQ6 c mSvd]X3+7p ɓqhڲݼrl+Vl_R-o *//7AXD?J  QJx KSxT=D %R2}U)tL|YB;;"X9= ?Ic6V-q.K"N-*T3枃hX¤¼plwFej0(}Fay87FUGF]16 Sbʌ¸<4c6>i;DNsRĂ<ʫ υ,[pm,=g69Y6djuC[(2pU8xCE { ]&X7ndưv0mCⶁuou塨llnbVOE0jԢkwʫ\u$IVl#p耵qG6 @C{n;JZ+V0f Keש u(2 dI9|ЦKޜ̴Uy'潵&Xl,9UU۔٩j_+Uk͵RmFͽ5 6mD|13)Ȝt9*>qVokW9~o Tr{F I|l?.Wpm f[\&DJDZr<_˳ խxάbE8|'ǹ:(WDk~rK%Xq/n n\["b-|s1'5(tKRJn5z]{.Ɇ[9 RhK/KQ ء^.%U{W{}gg_ԏ&% ylO{zv : Ws08],29SC5 fH@ | ,`yT"bd¡xrٔWFϗ =2jLW{SG;N58VZPnyWgVNyګs(_9QۜR77TꥶNF5?-|sk&[猫pKfk|qKk|qM?e5?s-|sK[-V0מm2ܪd$t+Ry'3յ~wKk|b\ E7YP[!wW(eӝ 44DdbwGuYF.7luHr+lPSs<wusWX6ѱWKhQ#\\]gE@$oL,SaJdC#iE׿f^҄_讃9z ,ix[:H}ci=oe̫&DӒ8"΢9t]R27uK_qߛb' `#(U¥;MupCs-|DEBimAIoc y̍EyJQW4}Y5-mwyon]TʵbΣqCQ7av6?|K^`Pʳ9/^A9DT'?H79<zb_B#*Ҷ6.mglT a"4uPV$2ABFOa͍66+z+8,ysFvgg(\m-4ւ;]4DtySYTz^7n֠Y*ʫbꆃfYj52,f3X_@9]Vɍ+qCU #[UX> j+iT=Vyχ>ϑ>ÈԼa0Cg 5g|"E&1퇀.Fjoqwj+![2}8lGz]*vPmFՉC7Y'Tg፸ Cj{ u҉e (gQة@BC`=JW-Qh{fm~*U+<]v*}JWT*a *=.6#LS5:IVa :{ciEj'v3 ,!Ysc;I-ĉȉzƓre=%A 5fGЧqxY!K{p_& k1 Z7nTUR/XK;%rהӔ~;(!Skr3\3,UY/m.fjQn3[.uzc>xNNqGW>_t;G'''c(99&N/~ irUD'ß~{stRٓ¿uk ~?K֠>Q{^W¿;5?`;rƠ8ڟdFdM€ Jdx6aqp]2 N"C#X, ȌF2S|"tzpm:0_(?/\TX@OhpyH{I8 D|\ע@i&$bYQpw,Kn;X( ²#Qyk/8ӥrr c6́x~<{қ,)2ӌx~27bW^[$p-h4k"~q(4Mo4j4i3fZm`c/[l:csPm&2xa8TWtfUL9T.,T 4hEk[Ojc;tl=V?jX`miS%q$'UQ3af19{m$!-܌"2Hh P7-O@$s6a'9AJKB`IgKJp|ENC!),z,0:`>_&"g||X$+ <~0ad%.4"ՄN=Xy/Y/wzMaZCbAf9#XT݈q&IL; -OԦBPDsʬh;͙f OY[& ,N!XJ>%#X55s c=Fěp8 {ѥM(>,0Er・?#0H|O~(oT"`B|q tJ5-of ;oAt ;k UD*3ɖD `9Py@İLxn6r! h- eɍ11X5qD+ߓf x eXWf > 8A'\/?4 M61mS CkhJLE\:ɝ!Ik6"q0+oD8e16q&R( 9{!pF3˧٤6K@~'K`o(]1CT6,HNK MAZŝ0F:f}hW5oaiجb]㑋=`p'~r\qTq.gSi;6 ȵŘ,VX\׀\I8/@o@^" c#Ԑ0t1rj_PHZ.v)t[M1{ǧei{tfkzZ U&?6|=tY…wR .JUB Z 6 u7l  (ebY)HdASCy$6dh觩fϻy@8dȀRFq ?{ eMNQ 4@XFƓEqH|岺9*t),< "%mΏ#6? A@:bO{_$fgKMѡ+WkD Z>94Pc#M-R;,[B?-a]Sv _"u+/HXt!P7y[*d"!鴿i ,~KELI@պhKT>AO1$G&um!/SEļ5SxSir0҈Dlt*+i[303.RZ|86^Q|͘DA嶜rحPd 3,iʴU-pH9 iJȟF .;a|UMhmA7o")AwZ$J|-B ߇G{A!!>P ~GFRC y3y1(>Xpt H R[0)KU!0zBh`y|kTtA+W\)R`~V4FD^ f^ZQͬ,ģfj^ڈY:MK6f̚h<%wfx;(r(aРpȤ~h$u@oX AhiVmU#%ȹ,d}%X™BcdbQ ơʽ`7Q$ [ԿG>F-]~Al7?#싎0(b'F$VWȹZڑ99ǻ6f#j6UM oG! hUn`)p<hNʚ&`2/u_\Aon(s@ em0>tipjjGLQЂFw)4 5x T/ƩP_g HecDcތN6wj0:>pK­yT9q F4h3opNYl۷L3heÝwoN}F,ŨPBr0Y h'6qij.> tm׸6? ge]NPq D/[I~ FKوdsѲѵ MG3P0Kls*`,ꃚC$jڷӾ|TKU\zL|3] x'e'*o"'Z)t3{NZoCe̕B#N-,QǺ)_ ^0 |Qb'ieuIiꊩeX:F!b9:z w}L=@d$*ioIgbMMXbjyHX8 @b[>yXpvl*K?[8,K7d_JN{G6Sx#?aDY+:IK; ܕ𩑯HedP.I@18meVvQ;/1lpiד`:;r*bLW ƹ"ϖ*3e-/0!M;#1R0l]DwʷR5SzgmD S0

5l˪鼸ɼxy^U_#onƯF[{M)X訁ߺf}Wm1ViŨSkg t }|~O g~pWW/3Gk(c!t v`͇N5gtEާ(-gICj.n98;=<,yۧZYG<9:}9Q]%obA}^L\9W/.߳o \t d-1  rm/iJ=N"bi /S~/r "5d{^y\KQ" X'C"~NqCM=^`djGդ1i$bԆ֧vML6O*~MDt&t쯅,c0l{|)_PfS\'Y . ix(-1*l4uJIEl62`&W~bg RfZ4vxvnB-=n\H:g%3oZ0ay/z qhbcam53Ym?aZ6s[thZc?0EE]8LS,z${J{C?>> ߰<'%jm^GQ*juCq{2r4/6S#B 1ƿcaWBJF|mULuB9|M:քH?ْ|yݘǺY2&v+y:@-tY%lowjb:5EOa̎]=i-YrtS\L=Ȇp FM@=^v^(+",_P6 "ZϽyf "ؚU(ȮNI;p K-@MDX,("ٱHټaU0. Q1otrCle25.r ߒTftiI9r:,T_2CA)MVU%ɯ22UsJlIc\v>l(]qTU-=A)-d&W4qpϥ 1rI/^d!1ƻ"u#"U=<(OOuxœBzV\cÙGL7wJM>V>b:zt?(m+"+b nM:`̊[U'bHq;o!7UW BӐq x敻89W͉ll? ۋNVur7:[vjODb$fAMV}jn@M4:HV !Lr]r\6ۜOx- ̇m耨ndzmR]$vזe!rzڦ1[`H&+m^J^6&o見ƵjcKG|=JXZa~*(x<~4A~uqsgAq*?^TKZ̔V)v\IS !NS K !b zX^Oc;xGMOBCk4QCѸYZ@0y|yuy"?]nAT:5bX5Bs`3Ȉhb)/.Sýw cs g4o'o-_}5~q4ac[Bƪ YDƉ-/+K 2Xl|{1P^XJiqx圏˃5_ps6-kq !޹s? t ur.2Hb䤘D:/Yy4 $=.9/HAw䘩-%뾓'/v؎SZ%NI?9б'm 2X>P,^穚#ϣj?ځ cQ䦕|W+ҟi "AX4&}dhZ-5 OV*+%,\t,jJIY5 {C4 ޞFKz:#%}L٘lXXbPʟp7cdCKB#L.;+ě;Pv쿭uU63攈h@U.zyPJSaj-{([=EôiK )8s͊9fxI7mm2c]GrntLCDC5'=4t4D|{ l Rp~azbg\).\,볬8 ?Nh4暳X!G2{#j[&8.)y#nH '[0m>HfW[3f<˻^lP\XF/R.>~۬5"3>XuhY pσ2P#/DWC+b8Is,ΎQ<&*_/&#B"XHr1{Q7=fhOS(;4'_B?hs}Gqi=H;*jtB*ƫUivV7XjvQP[Ψ_+:hg57r@#^WއF'9`k4/^̎D[7ƴd9%w#>< ;smMD7h=455Y3wLSϧfqQvRrURuJE;&iaj^IFVm>~YW*a֫-?YXG (* Ca^$ d|j=yUYrN!>;ŖLzzOh.3,7UbZNDw]Y-[ڻ[Ӆw톓׀` ,ǟs T3B.V垉캄?@?vO<ĔzI;bu-ƚW?CہYvݚp7Ӭml@A츧[RR=B):$.\0vT»oA٥7 c΢QSݶp5Ӭ*+?x-{ %)]BBKvfM`YoK]Zb6"(.N޾qBR}n~d=h+aA(wf(p\+R}" :p;S RAKsz  8vg]8!qc~˝RwL9{Ex \N)LX.aB(UhyTfcwy(Q@n(݌"os7(CACWȊO1wjGS=iwZ]cx>=J9'G'yެh⡣-(46N۫㼡o['?>eG>G=s95q ?@?{ W{>qM<|HM ?*|;h<3__*:y)rΊ~g58bjک>Ωܩ:)&?kg'*)5kh0ݎ~.( bI/{܇a']biʹ41URL-[!Ԣ0FSK,Dg}+ Z-'m?\pSofm>+nRWWBRsiridb-connector-2.0.5/setup.cfg000066400000000000000000000000471306021111700165740ustar00rootroot00000000000000[metadata] description-file = README.mdsiridb-connector-2.0.5/setup.py000066400000000000000000000022621306021111700164660ustar00rootroot00000000000000from distutils.core import setup import setuptools VERSION = '2.0.5' setup( name='siridb-connector', packages=[ 'siridb', 'siridb.connector', 'siridb.connector.lib'], version=VERSION, description='SiriDB Connector', author='Jeroen van der Heijden', author_email='jeroen@transceptor.technology', url='https://github.com/transceptor-technology/siridb-connector', download_url= 'https://github.com/transceptor-technology/' 'siridb-connector/tarball/{}'.format(VERSION), keywords=['siridb', 'connector', 'database', 'client'], classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Other Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3 :: Only', 'Topic :: Database', 'Topic :: Software Development' ], install_requires=['qpack'] ) siridb-connector-2.0.5/siridb/000077500000000000000000000000001306021111700162265ustar00rootroot00000000000000siridb-connector-2.0.5/siridb/__init__.py000066400000000000000000000000001306021111700203250ustar00rootroot00000000000000siridb-connector-2.0.5/siridb/connector/000077500000000000000000000000001306021111700202205ustar00rootroot00000000000000siridb-connector-2.0.5/siridb/connector/__init__.py000066400000000000000000000043661306021111700223420ustar00rootroot00000000000000import os import sys import asyncio from .lib.protocol import _SiriDBProtocol from .lib.protocol import _SiriDBInfoProtocol from .lib.connection import SiriDBConnection from .lib.defaults import DEFAULT_CLIENT_PORT from .lib.client import SiriDBClient __version_info__ = (2, 0, 5) __version__ = '.'.join(map(str, __version_info__)) __maintainer__ = 'Jeroen van der Heijden' __email__ = 'jeroen@transceptor.technology' __all__ = [ 'async_connect', 'async_server_info', 'connect', 'SiriDBClient', 'SiriDBProtocol', ] class SiriDBProtocol(_SiriDBProtocol): def on_connection_made(self): pass def on_authenticated(self): pass def on_connection_lost(self, exc): pass def connect(username, password, dbname, host='127.0.0.1', port=DEFAULT_CLIENT_PORT, loop=None, timeout=10, protocol=SiriDBProtocol): return SiriDBConnection( username, password, dbname, host=host, port=port, loop=loop, timeout=timeout, protocol=protocol) async def async_connect(username, password, dbname, host='127.0.0.1', port=DEFAULT_CLIENT_PORT, loop=None, timeout=10, keepalive=False, protocol=SiriDBProtocol): connection = SiriDBAsyncConnection() await connection.connect( username, password, dbname, host=host, port=port, loop=loop, timeout=timeout, keepalive=keepalive, protocol=protocol) return connection async def async_server_info(host='127.0.0.1', port=DEFAULT_CLIENT_PORT, loop=None, timeout=10): loop = loop or asyncio.get_event_loop() client = loop.create_connection( lambda: _SiriDBInfoProtocol(None, None, None), host=host, port=port) transport, protocol = \ await asyncio.wait_for(client, timeout=timeout) result = await protocol.future transport.close() return result siridb-connector-2.0.5/siridb/connector/lib/000077500000000000000000000000001306021111700207665ustar00rootroot00000000000000siridb-connector-2.0.5/siridb/connector/lib/__init__.py000066400000000000000000000002041306021111700230730ustar00rootroot00000000000000'''SiriDB Connector - Communication with SiriDB :copyright: 2017, Jeroen van der Heijden (Transceptor Technology) :license: MIT '''siridb-connector-2.0.5/siridb/connector/lib/client.py000066400000000000000000000263211306021111700226220ustar00rootroot00000000000000'''SiriDB Client SiriDB Client for python => 3.5 using asyncio. :copyright: 2016, Jeroen van der Heijden (Transceptor Technology) ''' import asyncio import functools import logging import random from .protocol import _SiriDBProtocol from .connection import SiriDBAsyncConnection from .exceptions import AuthenticationError from .exceptions import ServerError from .exceptions import PoolError class _SiriDBClientProtocol(_SiriDBProtocol): _is_available = False def __init__(self, *args, trigger_connect, inactive_time): super().__init__(*args) self._trigger_connect = trigger_connect self._inactive_time = inactive_time def on_authenticated(self): self._is_available = True def on_connection_lost(self, exc): self._is_available = False self._trigger_connect() def set_available(self): if self._connected: self._is_available = True def set_not_available(self, loop): if self._is_available: self._is_available = False loop.call_later(self._inactive_time, self.set_available) # never wait more than x seconds before trying to connect again DEFAULT_MAX_WAIT_RETRY = 90 # default timeout used while connecting to a SiriDB server DEFAULT_CONNECT_TIMEOUT = 10 # when a SiriDB server is marked as inactive, wait x seconds before releasing # the inactive status. DEFAULT_INACTIVE_TIME = 30 class SiriDBClient: ''' Exception handling: - InsertError (can only be raised when using the insert() method) Make sure the data is correct because this only happens when SiriDB could not process the request. Its likely to fail again on a retry. - QueryError (can only be raised when using the query() method) Make sure the query is correct because this only happens when SiriDB could not process the query. Its likely to fail again. - PoolError SiriDB has no online server for at least one required pool Try again later after some reasonable delay. - AuthenticationError Raised when credentials are invalid or insufficient - IndexError Raised when the database does not exist (anymore) - TypeError Raised when an unknown package is received. (might be caused by running a different SiriDB version) - RuntimeError Raised when a general error message is received. This should not happen unless a new bug is discovered. - OverflowError (can only be raised when using the insert() method) Raise when integer values cannot not be packed due to an overflow error. (integer values should be signed and not more than 63 bits) - UserAuthError The user as no rights to perform the insert or query. ''' def __init__(self, username, password, dbname, hostlist, loop=None, keepalive=True, timeout=DEFAULT_CONNECT_TIMEOUT, inactive_time=DEFAULT_INACTIVE_TIME, max_wait_retry=DEFAULT_MAX_WAIT_RETRY): '''Initialize. Arguments: username: User with permissions to use the database. password: Password for the given username. dbname: Name of the database. hostlist: List with SiriDB servers. (all servers or a subset of servers can be in this list.) Example: [ ('server1.local', 9000, {'weight': 3}), ('server2.local', 9000), ('backup1.local', 9000, {'backup': True}) ] Each server should at least has a hostname and port number. Optionally you can provide a dictionary with extra options. Available Options: - weight : Should be a value between 1 and 9. A higher value gives the server more weight so it will be more likely chosen. (default 1) - backup : Should be either True or False. When True the server will be marked as backup server and will only be chosen if no other server is available. (default: False) Keyword arguments: loop: Asyncio loop. When None the default event loop will be used. keepalive: SiriDB Version >= 0.9.35 supporting keep-alive packages timeout: Timeout used when reconnecting to a SiriDB server. inactive_time: When a server is temporary not available, for example the server could be paused, we mark the server inactive for x seconds. max_wait_retry: When the reconnect loop starts, we try to reconnect in a seconds, then 2 seconds, 4, 8 and so on until max_wait_retry is reached and then use this value to retry again. ''' self._username = username self._password = password self._dbname = dbname self._connection_pool = [] self._keepalive = keepalive for host, port, *config in hostlist: config = config.pop() if config else {} client = SiriDBAsyncConnection() client.host = host client.port = port client.is_backup = config.get('backup', False) client.weight = config.get('weight', 1) assert 0 < client.weight < 10, \ 'weight should be value between 1 and 9' for _ in range(client.weight): self._connection_pool.append(client) self._connections = set(self._connection_pool) self._loop = loop or asyncio.get_event_loop() self._timeout = timeout self._connect_task = None self._max_wait_retry = max_wait_retry self._protocol = \ functools.partial(_SiriDBClientProtocol, trigger_connect=self._trigger_connect, inactive_time=inactive_time) @property def is_closed(self): '''Can be used to check if close() has been called.''' return not self._retry_connect @staticmethod def _log_connect_result(result): for r in result: if r: logging.error(r) async def connect(self, timeout=None): self._retry_connect = True result = await self._connect(timeout) if result and set(result) - {None} and self._connect_task is None: self._connect_task = asyncio.ensure_future(self._connect_loop()) return result def close(self): self._retry_connect = False if self._connect_task is not None: self._connect_task.cancel() self._connect_task = None for connection in self._connections: if connection.connected: connection.close() async def insert(self, data, timeout=300): while True: connection = self._get_random_connection() try: result = await connection.insert(data, timeout) except (ConnectionError, ServerError) as e: logging.debug('Insert failed with error {!r}, trying another ' 'server if one is available...'.format(e)) if connection._protocol: connection._protocol.set_not_available(self._loop) else: return result async def query(self, query, time_precision=None, timeout=60): assert isinstance(query, (str, bytes)), \ 'query should be of type str, unicode or bytes' assert time_precision is None or isinstance(time_precision, int), \ 'time_precision should be None or an int type.' try_unavailable = True while True: connection = self._get_random_connection(try_unavailable) try: result = await connection.query(query, time_precision=time_precision, timeout=timeout) except (ConnectionError, ServerError) as e: logging.debug('Query failed with error {!r}, trying another ' 'server if one is available...'.format(e)) if connection._protocol: connection._protocol.set_not_available(self._loop) else: return result # only try unavailable once try_unavailable = False async def _connect(self, timeout=None): tasks = [ connection.connect( self._username, self._password, self._dbname, host=connection.host, port=connection.port, loop=self._loop, keepalive=self._keepalive, timeout=timeout or self._timeout, protocol=self._protocol) for connection in self._connections if not connection.connected] if not tasks: return logging.debug('Trying to connect to {} servers...' .format(len(tasks))) result = await asyncio.gather(*tasks, return_exceptions=True) self._log_connect_result(result) return result async def _connect_loop(self): sleep = 1 try: while [connection for connection in self._connections if not connection.connected]: logging.debug('Reconnecting in {} seconds...'.format(sleep)) await asyncio.sleep(sleep) if self._connect_task is None: break await self._connect() if self._connect_task is None: break sleep = min(sleep * 2, self._max_wait_retry) except asyncio.CancelledError: pass finally: self._connect_task = None def _trigger_connect(self): if self._retry_connect and self._connect_task is None: self._connect_task = asyncio.ensure_future(self._connect_loop()) def _get_random_connection(self, try_unavailable=False): available = \ [connection for connection in self._connection_pool if connection._protocol and connection._protocol._is_available] non_backups = \ [connection for connection in available if not connection.is_backup] if non_backups: return random.choice(non_backups) if available: return random.choice(available) if try_unavailable: connections = \ [connection for connection in self._connection_pool if connection.connected] if connections: return random.choice(connections) raise PoolError('No available connections found') siridb-connector-2.0.5/siridb/connector/lib/connection.py000066400000000000000000000137371306021111700235120ustar00rootroot00000000000000import asyncio import time import logging from .defaults import DEFAULT_CLIENT_PORT from .protocol import _SiriDBProtocol from .protomap import CPROTO_REQ_QUERY from .protomap import CPROTO_REQ_INSERT from .protomap import CPROTO_REQ_REGISTER_SERVER from .protomap import CPROTO_REQ_PING from .protomap import FILE_MAP class SiriDBConnection(): def __init__(self, username, password, dbname, host='127.0.0.1', port=DEFAULT_CLIENT_PORT, loop=None, timeout=10, protocol=_SiriDBProtocol): self._loop = loop or asyncio.get_event_loop() client = self._loop.create_connection( lambda: protocol(username, password, dbname), host=host, port=port) self._transport, self._protocol = self._loop.run_until_complete( asyncio.wait_for(client, timeout=timeout)) self._loop.run_until_complete(self._wait_for_auth()) async def _wait_for_auth(self): try: res = await self._protocol.auth_future except Exception as exc: logging.debug('Authentication failed: {}'.format(exc)) self._transport.close() raise exc else: self._protocol.on_authenticated() def close(self): if hasattr(self, '_protocol') and hasattr(self._protocol, 'transport'): self._protocol.transport.close() def query(self, query, time_precision=None, timeout=30): result = self._loop.run_until_complete( self._protocol.send_package(CPROTO_REQ_QUERY, data=(query, time_precision), timeout=timeout)) return result def insert(self, data, timeout=600): result = self._loop.run_until_complete( self._protocol.send_package(CPROTO_REQ_INSERT, data=data, timeout=timeout)) return result def _register_server(self, server, timeout=30): '''Register a new SiriDB Server. This method is used by the SiriDB manage tool and should not be used otherwise. Full access rights are required for this request. ''' result = self._loop.run_until_complete( self._protocol.send_package(CPROTO_REQ_REGISTER_SERVER, data=server, timeout=timeout)) return result def _get_file(self, fn, timeout=30): '''Request a SiriDB configuration file. This method is used by the SiriDB manage tool and should not be used otherwise. Full access rights are required for this request. ''' msg = FILE_MAP.get(fn, None) if msg is None: raise FileNotFoundError('Cannot get file {!r}. Available file ' 'requests are: {}' .format(fn, ', '.join(FILE_MAP.keys()))) result = self._loop.run_until_complete( self._protocol.send_package(msg, timeout=timeout)) return result class SiriDBAsyncConnection(): _protocol = None _keepalive = None async def keepalive_loop(self, interval=45): sleep = interval while True: await asyncio.sleep(sleep) if not self.connected: break sleep = \ max(0, interval - time.time() + self._last_resp) or interval if sleep == interval: logging.debug('Send keep-alive package...') try: await self._protocol.send_package(CPROTO_REQ_PING, timeout=15) except asyncio.CancelledError: break except Exception as e: logging.error(e) self.close() break async def connect(self, username, password, dbname, host='127.0.0.1', port=DEFAULT_CLIENT_PORT, loop=None, timeout=10, keepalive=False, protocol=_SiriDBProtocol): loop = loop or asyncio.get_event_loop() client = loop.create_connection( lambda: protocol(username, password, dbname), host=host, port=port) self._timeout = timeout _transport, self._protocol = \ await asyncio.wait_for(client, timeout=timeout) try: res = await self._protocol.auth_future except Exception as exc: logging.debug('Authentication failed: {}'.format(exc)) _transport.close() raise exc else: self._protocol.on_authenticated() self._last_resp = time.time() if keepalive and (self._keepalive is None or self._keepalive.done()): self._keepalive = asyncio.ensure_future(self.keepalive_loop()) def close(self): if self._keepalive is not None: self._keepalive.cancel() del self._keepalive if self._protocol is not None: self._protocol.transport.close() del self._protocol async def query(self, query, time_precision=None, timeout=3600): result = await self._protocol.send_package( CPROTO_REQ_QUERY, data=(query, time_precision), timeout=timeout) self._last_resp = time.time() return result async def insert(self, data, timeout=3600): result = await self._protocol.send_package( CPROTO_REQ_INSERT, data=data, timeout=timeout) self._last_resp = time.time() return result @property def connected(self): return self._protocol is not None and self._protocol._connectedsiridb-connector-2.0.5/siridb/connector/lib/datapackage.py000066400000000000000000000017401306021111700235670ustar00rootroot00000000000000'''Data Package. This class is used for unpacking a received data package. :copyright: 2016, Jeroen van der Heijden (Transceptor Technology) ''' import struct import qpack from . import protomap class DataPackage(object): __slots__ = ('pid', 'length', 'tipe', 'checkbit', 'data') struct_datapackage = struct.Struct('