U
    	mh2*                     @   st  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d e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j(ej)dd e*e+Z,eddddZ-e-j.edgddgdgd da/da0e-1ddd Z2e-1ddd Z3G dd deZ4e-5ddd Z6e-5d d!d" Z7e-j8d#ee9e	f d$e4ed%d&d'Z:e-j8d(ee9e	f d$eed%d)d*Z;e-j5d+ed$e9d,d-d.Z<e-5d/e9d,d0d1Z=e-8d2ed3fed4d5d6Z>e-5d7d8d9 Z?e-5d:d;d< Z@e+d=krpejAd>d?d@dAdBdC dS )D    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)titleZdescriptionversion*T)Zallow_originsZallow_credentialsZallow_methodsZallow_headersZstartupc               
      sT   zt  at atd W n4 tk
rN }  ztd|    W 5 d} ~ X Y nX dS )z!Initialize connections on startupz API Gateway started successfullyzFailed to start API Gateway: N)r   kafka_clientr   redis_clientloggerinfo	Exceptionerrore r)   services/api-gateway/main.pystartup_event3   s    r+   Zshutdownc                      s&   t rt   trt  td dS )z Clean up connections on shutdownzAPI Gateway shutdown completedN)r!   closer"   r#   r$   r)   r)   r)   r*   shutdown_event@   s
    r-   c                   @   sR   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< dS )SingleSearchRequestquerygooglesearch_engine
   max_results   delay   timeoutTheadlessN)__name__
__module____qualname__str__annotations__r1   r3   intr5   r7   r8   boolr)   r)   r)   r*   r.   K   s   
r.   /c                      s   ddt   dS )zRoot endpointz#WebSearch Microservices API Gatewayr   )messager   	timestamp)r   now	isoformatr)   r)   r)   r*   rootS   s    
rE   z/healthc               
      s   zft dk	} d}tr2ztj  d}W n   Y nX | r>|r>dnd}td|| rPdnd|rZdndddW S  tk
r } z.td	|  tddd
t|id W Y S d}~X Y nX dS )zHealth check endpointNFTZhealthyZ	unhealthyzapi-gateway)ZkafkaZredis)Zservice_namestatusZdetailszHealth check failed: r&   )	r!   r"   ZclientZpingr   r%   r#   r&   r<   )Zkafka_healthyZredis_healthyrF   r(   r)   r)   r*   health_check\   s0    



rG   z/search)Zresponse_model)requestbackground_tasksc              
      s&  zt | j| j| j| j| j| jd}ttd |j	d}t
|j	dd| j d| j d}tj|| td d t| j}tj|| |j	d	}|std
ddtd|j	 d|  |j	dd| j d| j d|j	 dW S  tk
r  } z$td|  td
t|dW 5 d}~X Y nX dS )zPerform a single search query)r/   r1   r3   r5   r7   r8   REQUEST_STATUS
request_idpendingzSearch request for 'z' using rL   rF   rA   ZexpiretopicrA   key  zFailed to send search requestZstatus_codeZdetailzSearch request z	 sent to zSearch request submitted for '/status/)rL   rF   rA   check_status_urlzError in single search: N)r   r/   r1   r3   r5   r7   r8   r   r   rL   r   r"   setdictr   r   r!   send_messager   r#   r$   r%   r&   r<   )rH   rI   Zsearch_request
status_keyinitial_statusrQ   Zmessage_sentr(   r)   r)   r*   single_search~   sB    


r\   z/search/batchc           
   
      sd  zt td | jd}t| jddt| j dt| j dd}tj||	 t
d d g }| jD ]6}| jD ]*}t||| j| j| j| jd	}|| qlqb|D ]$}t|j}tj||	 |jd
 qtd| j dt| d | jdt|dt| j dt| j dd| j dW S  tk
