
    iz~                     6   d Z ddlZddlZddlZ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 ddlZddlmZ  e        ddlmZ ddlmZ ddlmZ ddlZddlmZ  ed	       ej2                  j5                  ej2                  j7                  e            Zej2                  j5                  e      Zej2                  j?                  de       dd
l m!Z!  eddd      Z"ddl#Z#ddl$Z$ddl%Z%dejL                  d<   dejL                  d<    e$jN                  de(        e%jR                  d      jU                  e%jV                         dZ, ed        ede,      Z- ed        ed       i Z.g a/d Z0ddl1Z1 e1jd                  e0d      jg                          d Z4 e1jd                  e4d      jg                          d e5fd!Z6d e5d"e5d#e5fd$Z7 G d% d&e      Z8d' Z9d(e5d)e5fd*Z:d+e5fd,Z;d+e5fd-Z<d.d/d0d1d2Z=d"e5fd3Z>d4Z?d"e5fd5Z@e"j                  d6      d7e8fd8       ZBy)9a  
Backend API for Dr. Robert Young's semantic search Q&A system

This module provides a FastAPI application that:
1. Performs semantic search on scraped blog articles
2. Generates contextual answers using local LLM
3. Provides performance timing information
    N)deque)load_dotenv)FastAPI)StreamingResponse)	BaseModel)SentenceTransformerz&[INFO] Using only Ollama (local mode).)get_connectionz$Dr. Robert Young Semantic Search APIzBSemantic search and Q&A system for Dr. Robert Young's blog contentz1.0.0)titledescriptionversionfalseTOKENIZERS_PARALLELISM1HF_HUB_DISABLE_TELEMETRYignore)categorysentence_transformerscpuz5[MODEL] Loading embedding model (from local cache)...zall-MiniLM-L6-v2)devicez[MODEL] Embedding model ready!z[LLM] Using Ollama (Local mode)c            	      (   	 t        d       t               } | j                  d      }|j                  d       |j	                         }|j                          | j                          g }|D ]Q  }	 t        j                  t        j                  |d               }|j                  |d   |d   |d   |d	   |d
       S |at        dt        t               d       y# t        $ r Y ~w xY w# t        $ r}t        d|        Y d}~yd}~ww xY w)z:Load all article embeddings from DB into memory at startupz2
[CACHE] Loading article embeddings into memory...T
dictionaryzDSELECT id, title, url, content, embedding FROM dr_young_all_articles	embeddingidr
   urlcontent)r   r
   r   r   r   z[CACHE] Loaded z articles into memory!z[CACHE] Failed to load cache: N)printr	   cursorexecutefetchallclosenparrayastliteral_evalappend	Exceptionarticle_cachelen)conncurrows	new_cacherembes          /var/www/html/backend/main.pyload_article_cacher2   M   s   4CDkkTk*Z[||~		

	 	A
hhs//+?@  D'wZU8 |!$" 	 "M 233IJK    4.qc2334s=   A/C0 2AC!  C0 !	C-*C0 ,C--C0 0	D9DDT)targetdaemonc                     	 t        d       t        j                  dddddd      } | j                  d	k(  rt        d
       yt        d| j                          y# t        $ r#}t        d|        t        d       Y d}~yd}~ww xY w)z
    Warm up the Ollama model by making a simple request
    This pre-loads the model into memory to avoid delays on first user request
    z
[OLLAMA] Warming up model...#http://localhost:11434/api/generatellama3.2:latestHelloT)modelpromptstream<   )jsontimeout   z&[OLLAMA] Model warmed up successfully!z![OLLAMA] Warm-up returned status z[OLLAMA] Warm-up failed: zB[OLLAMA] Model will load on first request (may take 10-15 seconds)N)r   requestspoststatus_coder'   )responser0   s     r1   warm_up_ollama_modelrD   p   s    
T./==1*!
 
 3&:;5h6J6J5KLM T)!-.RSSTs   AA A 	B	&BB	conversation_idc                 J    | t         vrt        d      t         | <   t         |    S )z%Get conversation history for given ID   )maxlen)conversation_memoryr   )rE   s    r1   get_conversation_historyrJ      s%    11/4AO,//    questionanswerc                     t        |       }|j                  ||t        j                         d       t        d|  d       t        d|dd  d       t        d|dd  d       t        d	t	        |              y)
