
    `mh2*                        d dl Z d dlZd dlZd dlZd dlZd dlmZmZmZm	Z	 d dl
m
Z
 d dlmZmZmZmZmZ d dlmZ d dlmZ d dlZej,                  j/                  d       ej,                  j/                  d       d d	lmZmZmZmZmZmZ d d
lm Z m!Z!m"Z" d dl#m$Z$m%Z%m&Z&m'Z'  ejP                  ejR                  d        ejT                  e+      Z, eddd      Z-e-j]                  edgddgdg       da/da0e-jc                  d      d        Z2e-jc                  d      d        Z3 G d de      Z4e-jk                  d      d        Z6e-jk                  d      d        Z7e-jq                  dee9e	f          d!e4d"efd#       Z:e-jq                  d$ee9e	f          d!ed"efd%       Z;e-jk                  d&e       d'e9fd(       Z<e-jk                  d)      d'e9fd*       Z=e-jq                  d+       ed,      fd-efd.       Z>e-jk                  d/      d0        Z?e-jk                  d1      d2        Z@e+d3k(  r ej                  d4d5d6d7d89       yy):    N)ListOptionalDictAny)datetime)FastAPIHTTPExceptionBackgroundTasks
UploadFileFile)CORSMiddleware)	BaseModelz/appz/app/shared)SearchRequestSearchResponseBatchSearchRequestProcessingStatusErrorResponseHealthStatus)KafkaClientget_search_topicTOPICS)RedisClientget_cache_key
CACHE_KEYSCACHE_EXPIRATIONz4%(asctime)s - %(name)s - %(levelname)s - %(message)s)levelformatzWebSearch Microservices APIz-API Gateway for distributed web search system1.0.0)titledescriptionversion*T)allow_originsallow_credentialsallow_methodsallow_headersstartupc                     K   	 t               at               at        j                  d       y# t        $ r} t        j                  d|          d} ~ ww xY ww)z!Initialize connections on startupz API Gateway started successfullyzFailed to start API Gateway: N)r   kafka_clientr   redis_clientloggerinfo	Exceptionerrores    ./services/api-gateway/main.pystartup_eventr2   3   sL     
"}"}67 4QC89s$   A). A	AAAAshutdownc                     K   t         rt         j                          t        rt        j                          t        j	                  d       yw)z Clean up connections on shutdownzAPI Gateway shutdown completedN)r)   closer*   r+   r,        r1   shutdown_eventr8   @   s3     
 
KK01s   AAc                   ^    e Zd ZU eed<   dZeed<   dZeed<   dZeed<   dZ	eed	<   d
Z
eed<   y)SingleSearchRequestquerygooglesearch_engine
   max_results   delay   timeoutTheadlessN)__name__
__module____qualname__str__annotations__r=   r?   intrA   rC   rD   boolr6   r7   r1   r:   r:   K   s8    J!M3!KE3NGSHdr7   r:   /c                  V   K   ddt        j                         j                         dS w)zRoot endpointz#WebSearch Microservices API Gatewayr   )messager!   	timestamp)r   now	isoformatr6   r7   r1   rootrR   S   s*      9\\^--/ s   ')z/healthc            	      L  K   	 t         du} d}t        r!	 t        j                  j                          d}| r|rdnd}t	        d|| rdnd|rdndd      S #  Y %xY w# t
        $ r;}t        j                  d	|        t	        ddd
t        |      i      cY d}~S d}~ww xY ww)zHealth check endpointNFThealthy	unhealthyzapi-gateway)kafkaredis)service_namestatusdetailszHealth check failed: r.   )	r)   r*   clientpingr   r-   r+   r.   rH   )kafka_healthyredis_healthyrY   r0   s       r1   health_checkr_   \   s     
$D0 ##((* $ ,;&&3&3
 	
  
,QC01&c!f%
 	

sJ   B$A  A  A B$AA 	B!&0BB!B$B!!B$z/search)response_modelrequestbackground_tasksc                   K   	 t        | j                  | j                  | j                  | j                  | j
                  | j                        }t        t        d   |j                        }t        |j                  dd| j                   d| j                         }t        j                  ||j                         t        d          t        | j                        }t         j#                  ||j                         |j                  	      }|st%        d
d      t&        j)                  d|j                   d|        |j                  dd| j                   d| j                   d|j                   dS # t*        $ r3}t&        j-                  d|        t%        d
t/        |            d}~ww xY ww)zPerform a single search query)r;   r=   r?   rA   rC   rD   REQUEST_STATUS
request_idpendingzSearch request for 'z' using rf   rY   rN   expiretopicrN   key  zFailed to send search requeststatus_codedetailzSearch request z	 sent to zSearch request submitted for '/status/)rf   rY   rN   check_status_urlzError in single search: N)r   r;   r=   r?   rA   rC   rD   r   r   rf   r   r*   setdictr   r   r)   send_messager	   r+   r,   r-   r.   rH   )ra   rb   search_request
status_keyinitial_statusrl   message_sentr0   s           r1   single_searchr{   ~   s    *<&--!//++--OO%%
 #:.>#?NLeLef
)%00*7==/'BWBWAXY

 	^%8%8%:CSTdCef !!6!67#00"''))) 1 
 C8WXXon&?&?%@	%QR )337hwOdOdNef"*>+D+D*E F	
 	
  </s34CF;;<s)   F>E:E? >F>?	F;.F66F;;F>z/search/batchc           
      &  K   	 t        t        d   | j                        }t        | j                  ddt	        | j
                         dt	        | j                         d      }t        j                  ||j                         t        d          g }| j
                  D ]]  }| j                  D ]L  }t        ||| j                  | j                  | j                  | j                  	      }|j!                  |       N _ |D ]G  }t#        |j$                        }t&        j)                  ||j                         |j                  
       I t*        j-                  d| j                   dt	        |       d       | j                  dt	        |      dt	        | j
                         dt	        | j                         dd| j                   dS # t.        $ r3}	t*        j1                  d|	        t3        dt5        |	            d}	~	ww xY ww)z=Perform batch search with multiple queries and search enginesrd   re   rg   zBatch search with z queries across z enginesrh   ri   )r;   r=   r?   rA   user_id
session_idrk   zBatch search request z with z individual searcheszBatch search submitted with rr   )rf   rY   total_searchesrN   rs   zError in batch search: rn   ro   N)r   r   rf   r   lenqueriessearch_enginesr*   rt   ru   r   r   r?   rA   r}   r~   appendr   r=   r)   rv   r+   r,   r-   r.   r	   rH   )
ra   rb   rx   ry   search_requestsr;   engine
search_reqrl   r0   s
             r1   batch_searchr      s
    -<":.>#?GL^L^_
)))(W__)=(>>NsSZSiSiOjNkkst

 	^%8%8%:CSTdCef __ 
	3E!00 	3*"( ' 3 3!--#OO&11
  &&z2	3
	3 * 	J$Z%=%=>E%%"))) & 	 	+G,>,>+?vc/FZE[[opq ",,!/25c'//6J5KK[\_`g`v`v\w[x  yA  B"*7+=+=*> ?
 	
  <.qc23CF;;<s)   HGG H	H.H		HHz/status/{request_id}rf   c                 (  K   	 t        t        d   |       }t        j                  |      }|st	        dd      t        d
