test / app.py
sachinchandrankallar's picture
TEST ROUTES
36e31bf
"""
Hugging Face Spaces entry point.
This file serves as the main entry point for Hugging Face Spaces deployment.
It imports and exposes the FastAPI app from the ai_med_extract package.
"""
import os
import sys
import logging
import importlib.util
# Configure logging for Hugging Face Spaces
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
# Add the services/ai-service/src directory to the Python path
current_dir = os.path.dirname(os.path.abspath(__file__))
src_dir = os.path.join(current_dir, "services", "ai-service", "src")
if src_dir not in sys.path:
sys.path.insert(0, src_dir)
# Verify the path is correct
logging.info(f"Added src_dir to Python path: {src_dir}")
logging.info(f"src_dir exists: {os.path.exists(src_dir)}")
if os.path.exists(src_dir):
logging.info(f"Contents of src_dir: {os.listdir(src_dir)}")
ai_med_extract_path = os.path.join(src_dir, "ai_med_extract")
logging.info(f"ai_med_extract_path exists: {os.path.exists(ai_med_extract_path)}")
if os.path.exists(ai_med_extract_path):
logging.info(f"Contents of ai_med_extract: {os.listdir(ai_med_extract_path)}")
# Detect and set Hugging Face Spaces environment
# HF Spaces sets SPACE_ID environment variable
if os.getenv("SPACE_ID") or os.getenv("SPACE_AUTHOR_NAME"):
os.environ.setdefault("HF_SPACES", "true")
logging.info("Detected Hugging Face Spaces environment")
# Set environment variables for Hugging Face Spaces
os.environ.setdefault("FAST_MODE", "true")
os.environ.setdefault("PRELOAD_SMALL_MODELS", "false")
os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "max_split_size_mb:128")
os.environ.setdefault("TOKENIZERS_PARALLELISM", "false")
os.environ.setdefault("OMP_NUM_THREADS", "1")
os.environ.setdefault("MKL_NUM_THREADS", "1")
# Ensure Redis and Database are disabled on HF Spaces
os.environ.setdefault("REDIS_URL", "")
os.environ.setdefault("DATABASE_URL", "")
# Create a robust app instance with multiple fallback strategies
app = None
# Simplified import strategy with better error handling
try:
logging.info("Attempting to import from ai_med_extract package...")
logging.info(f"Python path: {sys.path[:3]}")
logging.info(f"Current working directory: {os.getcwd()}")
logging.info(f"Files in current directory: {os.listdir('.')}")
# Direct import approach - simpler and more reliable
from ai_med_extract.app import create_app, initialize_agents # type: ignore
logging.info("Successfully imported create_app and initialize_agents")
# Create the app instance WITHOUT initializing agents yet
try:
app = create_app(initialize=False)
logging.info("App instance created successfully (without agents)")
logging.info(f"App title: {app.title}")
logging.info(f"App version: {getattr(app, 'version', 'unknown')}")
except Exception as e:
logging.error(f"Failed to create app: {e}")
import traceback
logging.error(f"App creation traceback: {traceback.format_exc()}")
# Create minimal fallback app
from fastapi import FastAPI
app = FastAPI(title="Medical AI Service (fallback)")
@app.get("/")
async def root():
return {"message": "Medical AI Service - Fallback mode", "error": str(e)}
@app.get("/health")
async def health():
return {"status": "degraded", "message": "App creation failed", "error": str(e)}
# Initialize agents with minimal preloading for Hugging Face Spaces
try:
logging.info("Initializing agents with preload_small_models=False...")
initialize_agents(app, preload_small_models=False)
logging.info("Agents initialized successfully")
# Log all registered routes after initialization
logging.info("=" * 60)
logging.info("FINAL REGISTERED ROUTES ON HF SPACES:")
route_count = 0
for route in app.routes:
if hasattr(route, "methods") and hasattr(route, "path"):
logging.info(f" {list(route.methods)} {route.path}")
route_count += 1
logging.info(f"Total routes registered: {route_count}")
logging.info("=" * 60)
except Exception as e:
logging.error(f"Agent initialization failed: {e}")
import traceback
logging.error(f"Agent initialization traceback: {traceback.format_exc()}")
logging.warning("App will start with basic functionality")
# Add a basic health endpoint if agents fail
@app.get("/health/status")
async def basic_health():
return {"status": "degraded", "message": "Agents not initialized", "error": str(e)}
except Exception as e:
logging.error(f"Failed to import from ai_med_extract package: {e}")
import traceback
logging.error(f"Full traceback: {traceback.format_exc()}")
# Create a minimal FastAPI app as fallback
logging.info("Creating minimal fallback app...")
from fastapi import FastAPI
app = FastAPI(title="Medical AI Service (fallback)")
@app.get("/")
async def root():
return {
"message": "Medical AI Service - Fallback mode",
"error": str(e),
"status": "degraded"
}
@app.get("/health")
async def health():
return {"status": "degraded", "message": "Fallback mode active"}
@app.get("/docs")
async def docs():
return {"message": "API documentation not available in fallback mode"}
@app.get("/redoc")
async def redoc():
return {"message": "ReDoc not available in fallback mode"}
# Ensure we have an app instance
if app is None:
logging.error("No app instance created, creating emergency fallback...")
from fastapi import FastAPI
app = FastAPI(title="Medical AI Service (emergency fallback)")
@app.get("/")
async def root():
return {"message": "Emergency fallback mode", "status": "error"}
@app.get("/health")
async def health():
return {"status": "error", "message": "Emergency fallback mode"}
@app.get("/docs")
async def docs():
return {"message": "API documentation not available in emergency mode"}
@app.get("/redoc")
async def redoc():
return {"message": "ReDoc not available in emergency mode"}
# Export the app for Hugging Face Spaces
__all__ = ["app"]
# Ensure the app is available at module level
if 'app' not in locals():
logging.error("No app instance created, creating emergency fallback...")
from fastapi import FastAPI
app = FastAPI(title="Medical AI Service (emergency fallback)")
@app.get("/")
async def root():
return {"message": "Emergency fallback mode", "status": "error"}
@app.get("/health")
async def health():
return {"status": "error", "message": "Emergency fallback mode"}