PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /opt/imunify360/venv/lib/python3.11/site-packages/geoip2
Viewing File: /opt/imunify360/venv/lib/python3.11/site-packages/geoip2/records.py
""" Records ======= """ # pylint:disable=too-many-arguments,too-many-instance-attributes,too-many-locals import ipaddress # pylint:disable=R0903 from abc import ABCMeta from typing import Dict, List, Optional, Type, Union from geoip2.mixins import SimpleEquality class Record(SimpleEquality, metaclass=ABCMeta): """All records are subclasses of the abstract class ``Record``.""" def __repr__(self) -> str: args = ", ".join("%s=%r" % x for x in self.__dict__.items()) return f"{self.__module__}.{self.__class__.__name__}({args})" class PlaceRecord(Record, metaclass=ABCMeta): """All records with :py:attr:`names` subclass :py:class:`PlaceRecord`.""" names: Dict[str, str] _locales: List[str] def __init__( self, locales: Optional[List[str]] = None, names: Optional[Dict[str, str]] = None, ) -> None: if locales is None: locales = ["en"] self._locales = locales if names is None: names = {} self.names = names @property def name(self) -> Optional[str]: """Dict with locale codes as keys and localized name as value.""" # pylint:disable=E1101 return next((self.names.get(x) for x in self._locales if x in self.names), None) class City(PlaceRecord): """Contains data for the city record associated with an IP address. This class contains the city-level data associated with an IP address. This record is returned by ``city``, ``enterprise``, and ``insights``. Attributes: .. attribute:: confidence A value from 0-100 indicating MaxMind's confidence that the city is correct. This attribute is only available from the Insights end point and the GeoIP2 Enterprise database. :type: int .. attribute:: geoname_id The GeoName ID for the city. :type: int .. attribute:: name The name of the city based on the locales list passed to the constructor. :type: unicode .. attribute:: names A dictionary where the keys are locale codes and the values are names. :type: dict """ confidence: Optional[int] geoname_id: Optional[int] def __init__( self, locales: Optional[List[str]] = None, confidence: Optional[int] = None, geoname_id: Optional[int] = None, names: Optional[Dict[str, str]] = None, **_, ) -> None: self.confidence = confidence self.geoname_id = geoname_id super().__init__(locales, names) class Continent(PlaceRecord): """Contains data for the continent record associated with an IP address. This class contains the continent-level data associated with an IP address. Attributes: .. attribute:: code A two character continent code like "NA" (North America) or "OC" (Oceania). :type: unicode .. attribute:: geoname_id The GeoName ID for the continent. :type: int .. attribute:: name Returns the name of the continent based on the locales list passed to the constructor. :type: unicode .. attribute:: names A dictionary where the keys are locale codes and the values are names. :type: dict """ code: Optional[str] geoname_id: Optional[int] def __init__( self, locales: Optional[List[str]] = None, code: Optional[str] = None, geoname_id: Optional[int] = None, names: Optional[Dict[str, str]] = None, **_, ) -> None: self.code = code self.geoname_id = geoname_id super().__init__(locales, names) class Country(PlaceRecord): """Contains data for the country record associated with an IP address. This class contains the country-level data associated with an IP address. Attributes: .. attribute:: confidence A value from 0-100 indicating MaxMind's confidence that the country is correct. This attribute is only available from the Insights end point and the GeoIP2 Enterprise database. :type: int .. attribute:: geoname_id The GeoName ID for the country. :type: int .. attribute:: is_in_european_union This is true if the country is a member state of the European Union. :type: bool .. attribute:: iso_code The two-character `ISO 3166-1 <http://en.wikipedia.org/wiki/ISO_3166-1>`_ alpha code for the country. :type: unicode .. attribute:: name The name of the country based on the locales list passed to the constructor. :type: unicode .. attribute:: names A dictionary where the keys are locale codes and the values are names. :type: dict """ confidence: Optional[int] geoname_id: Optional[int] is_in_european_union: bool iso_code: Optional[str] def __init__( self, locales: Optional[List[str]] = None, confidence: Optional[int] = None, geoname_id: Optional[int] = None, is_in_european_union: bool = False, iso_code: Optional[str] = None, names: Optional[Dict[str, str]] = None, **_, ) -> None: self.confidence = confidence self.geoname_id = geoname_id self.is_in_european_union = is_in_european_union self.iso_code = iso_code super().__init__(locales, names) class RepresentedCountry(Country): """Contains data for the represented country associated with an IP address. This class contains the country-level data associated with an IP address for the IP's represented country. The represented country is the country represented by something like a military base. Attributes: .. attribute:: confidence A value from 0-100 indicating MaxMind's confidence that the country is correct. This attribute is only available from the Insights end point and the GeoIP2 Enterprise database. :type: int .. attribute:: geoname_id The GeoName ID for the country. :type: int .. attribute:: is_in_european_union This is true if the country is a member state of the European Union. :type: bool .. attribute:: iso_code The two-character `ISO 3166-1 <http://en.wikipedia.org/wiki/ISO_3166-1>`_ alpha code for the country. :type: unicode .. attribute:: name The name of the country based on the locales list passed to the constructor. :type: unicode .. attribute:: names A dictionary where the keys are locale codes and the values are names. :type: dict .. attribute:: type A string indicating the type of entity that is representing the country. Currently we only return ``military`` but this could expand to include other types in the future. :type: unicode """ type: Optional[str] def __init__( self, locales: Optional[List[str]] = None, confidence: Optional[int] = None, geoname_id: Optional[int] = None, is_in_european_union: bool = False, iso_code: Optional[str] = None, names: Optional[Dict[str, str]] = None, # pylint:disable=redefined-builtin type: Optional[str] = None, **_, ) -> None: self.type = type super().__init__( locales, confidence, geoname_id, is_in_european_union, iso_code, names ) class Location(Record): """Contains data for the location record associated with an IP address. This class contains the location data associated with an IP address. This record is returned by ``city``, ``enterprise``, and ``insights``. Attributes: .. attribute:: average_income The average income in US dollars associated with the requested IP address. This attribute is only available from the Insights end point. :type: int .. attribute:: accuracy_radius The approximate accuracy radius in kilometers around the latitude and longitude for the IP address. This is the radius where we have a 67% confidence that the device using the IP address resides within the circle centered at the latitude and longitude with the provided radius. :type: int .. attribute:: latitude The approximate latitude of the location associated with the IP address. This value is not precise and should not be used to identify a particular address or household. :type: float .. attribute:: longitude The approximate longitude of the location associated with the IP address. This value is not precise and should not be used to identify a particular address or household. :type: float .. attribute:: metro_code The metro code of the location if the location is in the US. MaxMind returns the same metro codes as the `Google AdWords API <https://developers.google.com/adwords/api/docs/appendix/cities-DMAregions>`_. :type: int .. attribute:: population_density The estimated population per square kilometer associated with the IP address. This attribute is only available from the Insights end point. :type: int .. attribute:: time_zone The time zone associated with location, as specified by the `IANA Time Zone Database <http://www.iana.org/time-zones>`_, e.g., "America/New_York". :type: unicode """ average_income: Optional[int] accuracy_radius: Optional[int] latitude: Optional[float] longitude: Optional[float] metro_code: Optional[int] population_density: Optional[int] time_zone: Optional[str] def __init__( self, average_income: Optional[int] = None, accuracy_radius: Optional[int] = None, latitude: Optional[float] = None, longitude: Optional[float] = None, metro_code: Optional[int] = None, population_density: Optional[int] = None, time_zone: Optional[str] = None, **_, ) -> None: self.average_income = average_income self.accuracy_radius = accuracy_radius self.latitude = latitude self.longitude = longitude self.metro_code = metro_code self.population_density = population_density self.time_zone = time_zone class MaxMind(Record): """Contains data related to your MaxMind account. Attributes: .. attribute:: queries_remaining The number of remaining queries you have for the end point you are calling. :type: int """ queries_remaining: Optional[int] def __init__(self, queries_remaining: Optional[int] = None, **_) -> None: self.queries_remaining = queries_remaining class Postal(Record): """Contains data for the postal record associated with an IP address. This class contains the postal data associated with an IP address. This attribute is returned by ``city``, ``enterprise``, and ``insights``. Attributes: .. attribute:: code The postal code of the location. Postal codes are not available for all countries. In some countries, this will only contain part of the postal code. :type: unicode .. attribute:: confidence A value from 0-100 indicating MaxMind's confidence that the postal code is correct. This attribute is only available from the Insights end point and the GeoIP2 Enterprise database. :type: int """ code: Optional[str] confidence: Optional[int] def __init__( self, code: Optional[str] = None, confidence: Optional[int] = None, **_ ) -> None: self.code = code self.confidence = confidence class Subdivision(PlaceRecord): """Contains data for the subdivisions associated with an IP address. This class contains the subdivision data associated with an IP address. This attribute is returned by ``city``, ``enterprise``, and ``insights``. Attributes: .. attribute:: confidence This is a value from 0-100 indicating MaxMind's confidence that the subdivision is correct. This attribute is only available from the Insights end point and the GeoIP2 Enterprise database. :type: int .. attribute:: geoname_id This is a GeoName ID for the subdivision. :type: int .. attribute:: iso_code This is a string up to three characters long contain the subdivision portion of the `ISO 3166-2 code <http://en.wikipedia.org/wiki/ISO_3166-2>`_. :type: unicode .. attribute:: name The name of the subdivision based on the locales list passed to the constructor. :type: unicode .. attribute:: names A dictionary where the keys are locale codes and the values are names :type: dict """ confidence: Optional[int] geoname_id: Optional[int] iso_code: Optional[str] def __init__( self, locales: Optional[List[str]] = None, confidence: Optional[int] = None, geoname_id: Optional[int] = None, iso_code: Optional[str] = None, names: Optional[Dict[str, str]] = None, **_, ) -> None: self.confidence = confidence self.geoname_id = geoname_id self.iso_code = iso_code super().__init__(locales, names) class Subdivisions(tuple): """A tuple-like collection of subdivisions associated with an IP address. This class contains the subdivisions of the country associated with the IP address from largest to smallest. For instance, the response for Oxford in the United Kingdom would have England as the first element and Oxfordshire as the second element. This attribute is returned by ``city``, ``enterprise``, and ``insights``. """ def __new__( cls: Type["Subdivisions"], locales: Optional[List[str]], *subdivisions ) -> "Subdivisions": subobjs = tuple(Subdivision(locales, **x) for x in subdivisions) obj = super().__new__(cls, subobjs) # type: ignore return obj def __init__( self, locales: Optional[List[str]], *subdivisions # pylint:disable=W0613 ) -> None: self._locales = locales super().__init__() @property def most_specific(self) -> Subdivision: """The most specific (smallest) subdivision available. If there are no :py:class:`Subdivision` objects for the response, this returns an empty :py:class:`Subdivision`. :type: :py:class:`Subdivision` """ try: return self[-1] except IndexError: return Subdivision(self._locales) class Traits(Record): """Contains data for the traits record associated with an IP address. This class contains the traits data associated with an IP address. This class has the following attributes: .. attribute:: autonomous_system_number The `autonomous system number <http://en.wikipedia.org/wiki/Autonomous_system_(Internet)>`_ associated with the IP address. This attribute is only available from the City and Insights web service end points and the GeoIP2 Enterprise database. :type: int .. attribute:: autonomous_system_organization The organization associated with the registered `autonomous system number <http://en.wikipedia.org/wiki/Autonomous_system_(Internet)>`_ for the IP address. This attribute is only available from the City and Insights web service end points and the GeoIP2 Enterprise database. :type: unicode .. attribute:: connection_type The connection type may take the following values: - Dialup - Cable/DSL - Corporate - Cellular Additional values may be added in the future. This attribute is only available in the GeoIP2 Enterprise database. :type: unicode .. attribute:: domain The second level domain associated with the IP address. This will be something like "example.com" or "example.co.uk", not "foo.example.com". This attribute is only available from the City and Insights web service end points and the GeoIP2 Enterprise database. :type: unicode .. attribute:: ip_address The IP address that the data in the model is for. If you performed a "me" lookup against the web service, this will be the externally routable IP address for the system the code is running on. If the system is behind a NAT, this may differ from the IP address locally assigned to it. :type: unicode .. attribute:: is_anonymous This is true if the IP address belongs to any sort of anonymous network. This attribute is only available from GeoIP2 Precision Insights. :type: bool .. attribute:: is_anonymous_proxy This is true if the IP is an anonymous proxy. See http://dev.maxmind.com/faq/geoip#anonproxy for further details. :type: bool .. deprecated:: 2.2.0 Use our our `GeoIP2 Anonymous IP database <https://www.maxmind.com/en/geoip2-anonymous-ip-database GeoIP2>`_ instead. .. attribute:: is_anonymous_vpn This is true if the IP address is registered to an anonymous VPN provider. If a VPN provider does not register subnets under names associated with them, we will likely only flag their IP ranges using the ``is_hosting_provider`` attribute. This attribute is only available from GeoIP2 Precision Insights. :type: bool .. attribute:: is_hosting_provider This is true if the IP address belongs to a hosting or VPN provider (see description of ``is_anonymous_vpn`` attribute). This attribute is only available from GeoIP2 Precision Insights. :type: bool .. attribute:: is_legitimate_proxy This attribute is true if MaxMind believes this IP address to be a legitimate proxy, such as an internal VPN used by a corporation. This attribute is only available in the GeoIP2 Enterprise database. :type: bool .. attribute:: is_public_proxy This is true if the IP address belongs to a public proxy. This attribute is only available from GeoIP2 Precision Insights. :type: bool .. attribute:: is_residential_proxy This is true if the IP address is on a suspected anonymizing network and belongs to a residential ISP. This attribute is only available from GeoIP2 Precision Insights. :type: bool .. attribute:: is_satellite_provider This is true if the IP address is from a satellite provider that provides service to multiple countries. :type: bool .. deprecated:: 2.2.0 Due to the increased coverage by mobile carriers, very few satellite providers now serve multiple countries. As a result, the output does not provide sufficiently relevant data for us to maintain it. .. attribute:: is_tor_exit_node This is true if the IP address is a Tor exit node. This attribute is only available from GeoIP2 Precision Insights. :type: bool .. attribute:: isp The name of the ISP associated with the IP address. This attribute is only available from the City and Insights web service end points and the GeoIP2 Enterprise database. :type: unicode .. attribute:: network The network associated with the record. In particular, this is the largest network where all of the fields besides ip_address have the same value. :type: ipaddress.IPv4Network or ipaddress.IPv6Network .. attribute:: organization The name of the organization associated with the IP address. This attribute is only available from the City and Insights web service end points and the GeoIP2 Enterprise database. :type: unicode .. attribute:: static_ip_score An indicator of how static or dynamic an IP address is. The value ranges from 0 to 99.99 with higher values meaning a greater static association. For example, many IP addresses with a user_type of cellular have a lifetime under one. Static Cable/DSL IPs typically have a lifetime above thirty. This indicator can be useful for deciding whether an IP address represents the same user over time. This attribute is only available from GeoIP2 Precision Insights. :type: float .. attribute:: user_count The estimated number of users sharing the IP/network during the past 24 hours. For IPv4, the count is for the individual IP. For IPv6, the count is for the /64 network. This attribute is only available from GeoIP2 Precision Insights. :type: int .. attribute:: user_type The user type associated with the IP address. This can be one of the following values: * business * cafe * cellular * college * content_delivery_network * dialup * government * hosting * library * military * residential * router * school * search_engine_spider * traveler This attribute is only available from the Insights end point and the GeoIP2 Enterprise database. :type: unicode """ autonomous_system_number: Optional[int] autonomous_system_organization: Optional[str] connection_type: Optional[str] domain: Optional[str] is_anonymous: bool is_anonymous_proxy: bool is_anonymous_vpn: bool is_hosting_provider: bool is_legitimate_proxy: bool is_public_proxy: bool is_residential_proxy: bool is_satellite_provider: bool is_tor_exit_node: bool isp: Optional[str] ip_address: Optional[str] organization: Optional[str] static_ip_score: Optional[float] user_count: Optional[int] user_type: Optional[str] _network: Optional[str] _prefix_len: Optional[int] def __init__( self, autonomous_system_number: Optional[int] = None, autonomous_system_organization: Optional[str] = None, connection_type: Optional[str] = None, domain: Optional[str] = None, is_anonymous: bool = False, is_anonymous_proxy: bool = False, is_anonymous_vpn: bool = False, is_hosting_provider: bool = False, is_legitimate_proxy: bool = False, is_public_proxy: bool = False, is_residential_proxy: bool = False, is_satellite_provider: bool = False, is_tor_exit_node: bool = False, isp: Optional[str] = None, ip_address: Optional[str] = None, network: Optional[str] = None, organization: Optional[str] = None, prefix_len: Optional[int] = None, static_ip_score: Optional[float] = None, user_count: Optional[int] = None, user_type: Optional[str] = None, **_, ) -> None: self.autonomous_system_number = autonomous_system_number self.autonomous_system_organization = autonomous_system_organization self.connection_type = connection_type self.domain = domain self.is_anonymous = is_anonymous self.is_anonymous_proxy = is_anonymous_proxy self.is_anonymous_vpn = is_anonymous_vpn self.is_hosting_provider = is_hosting_provider self.is_legitimate_proxy = is_legitimate_proxy self.is_public_proxy = is_public_proxy self.is_residential_proxy = is_residential_proxy self.is_satellite_provider = is_satellite_provider self.is_tor_exit_node = is_tor_exit_node self.isp = isp self.organization = organization self.static_ip_score = static_ip_score self.user_type = user_type self.user_count = user_count self.ip_address = ip_address self._network = network self._prefix_len = prefix_len # This code is duplicated for performance reasons # pylint: disable=duplicate-code @property def network(self) -> Optional[Union[ipaddress.IPv4Network, ipaddress.IPv6Network]]: """The network for the record""" network = self._network if isinstance(network, (ipaddress.IPv4Network, ipaddress.IPv6Network)): return network if network is None: ip_address = self.ip_address prefix_len = self._prefix_len if ip_address is None or prefix_len is None: return None network = f"{ip_address}/{prefix_len}" network = ipaddress.ip_network(network, False) self._network = network return network # type: ignore