File size: 3,645 Bytes
5b92ed7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# app/main.py - PERMISSION ERROR TUZATILGAN VERSIYA

import os
import asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles

from app.api.routes import router as bemor_router
from app.api.dispatcher_routes import router as dispatcher_router
from app.services.models import load_models

# πŸ†• Brigade Simulator import
from app.services.brigade_simulator import get_simulator
from app.core.database import db

# --- YECHIM UCHUN O'ZGARTIRISH ---
# Barcha o'zgaruvchan (dinamik) ma'lumotlar uchun yagona papka yaratamiz.
# Bu papkaga yozish uchun ruxsat bo'ladi.
PERSISTENT_DIR = "persistent_storage"

# Yaratilishi kerak bo'lgan papkalar yo'lini yangi asosiy papkaga nisbatan belgilaymiz
TEMP_AUDIO_DIR = os.path.join(PERSISTENT_DIR, "audio")
UPLOAD_DIR = os.path.join(PERSISTENT_DIR, "uploads")
DATA_DIR = os.path.join(PERSISTENT_DIR, "data")

# Faqat dinamik papkalarni yaratamiz
os.makedirs(TEMP_AUDIO_DIR, exist_ok=True)
os.makedirs(UPLOAD_DIR, exist_ok=True)
os.makedirs(DATA_DIR, exist_ok=True)

# ESLATMA: `static/bemor` va `static/dispatcher` uchun `os.makedirs` olib tashlandi.
# Chunki bu papkalardagi `index.html` kabi fayllar sizning loyihangizda
# oldindan mavjud bo'lishi kerak va ularni dastur yordamida yaratish shart emas.
# ------------------------------------

# πŸ†• Global simulator task
simulator_task = None

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Ilova ishga tushishidan oldin
    print("πŸš€ Ilova ishga tushmoqda...")
    
    print("πŸ“¦ AI modellari yuklanmoqda...")
    load_models()
    print("βœ… Barcha modellar tayyor!")
    
    # πŸ†• Brigade simulator ishga tushirish
    print("πŸš‘ Brigade simulator ishga tushmoqda...")
    global simulator_task
    simulator = get_simulator(db)
    simulator_task = asyncio.create_task(simulator.start())
    print("βœ… Brigade simulator tayyor!")
    
    yield
    
    # Ilova to'xtagandan keyin
    print("πŸ›‘ Ilova to'xtatilmoqda...")
    
    # πŸ†• Simulator to'xtatish
    if simulator_task:
        simulator.stop()
        simulator_task.cancel()
        try:
            await simulator_task
        except asyncio.CancelledError:
            pass
        print("βœ… Simulator to'xtatildi")
    
    print("πŸ‘‹ Ilova ishini yakunladi.")

app = FastAPI(
    title="Help.me - Tez Tibbiy Yordam AI Tizimi",
    description="Bemorlardan ovozli xabarlar qabul qilib, AI tahlil qiluvchi va dispetcherlarga yuboruvchi tizim",
    version="1.0.0 (MVP)",
    lifespan=lifespan
)

# Routerlarni ulash
app.include_router(bemor_router)  # Bemor WebSocket va APIlar
app.include_router(dispatcher_router)  # Dispetcher APIlar

# Static fayllar
# --- YECHIM UCHUN O'ZGARTIRISH ---
# /audio endi yangi, yozish mumkin bo'lgan `persistent_storage/audio` papkasidan olinadi
app.mount("/audio", StaticFiles(directory=TEMP_AUDIO_DIR), name="audio")

# Bu qator o'zgarmaydi. U `static` papkasidagi (bemor/index.html kabi)
# o'zgarmas fayllarni topish uchun kerak.
app.mount("/static", StaticFiles(directory="static"), name="static")
# ------------------------------------

# Bemor interfeysi (Root URL)
@app.get("/", include_in_schema=False)
async def read_root():
    """Bemor uchun asosiy sahifa"""
    # Bu yo'l to'g'ri, chunki u `app.mount("/static", ...)` ga nisbatan ishlaydi
    return FileResponse('static/bemor/index.html')

# Dispetcher paneli
@app.get("/dispatcher", include_in_schema=False)
async def dispatcher_panel():
    """Dispetcher dashboard"""
    # Bu yo'l ham to'g'ri
    return FileResponse('static/dispatcher/index.html')