z'Add interaction to conversation history)rL   rM   	timestampz[SAVED] Session [z]:z   Question: Nr<   z...z   Answer: z   Total interactions: )rJ   r&   timer   r)   )rE   rL   rM   historys       r1   add_to_conversation_historyrR      s    &7GNNYY[  
o.b
12	M(3B-
,-	Ks}C
()	#CL>
23rK   c                   *    e Zd ZU dZeed<   dZeed<   y)ChatRequestz
    Request model for chat endpoint
    
    Attributes:
        question (str): The user's question to be answered
        conversation_id (str): Optional conversation identifier to maintain context
    rL   defaultrE   N)__name__
__module____qualname____doc__str__annotations__rE    rK   r1   rT   rT      s     M$OS$rK   rT   c                     t        j                  | |      t         j                  j                  |       t         j                  j                  |      z  z  S )z
    Calculate cosine similarity between two vectors
    
    Args:
        a (numpy.ndarray): First vector
        b (numpy.ndarray): Second vector
        
    Returns:
        float: Cosine similarity score between 0 and 1
    )r"   dotlinalgnorm)abs     r1   cosinerc      s8     66!Q<299>>!,ryy~~a/@@AArK   textreturnc                    t        j                  dd|       } t        j                  dd|       } t        j                  dd| t         j                  t         j                  z        } | j	                  dd      } | j                         S )	a"  
    Clean and preprocess context text for LLM consumption
    
    This function removes unwanted formatting elements that might confuse the LLM.
    
    Args:
        text (str): Raw text content to be cleaned
        
    Returns:
        str: Cleaned text ready for LLM processing
    z\n?\s*\d+[\.]\)\s* u   [•\-–▪]z\n\s*References?\s*:\s*$ )flags   ZeolitéZeolite)resub	MULTILINE
IGNORECASEreplacestrip)rd   s    r1   clean_contextrr      sn     66'd3D 66"C.D 66-r4r||bmm?[\D <<
I.D::<rK   r:   c              #     K   	 t        j                  dd| ddddddd	dd
      5 }|j                  dk7  rQt        |d      r|j                  nd}t        d|j                   d|        d|j                   d 	 ddd       yd}|j                         D ]a  }|s	 t        j                  |j                  d            }d|v r |d   rd}|d   j                  dd      }| |j                  d      r nc |sd ddd       y# t        j                  $ r Y t        $ r}dt        |        Y d}~ Bd}~ww xY w# 1 sw Y   yxY w# t         j                  j                   $ r d Y yt         j                  j"                  $ r d Y yt        $ r]}t        dt%        |      j&                   dt        |              dt%        |      j&                   d t        |        Y d}~yd}~ww xY ww)!a  
    Call locally running LLM via Ollama with streaming capability

    This function establishes a streaming connection to the Ollama service
    and yields response chunks as they become available, enabling real-time
    response delivery to the client.

    Args:
        prompt (str): Formatted prompt including context and question

    Yields:
        str: Response chunks from the LLM as they are generated

    Raises:
        Exception: If connection to Ollama fails or streaming encounters errors
    r6   r7   T皙??333333?   temperaturetop_prepeat_penaltynum_predictr9   r:   r;   options,  r=   r;   r>   r?   rd   zNo error detailsz[OLLAMA ERROR] Status z: z$[LLM ERROR]: Ollama returned status z?. The model may be loading. Please wait a moment and try again.NFutf-8rC   rj   rk   donez[PARSING ERROR]: zT[LLM ERROR]: No response received. The model may still be loading. Please try again.zZ[LLM ERROR]: Cannot connect to Ollama service. Is it running? Start it with 'ollama serve'za[LLM ERROR]: Ollama request timed out. The model may be loading or the prompt may be too complex.z[OLLAMA EXCEPTION]: [LLM ERROR]: z - )r@   rA   rB   hasattrrd   r   
