File size: 4,595 Bytes
cbc783a
 
 
 
 
 
 
 
2fb6539
 
 
 
 
 
 
 
 
 
cbc783a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2fb6539
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1a9bcb2
2fb6539
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
from fastapi import FastAPI, Query, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware
from utils.vector_search import get_similar_symptoms
from utils.sql_queries import get_diseases_by_symptoms, get_related_symptoms
import sqlite3
import os
import httpx
import json
from dotenv import load_dotenv

# Load environment variables
load_dotenv()

# Get Groq API key from environment variables
GROQ_API_KEY = os.environ.get("GROQ_API_KEY")

app = FastAPI()

# Add CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # Allow all origins
    allow_credentials=True,
    allow_methods=["*"],  # Allow all methods
    allow_headers=["*"],  # Allow all headers
)

templates = Jinja2Templates(directory="templates")

@app.get("/", response_class=HTMLResponse)
def index(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

# Helper function to check if a symptom exists in the database
def is_valid_symptom(symptom):
    conn = sqlite3.connect("disease.db")
    cur = conn.cursor()
    cur.execute("SELECT COUNT(*) FROM symptom WHERE name = ?", (symptom,))
    count = cur.fetchone()[0]
    conn.close()
    return count > 0

@app.get("/search")
def search(symptom: str, selected: list[str] = Query([])):
    # Get similar symptoms from vector search
    similar = get_similar_symptoms(symptom)
    
    # Check if the exact symptom exists in our database
    if is_valid_symptom(symptom):
        # Use the exact symptom if it exists
        search_symptoms = [symptom] + selected
    else:
        # Otherwise, try to use the first similar symptom that exists in our database
        valid_symptom_found = False
        for sim in similar:
            if is_valid_symptom(sim):
                search_symptoms = [sim] + selected
                valid_symptom_found = True
                break
        
        # If no valid symptom found, just use all similar symptoms
        if not valid_symptom_found:
            search_symptoms = similar + selected
    
    # Get diseases that have ALL the selected search symptoms
    diseases = get_diseases_by_symptoms(search_symptoms)
    
    # Get related symptoms from the matching diseases, excluding already selected symptoms
    suggestions = get_related_symptoms(diseases, exclude=search_symptoms)

    return {
        "matching_diseases": diseases,
        "related_symptoms": suggestions,
        "semantic_matches": similar
    }

@app.get("/disease-info")
async def disease_info(name: str):
    """
    Get detailed information about a disease using Groq's LLM API
    """
    if not GROQ_API_KEY:
        return {"info": "<p>Error: Groq API key not found in environment variables.</p>"}
    
    try:
        async with httpx.AsyncClient(timeout=30.0) as client:
            response = await client.post(
                "https://api.groq.com/openai/v1/chat/completions",
                headers={
                    "Authorization": f"Bearer {GROQ_API_KEY}",
                    "Content-Type": "application/json"
                },
                json={
                    "model": "meta-llama/llama-4-scout-17b-16e-instruct",
                    "messages": [
                        {
                            "role": "system",
                            "content": "You are a helpful medical assistant. Provide accurate, well-structured information about diseases. Format your response in HTML paragraphs with appropriate headings using <h4> tags. Include symptoms, causes, treatments, and prevention when possible. Keep responses concise but informative."
                        },
                        {
                            "role": "user",
                            "content": f"Provide detailed information about {name}, including symptoms, causes, diagnosis, treatments, and prevention methods when applicable."
                        }
                    ],
                    "max_tokens": 1500,
                    "temperature": 0.5
                }
            )
            
            if response.status_code == 200:
                data = response.json()
                content = data["choices"][0]["message"]["content"]
                return {"info": content}
            else:
                return {"info": f"<p>Error: Failed to fetch information. Status code: {response.status_code}</p>"}
                
    except Exception as e:
        return {"info": f"<p>Error: {str(e)}</p>"}