File size: 5,132 Bytes
5374a2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
175
176
177
"""
Main application entry point for EvoAgentX.
"""
import logging
# import asyncio
from contextlib import asynccontextmanager

import uvicorn
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError, HTTPException

from evoagentx.app.config import settings
from evoagentx.app.db import Database
from evoagentx.app.security import init_users_collection
from evoagentx.app.api import (
    auth_router,
    agents_router,
    workflows_router,
    executions_router,
    system_router
)

# Configure logging
logging.basicConfig(
    level=getattr(logging, settings.LOG_LEVEL.upper()),
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# Lifespan context manager for startup and shutdown events
@asynccontextmanager
async def lifespan(app: FastAPI):
    """
    Async context manager to handle application startup and shutdown events.
    """
    # Startup tasks
    try:
        # Connect to database
        await Database.connect()
        
        # Initialize users collection and create admin user if not exists
        await init_users_collection()
        
        logger.info("Application startup completed successfully")
        yield
    except Exception as e:
        logger.error(f"Error during application startup: {e}")
        raise
    finally:
        # Shutdown tasks
        try:
            await Database.disconnect()
            logger.info("Application shutdown completed successfully")
        except Exception as e:
            logger.error(f"Error during application shutdown: {e}")

# Create FastAPI application
app = FastAPI(
    title="EvoAgentX API",
    description="API for EvoAgentX platform",
    version="1.0.0",
    lifespan=lifespan,
    docs_url="/docs",
    redoc_url="/redoc"
)

# Configure CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.CORS_ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Include routers
app.include_router(auth_router)
app.include_router(agents_router)
app.include_router(workflows_router)
app.include_router(executions_router)
app.include_router(system_router)

# Global exception handlers
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    """
    Custom validation error handler to provide more detailed error responses.
    """
    return JSONResponse(
        status_code=422,
        content={
            "status": "error",
            "message": "Validation error",
            "errors": exc.errors()
        }
    )

@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
    """
    Custom HTTP exception handler to provide consistent error responses.
    """
    return JSONResponse(
        status_code=exc.status_code,
        content={
            "status": "error",
            "message": exc.detail
        }
    )

# Root endpoint for health check
@app.get("/")
async def root():
    """
    Root endpoint for application health check.
    """
    return {
        "app_name": settings.APP_NAME,
        "status": "healthy",
        "version": "0.1.0"
    }

# Workflow logging and monitoring endpoint
@app.get("/metrics")
async def get_metrics():
    """
    Endpoint to retrieve system metrics and stats.
    """
    # Collect metrics from different services
    try:
        # Collect agent metrics
        total_agents = await Database.agents.count_documents({})
        active_agents = await Database.agents.count_documents({"status": "active"})
        
        # Collect workflow metrics
        total_workflows = await Database.workflows.count_documents({})
        running_workflows = await Database.workflows.count_documents({"status": "running"})
        
        # Collect execution metrics
        total_executions = await Database.executions.count_documents({})
        failed_executions = await Database.executions.count_documents({"status": "failed"})
        
        return {
            "agents": {
                "total": total_agents,
                "active": active_agents
            },
            "workflows": {
                "total": total_workflows,
                "running": running_workflows
            },
            "executions": {
                "total": total_executions,
                "failed": failed_executions
            }
        }
    except Exception as e:
        logger.error(f"Error retrieving metrics: {e}")
        return {
            "status": "error",
            "message": "Unable to retrieve metrics"
        }

# Run the application if this script is executed directly
if __name__ == "__main__":
    # Configuration for running the server
    uvicorn_config = {
        "host": settings.HOST,
        "port": settings.PORT,
        "reload": settings.DEBUG,
        "log_level": settings.LOG_LEVEL.lower()
    }
    
    # Start the server
    uvicorn.run("evoagentx.app.main:app", **uvicorn_config)