iter_linesr=   loadsdecoderp   getJSONDecodeErrorr'   rZ   
exceptionsConnectionErrorTimeouttyperV   )r:   r.   
error_textreceived_responselinedatachunkr0   s           r1   call_llama2_streamr      s+    "B<]]1* #& &)#&		
 
 7	m }}#'.q&'9QVV?Q
.q}}oR
|LM<Q]]O  LK  L  L-7	m 7	m2 !&  ::dkk'&:;D "T)d:.>,0) $Z 0 8 8Y O# xx' (4 %llo7	m 7	m\ ++   -c!fX66c7	m 7	mr .. kjj&& rqq <$T!W%5%5$6bQABd1g../s3q6(;;<s   H#E AE?E HE!AD:
EE HE E"E*E :E EEEE HE !G>5H7 G>HG>!AG94H9G>>Hc              #     K   	 t        j                  dd| ddddddd	dd
      5 }|j                         D ]Y  }|st        j                  |j                  d            }d|v r|d   j                  dd      }| |j                  d      sY n ddd       y# 1 sw Y   yxY w# t        $ r}dt        |        Y d}~yd}~ww xY ww)a  
    Call locally running LLM via Ollama with streaming capability for direct responses

    This function establishes a streaming connection to the Ollama service
    and yields response chunks as they become available.

    Args:
        prompt (str): Formatted prompt including context and question

    Yields:
        str: Response chunks from the LLM as they are generated

    Raises:
        Exception: If connection to Ollama fails or streaming encounters errors
    r6   r7   Trt   ru   rv   rw   rx   r}   r   r   r   rC   rj   rk   r   Nz
[LLM ERROR]: )
r@   rA   r   r=   r   r   rp   r   r'   rZ   )r:   r.   r   r   r   r0   s         r1   call_llama2_stream_directr   /  s      &)]]1* #& &)#&		
 
  	    zz$++g"67 % ,44ZKEK 88F#% 	  	  	D  )Ax(()sX   C#B) A)BBB) CB&"B) %C&B) )	C2CCCCzYes I am an AI programmed by Team MasterPeace to help. To email a human on Team MasterPeace please email help@masterpeacebyhcs.com. If it takes too long to hear back, please reply to the email you already sent to follow up.zNo I am not a human. I am an AI programmed by Team MasterPeace to help. To email a human on Team MasterPeace please email help@masterpeacebyhcs.com. If it takes too long to hear back, please reply to the email you already sent to follow up.zYes I am an AI bot programmed by Team MasterPeace to help. To email a human on Team MasterPeace please email help@masterpeacebyhcs.com. If it takes too long to hear back, please reply to the email you already sent to follow up.zNo, I am not a real person. I am an AI programmed by Team MasterPeace to help. To email a human on Team MasterPeace please email help@masterpeacebyhcs.com. If it takes too long to hear back, please reply to the email you already sent to follow up.)aihumanbotreal_personc                 .   | j                         j                         j                  d      }g d}g d}ddg}ddg}|D ]  }||v st        d   c S  |D ]  }||v st        d	   c S  |D ]  }||v st        d
   c S  |D ]  }||v st        d   c S  y)zKCheck if question is about the bot's identity and return hardcoded responsez?!. )	z