i |S # t        $ r  t        $ r6}t        j                  d|  d|        t	        dt        |            d	}~ww xY ww)z"Get the status of a search requestrd   re     zRequest not foundro   zError getting status for : rn   Nr6   )
r   r   r*   getr	   r   r-   r+   r.   rH   )rf   rx   status_datar0   s       r1   
get_statusr      s     <":.>#?JW
"&&z2C8KLL.+..  <0BqcBCCF;;<s)   BAA BB1B

BBz/results/{request_id}c                   K   	 t        t        d   |       }t        j                  |      }|st	        dd      |S # t        $ r  t
        $ r6}t        j                  d|  d|        t	        dt        |            d	}~ww xY ww)
z-Get the results of a completed search requestSEARCH_RESULTSre   r   zResults not foundro   zError getting results for r   rn   N)	r   r   r*   r   r	   r-   r+   r.   rH   )rf   results_keyresults_datar0   s       r1   get_resultsr      s     <#J/?$@ZX#''4C8KLL  <1*RsCDCF;;<s%   B	9> B	B1BBB	z/upload/queries.filec                 *  K   	 | j                   j                  d      st        dd      d| j                    }t        j                  t        j
                  j                  |      d       t        |d      5 }| j                          d	{   }|j                  |       d	d	d	       | j                   t              d
dS 7 6# 1 sw Y   $xY w# t        $ r3}t        j                  d|        t        dt        |            d	}~ww xY ww)z5Upload a file containing queries for batch processing)z.csvz.xlsxz.xlsi  z&Only CSV and Excel files are supportedro   z/app/results/uploads/T)exist_okwbNzGFile uploaded successfully. Processing functionality to be implemented.)filenamesizerN   zError uploading file: rn   )r   endswithr	   osmakedirspathdirnameopenreadwriter   r-   r+   r.   rH   )r   	file_pathbuffercontentr0   s        r1   upload_queriesr     s     <}}%%&?@C8`aa ,DMM?;	
BGGOOI.>)T" 	"f IIK'GLL!	" L`
 	
 (	" 	"  <-aS12CF;;<sS   DA7C ;CCC% C DCCC 	D.DDDz/enginesc                     K   g dddS w)z$Get list of available search engines)r<   bingyandex
duckduckgoyahoobaidur<   )enginesdefaultr6   r6   r7   r1   get_available_enginesr     s      P s   
z/metricsc                     K   	 ddddt        j                         j                         dS # t        $ r3} t        j                  d|         t        dt        |             d} ~ ww xY ww)z!Get system metrics and statisticsr   g        )requests_processedactive_requestssuccess_rateaverage_response_timerO   zError getting metrics: rn   ro   N)r   rP   rQ   r-   r+   r.   r	   rH   r/   s    r1   get_metricsr   &  sk     < #$ %(!113
 	
  <.qc23CF;;<s$   A+', A+	A(.A##A((A+__main__zmain:appz0.0.0.0i@  r,   F)hostport	log_levelreload)Br   sysloggingasynciouuidtypingr   r   r   r   r   fastapir   r	   r
   r   r   fastapi.middleware.corsr   pydanticr   uvicornr   r   shared.models.schemasr   r   r   r   r   r   shared.utils.kafka_utilsr   r   r   shared.utils.redis_utilsr   r   r   r   basicConfigINFO	getLoggerrE   r+   appadd_middlewarer)   r*   on_eventr2   r8   r:   r   rR   r_   postrH   r{   r   r   r   r   r   r   runr6   r7   r1   <module>r      s   	 
    , ,  M M 2        K J ] ]   
,,A 
		8	$
'?   %%%   i
 
 j2 2)    
 
B )DcN3,<!4 ,< ,< 4,<\ /$sCx.9/< 2 /<o /< :/<b 	0@A< < B<" 	 !<# < "<" 
,0I <z < <4   < < zGKK r7   