o
    +i8G                     @   s  d dl mZ d dlmZ d dlmZ d dlmZmZm	Z	 d dl
Z
d dlZd dlmZ d dlmZ d dlmZmZ ed	d
dZdddddejjdZedd Zde	eef fddZdee	 fddZde	fddZdedee fddZe
jddZ dZ!e red e d!d"Z!ej"ed#gd#gd#gd$ d%d&d'd%d(d'd)d%d*d'd+d,d'd-d%d.d'd%d/d'd0d1d2d'd1d3d'd4d%d5d'd%d6d'd7d8Z#de	fd9d:Z$e$ Z%G d;d< d<eZ&G d=d> d>eZ'd?e&dee fd@dAZ(dBedCee dee) fdDdEZ*edFdGdH Z+edIdJdK Z,e-dLd?e&fdMdNZ.e-dOdPed?e&fdQdRZ/edSdTdU Z0dVZ1e-dWdXe'fdYdZZ2ed[d\d] Z3e4d^kr[d dl5Z5e5j6ed_d`da dS dS )b    )FastAPI)CORSMiddleware)	BaseModel)ListOptionalDictN)contextmanager)ChatAnthropic)HumanMessageSystemMessagezPsyMed AI APIz0.4.0)titleversion	localhostrootzfastcoin12*psychological_hubutf8mb4)hostuserpassworddatabasecharsetcursorclassc                  c   s2    t jdi t} z
| V  W |   d S |   w )N )pymysqlconnect	DB_CONFIGclose)connr   r   /var/www/html/psymed-ai/main.pyget_db_connection   s
   r   returnc               	   C   s   t  F} |  1}|d i }| D ]}|d r|d n|d }|||d < q|W  d   W  d   S 1 s<w   Y  W d   dS 1 sLw   Y  dS )u-   약물 목록 로드: {drug_id: drug_name_en}z5SELECT drug_id, drug_name, drug_name_en FROM pm_drugsdrug_name_en	drug_namedrug_idNr   cursorexecutefetchall)r   r%   drugsrownamer   r   r   load_drugs_from_db#   s   

"r+   c               	   C   st   t  -} |  }|d | W  d   W  d   S 1 s#w   Y  W d   dS 1 s3w   Y  dS )u   금기사항 로드a  
                SELECT c.drug_id, d.drug_name_en, d.drug_name,
                       c.contraindication_type, c.contraindication, c.reason
                FROM pm_drug_contraindications c
                JOIN pm_drugs d ON c.drug_id = d.drug_id
            Nr$   )r   r%   r   r   r   load_contraindications_from_db/   s   

"r,   c               
   C   s   i } zDt  }|D ];}|d r|d n|d }|sq|| vr!i | |< t|d }|s*q|d dkr2dnd}||d p<|d d	| | |< q| W S  tya } ztd