are you aizare you an aizare you artificial intelligencezare you a robotzare you machinezare you a machinezare you chatbotzare you a chatbotzare you chat bot)zare you humanzare you a humanzare you a real humanzare you a personzare you real personzare you a real personzare you a botzare you botzwho are youzwhat are your   r   r   N)lowerrq   rstripIDENTITY_QA)rL   q_lowerai_patternshuman_patternsbot_patternswho_patternsps          r1   check_identity_questionr   q  s    nn$$&--f5G LK VN#]3L!>2L %<t$$%  (<w''(  &<u%%&  %<t$$% rK   aY  I'm sorry, I'm not able to provide personal advice. I am an AI programmed by Team MasterPeace to help with general information about Dr. Robert Young's research and the alkaline lifestyle. For personal assistance, please email help@masterpeacebyhcs.com. If it takes too long to hear back, please reply to the email you already sent to follow up.c                 n    | j                         j                         }g d}|D ]  }||v st        c S  y)z6Check if question is a personal/medical advice request)2zwhat should i dozwhat should i takezwhat should i eatzwhat should i drinkzwhat can i dozcan you help mezhelp me with myzi have been diagnosedzi was diagnosedzmy doctor saidzmy doctor toldzi am sufferingz	i am sickzi feel sickzi'm sickzim sickzwhat medicinez	what drugzwhat treatment shouldzshould i takezshould i usezshould i tryzrecommend for mezsuggest for mez	advise mezi have cancerzi have diabeteszi have diseasezcure myztreat myzheal myzwhat do you recommend for myzwhat would you suggest for myzhow do i curezhow do i treatzhow can i curezcan you diagnosezcan you prescribezwhat is wrong with mez	am i sickzmy symptomszi have symptomszpersonal advicezpersonal recommendationzwhat's your phonezwhat's your numberz
your emailzwhere do you livezwhere are you locatedzyour addressN)r   rq   PERSONAL_RESPONSE)rL   r   personal_patternsr   s       r1   check_personal_questionr     sB    nn$$&G,  %<$$% rK   z/chatqc                 f   ()*+,-./012345678K   t         j                        //r0t        d j                   d       /fd}t         |       d      S t	         j                        22r0t        d j                   d       2fd}t         |       d      S t        j
                         7t         j                        }t        d j                          t        d	t        |       d
       t        j
                         }t        j                   j                  dd      }t        j
                         |z
  -t        j
                         }t               ((j                  d      +t        j
                         |z
  ,g }t        j
                         }d}	t        D ]  }
t        ||
d         }h d} j                  j                         j!                         D cg c]  }||vst        |      dkD  s| }}|r|
d   j                         8|
j#                  d      xs ddd j                         )t%        8fd|D              }t%        )fd|D              }|t'        |dz  d      z  }|t'        |dz  d      z  }||	kD  r|}	|dkD  s|j)                  ||
f       	 t+        |d d       }t-               }g }|D ]^  \  }}
|
d   j/                         j                         }||vr$|j1                  |       |j)                  ||
f       t        |      dk(  s^ n |}t        j
                         |z
  6t        d!|	d"       |r3t3        |d#      D ]#  \  }\  }}
t        d$| d%|
d   dd&  d'|d"       % nt        d( j                   d       |s j                  j                         4|st        d) j                   d       d*.n|r|r|d+   ni }|r |j#                  d,d      j                         nd}|r |j#                  d-d      j                         nd}| d.| }t-        |j!                               }t-        4j!                               }t        |j5                  |            }t        |j7                  |            }|d/kD  r||z  nd/}|d0kD  s%t9        4fd1|j!                         dd2 D              rwt        d3|d4d5 j                   d       t        d6|dd&  d7|dd&  d8       |dd9  d: j                   d;0t        j
                         101 fd<}t         |       d      S t        d=|d4d5 j                   d       t        d>|dd&  d7|dd&  d8       d*..fd?} t         |        d      S t        j
                         }!g }"g 5|D ]g  \  }#}
