import traceback import uuid from models.whisper import model import modules.register as register from processor import generate_audio import json from fastapi import FastAPI, HTTPException from pydantic import BaseModel, HttpUrl from fastapi.middleware.cors import CORSMiddleware from fastapi.openapi.docs import get_swagger_ui_html import os import requests from modules.audio import convert, get_audio_duration from modules.r2 import upload_to_s3 from concurrent.futures import ThreadPoolExecutor vpv_webhook = os.environ.get("VPV_WEBHOOK") app = FastAPI(title="Minha API", description="API de exemplo com FastAPI e Swagger", version="1.0.0") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) def download_file(url: str) -> str: """ Baixa um arquivo da URL fornecida e o salva no diretório 'downloads/'. O nome do arquivo é extraído da URL automaticamente. """ try: os.makedirs("downloads", exist_ok=True) file_name = os.path.basename(url.split("?")[0]) save_path = os.path.join("downloads", file_name) response = requests.get(url) response.raise_for_status() with open(save_path, 'wb') as f: f.write(response.content) return save_path except requests.exceptions.RequestException as e: raise Exception(f"Erro ao baixar o arquivo: {e}") @app.get("/test", include_in_schema=False) def test(): return {"ok": True} @app.get("/", include_in_schema=False) async def custom_swagger_ui_html(): return get_swagger_ui_html(openapi_url="/openapi.json", title="Alert Pix Ai v2") @app.get("/openapi.json", include_in_schema=False) async def openapi(): with open("swagger.json") as f: return json.load(f) class ProcessRequest(BaseModel): key: str text: str id: str receiver: str webhook: str censor: bool = False offset: float = -0.3 format: str = "wav" speed: float = 0.8 crossfade: float = 0.1 executor = ThreadPoolExecutor(max_workers=8) def process_queue(item): key, censor, offset, text, format, speed, crossfade, id, receiver, webhook = item audio = generate_audio(key, text, censor, offset, speed=speed, crossfade=crossfade) convertedAudioPath = convert(audio, format) duration = get_audio_duration(convertedAudioPath) audioUrl = upload_to_s3(convertedAudioPath, f"{id}", format) os.remove(audio) os.remove(convertedAudioPath) payload = { "id": id, "duration": duration, "receiver": receiver, "url": audioUrl } requests.post(webhook, json=payload) @app.post("/process") def process_audio(payload: ProcessRequest): key = payload.key censor = payload.censor offset = payload.offset text = payload.text format = payload.format speed = payload.speed crossfade = payload.crossfade id = payload.id receiver = payload.receiver webhook = payload.webhook if len(text) >= 1000: raise HTTPException(status_code=500, detail=str(e)) try: executor.submit(process_queue, (key, censor, offset, text, format, speed, crossfade, id, receiver, webhook)) return {"success": True, "err": ""} except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: error_trace = traceback.format_exc() dc_callback = "https://discord.com/api/webhooks/1285586984898662511/QNVvY2rtoKICamlXsC1BreBaYjS9341jz9ANCDBzayXt4C7v-vTFzKfUtKQkwW7BwpfP" data = { "content": "", "tts": False, "embeds": [ { "type": "rich", "title": f"Erro aconteceu na IA - MIMIC - processo", "description": f"Erro: {str(e)}\n\nDetalhes do erro:\n```{error_trace}```" } ] } headers = { "Content-Type": "application/json", "Accept": "application/json", } requests.post(dc_callback, headers=headers, data=json.dumps(data)) raise HTTPException(status_code=500, detail=str(e)) class TrainRequest(BaseModel): audio: HttpUrl key: str endpoint: str id: str @app.post("/train") def create_item(payload: TrainRequest): audio = payload.audio key = payload.key endpoint = payload.endpoint try: src = download_file(str(audio)) data = register.process_audio(src, key) for i in range(3): try: payload = {"success": True, "id": payload.id} requests.post(endpoint, json=payload) break except Exception as e: pass return data except ValueError as e: raise HTTPException(status_code=400, detail=str(e)) except Exception as e: error_trace = traceback.format_exc() dc_callback = "https://discord.com/api/webhooks/1285586984898662511/QNVvY2rtoKICamlXsC1BreBaYjS9341jz9ANCDBzayXt4C7v-vTFzKfUtKQkwW7BwpfP" data = { "content": "", "tts": False, "embeds": [ { "type": "rich", "title": f"Erro aconteceu na IA -MIMIC - treinar", "description": f"Erro: {str(e)}\n\nDetalhes do erro:\n```{error_trace}```" } ] } headers = { "Content-Type": "application/json", "Accept": "application/json", } requests.post(dc_callback, headers=headers, data=json.dumps(data)) raise HTTPException(status_code=500, detail=str(e)) if __name__ == "__main__": import uvicorn uvicorn.run("app:app", host="0.0.0.0", port=7860)