ankahi / mobile /ankahi_flutter /lib /api /ankahi_api.dart
bhriguverma's picture
Add files using upload-large-folder tool
bd9eadd verified
Raw
History Blame Contribute Delete
4.56 kB
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../config/app_config.dart';
import '../models/persona.dart';
import '../models/pictogram.dart';
import '../models/prediction.dart';
class ApiException implements Exception {
final int statusCode;
final String message;
ApiException(this.statusCode, this.message);
@override
String toString() => 'ApiException: $statusCode - $message';
}
class ApiTimeoutException implements Exception {
final String message;
ApiTimeoutException(this.message);
@override
String toString() => 'ApiTimeoutException: $message';
}
class HealthStatus {
final bool isOk;
final bool modelLoaded;
HealthStatus(this.isOk, this.modelLoaded);
}
class AnkahiApi {
final String baseUrl = AppConfig.apiBaseUrl;
Future<PredictionResult> predict(
List<String> sequence,
String personaId, {
String? context,
String? audioHint
}) async {
final response = await http.post(
Uri.parse('$baseUrl/predict'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'pictogram_sequence': sequence,
'persona_id': personaId,
'context': context ?? 'daily',
'audio_transcript': audioHint,
}),
).timeout(AppConfig.apiTimeout, onTimeout: () {
throw ApiTimeoutException('Prediction timed out');
});
if (response.statusCode == 200) {
return PredictionResult.fromJson(jsonDecode(response.body));
} else {
throw ApiException(response.statusCode, response.body);
}
}
Future<String> speak(String text, String personaId, String language) async {
final response = await http.post(
Uri.parse('$baseUrl/speak'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'text': text,
'persona_id': personaId,
'language': language,
}),
).timeout(AppConfig.apiTimeout, onTimeout: () {
throw ApiTimeoutException('Speak request timed out');
});
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
return '$baseUrl${data['audio_url']}';
} else {
throw ApiException(response.statusCode, response.body);
}
}
Future<void> logUtterance(
List<String> seq,
String confirmed,
String personaId, {
bool wasFirst = true
}) async {
try {
await http.post(
Uri.parse('$baseUrl/utterances/log'),
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
'pictogram_sequence': seq,
'confirmed_sentence': confirmed,
'persona_id': personaId,
'was_first_alternative': wasFirst,
}),
).timeout(const Duration(seconds: 10));
} catch (e) {
// Background task, ignore errors
print('Failed to log utterance: $e');
}
}
Future<List<PersonaModel>> getPersonas() async {
final response = await http.get(Uri.parse('$baseUrl/personas'))
.timeout(AppConfig.apiTimeout);
if (response.statusCode == 200) {
final List<dynamic> data = jsonDecode(response.body);
return data.map((json) => PersonaModel.fromJson(json)).toList();
} else {
throw ApiException(response.statusCode, response.body);
}
}
Future<bool> switchPersona(String personaId) async {
final response = await http.post(Uri.parse('$baseUrl/personas/switch/$personaId'))
.timeout(AppConfig.apiTimeout);
if (response.statusCode == 200) {
return true;
} else {
throw ApiException(response.statusCode, response.body);
}
}
Future<List<PictogramModel>> searchSymbols(
String query, {
String language = 'en',
int limit = 20
}) async {
final response = await http.get(
Uri.parse('$baseUrl/symbols/search?query=$query&language=$language&limit=$limit')
).timeout(AppConfig.apiTimeout);
if (response.statusCode == 200) {
final List<dynamic> data = jsonDecode(response.body);
return data.map((json) => PictogramModel.fromJson(json)).toList();
} else {
throw ApiException(response.statusCode, response.body);
}
}
Future<HealthStatus> getHealth() async {
try {
final response = await http.get(Uri.parse('$baseUrl/health'))
.timeout(const Duration(seconds: 5));
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
return HealthStatus(true, data['model_loaded']);
}
} catch (e) {
print('Health check failed: $e');
}
return HealthStatus(false, false);
}
}