|  i W  Y d}~S d}~ww )u   DB에서 규칙 구축r!   r"   contraindicationcontraindication_typeu   절대bannedcautionreasonlevelr1   u   DB 로드 오류: N)r,   map_condition	Exceptionprint)rulescontrasr)   r"   	conditionr3   er   r   r   build_rules_from_db;   s,   r;   condition_namec                 C   sL  | sdS |   }d| v sd|v rdS d| v sd|v rdS d| v s(d|v s(d|v r*d	S d
| v r8d| v s6d| v r8dS d|v s@d|v rBdS d| v sNd|v sNd|v rPdS d| v sXd| v rZdS d| v r`dS d| v shd|v rjdS d| v srd|v rtdS d| v s|d|v r~dS d| v sd| v sd|v rdS d | v sd!| v sd"|v rd"S d#| v sd$| v rd%S dS )&u-   DB 조건명을 시스템 조건으로 매핑N   임신	pregnancy   수유	lactationu   간hepatliverliver_severeu   신u   기능u   장애renal_severerenalkidneyu   심cardiacheartu   심근경색MIQT   당뇨diabetes	   고혈압hypertension	   녹내장glaucomau   발작u   경련seizureseizure_historyu   노인u   고령elderlyMAOIu   MAO억제제maoi_interaction)lower)r<   condition_lowerr   r   r   r4   \   s@   r4   ANTHROPIC_API_KEY claude-sonnet-4-20250514i   )modelapi_key
max_tokens*)allow_originsallow_methodsallow_headersr/   u"   신경관결손 5-9%, 자폐위험r2   u   간독성 위험)r>   rC   u   1삼분기 심장기형 위험r0   u*   체중증가로 혈당조절 악화 가능)r>   rL   u   Ebstein 기형 위험u    중증 신기능저하시 금기)r>   rD   	preferredu+   임신중 안전성 데이터 가장 풍부u(   심근경색 후 안전 (SADHART 연구))r>   rG   u   부정맥 위험u   녹내장 악화)rG   rP   )	Valproate
ParoxetineLithium
SertralineTCAc               
   C   s   z1t  } | r/i t}|  D ]\}}||vri ||< || | qtdt|  d |W S W tS  tyK } ztd|  W Y d}~tS d}~ww )u1   DB에서 규칙 로드, 실패시 fallback 사용u	   DB에서 u   개 약물 규칙 로드됨u#   DB 로드 실패, fallback 사용: N)r;   FALLBACK_RULESitemsupdater6   lenr5   )db_rulesmergeddrug
conditionsr:   r   r   r   get_drug_rules   s"   rp   c                   @   s   e Zd ZU dZeed< dZeed< dZe	ed< dZ
e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Ze	ed< dZe	ed< dZe	ed< dZe	ed< dZe	ed< g Zee ed< dS )PatientInforY   	diagnosis   ageFr>   N	trimesterr@   noneliver_diseasenormalrenal_functionrL   rG   rN   hypothyroidismrR   rP   eating_disordercurrent_medications)__name__
__module____qualname__rr   str__annotations__rt   intr>   boolru   r   r@   rw   ry   rL   rG   rN   rz   rR   rP   r{   r|   r   r   r   r   r   rq      s    
 rq   c                   @   s2   e Zd ZU eed< dZeed< dZee	 ed< dS )ExplainRequestpatientrY   questionNrules_result)
r}   r~   r   rq   r   r   r   r   r   dictr   r   r   r   r      s   
 r   r   c                 C   s,  g }| j r
|d | jr|d | jdkr|d n| jdkr(|d n
| jdkr2|d | jdkr=|d	 n| jdkrH|d
 n
| jdkrR|d | jrZ|d | jrb|d | jrj|d | jdkrt|d | j	r||d | j
r|d | jr|d | jr|d |S )Nr>   r@   mild
liver_mildmoderateliver_moderatesevererC   
renal_mildrenal_moderaterD   rL   rG   rN   A   rS   rz   rR   rP   r{   )r>   appendr@   rw   ry   rL   rG   rN   rt   rz   rR   rP   r{   )r   ro   r   r   r   get_patient_conditions   sD   


















r   rn   ro   c              	   C   sj   g }| t vr|S t |  }|D ]$}||v r2|| }|| d|}|| ||d |d |d d q|S )N_kor3   r1   )rn   r9   r3   r1   	reason_ko)
DRUG_RULESgetr   )rn   ro   resultsr7   r9   rulerule_kor   r   r   check_drug_for_conditions  s"   r   z/healthc                   C   s   ddt tdS )Nokz0.2.0)statusr   drugs_count)rk   r   r   r   r   r   health3  s   r   z
/api/drugsc                   C   s   t t ttdS )N)r(   count)listr   keysrk   r   r   r   r   
list_drugs7  s   r   z/api/check-safetyc                 C   s
  t | }g }g }g }t D ]G}t||}|D ]=}|d dkr%|| q|d dkr1|| q|d dkr=|| q|d dkrI|| q|d dkrT|| qqdd |D }d	d |D }	d
d |D }
|||	|
||t|t|	t|
t|t|ddS )Nr3   r/   avoidr0   rb   safec                 S      g | ]
}|d  dkr|qS r3   r/   r   .0wr   r   r   
<listcomp>P      z check_safety.<locals>.<listcomp>c                 S   r   r3   r   r   r   r   r   r   r   Q  r   c                 S   r   r3   r0   r   r   r   r   r   r   R  r   )banned_countavoid_countcaution_countpreferred_count
safe_count)ro   r/   r   r0   rb   r   summary)r   r   r   r   r   rk   )r   ro   all_warningsrb   	safe_listrn   drug_resultsresultr/   r   r0   r   r   r   check_safety;  sF   

r   z/api/check-drugr"   c                 C   s6   t |}t| |}tdd |D dk}| |||dS )Nc                 S   s   g | ]
}|d  dv r|qS )r3   )r/   r   r   r   rr   r   r   r   i  r   z%check_single_drug.<locals>.<listcomp>r   )rn   ro   warningsis_safe)r   r   rk   )r"   r   ro   r   r   r   r   r   check_single_drugd  s   
r   z/api/conditionsc                   C   s   ddddddddddd	d
g ddddd
g ddddddddddddddddddddddddddddddddd dgiS )!Nro   r>   r=   r   )keylabeltyper@   r?   rw   u	   간질환select)rv   r   r   r   )r   r   r   optionsry   u	   신기능)rx   r   r   r   rL   rK   rG   u   심장질환rN   rM   rz   u   갑상선저하증rR   u	   발작력rP   rO   r{   u   섭식장애rt   u   나이numberr   r   r   r   r   list_conditionsr  s   









r   uS  당신은 정신건강의학과 전문의를 보조하는 약물 안전성 전문가입니다.
환자 정보와 규칙 기반 분석 결과를 바탕으로 임상적 설명을 제공합니다.

원칙:
1. 규칙 엔진의 금기/주의 판정은 절대적으로 존중합니다 (L1 = 사실)
2. 복합 상황에서는 우선순위와 대안을 제시합니다 (L2 = 판단)
3. 의사가 이해하기 쉽게 근거와 함께 설명합니다 (L3 = 설명)
4. 한국어로 답변하고, 약물명은 영문 그대로 사용합니다
5. 간결하게 핵심만 전달합니다 (200자 이내 권장)
z/api/explainrequestc              
      s  t s	ddd dS | jsdt| j}g }g }g }t D ]/}t||}|D ]%}|d dv r2|| q$|d dkr>|| q$|d dkrI|| q$q|dd	 |D d
d	 |D dd	 |D ||d}n| j}| j}	d|	j d}
|	j	rx|
d7 }
|	j
r|
d7 }
|	jdkr|
d|	j 7 }
|	jdkr|
d|	j 7 }
|	jr|
d7 }
|	jr|
d7 }
|	jr|
d|	j 7 }
d}|drdd	 |d D }|dd| d 7 }|drdd	 |d D }|d d| d 7 }|d!rd"d	 |d! D }|d#d| d 7 }|drd$d	 |d D }|d%d| d 7 }| jr | jnd&}|
 d'| d(| }zttd)t|d)g}t |}d*|j|
|d+W S  ty_ } zdt|d dW  Y d }~S d }~ww ),NFzAPI key not configured)successerrorexplanationr3   )r/   r   r0   rb   r   c                 S   r   r   r   r   r   r   r   r     r   z#explain_with_ai.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   r     r   c                 S   r   r   r   r   r   r   r   r     r   )ro   r/   r   r0   rb   r   u   환자: u   세u   , 임신u   , 수유중rv   u   , 간기능 rx   u   , 신기능 u   , 당뇨u   , 심장질환u
   , 진단: u   규칙 분석 결과:
r/   c                 S   $   g | ]}|d  d |d  d qS rn   (r   )r   r   r   r   r   r        $ u
   - 금기: z, 
r   c                 S   r   r   r   r   r   r   r   r     r   u
   - 회피: r0   c                 S   r   r   r   r   r   r   r   r     r   u
   - 주의: c                 S   r   r   r   r   r   r   r   r     r   u
   - 권장: uV   이 환자에게 적합한 약물 선택에 대해 종합적으로 설명해주세요.z

u
   

질문: )contentT)r   r   patient_summaryrules_summary)llmr   r   r   r   r   r   r   rt   r>   r@   rw   ry   rL   rG   rr   r   joinr   r   SYSTEM_PROMPTr
   invoker   r5   r   )r   ro   r   rb   r   rn   r   r   r   r   r   r   ri   r   user_messagemessagesresponser:   r   r   r   explain_with_ai  s   


		





r   z/api/ai-statusc                   C   s   t d ut r	ddS d dS )NrZ   )llm_availabler[   )r   r   r   r   r   	ai_status  s
   r   __main__z0.0.0.0i@  )r   port)7fastapir   fastapi.middleware.corsr   pydanticr   typingr   r   r   osr   
contextlibr   langchain_anthropicr	   langchain_core.messagesr
   r   appcursors
DictCursorr   r   r   r   r+   r,   r;   r4   environr   rX   r   add_middlewarerh   rp   r   rq   r   r   r   r   r   r   postr   r   r   r   r   r   r}   uvicornrunr   r   r   r   <module>   s    	
!<	$

(
c

