import os import json import re from fastapi import FastAPI, UploadFile, File from fastapi.middleware.cors import CORSMiddleware from groq import Groq from dotenv import load_dotenv from presidio_analyzer import AnalyzerEngine, PatternRecognizer, Pattern from presidio_anonymizer import AnonymizerEngine from presidio_anonymizer.entities import OperatorConfig load_dotenv() app = FastAPI(title="VoiceGuard Engine") app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"]) # Initialize Groq Client & Presidio client = Groq(api_key=os.getenv("GROQ_API_KEY")) analyzer = AnalyzerEngine() anonymizer = AnonymizerEngine() # --- ENHANCED SECURITY: Custom Credit Card / Account Number Recognizer --- # This regex catches variations of numbers separated by hyphens or spaces (e.g., 4-3-3-5 patterns) card_pattern = Pattern( name="custom_card_pattern", regex=r"\b(?:\d[ -]*?){10,19}\b", score=0.85 ) custom_card_recognizer = PatternRecognizer( supported_entity="CUSTOM_CARD", patterns=[card_pattern] ) # Register the custom firewall rule analyzer.registry.add_recognizer(custom_card_recognizer) # ------------------------------------------------------------------------- def scrub_pii(text: str) -> str: """Detects and redacts sensitive data (Names, Phones, Cards, APIs).""" # Added "CUSTOM_CARD" to the target entities list target_entities = ["PHONE_NUMBER", "EMAIL_ADDRESS", "PERSON", "CREDIT_CARD", "CUSTOM_CARD"] results = analyzer.analyze( text=text, entities=target_entities, language='en' ) operators = { "PERSON": OperatorConfig("replace", {"new_value": "[NAME REDACTED]"}), "PHONE_NUMBER": OperatorConfig("replace", {"new_value": "[PHONE REDACTED]"}), "CREDIT_CARD": OperatorConfig("replace", {"new_value": "[CARD REDACTED]"}), "CUSTOM_CARD": OperatorConfig("replace", {"new_value": "[CARD REDACTED]"}) # Map custom matches to standard redactor tag } return anonymizer.anonymize(text=text, analyzer_results=results, operators=operators).text def extract_analytics(text: str) -> dict: """Uses Llama 3 to generate structured business analytics from the safe text.""" prompt = f"""Analyze the following transcript. Output ONLY valid JSON with no markdown formatting. Format required: {{"sentiment": "Positive/Neutral/Negative", "compliance_flag": true/false, "action_items": ["item1"]}} Transcript: {text}""" response = client.chat.completions.create( model="llama-3.3-70b-versatile", messages=[{"role": "user", "content": prompt}], temperature=0, response_format={"type": "json_object"} ) return json.loads(response.choices[0].message.content) @app.post("/process-audio") async def process_audio(file: UploadFile = File(...)): temp_file_path = f"temp_{file.filename}" with open(temp_file_path, "wb") as buffer: buffer.write(await file.read()) try: with open(temp_file_path, "rb") as audio_file: transcription = client.audio.transcriptions.create( file=(temp_file_path, audio_file.read()), model="whisper-large-v3", response_format="text" ) raw_text = transcription safe_text = scrub_pii(raw_text) analytics = extract_analytics(safe_text) return { "raw_transcript": raw_text, "safe_transcript": safe_text, "analytics": analytics } finally: if os.path.exists(temp_file_path): os.remove(temp_file_path)