File size: 4,668 Bytes
dc41b87
 
 
 
 
 
 
 
 
2554c1f
 
dc41b87
2554c1f
 
 
dc41b87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2d9f1d9
35fa9cf
b2ef58c
 
 
 
 
 
dc41b87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2554c1f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dc41b87
 
 
2d9f1d9
dc41b87
 
 
 
 
 
4a66515
dc41b87
 
 
 
 
 
 
 
 
 
 
 
2d9f1d9
 
dc41b87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2d9f1d9
dc41b87
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
"""
راوي (Rawi) - Arabic AI Storytelling Platform
Main application file for FastAPI server
"""

import os
import sys
import uvicorn
import logging
import traceback
from fastapi import FastAPI, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.exception_handlers import http_exception_handler
from starlette import status
from dotenv import load_dotenv
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from pathlib import Path

# Add the current directory to Python path to enable imports
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

# Import application routers
from routers import story

# ======== Configure Logging ========
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# ======== Load Environment Variables ========
load_dotenv()

# ======== Server Configuration ========
HOST = os.getenv("BACKEND_HOST", "0.0.0.0")
PORT = int(os.getenv("BACKEND_PORT", "7860"))  # Default port for Hugging Face Spaces
BASE_URL = os.getenv("BASE_URL", f"http://{HOST}:{PORT}")

# For Hugging Face Spaces, use a directory we know has write permissions
if os.path.exists("/code"):  # Check if we're in Hugging Face Spaces environment
    AUDIO_STORAGE_PATH = os.path.abspath("/tmp/audio_files")
else:
    AUDIO_STORAGE_PATH = os.path.abspath(os.getenv("AUDIO_STORAGE_PATH", "./audio_files"))

# DeepSeek API Key check
DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY")

# Log server settings
logger.info(f"Server settings:")
logger.info(f"Host: {HOST}")
logger.info(f"Port: {PORT}")
logger.info(f"Base URL: {BASE_URL}")
logger.info(f"Audio storage path: {AUDIO_STORAGE_PATH}")
logger.info(f"DeepSeek API Key set: {bool(DEEPSEEK_API_KEY)}")

# ======== Ensure Audio Storage Directory Exists ========
try:
    Path(AUDIO_STORAGE_PATH).mkdir(parents=True, exist_ok=True)
    logger.info(f"Created/verified audio storage directory at: {AUDIO_STORAGE_PATH}")
except Exception as e:
    logger.error(f"Error creating audio storage directory: {str(e)}")
    raise

# ======== Initialize FastAPI Application ========
app = FastAPI(
    title="راوي API",
    description="واجهة برمجة تطبيقات لمنصة راوي لتوليد القصص العربية باستخدام الذكاء الاصطناعي",
    version="1.0.0"
)

# ======== Exception Handlers ========
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    """
    Global exception handler for unhandled exceptions
    """
    logger.error(f"Unhandled exception: {str(exc)}")
    logger.error(traceback.format_exc())
    
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={"detail": f"حدث خطأ داخلي في الخادم: {str(exc)}"}
    )

@app.exception_handler(HTTPException)
async def custom_http_exception_handler(request: Request, exc: HTTPException):
    """
    Custom HTTP exception handler
    """
    logger.warning(f"HTTP exception: {exc.status_code} - {exc.detail}")
    return await http_exception_handler(request, exc)

# ======== Configure CORS ========
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # Allow all origins for Hugging Face Space
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# ======== Mount Static Files ========
app.mount("/audio", StaticFiles(directory=AUDIO_STORAGE_PATH), name="audio")

# ======== Register Routers ========
app.include_router(story.router, prefix="/api/stories", tags=["قصص"])

# ======== API Endpoints ========
@app.get("/", tags=["الرئيسية"])
async def root():
    """
    Root endpoint for the API
    """
    return {
        "message": "مرحباً بك في واجهة برمجة تطبيقات راوي",
        "docs": f"{BASE_URL}/docs",
        "status": "active"
    }

@app.get("/health", tags=["الحالة"])
async def health_check():
    """
    Health check endpoint to verify API configuration
    """
    health_status = {
        "status": "healthy",
        "deepseek_api": bool(DEEPSEEK_API_KEY),
        "audio_storage": os.path.exists(AUDIO_STORAGE_PATH),
    }
    
    if not DEEPSEEK_API_KEY:
        health_status["status"] = "degraded"
        health_status["message"] = "DeepSeek API key is not set. Story generation will not work."
        
    return health_status

# ======== Run Application ========
if __name__ == "__main__":
    uvicorn.run(
        "main:app",
        host=HOST,
        port=PORT,
        reload=False  # Disable in production for better performance
    )