+
    0jJ                       a  R t:0 t R t^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
HtHt ^ RIHt ^ RIHt ^ RIHtHt ^ RIHt ^ RIHtHt ^ RIt^RIHt ^R	IHt ^R
IHtHt ^RI H!t! ^RI"H#t# ^RI$H%t% ^RI&H't' ]PP                  ! ])4      t*Rt+Rt,Rt-Rs.] ^ k Rs/] ^k ]P`                  ! 4       t1Rs2] ^k Rs3] ^k R R lt4]Pj                  ! ]44       R R lt6R R lt7R R lt8 ! R R4      t9R# )zDDGS class implementation.N)ThreadPoolExecutorwait)ceil)Path)randomshuffle)TracebackType)AnyClassVar)BaseSearchEngine)ENGINES)DDGSExceptionTimeoutException)
HttpClient)ResultsAggregator)SimpleFilterRanker)_expand_proxy_tb_aliaszhttp://localhost:4479      $@g      ?c                    V ^8  d   QhRR/#    returnN )formats   "^/Users/mitch_tango/dev/rabbit-r1-livekit/agent/.venv/lib/python3.14/site-packages/ddgs/ddgs.py__annotate__r   *   s     &# &#d &#    c                    \         P                  e    \         P                  P                  4       fm   \        P	                  R\         P                  P
                  4       \         P                  P                  4        \         P                  P                  RR7       R\         n        \        ea   \        P                  4       '       dG    \        P                  \        P                  4       \        e   \        P!                  RR7       RsRs\"        e    \"        P%                  R	R
7       RsR# R#   \         d   p \        P                  RT 4        \         P                  P                  4        \         P                  P                  RR7        Rp ? L  \         d&   p \        P                  RT 4        Rp ?  Rp ? EL(Rp ? ii ; iRp ? ii ; i  R\         n        i ; i  \         d!   p \        P                  RT 4        Rp ? LRp ? ii ; i  RsRsi ; i  \         d"   p \        P                  RT 4        Rp ? ELRp ? ii ; i  Rsi ; i)z/Cleanup any spawned API server process on exit.Nz%Stopping spawned API server (PID: %d)g      @timeoutzFailed to stop API server: %rg       @zFailed to kill API server: %rzFailed to stop async loop: %rT)r   z%Failed to shutdown cache executor: %r)DDGS_api_processpollloggerinfopid	terminater   	Exceptiondebugkill_async_loop
is_runningcall_soon_threadsafestop_async_threadjoin_cache_executorshutdown)exs    r   _cleanup_api_processr3   *   s   $	%  %%'/CTEVEVEZEZ[!!++-!!&&s&3 !%D ;#9#9#;#;	!,,[-=-=>(""3"/ K M "	#$$$$/ #O #1  	BLL8"=B!!&&(!!&&s&33 B<bAAB	B !%D  	>LL8"==	> K M  	FLL@"EE	F #Os   BD8 AG( H 8GG>FG G(G>GG GGGG G%(H3H	H HH HI*I I II Ic                $    V ^8  d   QhR\         /# r   r   )r   )r   s   "r   r   r   W   s      / r   c                 8    \         f   \        ^RR7      s \         # )z@Get shared thread pool executor for background cache operations.z
DDGS-Cachemax_workersthread_name_prefix)r0   r   r   r   r   _get_cache_executorr:   W   s     ,|\r   c                8    V ^8  d   QhR\         P                  /# r5   )primpClient)r   s   "r   r   r   `   s      %,, r   c                 L    \         f   \        P                  ! ^R7      s \         # )z+Get or create the shared primp HTTP client.r   )_http_clientr<   r=   r   r   r   _get_http_clientr@   `   s     ||A.r   c                8    V ^8  d   QhR\         P                  /# r5   )asyncioAbstractEventLoop)r   s   "r   r   r   h   s      22 r   c                 &   \         fm   \        ;_uu_ 4        \         fH   \        P                  ! 4       s R R lp \        P
                  ! V RR7      s\        P                  4        RRR4       \         # \         #   + '       g   i     \         # ; i)z<Get or create shared async loop running in dedicated thread.Nc                    V ^8  d   QhRR/# r   r   )r   s   "r   r   %_get_async_loop.<locals>.__annotate__p   s     . .4 .r   c                  b    \         P                  ! \        4       \        P                  4        R # N)rB   set_event_loopr*   run_foreverr   r   r   	_run_loop"_get_async_loop.<locals>._run_loopp   s    **;7++-r   T)targetdaemon)r*   _network_lockrB   new_event_loop	threadingThreadr.   start)rK   s    r   _get_async_looprT   h   sj     ]"%446. !* 0 0	$ O##%  ; ] s   AA;;B	c                   t  a  ] tR t^yt o RtRtRtRtR/RRRRRR/V 3R lR	 llltV 3R
 lR lt	R0V 3R lR llt