5j)                  |
d   |
d@   dA       +j;                  dB|
dC   f       +j=                         }$|$sIt?        |$d         }%|"j)                  |%       i t        dDdE        t        dFt        |"       dG       t3        |d#      D ]<  \  }\  }}
t        dH| dI|
d           t        dJ|
d@           t        dK|d"       > t        dE        dLjA                  |"      }&t        j
                         |!z
  *t        dMt        |&       dNt        |&ddO               t        dP j                          t        dDdQ        t        dR       t        dQ        t        |&ddO        t        dQ        t        dS       t        dE        dT|&ddO  dU j                   dV3t        j
                         1(*+,-13 567fdW}'t         |'       d      S c c}w w)Xa  
    Main chat endpoint that processes user questions with session-based memory

    This endpoint performs semantic search on the blog database, maintains conversation
    context, and generates contextual answers using a local LLM.

    Args:
        q (ChatRequest): The user's question request with optional conversation ID

    Returns:
        StreamingResponse: Streaming response containing answer and references
    z'[IDENTITY] Matched identity question: ''c               3      K   j                         } t        |       D ]4  \  }}||t        |       dz
  k  rdndz    t        j                  d       6 y wN   rg   rh   {Gz?split	enumerater)   rP   sleep)wordsiwordidentity_answers      r1   stream_identityzchat.<locals>.stream_identity  U     #))+E$U+ !4QUa%7cR@@

4 !   AAz
text/plain)
media_typez'[PERSONAL] Matched personal question: 'c               3      K   j                         } t        |       D ]4  \  }}||t        |       dz
  k  rdndz    t        j                  d       6 y wr   r   )r   r   r   personal_answers      r1   stream_personalzchat.<locals>.stream_personal  r   r   z[SESSION] CONVERSATION: z[HISTORY] LENGTH: z interactionsTr   )convert_to_numpyr   r   g        r   >)   ra   r   andoinisitmemyofortoandcanforhowthewhydoesfromgivehelplongmeanneedsuchtelltermthatthemthiswhataboutaftertheirthesethoseusingreallyexampleexplain   r
   r   rh   Ni  c              3   ,   K   | ]  }|v sd   ywr   Nr\   ).0wtitle_lowers     r1   	<genexpr>zchat.<locals>.<genexpr>  s     PaqK?OP   	c              3   ,   K   | ]  }|v sd   ywr   r\   )r   r   content_lowers     r1   r   zchat.<locals>.<genexpr>  s     !TmAS!!Tr   g?g333333?r   rt   g      ?c                     | d   S )Nr   r\   )xs    r1   <lambda>zchat.<locals>.<lambda>  s
    !A$ rK   )keyreversez[SEARCH] Highest score found: z.3fr   z[SEARCH] Match z: '2   z' score=z#[SEARCH] No match above 0.25 for: 'z?[CASE 4] TRIGGERED: No DB match + No conversation history for 'a#  I don't have reliable information about this specific topic in the available content. Could you please provide more details or rephrase your question? Alternatively, you might want to ask about related topics like general health principles, wellness practices, or preventive care approaches.rL   rM   rg   r   g333333?c              3   &   K   | ]  }|v  
 y w)Nr\   )r   r   question_lowers     r1   r   zchat.<locals>.<genexpr>N  s     ,nT^-C,ns   
   z4[CASE 3] TRIGGERED: No DB match + Continuing topic (.2fz similarity) for 'z   Matching against: Question='z...' Answer='z...'i  z

Q: z
A:c               3     K   d} 	 t         } |      D ]1  }|j                         s| |z  } | t        j                  d       3 dj	                  | j                               }t        j                  j                  |       t        j                         z
  }t        d|dd       y # t        $ r}dt        |        Y d }~y d }~ww xY ww)Nrh   {Gz?rg   z[TIMING] CASE 3 LLM: r   sr   )r   rq   rP   r   joinr   rR   rE   rL   r   r'   rZ   )	full_answerllm_functionr   clean_answerllm_timer0   
llm_prompt	llm_startr   s	         r1   stream_case3_responsez#chat.<locals>.stream_case3_response\  s     "$K7'@%1*%= 1E${{} +u 4&+ $