r^ }	 z$td|	  tdt|	dW 5 d}	~	X Y nX dS )z=Perform batch search with multiple queries and search enginesrJ   rK   rM   zBatch search with z queries across z enginesrN   rO   )r/   r1   r3   r5   user_id
session_idrP   zBatch search request z with z individual searcheszBatch search submitted with rU   )rL   rF   Ztotal_searchesrA   rV   zError in batch search: rS   rT   N)r   r   rL   r   lenZqueriesZsearch_enginesr"   rW   rX   r   r   r3   r5   r]   r^   appendr   r1   r!   rY   r#   r$   r%   r&   r   r<   )
rH   rI   rZ   r[   Zsearch_requestsr/   ZengineZ
search_reqrQ   r(   r)   r)   r*   batch_search   sJ    



ra   z/status/{request_id}rK   c              
      s   z6t td | d}t|}|s,tdddtf |W S  tk
rL    Y nH tk
r } z*td|  d|  tdt	|dW 5 d	}~X Y nX d	S )
z"Get the status of a search requestrJ   rK     zRequest not foundrT   zError getting status for : rS   N)
r   r   r"   getr   r   r%   r#   r&   r<   )rL   rZ   Zstatus_datar(   r)   r)   r*   
get_status   s    
re   z/results/{request_id}c              
      s   z0t td | d}t|}|s,tddd|W S  tk
rF    Y nH tk
r } z*td|  d|  tdt|dW 5 d	}~X Y nX d	S )
z-Get the results of a completed search requestZSEARCH_RESULTSrK   rb   zResults not foundrT   zError getting results for rc   rS   N)	r   r   r"   rd   r   r%   r#   r&   r<   )rL   Zresults_keyZresults_datar(   r)   r)   r*   get_results   s    
rf   z/upload/queries.)filec              
      s   z|| j dstdddd| j  }tjtj|dd t|d}|  I d	H }|	| W 5 Q R X | j t
|d
dW S  tk
r } z$td|  tdt|dW 5 d	}~X Y nX d	S )z5Upload a file containing queries for batch processing)z.csvz.xlsxz.xlsi  z&Only CSV and Excel files are supportedrT   z/app/results/uploads/T)exist_okwbNzGFile uploaded successfully. Processing functionality to be implemented.)filenamesizerA   zError uploading file: rS   )rj   endswithr   osmakedirspathdirnameopenreadwriter_   r%   r#   r&   r<   )rg   Z	file_pathbufferZcontentr(   r)   r)   r*   upload_queries  s    ru   z/enginesc                      s   ddddddgddS )z$Get list of available search enginesr0   ZbingZyandexZ
duckduckgoZyahooZbaidu)Zenginesdefaultr)   r)   r)   r)   r*   get_available_engines  s    rw   z/metricsc               
      sb   zddddt   dW S  tk
r\ }  z$td|   tdt| dW 5 d} ~ X Y nX dS )z!Get system metrics and statisticsr   g        )Zrequests_processedZactive_requestsZsuccess_rateZaverage_response_timerB   zError getting metrics: rS   rT   N)r   rC   rD   r%   r#   r&   r   r<   r'   r)   r)   r*   get_metrics&  s    
rx   __main__zmain:appz0.0.0.0i@  r$   F)ZhostZportZ	log_levelreload)Brm   sysZloggingZasyncioZuuidtypingr   r   r   r   r   Zfastapir   r   r	   r
   r   Zfastapi.middleware.corsr   Zpydanticr   Zuvicornro   r`   Zshared.models.schemasr   r   r   r   r   r   Zshared.utils.kafka_utilsr   r   r   Zshared.utils.redis_utilsr   r   r   r   ZbasicConfigINFOZ	getLoggerr9   r#   ZappZadd_middlewarer!   r"   Zon_eventr+   r-   r.   rd   rE   rG   Zpostr<   r\   ra   re   rf   ru   rw   rx   runr)   r)   r)   r*   <module>   s    
	




!.1