V 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltR1RRRRRRR^
R^RR/V 3R lR  llltV 3R! lR" ltV 3R# lR$ ltV 3R% lR& ltV 3R' lR( ltV 3R) lR* ltR2V 3R+ lR, lltV 3R- ltR.tV tR# )3r    a^  DDGS | Dux Distributed Global Search.

A metasearch library that aggregates results from diverse web search services.

Args:
    proxy: The proxy to use for the search. Defaults to None.
    timeout: The timeout for the search. Defaults to 5.
    verify: bool (True to verify, False to skip) or str path to a PEM file. Defaults to True.

Attributes:
    threads: The maximum number of threads per search. Defaults to None (automatic, based on max_results).

Raises:
    DDGSException: If an error occurs during the search.

Example:
    >>> from ddgs import DDGS
    >>> results = DDGS().search("python")

NverifyTapi_url	spawn_apiFc                v   < V ^8  d   QhRS[ R,          RS[R,          RS[S[ ,          RS[ R,          RS[RR/# )r   proxyNr   rV   rW   rX   r   )strintbool)r   __classdict__s   "r   r   DDGS.__annotate__   sW     + +Tz+ t+
 s
+ t+ + 
+r   c               "   \        V4      ;'       g     \        P                  P                  R 4      V n        W n        W0n        W@n        WPn        / V n	        V P                  '       d'   \        P                  f   V P                  4        R# R# R# )
DDGS_PROXYN)r   osenvironget_proxy_timeout_verify_api_url
_spawn_api_engines_cacher    _network_client_ensure_network_running)selfrZ   r   rV   rW   rX   s   &&&$$$r   __init__DDGS.__init__   so     -U3SSrzz~~l7S#  	
 ===T119((* :=r   c                   < V ^8  d   QhRR/# )r   r   r    r   )r   r^   s   "r   r   r_      s      6 r   c                    V # )z7Enter the context manager and return the DDGS instance.r   rm   s   &r   	__enter__DDGS.__enter__   s    r   c                j   < V ^8  d   QhRS[ S[,          R,          RS[R,          RS[R,          RR/# )r   exc_typeNexc_valexc_tbr   )typeBaseExceptionr   )r   r^   s   "r   r   r_      sG     ( (}%,( %( $	(
 
(r   c                    R# )zExit the context manager.Nr   )rm   rv   rw   rx   s   &&&&r   __exit__DDGS.__exit__   s    r   c                   < V ^8  d   QhRR/# r   r   )r   r^   s   "r   r   r_      s     IX IX IXr   c                   \         P                  e   R# \        ;_uu_ 4        \         P                  e    RRR4       R# V P                  ;'       g    \        p \        4       P                  V R24      pVP                  ^8X  d:   ^RIH	p V! VR7      \         n        \        P                  RV4        RRR4       R#  V P                  '       Ed*   \         P                   e!   \         P                   P#                  4       e    \%        \'        \(        P*                  4      P,                  4      p/ \.        P0                  CRV \.        P2                   \.        P0                  P                  RR	4       2/Cp\4        P6                  ! \(        P*                  R
RRR.V\4        P8                  \4        P8                  RRR7      \         n        \        P                  R\         P                   P:                  4       \>        P>                  ! 4       p\>        P>                  ! 4       V,
          \@        8  d    \        4       P                  V R24      pVP                  ^8X  d   Mv \@        \>        P>                  ! 4       V,
          ,
          pV^ 8:  d   MF\>        PB                  ! \E        \F        V4      4       K  \        P=                  R4        RRR4       R#  ^RIH	p V! VR7      \         n        \        P                  RV4       RRR4       R#   \         d    \        P                  R4        ELw\         d"   p\        P                  RT4        Rp?ELRp?ii ; i  \         d*   p\        P=                  RT4        Rp?RRR4       R# Rp?ii ; i  \         d     ELDi ; i  \         d    \        P                  R4        Li ; i  + '       g   i     R# ; i)zpEnsure the network service is running.

If not running, spawn a new ddgs api process only if spawn_api is True.
Nz/health)	DhtClient)rW   zNetwork client ready: %sz7DHT dependencies not available - network cache disabledzAPI health check failed: %rPATH z-mddgsapiz-dT)envstdoutstderrstart_new_sessiontextz"Spawned ddgs api service (PID: %d)zFailed to spawn ddgs api: %rz/Timed out waiting for ddgs api service to start)$r    rk   rO   rh   DEFAULT_API_URLr@   rd   status_codedhtr   r#   r$   ImportErrorr(   r'   ri   r!   r"   r[   r   sys
executableparentrb   rc   pathsep
subprocessPopenDEVNULLr%   warningtimeNETWORK_START_TIMEOUTsleepminNETWORK_CHECK_INTERVAL)	rm   rW   respr   r2   venv_binr   
start_time	remainings	   &        r   rl   DDGS._ensure_network_running   s   
 +]##/ ] mm66G@')--	.AB##s*.+4W+ED(KK :GD ] + D$5$5$=ARARAWAWAYAe"4#7#>#>?HgRZZgH:bjj\"**..Y_acJdIe1fgC(2(8(8vudC)11)11*.!)D% KK DdFWFWF[F[\
 J))+
*-BB+-11WIW2EFD''3. / 2TYY[:5MN	>

35yABPQq ]vX*'0'A$6@ ]   XVW @:B??@" ! NN#A2FM ]H ! $  XVWXA ]]s   OOOALO2O	C6M(?:O:-N'A-O.N1 M%7O:M%M%M O M%%O(N3N	ONON.*O-N..O1 OOOOO(	c                    < V ^8  d   QhRS[ /# r5   )r	   )r   r^   s   "r   r   r_      s     $ $S $r   c                "    \         P                  # )zdGet the network client for caching.

