File size: 2,786 Bytes
857b1b2
 
c6fd654
857b1b2
 
 
c6fd654
 
857b1b2
 
 
 
 
 
 
 
 
 
 
 
 
 
c6fd654
857b1b2
c6fd654
 
857b1b2
 
c6fd654
857b1b2
 
 
 
 
c6fd654
 
857b1b2
c6fd654
 
 
857b1b2
 
c6fd654
857b1b2
 
c6fd654
857b1b2
 
c6fd654
 
857b1b2
c6fd654
857b1b2
 
 
 
 
c6fd654
 
 
 
 
 
 
 
857b1b2
 
 
 
 
c6fd654
857b1b2
 
 
 
c6fd654
857b1b2
 
 
 
 
 
 
 
c6fd654
857b1b2
 
ccb716c
c6fd654
 
 
 
857b1b2
 
 
c6fd654
857b1b2
e1b6ee8
857b1b2
e1b6ee8
 
 
857b1b2
 
 
 
 
 
 
 
 
c6fd654
 
 
 
 
 
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
"""
PrecisionVoice - Speech-to-Text & Speaker Diarization Application
Main FastAPI entry point 
"""

import logging
import gc
import jinja2
from contextlib import asynccontextmanager

from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import HTMLResponse

from app.core.config import get_settings
from app.api.routes import router
from app.services.transcription import TranscriptionService
from app.services.diarization import DiarizationService
from app.services.emo import EmotionService


logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)

logger = logging.getLogger(__name__)
settings = get_settings()


@asynccontextmanager
async def lifespan(app: FastAPI):
    logger.info("Starting PrecisionVoice...")

    logger.info(f"Device: {settings.resolved_device}")
    logger.info(f"Whisper: {settings.default_whisper_model}")
    logger.info(f"Diarization: {settings.diarization_backend}")
    logger.info(f"Emotion: {settings.default_dual_emotion_model}")

    try:
        logger.info("Preloading Whisper...")
        TranscriptionService.preload_model()
    except Exception as e:
        logger.error(f"Whisper preload failed: {e}")

    try:
        logger.info("Preloading diarization...")
        DiarizationService.preload_pipeline()
    except Exception as e:
        logger.warning(f"Diarization failed: {e}")

    try:
        logger.info("Preloading emotion model...")
        EmotionService.preload_model()
    except Exception as e:
        logger.warning(f"Emotion preload failed: {e}")

    logger.info("Startup complete")

    yield

    logger.info("Shutting down...")
    gc.collect()



app = FastAPI(
    title="PrecisionVoice",
    description="Speech-to-Text + Diarization + Emotion",
    version="2.0.0",
    lifespan=lifespan,
)


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


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



templates = Jinja2Templates(directory="app/templates")


app.include_router(router)


@app.get("/", response_class=HTMLResponse)
async def index(request: Request):

    return templates.TemplateResponse(
        request=request,
        name="index.html",
        context={
            "max_upload_mb": settings.max_upload_size_mb,
            "allowed_formats": ", ".join(settings.allowed_extensions),
        },
    )


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(
        "app.main:app",
        host=settings.host,
        port=settings.port,
        reload=True
    )