File size: 5,917 Bytes
45274c2
1cd888a
5dd80b4
4761e94
e17b0a7
 
bc35722
417c5c4
b38fca0
e17b0a7
941dee3
5c1fa92
 
 
 
 
02e2dc3
 
e17b0a7
 
1bd9bbb
02e2dc3
1bd9bbb
02e2dc3
1bd9bbb
02e2dc3
5c1fa92
4624a2d
56f4fd7
dcf4aad
c93381f
84e8d07
56f4fd7
 
89a41e2
dcf4aad
45274c2
56f4fd7
dcf4aad
3d81965
45274c2
 
56f4fd7
 
f73c316
417c5c4
 
45274c2
e17b0a7
1bd9bbb
e17b0a7
 
 
 
5c1fa92
e17b0a7
1bd9bbb
e17b0a7
5c1fa92
1bd9bbb
e17b0a7
1bd9bbb
e17b0a7
1bd9bbb
e17b0a7
 
082656b
e17b0a7
1bd9bbb
e17b0a7
1bd9bbb
e17b0a7
082656b
e17b0a7
1bd9bbb
e17b0a7
1bd9bbb
e17b0a7
 
082656b
1bd9bbb
e17b0a7
1bd9bbb
e17b0a7
1bd9bbb
e17b0a7
2380390
 
 
45274c2
 
5f7ea1c
3d81965
 
c93381f
 
 
 
 
 
 
 
 
 
 
56f4fd7
4761e94
 
f73c316
e17b0a7
 
1bd9bbb
e17b0a7
 
 
082656b
6e61aeb
082656b
 
e17b0a7
082656b
e17b0a7
 
 
417c5c4
 
 
e17b0a7
 
 
 
417c5c4
 
 
c4db12d
e17b0a7
 
 
 
 
0d34ce3
 
bc35722
 
 
ac6266d
89a41e2
56f4fd7
 
4624a2d
89a41e2
56f4fd7
 
ba5b57f
c93381f
b38fca0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# src/main.py
# Access via: https://medai-cos30018-medicaldiagnosissystem.hf.space/

import os
from contextlib import asynccontextmanager

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.routing import APIRoute
from fastapi.staticfiles import StaticFiles

from src.utils.logger import logger, setup_logging

# Needs to be called before any logs are sent
setup_logging()

# Load environment variables from .env file
try:
	from dotenv import load_dotenv
	load_dotenv()
	logger(tag="env").info("Environment variables loaded from .env file")
except ImportError:
	logger(tag="env").warning("python-dotenv not available, using system environment variables")
except Exception as e:
	logger(tag="env").warning(f"Error loading .env file: {e}")

# Import project modules after trying to load environment variables
from src.api.routes import account as account_route
from src.api.routes import audio as audio_route
from src.api.routes import emr as emr_route
from src.api.routes import migration as migration_route
from src.api.routes import patient as patients_route
from src.api.routes import session as session_route
from src.api.routes import static as static_route
from src.api.routes import summarise as summarise_route
from src.api.routes import system as system_route
from src.core.state import AppState, get_state
from src.data.repositories import account as account_repo
from src.data.repositories import emr as emr_repo
from src.data.repositories import information as information_repo
from src.data.repositories import medical_memory as medical_memory_repo
from src.data.repositories import medical_record as medical_record_repo
from src.data.repositories import patient as patient_repo
from src.data.repositories import session as session_repo
from src.services import local_llm_service


def startup_event(state: AppState):
	"""Initialize application on startup"""
	logger(tag="startup").info("Starting Medical AI Assistant...")

	# Check system resources
	try:
		import psutil
		ram = psutil.virtual_memory()
		cpu = psutil.cpu_percent(interval=1)
		logger(tag="startup").info(f"System Resources – RAM: {ram.percent}%, CPU: {cpu}%")

		if ram.percent > 85:
			logger(tag="startup").warning("High RAM usage detected!")
		if cpu > 90:
			logger(tag="startup").warning("High CPU usage detected!")
	except ImportError:
		logger(tag="startup").info("psutil not available, skipping system resource check")

	# Check API keys
	gemini_keys = len([k for k in state.gemini_rotator.keys if k])
	if gemini_keys == 0:
		logger(tag="startup").warning("No Gemini API keys found! Set GEMINI_API_1, GEMINI_API_2, etc. environment variables.")
	else:
		logger(tag="startup").info(f"{gemini_keys} Gemini API keys available")

	nvidia_keys = len([k for k in state.nvidia_rotator.keys if k])
	if nvidia_keys == 0:
		logger(tag="startup").warning("No NVIDIA API keys found! Set NVIDIA_API_1, NVIDIA_API_2, etc. environment variables.")
	else:
		logger(tag="startup").info(f"{nvidia_keys} NVIDIA API keys available")

	# Check embedding client
	if state.embedding_client.is_available():
		logger(tag="startup").info("Embedding model loaded successfully")
	else:
		logger(tag="startup").info("Using fallback embedding mode")

	logger(tag="startup").info("Medical AI Assistant startup complete")

	account_repo.init()
	patient_repo.init()
	session_repo.init()
	medical_memory_repo.init()
	medical_record_repo.init()
	emr_repo.init()
	information_repo.init()

	# Run database migration to fix any existing records with missing required fields
	try:
		from src.data.migration import run_database_migration
		logger(tag="startup").info("Running database migration...")
		migration_result = run_database_migration()
		if migration_result['success']:
			logger(tag="startup").info(f"Database migration completed: {migration_result['total_fixed']} records fixed")
		else:
			logger(tag="startup").warning(f"Database migration failed: {migration_result.get('error', 'Unknown error')}")
	except Exception as e:
		logger(tag="startup").warning(f"Database migration error: {e}")

	if os.getenv("USE_LOCAL_MODEL", "False") == "True":
		local_llm_service.load_model()

def shutdown_event():
	"""Cleanup on shutdown"""
	logger(tag="shutdown").info("Shutting down Medical AI Assistant...")

@asynccontextmanager
async def lifespan(app: FastAPI):
	# Initialize state
	state = get_state()
	state.initialize()

	# Startup code here
	startup_event(state)
	yield
	# Shutdown code here
	shutdown_event()

# Initialize FastAPI app
app = FastAPI(
	lifespan=lifespan,
	title="Medical AI Assistant",
	description="AI-powered medical chatbot with memory and context awareness",
	version="1.0.0"
)

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

# Mount static files
app.mount("/static", StaticFiles(directory="static"), name="static")

# Include routers
app.include_router(static_route.router)
app.include_router(session_route.router)
app.include_router(patients_route.router)
app.include_router(account_route.router)
app.include_router(summarise_route.router)
app.include_router(system_route.router)
app.include_router(audio_route.router)
app.include_router(emr_route.router)
app.include_router(migration_route.router)

@app.get("/api/info")
async def get_api_info():
	"""Get API information and capabilities, lists all paths available in the api."""
	return {
		"name": "Medical Diagnosis System",
		"version": "1.0.0",
		"description": "AI-powered medical chatbot with memory and context awareness",
		"features": [
			"Multi-user support with profiles",
			"Chat session management",
			"Medical context memory",
			"API key rotation",
			"Embedding-based similarity search",
			"Medical knowledge base integration"
		],
		"endpoints": [route.path for route in app.routes if isinstance(route, APIRoute)]
	}