o
     )hk                     @   sp  d dl mZmZmZ d dlmZ d dlmZ d dlZd dl	Z	d dl
Z
d dlmZ d dlZd dlZd dlZd dlZd dlmZmZ d dlmZ e  e
dZe
je
jd	 ed
ddZe	dZesfedeeZG dd deZ G dd deZ!ej"dddde fddZ#ej"dddde!fddZ$e"ddefdd Z%e&d!krd dl'Z'e'j(d"d#d$d%d& dS dS )'    )FastAPIHTTPExceptionBackgroundTasks)	BaseModel)JSONResponseN)load_dotenv)fetch_page_htmlextract_text_from_html)parse_funding_textzuvicorn.error)levelzQAAPT Funders Microservicez1.0.0)titleversionCOHERE_API_KEYu-   ❌ COHERE_API_KEY is not set in environment.c                   @   s*   e Zd ZU ee ed< eed< eed< dS )QueryRequest	variablesdatasetNamequeryN)__name__
__module____qualname__liststr__annotations__ r   r   2/var/www/qbot.qaapt.com/qbot.qaapt.com/app/main.pyr   %   s   
 r   c                   @   s.   e Zd ZU dZedB ed< dZedB ed< dS )FundingRequestNurlhtml)r   r   r   r   r   r   r   r   r   r   r   r   *   s   
 r   z/api/sql/generatez"Generate SQL from Natural Language)summaryrequestc              
      s   d| j  dd| j d| j d }z+tjd|ddd	gd
}|jd j }|	 
ds<td|  tdd|iW S  tyW } ztd tdddd}~ww )zR
    Convert natural language query into MySQL SELECT statement using Cohere.
    zv
You are a data analyst. Translate the following natural language query into a valid MySQL SELECT statement:
Dataset: z

Columns: z, z
User Query: zU
Provide only the SQL SELECT query without any explanation or code block formatting.
zcommand-xlarge-nightly   g?;)modelprompt
max_tokenstemperaturestop_sequencesr   selectzInvalid SQL generated: z)Generated SQL does not start with SELECT.sqlu   ❌ Failed to generate SQL  z"Failed to generate SQL from query.status_codedetailN)r   joinr   r   stripcogenerategenerationstextlower
startswithloggerwarning
ValueError	Exception	exceptionr   )r   r#   responsesql_texter   r   r   generate_sql0   s8   


r=   z/api/funding/parsezExtract structured funding infoc              
      s  | j s| jstdddz]| jpt| j }|stdt|}|r*t| dk r.tdt|t	}t
d tjdd	| tjd
}zt|}W n tye } zt
d|  tdddd}~ww d|iW S  ty } zt
d tddt| dd}~ww )z
    Accepts a funding webpage (URL or raw HTML), extracts plain text,
    and uses LLM to parse key funding opportunity metadata.
    i  z(Either 'url' or 'html' must be provided.r*   z+No HTML content found from provided source.2   z*Extracted text appears too short or empty.zRaw LLM response received.z^```(json)?|```$ )flagsu   ⚠️ JSON parse error: r)   z"Failed to parse funding info JSON.Nparsedu   ❌ Funding parsing failedzFunding parsing failed: )r   r   r   r   r7   r	   lenr.   r
   r/   r5   inforesub	MULTILINEjsonloadsr8   errorr9   r   )r   r   
plain_textparsed_resultcleaned_textparsed_jsonjson_errr<   r   r   r   parse_fundingT   s4   



rO   z/api/funding/scrapebackground_tasksc                    s   dd }|  | ddiS )Nc                  S   sp   t jt  dd} tjddddddg}tj|| ddd	}td
|j	 td|j
 |jdkr6td|j d S )Nfunderspiderz-mscrapycrawlfunder_spiderz-ozfunding_data.jsonT)cwdcapture_outputr2   zScrapy STDOUT:zScrapy STDERR:r   z$Scrapy spider failed with exit code )ospathr-   getcwdsys
executable
subprocessrunprintstdoutstderr
returncodeRuntimeError)rU   cmdresultr   r   r   
run_spiderz   s   
z%run_scrapy_spider.<locals>.run_spidermessagezKSpider started, results will be saved to app/funderspider/funding_data.json)add_task)rP   re   r   r   r   run_scrapy_spiderx   s   
rh   __main__zmain:appz0.0.0.0i@  T)hostportreload))fastapir   r   r   pydanticr   fastapi.responsesr   cohererW   loggingdotenvr   rG   rD   r\   rZ   funder_scraperr   r	   funder_parserr
   	getLoggerr5   basicConfigINFOappgetenvr   rb   Clientr/   r   r   postr=   rO   rh   r   uvicornr]   r   r   r   r   <module>   sB    


##