4 0	1 (+xx0A0A0C'D3A4E4EqzzS_`#'99;#: 5hs^1EF$ 7 -c!fX667s4   C!B1 BB1 0C1	C:C
CCCz3[CASE 4] TRIGGERED: No DB match + Different topic (z   Context: Question='c               3      K   j                         } t        |       D ]4  \  }}||t        |       dz
  k  rdndz    t        j                  d       6 y w)Nr   rg   rh   r   r   )r   r   r   general_answers      r1   stream_general_responsez%chat.<locals>.stream_general_response  sU     "((*E$U+ !4QUa%7cR@@

4 !r   r   )r
   r   z7SELECT content FROM dr_young_all_articles WHERE id = %sr   
z<============================================================z
[CONTEXT] z articles matched:z  [z	] Title: z      URL: z      Score: z

u'   
[CONTEXT → MODEL] Total Characters: z | Sent to LLM: ip  z[QUESTION] u   ────────────────────────────────────────────────────────────z[FULL CONTEXT FROM DB]:z[END CONTEXT]a`  <|system|>
You are a strict Q&A assistant for Dr. Robert O. Young's alkaline lifestyle research.

RULES:
1. ONLY use information from the CONTEXT below. Do NOT add outside knowledge.
2. If context lacks the answer, say: "I don't have enough information based on the available articles."
3. Do NOT invent, guess, or fabricate any facts not in the context.
4. Start your answer directly. No preambles like "Sure!", "Based on the context..." etc.
5. Use professional scientific tone. Be concise and accurate.
6. Use numbered lists (1.) or bullet points (-). Each item on its own line.
7. Always spell "Zeolite" (no accents) and "pH" (lowercase p, uppercase H).
8. CRITICAL: When the context labels something as "FALSE" or a "myth", it means that claim is WRONG. Do NOT present false/myth claims as facts. Instead explain why they are wrong according to the context.
9. Dr. Young PROMOTES the alkaline lifestyle. All answers should reflect his pro-alkaline position as stated in the context.
10. Do NOT recommend fruits, dairy, sugar, or acidic foods as healthy unless the context explicitly says so.
</s>
<|user|>
CONTEXT:
z

QUESTION: z
</s>
<|assistant|>c            	   3   @  K   d} 	 t         } |      D ]C  }|j                         s|j                  dd      }| |z  } | t        j                  d       E g }t               }D ]J  }|d   j                         j                         }||vs)|j                  |       |j                  |       L |rAd |D ]  }|d   s	d|d    d	  d
 t        |d      D ]  \  }}| d|d    d	  dj                  | j                               }t        j                  j                  |       t        j                         z
  }	t        j                         z
  }
t        d       t        ddddddd       t        ddd|	dd|
dd       	 j%                          j%                          y # t         $ r}dt#        |        Y d }~@d }~ww xY w#  Y y xY w# 	 j%                          j%                          w #  Y w xY wxY ww)Nrh   rj   rk   r   r
   z

See here for more info:
r   z- r
  z
References:
r   z. rg   z	[TIMING]:zEmbedding: r   zs | DB: zs | Search: r   z	Context: z	s | LLM: zs | Total: r   )r   rq   rp   rP   r   setr   r&   addr   r   r   rR   rE   rL   r   r'   rZ   r!   )r   r  r   unique_referencesseen_titlesreftitle_cleanr   r  r  
total_timer0   r*   context_timer+   db_time
embed_timer  r:   r   
referencessearch_time
start_times               r1   stream_responsezchat.<locals>.stream_response  s1    /	-L%f- %;;=!MM*i@E5(KKJJt$% !#%K! 1!'l00288:k1%,,S1OOK0	1 !55, 2C5z "3u:,b112 (''(91= 3FAsCr#g,r223 88K$5$5$78L'(9(91::|Tyy{Y.Hz1J+K
3/x}LQ\]`PaabcdIl3/y#kR\]`Qaabcd		

  	+!#a&**	+			