Returns:
    DhtClient instance if available, None otherwise.

)r    rk   rr   s   &r   _get_network_clientDDGS._get_network_client   s     ###r   c                V   < V ^8  d   QhRS[ RS[S[S[ S[3,          ,          RS[ RR/# )r   queryresultscategoryr   N)r[   listdictr	   )r   r^   s   "r   r   r_   	  s@     ' '' d38n%' 	'
 
'r   c                   aaaa V P                  4       oS'       g   R# R VVVV3R llp\        4       pVP                  V4       R# )z$Cache search results asynchronously.Nc                    V ^8  d   QhRR/# r   r   )r   s   "r   r   /DDGS._cache_results_async.<locals>.__annotate__  s     	5 	5t 	5r   c                    <  \        4       p \        P                  ! SP                  SSS4      V 4      pVP	                  R R7       \
        P                  RS4       R#   \         d"   p\
        P                  RT4        Rp?R# Rp?ii ; i)r   r   zCached results: %szCache failed: %rN)rT   rB   run_coroutine_threadsafecacheresultr#   r(   r'   )loopfuturer2   r   networkr   r   s      r   _cache_worker0DDGS._cache_results_async.<locals>._cache_worker  sp    5&( 99'--wX`:acghd+159 5/445s   AA B*BB)r   r:   submit)rm   r   r   r   r   executorr   s   &fff  @r   _cache_results_asyncDDGS._cache_results_async	  s9     **,	5 	5 '(&r   c                L   < V ^8  d   QhRS[ RS[ RS[S[S[,          ,          /# )r   r   backendr   )r[   r   r   r	   )r   r^   s   "r   r   r_      s4     = == = 
