Download frontend/src/services/api.ts from yusufcalisir/Collaborative-Fraud-Intelligence-Simulator: direct link, hf CLI and curl.
- Browser
- Download file 5.1 kB
-
https://huggingface.co/spaces/yusufcalisir/Collaborative-Fraud-Intelligence-Simulator/resolve/main/frontend/src/services/api.ts
- Command line
-
hf download hf://spaces/yusufcalisir/Collaborative-Fraud-Intelligence-Simulator/frontend/src/services/api.ts
-
curl -L -o api.ts https://huggingface.co/spaces/yusufcalisir/Collaborative-Fraud-Intelligence-Simulator/resolve/main/frontend/src/services/api.ts
5.1 kB
| import { | |
| CounterfactualReport, | |
| CounterfactualSimulationParams, | |
| FLRoundResult, | |
| FLSimulationRequest, | |
| PredictPayload, | |
| PredictResponse, | |
| SystemHealthStatus, | |
| } from '../types'; | |
| const BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api/v1'; | |
| export async function checkSystemHealth(): Promise<SystemHealthStatus> { | |
| try { | |
| const res = await fetch('/health'); | |
| if (!res.ok) throw new Error('Health check failed'); | |
| return await res.json(); | |
| } catch { | |
| return { | |
| status: 'offline', | |
| service: 'cfi-backend', | |
| environment: 'development', | |
| redis_connected: false, | |
| version: '2.4.0', | |
| }; | |
| } | |
| } | |
| export async function predictTransaction(payload: PredictPayload): Promise<PredictResponse> { | |
| const res = await fetch(`${BASE_URL}/predict`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify(payload), | |
| }); | |
| if (!res.ok) { | |
| throw new Error(`Prediction API error: ${res.statusText}`); | |
| } | |
| return res.json(); | |
| } | |
| export async function fetchCounterfactual( | |
| alertIdOrParams: string | CounterfactualSimulationParams = 'alt_1001', | |
| targetScore: number = 350.0 | |
| ): Promise<CounterfactualReport> { | |
| const query = new URLSearchParams(); | |
| if (typeof alertIdOrParams === 'object') { | |
| query.set('alert_id', alertIdOrParams.alert_id || 'alt_1001'); | |
| query.set('target_score', String(alertIdOrParams.target_score ?? targetScore)); | |
| if (alertIdOrParams.amount !== undefined) query.set('amount', String(alertIdOrParams.amount)); | |
| if (alertIdOrParams.velocity !== undefined) query.set('velocity', String(alertIdOrParams.velocity)); | |
| if (alertIdOrParams.merchant_risk !== undefined) query.set('merchant_risk', String(alertIdOrParams.merchant_risk)); | |
| } else { | |
| query.set('alert_id', alertIdOrParams || 'alt_1001'); | |
| query.set('target_score', String(targetScore)); | |
| } | |
| const res = await fetch(`${BASE_URL}/explainability/counterfactuals?${query.toString()}`); | |
| if (!res.ok) { | |
| throw new Error(`Counterfactual API error (${res.status}): ${res.statusText}`); | |
| } | |
| const data = await res.json(); | |
| return { | |
| alert_id: data.alert_id, | |
| original_score: data.original_score, | |
| remediated_score: data.remediated_score, | |
| is_cleared: data.is_cleared, | |
| changes: (data.changes || []).map((c: any) => ({ | |
| feature: c.feature, | |
| original_value: c.original_value, | |
| suggested_value: c.suggested_value ?? c.remediated_value, | |
| delta: c.delta ?? 0, | |
| description: c.description ?? c.delta_explanation ?? '', | |
| })), | |
| summary_text: data.summary_text, | |
| }; | |
| } | |
| export async function runFLSimulation( | |
| simReq: FLSimulationRequest | |
| ): Promise<FLRoundResult[]> { | |
| const methodMap: Record<string, string> = { | |
| FED_AVG: 'fed_avg', | |
| FED_ADAM: 'fed_avg_weighted', | |
| KRUM: 'krum', | |
| BULYAN: 'bulyan', | |
| SCAFFOLD: 'fed_avg', | |
| FED_ASYNC: 'fed_avg', | |
| }; | |
| const aggregation_method = methodMap[simReq.algorithm] || simReq.algorithm || 'fed_avg_weighted'; | |
| const res = await fetch(`${BASE_URL}/simulations`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ | |
| num_rounds: simReq.num_rounds, | |
| local_epochs: simReq.local_epochs || 2, | |
| learning_rate: simReq.learning_rate || 0.01, | |
| privacy_mechanism: simReq.dp_epsilon ? 'differential_privacy' : 'none', | |
| dp_epsilon: simReq.dp_epsilon || 1.0, | |
| dp_delta: simReq.dp_delta || 1e-5, | |
| aggregation_method, | |
| }), | |
| }); | |
| if (!res.ok) { | |
| throw new Error(`Federated learning simulation request failed: ${res.status} ${res.statusText}`); | |
| } | |
| const data = await res.json(); | |
| if (Array.isArray(data.rounds)) { | |
| return data.rounds; | |
| } | |
| const simulationId = data.id; | |
| if (!simulationId) { | |
| return []; | |
| } | |
| // Poll simulation until rounds are populated or completed | |
| const maxAttempts = 30; | |
| for (let attempt = 0; attempt < maxAttempts; attempt++) { | |
| await new Promise((resolve) => setTimeout(resolve, 800)); | |
| const statusRes = await fetch(`${BASE_URL}/simulations/${simulationId}`); | |
| if (statusRes.ok) { | |
| const statusData = await statusRes.json(); | |
| if (Array.isArray(statusData.rounds) && statusData.rounds.length > 0) { | |
| if (statusData.status === 'completed' || statusData.rounds.length >= simReq.num_rounds) { | |
| return statusData.rounds.map((r: any) => ({ | |
| round_number: r.round_number, | |
| global_loss: r.global_loss, | |
| per_bank_loss: r.per_bank_loss || { | |
| bank_a: r.global_loss, | |
| bank_b: r.global_loss, | |
| bank_c: r.global_loss, | |
| }, | |
| participating_bank_ids: r.participating_banks || ['bank_a', 'bank_b', 'bank_c'], | |
| dropped_bank_ids: r.dropped_banks || [], | |
| aggregation_time_ms: r.duration_ms || 25, | |
| })); | |
| } | |
| } | |
| if (statusData.status === 'failed') { | |
| throw new Error(statusData.error_message || 'Federated learning simulation execution failed'); | |
| } | |
| } | |
| } | |
| throw new Error('Simulation timed out waiting for round completion'); | |
| } | |