RAG / frontend-react /src /api.js
JenishMakwana's picture
feat: implement backend configuration, dynamic frontend API routing, and core React application structure with modular components
320a9c2
Raw
History Blame Contribute Delete
6.01 kB
// Helper to check if the current hostname is a local loopback or private network address
const isLocalHost = () => {
const hostname = window.location.hostname;
return (
hostname === 'localhost' ||
hostname === '127.0.0.1' ||
hostname === '[::1]' ||
// Private IPv4 ranges (RFC 1918)
/^192\.168\./.test(hostname) ||
/^10\./.test(hostname) ||
/^172\.(1[6-9]|2\d|3[01])\./.test(hostname) ||
// mDNS local hostnames
/\.local$/.test(hostname)
);
};
// Dynamic backend URL to support local development and production Hugging Face Space
const BASE_URL = isLocalHost()
? `http://${window.location.hostname}:8001`
: 'https://jenishmakwana-rag.hf.space';
// Helper to parse error details and attach status code
async function handleResponseError(response, defaultMsg) {
let errorMsg = defaultMsg;
try {
const errorData = await response.json();
errorMsg = errorData.detail || errorMsg;
} catch (e) {
// Ignore JSON parsing errors for non-JSON responses
}
const err = new Error(errorMsg);
err.status = response.status;
throw err;
}
export async function login(email, password) {
const formData = new URLSearchParams();
formData.append('username', email); // OAuth2 expects 'username' field
formData.append('password', password);
const response = await fetch(`${BASE_URL}/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: formData,
});
if (!response.ok) {
await handleResponseError(response, 'Login failed');
}
return await response.json();
}
export async function register(username, email, password) {
const response = await fetch(`${BASE_URL}/register`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ username, email, password }),
});
if (!response.ok) {
await handleResponseError(response, 'Registration failed');
}
return await response.json();
}
export async function fetchDocuments(token) {
const response = await fetch(`${BASE_URL}/documents/`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) {
await handleResponseError(response, 'Failed to fetch documents');
}
return await response.json();
}
export async function uploadDocument(token, file, sessionId = null) {
const formData = new FormData();
formData.append('file', file);
if (sessionId) {
formData.append('session_id', sessionId);
}
const response = await fetch(`${BASE_URL}/documents/upload`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
},
body: formData,
});
if (!response.ok) {
await handleResponseError(response, 'Upload failed');
}
return await response.json();
}
export async function deleteDocument(token, filename) {
const response = await fetch(`${BASE_URL}/documents/${encodeURIComponent(filename)}`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) {
await handleResponseError(response, 'Delete failed');
}
return await response.json();
}
export async function chatQuery(token, query, sessionId, filename = null, filenames = null) {
const response = await fetch(`${BASE_URL}/chat/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({
query,
session_id: sessionId,
filename,
filenames
}),
});
if (!response.ok) {
await handleResponseError(response, 'Chat query failed');
}
// Return the raw response so the UI can read the stream
return response;
}
export async function fetchChatSessions(token) {
const response = await fetch(`${BASE_URL}/chat/sessions`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) {
await handleResponseError(response, 'Failed to fetch chat sessions');
}
return await response.json();
}
export async function fetchChatHistory(token, sessionId) {
const response = await fetch(`${BASE_URL}/chat/history/${sessionId}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) {
await handleResponseError(response, 'Failed to fetch chat history');
}
return await response.json();
}
export async function fetchSessionDocuments(token, sessionId) {
const response = await fetch(`${BASE_URL}/documents/session/${sessionId}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) {
await handleResponseError(response, 'Failed to fetch session documents');
}
return await response.json();
}
export async function deleteChatSession(token, sessionId) {
const response = await fetch(`${BASE_URL}/chat/session/${sessionId}`, {
method: 'DELETE',
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) {
await handleResponseError(response, 'Failed to delete chat session');
}
return await response.json();
}
export async function transcribeVoice(token, audioBlob) {
const formData = new FormData();
// Name the file 'recording.webm' so backend knows how to save it
formData.append('file', audioBlob, 'recording.webm');
const response = await fetch(`${BASE_URL}/voice/transcribe`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
},
body: formData,
});
if (!response.ok) {
await handleResponseError(response, 'Failed to transcribe audio');
}
return await response.json();
}
export async function getTtsAudio(token, text, signal) {
const response = await fetch(`${BASE_URL}/chat/speak`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ text }),
signal
});
if (!response.ok) {
await handleResponseError(response, 'TTS request failed');
}
return response;
}