forked from StellarSplit/StellarSplit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
106 lines (83 loc) · 2.87 KB
/
Copy pathmain.py
File metadata and controls
106 lines (83 loc) · 2.87 KB
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
"""FastAPI application entry point."""
import time
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from prometheus_client import Counter, Histogram, generate_latest, CONTENT_TYPE_LATEST
from app.config import get_settings
from app.api import analyze, models, feedback, health
# Metrics
REQUEST_COUNT = Counter(
'ml_service_requests_total',
'Total requests',
['method', 'endpoint', 'status']
)
REQUEST_DURATION = Histogram(
'ml_service_request_duration_seconds',
'Request duration',
['method', 'endpoint']
)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Application lifespan manager."""
# Startup
settings = get_settings()
print(f"Starting ML Fraud Detection Service v1.0.0")
print(f"Model registry path: {settings.model_registry_path}")
print(f"High risk threshold: {settings.high_risk_threshold}")
yield
# Shutdown
print("Shutting down ML Fraud Detection Service")
app = FastAPI(
title="StellarSplit Fraud Detection ML Service",
description="ML-based fraud detection for suspicious splits and payments",
version="1.0.0",
lifespan=lifespan
)
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.middleware("http")
async def metrics_middleware(request: Request, call_next):
"""Collect request metrics."""
start_time = time.time()
response = await call_next(request)
duration = time.time() - start_time
endpoint = request.url.path
method = request.method
status = str(response.status_code)
REQUEST_COUNT.labels(method=method, endpoint=endpoint, status=status).inc()
REQUEST_DURATION.labels(method=method, endpoint=endpoint).observe(duration)
return response
# Include routers
app.include_router(health.router, tags=["Health"])
app.include_router(analyze.router, prefix="/api/v1", tags=["Analysis"])
app.include_router(models.router, prefix="/api/v1", tags=["Models"])
app.include_router(feedback.router, prefix="/api/v1", tags=["Feedback"])
@app.get("/metrics")
async def metrics():
"""Prometheus metrics endpoint."""
from fastapi.responses import Response
return Response(content=generate_latest(), media_type=CONTENT_TYPE_LATEST)
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
"""Global exception handler."""
return JSONResponse(
status_code=500,
content={"detail": "Internal server error", "message": str(exc)}
)
if __name__ == "__main__":
import uvicorn
settings = get_settings()
uvicorn.run(
"app.main:app",
host=settings.host,
port=settings.port,
reload=settings.debug
)