sw   H!G A(G 4G CG # G* H	G'G"G1 "G''G1 *G.,H1H3 HHHHH)!r   rL   r   r   r   rP   rJ   rE   r)   embed_modelencoder	   r   r(   rc   r   r   r   summinr&   sortedr  rq   r  r   intersectionunionanyr   fetchonerr   r   )9r   r   r   rQ   embed_start	query_embdb_startscoredsearch_starthighest_scoreartscore
skip_wordsr   meaningful_wordstitle_matchescontent_matchesr  unique_scoredr   	title_keyr   last_interactionlast_questionlast_answercombined_contextconversation_keywordscurrent_keywordsoverlaptotal_uniquesimilarity_ratior  r	  context_startcontext_parts_content_rowcleanedcontextr  r*   r   r  r+   r  r  r  r   r  r  r   r:   r   r  r  r  r   s9   `                                       @@@@@@@@@@@@@@@@@r1   chatr@    s1     .ajj9O7

|1EF	!
 !!2|LL .ajj9O7

|1EF	!
 !!2|LL J 'q'8'89G 
$Q%6%6$7
89	s7|nM
:; ))+K""	

 # I
 {*J yy{HD
+++
&CiikH$G F 99;LM (y#k"23 L
'(zz'7'7'9'?'?'Ah!QjEX]`ab]cfg]gAhhg,,,.K WWY/52u=CCEM  P+;PPM!!T-=!TTO S-t44ES4/66E= !M 4<MM5#,'7(< F=F%KM 3L&&(..0	K'OOI&  !S*}" F))+,K 
*=*=
>?(3 	ROA|sOA3c#g,s*;)<HU3KPQ	R 	3AJJ<qAB ))+ STUT^T^S__`abE   /6wr{2L\,00R@FFHbdMHX*..x<BBD^`K #0+?$'(8(>(>(@$A!">#7#7#9: /<<=MNOG4::;KLML9E9Iw5q  #%,nP`PfPfPhiljlPm,n)nLM]^aLbbtuvuu  uA  AB  C  D7cr8J7K=YdehfhYiXjjnop #.ds"3!4 5JJ< 
 !IIK	7, ))>)@\ZZ KL\]`Kaastut~t~s  @A  B  C.}Sb/A.B-P[\_]_P`OaaefgI 	! !!8!:|TT IIKMMJ *3\u:
 	
 	MPSTXPY|\lln#K	$:;G  )* 
Bvh-	Js=)**<
=>$VQ/ +<E3A3iG~./CJ<()eC[)*+ 
VH kk-(G99;.L 
4S\NBRSVW^_d`dWeSfRg
hi	K

|
$%	Bxj/	#%	XJ	'%4.	XJ	M	VH" 	$  ::, 'F. 		I4 4l  E is4   G^1/	^,9^,^,B^1"B^13K^1F*^1)CrY   sysosrP   rl   r$   r=   
subprocessnumpyr"   collectionsr   asynciodotenvr   fastapir   fastapi.responsesr   pydanticr   r@   r   r   r   pathdirnameabspath__file__current_dirproject_rootinsertdatabase.dbr	   apptorchwarningsloggingenvironfilterwarningsFutureWarning	getLoggersetLevelERRORr   r  rI   r(   r2   	threadingThreadstartrD   rZ   rJ   rR   rT   rc   rr   r   r   r   r   r   r   rA   r@  r\   rK   r1   <module>r`     sd    	  	 
         /   5 . / ggoobggooh78ww{+ <   & 
0T   '.

# $),

% &   = 9   ) * 3 3GMM B	 = >! & ' ' (   4<  	  *4 8 > > @T4 	  ,T : @ @ B0c 04 4 4S 4 	%) 	%B  :S<s S<l6)c 6)x l @ q M	c 8b c D 'M+ M MrK   