joao-dutra's picture
Update app.py
6cb5ec5 verified
Raw
History Blame Contribute Delete
3.53 kB
from fastapi import FastAPI, File, UploadFile, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
app = FastAPI(
title="JMeter Performance Analyzer API",
description="API que recebe um CSV do JMeter, treina um modelo linear e retorna métricas e dados para visualização.",
version="1.0.0"
)
# ======================================
# 🔓 CORS – permite chamadas do front-end React
# ======================================
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 🔒 em produção, especifique seu domínio
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# ======================================
# 🧠 Função auxiliar
# ======================================
def treinar_modelo(df: pd.DataFrame):
"""Treina o modelo linear e retorna métricas e previsões."""
df['timeStamp'] = pd.to_datetime(df['timeStamp'], unit='ms', errors='coerce')
df.dropna(subset=['timeStamp', 'elapsed'], inplace=True)
# Cria eixo temporal
df['t'] = (df['timeStamp'] - df['timeStamp'].min()).dt.total_seconds()
# Variáveis
X = df[['t']]
y = df['elapsed']
# Modelo linear
model = LinearRegression().fit(X, y)
df['predito'] = model.predict(X)
df['erro'] = df['elapsed'] - df['predito']
# Métricas
r2 = r2_score(y, df['predito'])
mse = mean_squared_error(y, df['predito'])
rmse = mse ** 0.5
# Previsão futura (ex: próximos 5 minutos = 300s)
future_t = np.linspace(df['t'].max(), df['t'].max() + 300, 100)
future_pred = model.predict(pd.DataFrame({'t': future_t}))
return {
"coeficiente": float(model.coef_[0]),
"intercepto": float(model.intercept_),
"r2": float(r2),
"rmse": float(rmse),
"dados": {
"t": df['t'].tolist(),
"elapsed": df['elapsed'].tolist(),
"predito": df['predito'].tolist(),
"erro": df['erro'].tolist(),
"future_t": future_t.tolist(),
"future_pred": future_pred.tolist(),
}
}
# ======================================
# 🚀 Endpoint principal
# ======================================
@app.post("/analisar/")
async def analisar_csv(file: UploadFile = File(...)):
"""
Recebe um arquivo CSV do JMeter e retorna métricas e previsões.
"""
try:
# Lê o arquivo CSV enviado
contents = await file.read()
df = pd.read_csv(
pd.io.common.BytesIO(contents),
encoding="utf-8"
)
# Validação mínima
required_cols = {"timeStamp", "elapsed"}
if not required_cols.issubset(df.columns):
raise HTTPException(
status_code=400,
detail=f"O CSV precisa conter as colunas: {', '.join(required_cols)}"
)
# Processar e treinar o modelo
resultado = treinar_modelo(df)
return JSONResponse(content=resultado)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# ======================================
# 🏠 Endpoint básico de teste
# ======================================
@app.get("/")
async def root():
return {
"status": "ok",
"message": "API JMeter Performance Analyzer está ativa. Envie um CSV para /analisar/"
}