s#	$	=r   c           	     v   \        V\        4      '       d   RP                  V4      pVP                  R4       Uu. uF  q3P	                  4       NK  	  pp\        \
        V,          P                  4       4      p\        V4       RV9   g   RV9   d.   TpVR8X  d$   RR.V Uu. uF  qwR9  g   K  VNK  	  up,           pMTp. p. p	V FK  p
\
        V,          P                  V
4      ;p'       d   VP                  V4       K:  V	P                  V
4       KM  	  V	'       dH   \        P                  RRP                  \        V	4      4      RP                  \        V4      4      4       . pV F  pWP                  9   d%   VP                  V P                  V,          4       K7  V! V P                  V P                  V P                   R	7      pWP                  V&   VP                  V4       K  	  V'       g(   \        P                  R
4       V P#                  VR4      # VP%                  R RR7       V# u upi u upi )a~  Retrieve a list of search engine instances for a given category and backend.

Args:
    category: The category of search engines (e.g., 'text', 'images', etc.).
    backend: A single or comma-delimited backends. Defaults to "auto".

Returns:
    A list of initialized search engine instances corresponding to the specified
    category and backend. Instances are cached for reuse.

,autoallr   	wikipedia
grokipediaz9%s - backends do not exist or are disabled. Available: %sz, rZ   r   rV   z backend is not set. Using 'auto'c                 &    V P                   \        3# rH   )priorityr   )es   &r   <lambda>#DDGS._get_engines.<locals>.<lambda>\  s    ajj&%9r   T)keyreverse)r   r   )
isinstancer   r/   splitstripr   keysr   rd   appendr#   r   sortedrj   re   rf   rg   _get_enginessort)rm   r   r   xbackend_listengine_keysr   kengine_classesinvalid_keysr   engine_class	instancesengine_instances   &&&           r   r   DDGS._get_engines   s     gt$$hhw'G+2==+=>+=a	+=>78,1134\!Ul%:D6!#\25nARmImaa5nnDC&x044S99|9%%l3##C(	  NNK		&./		&-. 	*L222  !4!4\!BC #/T[[$--`d`l`l"m4C##L1  1 + NN=>$$Xv66 	94HW ? 6os   H1"H6/H6regionzus-en
safesearchmoderate	timelimitmax_resultspager   r   c                   < V ^8  d   QhRS[ RS[ RS[ R,          RS[ RS[ RS[ R,          RS[R,          R	S[R
S[ RS[ RS[S[S[ S[3,          ,          /# )r   r   r   keywordsNr   r   r   r   r   r   kwargsr   )r[   r\   r   r   r	   )r   r^   s   "r   r   r_   _  s     g8 g8g8 g8 *	g8 g8 g8 :g8 4Zg8 g8 g8 g8 
d38n	g8r   c               F   T;'       g    TpV'       g   Rp\        V4      hV P                  4       pV'       de    \        4       p\        P                  ! VP                  W!4      V4      pVP                  RR7      pV'       d   \        P                  RV4       V#  V P                  W4      p\        V Uu0 uF  pVP                  kK  	  up4      p\        4       p\        0 Rm4      pV'       d$   \        V\!        V^
,          4      ^,           4      MTp\"        P$                  '       d   \        V\"        P$                  4      p/ Rpp\'        VRR7      ;_uu_ 4       p\)        V^R	7       EF  w  ppVP                  V9   d   K  VP*                  ! VP,                  V3R
VRVRVRV/V
B pVVV&   \        V4      V8  g   VV8  d   \/        VV P0                  RR7      w  ppVP3                  4        FV  w  ppVV9   g   K   VP                  4       ;p'       d/   VP5                  V4       VP7                  VP                  4       KV  KX  	  V Uu/ uF  pVVV,          bK  	  ppV'       g   EK  \        V4      V8  g   EK   M	  RRR4       VP=                  4       p \?        4       p!V!PA                  V V4      p V '       d+   V'       d   V PC                  VV V4       V'       d   V RV # T # RV 9   d   \E        V4      h\        T;'       g    R4      h  \         d"   p\        P                  RT4        Rp?ELRp?ii ; iu upi   \         d0   pTp\        P9                  RTP:                  T4        Rp?EK  Rp?ii ; iu upi   + '       g   i     EL; i)a  Perform a search across engines in the given category.

Args:
    category: The category of search engines (e.g., 'text', 'images', etc.).
    query: The search query.
    keywords: Deprecated alias for `query`.
    region: The region to use for the search (e.g., us-en, uk-en, ru-ru, etc.).
    safesearch: The safesearch setting (e.g., on, moderate, off).
    timelimit: The timelimit for the search (e.g., d, w, m, y) or custom date range.
    max_results: The maximum number of results to return. Defaults to 10.
    page: The page of results to return. Defaults to 1.
    backend: A single or comma-delimited backends. Defaults to "auto".
    **kwargs: Additional keyword arguments to pass to the search engines.

Returns:
    A list of dictionaries containing the search results.

zquery is mandatory.g      ?r   zCache hit: %szCache check failed: %rNr    r7   )rS   r   r   r   r   FIRST_EXCEPTION)r   return_whenzError in engine %s: %rz	timed outzNo results found.>   urlhrefimage	embed_url)#r   r   rT   rB   r   
get_cachedr   r#   r(   r'   r   lenprovidersetr   r   r   r    threadsr   	enumerater   searchr   rf   itemsextendaddr$   nameextract_dictsr   rankr   r   )"rm   r   r   r   r   r   r   r   r   r   r   msgr   r   r   cachedr2   enginesenginelen_unique_providersseen_providersresults_aggregatorr8   futureserrr   idonenot_doneff_enginerr   rankers"   &&&&$$$$$$,                       r   _search_syncDDGS._search_sync_  sG   @ !!E'C$$**,	;&( 99':L:LU:]_cds3LL%8!M  ##H6"'#J'FOO'#JK#&5 ;LLq:rOZc.[25E0F0JK`t<<<k4<<8K4KFSSW_&wa88	6??n4!MM "  *	
 (   #)w<;.!{2B%)'4==Vg%hND('.}}89Y()
?1?$6$=$=a$@$2$6$6x7H7H$I $3 (7 7??hq'!*}hG?;3'9#:k#I9 9 T> %224#%++gu-))%(C,77<K(DWDSE""3''C66#677s  ;5r::;
 $K@ $- Y&( &,DhmmUW X XY @5 TSSss   A!L 8M!BNM,M

NN

'N4NNM$M  MN#N;NNNN 	c          	      R   < V ^8  d   QhRS[ RS[RS[S[S[ S[3,          ,          /# r   r   r   r   r[   r	   r   r   )r   r^   s   "r   r   r_     /     : :# : :d38n1E :r   c                *    V P                   ! RV3/ VB # )zPerform a text search.r   r	  rm   r   r   s   &&,r   r   	DDGS.text        9&99r   c          	      R   < V ^8  d   QhRS[ RS[RS[S[S[ S[3,          ,          /# r  r  )r   r^   s   "r   r   r_     /     < <C <3 <4S#X3G <r   c                *    V P                   ! RV3/ VB # )zPerform an image search.imagesr  r  s   &&,r   r  DDGS.images        5;F;;r   c          	      R   < V ^8  d   QhRS[ RS[RS[S[S[ S[3,          ,          /# r  r  )r   r^   s   "r   r   r_     r  r   c                *    V P                   ! RV3/ VB # )zPerform a news search.newsr  r  s   &&,r   r  	DDGS.news  r  r   c          	      R   < V ^8  d   QhRS[ RS[RS[S[S[ S[3,          ,          /# r  r  )r   r^   s   "r   r   r_     r  r   c                *    V P                   ! RV3/ VB # )zPerform a video search.videosr  r  s   &&,r   r   DDGS.videos  r  r   c          	      R   < V ^8  d   QhRS[ RS[RS[S[S[ S[3,          ,          /# r  r  )r   r^   s   "r   r   r_     s/     ; ;3 ;# ;$tCH~2F ;r   c                *    V P                   ! RV3/ VB # )zPerform a book search.booksr  r  s   &&,r   r$  
DDGS.books  s      %:6::r   c          	      R   < V ^8  d   QhRS[ RS[ RS[S[ S[ S[,          3,          /# )r   r   fmtr   )r[   r   bytes)r   r^   s   "r   r   r_     s5     Q Q3 QS QtCuDT?U Qr   c           
        \        V P                  V P                  V P                  R7      pVP	                  V4      pVP
                  ^8w  d   RV RVP
                   2p\        V4      hRVP                  RVP                  RVP                  RVP                  RVP                  /pR	VRVP	                  W$P                  4      /# )
a	  Fetch a URL and extract its content.

Args:
    url: The URL to fetch and extract content from.
    fmt: Output format: "text_markdown", "text_plain", "text_rich", "text" (raw HTML), "content" (raw bytes).

Returns:
    A dictionary with 'url' and 'content' keys.

r   zFailed to fetch z: HTTP text_markdown
text_plain	text_richr   contentr   )r   re   rf   rg   rd   r   r   r*  r+  r,  r   r-  )rm   r   r'  clientr   r   content_maps   &&&    r   extractDDGS.extract  s     $++t}}T\\Zzz#s"$SE1A1A0BCC$$ T//$//DIIt||/
 sI{s<N<N'OPPr   c                   < V ^8  d   Qh/ S[ S[R,          ,          ;R&   S[ S[,          ;R&   S[ S[P                  S[,          R,          ,          ;R&   # )r   Nr   rk   r!   )r
   r\   r	   r   r   r[   )r   r^   s   "r   r   r_   y   sN     , cDj!(- . c])/ 0 :++C0478?1 r   )rh   rj   re   ri   rf   rg   )N   )NNNrH   )r*  )__name__
__module____qualname____firstlineno____doc__r   rk   r!   rn   rs   r|   rl   r   r   r   r	  r   r  r  r   r$  r0  __annotate_func____static_attributes____classdictcell__)r^   s   @r   r    r    y   s    * %)G%)O;?L+
 "+ #+  + +, ( (IX IXV$ $' '.= =~g8 g8 %g8 !%g8 #%g8 g8 g8 g8R: :< <: :< <; ;Q QG  r   r    c                ,   V ^8  d   Qh/ ^ \         9   d   \        P                  R,          ;R&   ^\         9   d   \        R,          ;R&   ^\         9   d   \        P
                  R,          ;R&   ^\         9   d   \        P                  R,          ;R&   # )r   Nr?   r0   r*   r.   )__conditional_annotations__r<   r=   r   rB   rC   rQ   rR   )r   s   "r   r   r      s}        D ) (ellT! (E !F 2 1#d* 1G !J 5 4W&&- 4K !L . -y$& -M !r   );r=  r8  rB   atexitloggingrb   r   r   rQ   r   concurrent.futuresr   r   mathr   pathlibr   r   r   typesr   typingr	   r
   r<   baser   r   r   
exceptionsr   r   http_clientr   r   r   
similarityr   utilsr   	getLoggerr4  r#   r   r   r   r?   r0   LockrO   r*   r.   r3   registerr:   r@   rT   r    r   )r=  s   @r   <module>rM     s         	  
   7   "     "  7 # & * )			8	$)   %) (-1 1 04 4)- -&#T $ %"{Q {Qr   