Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
| /** | |
| * HuggingFace Spaces API Client | |
| * | |
| * Calls the ML API hosted on HuggingFace Spaces instead of local Python. | |
| * This enables deployment on platforms without Python support. | |
| * | |
| * Set HF_SPACES_URL environment variable to your Space URL: | |
| * HF_SPACES_URL=https://username-space-name.hf.space | |
| */ | |
| import FormData from 'form-data'; | |
| import fs from 'fs'; | |
| import path from 'path'; | |
| const HF_SPACES_URL = process.env.HF_SPACES_URL; | |
| export function isHfSpacesEnabled(): boolean { | |
| return !!HF_SPACES_URL; | |
| } | |
| export function getSpacesUrl(): string | undefined { | |
| return HF_SPACES_URL; | |
| } | |
| interface EmbeddingResult { | |
| success: boolean; | |
| embedding?: number[]; | |
| dimension?: number; | |
| error?: string; | |
| } | |
| interface ChunkResult { | |
| success: boolean; | |
| total_duration?: number; | |
| chunk_count?: number; | |
| chunks?: Array<{ | |
| start_time: number; | |
| end_time: number; | |
| embedding: number[]; | |
| }>; | |
| error?: string; | |
| } | |
| interface SearchResult { | |
| matches: Array<{ | |
| score: number; | |
| trackId: string; | |
| title: string; | |
| artist: string; | |
| distinctiveness?: number; | |
| }>; | |
| mean_similarity?: number; | |
| } | |
| /** | |
| * Extract MERT embedding via HuggingFace Spaces API | |
| */ | |
| export async function extractEmbedding(audioPath: string): Promise<EmbeddingResult> { | |
| if (!HF_SPACES_URL) { | |
| return { success: false, error: "HF_SPACES_URL not configured" }; | |
| } | |
| try { | |
| const formData = new FormData(); | |
| formData.append('audio_file', fs.createReadStream(audioPath)); | |
| const response = await fetch(`${HF_SPACES_URL}/api/extract_embedding`, { | |
| method: 'POST', | |
| body: formData as any, | |
| }); | |
| const text = await response.text(); | |
| return JSON.parse(text); | |
| } catch (error) { | |
| return { success: false, error: String(error) }; | |
| } | |
| } | |
| /** | |
| * Extract chunk embeddings via HuggingFace Spaces API | |
| */ | |
| export async function extractChunks( | |
| audioPath: string, | |
| chunkDuration: number = 10.0, | |
| overlap: number = 5.0 | |
| ): Promise<ChunkResult> { | |
| if (!HF_SPACES_URL) { | |
| return { success: false, error: "HF_SPACES_URL not configured" }; | |
| } | |
| try { | |
| const formData = new FormData(); | |
| formData.append('audio_file', fs.createReadStream(audioPath)); | |
| formData.append('chunk_duration', String(chunkDuration)); | |
| formData.append('overlap', String(overlap)); | |
| const response = await fetch(`${HF_SPACES_URL}/api/extract_chunks`, { | |
| method: 'POST', | |
| body: formData as any, | |
| }); | |
| const text = await response.text(); | |
| return JSON.parse(text); | |
| } catch (error) { | |
| return { success: false, error: String(error) }; | |
| } | |
| } | |
| /** | |
| * Search for similar tracks via HuggingFace Spaces API | |
| */ | |
| export async function searchSimilar( | |
| queryEmbedding: number[], | |
| indexData: { entries: Array<{ trackId: string; title: string; artist: string; embedding: number[] }> }, | |
| k: number = 5 | |
| ): Promise<SearchResult> { | |
| if (!HF_SPACES_URL) { | |
| return { matches: [] }; | |
| } | |
| try { | |
| const formData = new FormData(); | |
| formData.append('query_embedding_json', JSON.stringify(queryEmbedding)); | |
| formData.append('index_json', JSON.stringify(indexData)); | |
| formData.append('k', String(k)); | |
| const response = await fetch(`${HF_SPACES_URL}/api/search`, { | |
| method: 'POST', | |
| body: formData as any, | |
| }); | |
| const text = await response.text(); | |
| return JSON.parse(text); | |
| } catch (error) { | |
| return { matches: [] }; | |
| } | |
| } | |
| /** | |
| * Check if HuggingFace Spaces API is healthy | |
| */ | |
| export async function checkHealth(): Promise<{ ok: boolean; details?: any }> { | |
| if (!HF_SPACES_URL) { | |
| return { ok: false, details: { error: "HF_SPACES_URL not configured" } }; | |
| } | |
| try { | |
| const response = await fetch(`${HF_SPACES_URL}/api/health`, { | |
| method: 'POST', | |
| }); | |
| const text = await response.text(); | |
| const data = JSON.parse(text); | |
| return { ok: data.status === 'ok', details: data }; | |
| } catch (error) { | |
| return { ok: false, details: { error: String(error) } }; | |
| } | |
| } | |