|
|
import { SingleAnalysisReport, BatchStreamResult } from "../types"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const uploadSingle = async (file: File): Promise<string> => { |
|
|
const formData = new FormData(); |
|
|
formData.append('file', file); |
|
|
|
|
|
const response = await fetch('/upload_single', { |
|
|
method: 'POST', |
|
|
body: formData, |
|
|
}); |
|
|
|
|
|
if (!response.ok) { |
|
|
throw new Error(`Upload failed: ${response.statusText}`); |
|
|
} |
|
|
|
|
|
const data = await response.json(); |
|
|
return data.filename; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const classifySingle = async (filename: string): Promise<SingleAnalysisReport> => { |
|
|
const response = await fetch('/classify_single', { |
|
|
method: 'POST', |
|
|
headers: { |
|
|
'Content-Type': 'application/json', |
|
|
}, |
|
|
body: JSON.stringify({ filename }), |
|
|
}); |
|
|
|
|
|
if (!response.ok) { |
|
|
throw new Error(`Classification failed: ${response.statusText}`); |
|
|
} |
|
|
|
|
|
const data = await response.json(); |
|
|
return { |
|
|
classification: data.classification, |
|
|
detailed_results: data.detailed_results, |
|
|
html: data.result_table |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const uploadMultiple = async (files: File[]): Promise<void> => { |
|
|
const formData = new FormData(); |
|
|
files.forEach(file => { |
|
|
formData.append('file', file); |
|
|
}); |
|
|
|
|
|
const response = await fetch('/upload_multiple', { |
|
|
method: 'POST', |
|
|
body: formData, |
|
|
}); |
|
|
|
|
|
if (!response.ok) { |
|
|
throw new Error(`Batch upload failed: ${response.statusText}`); |
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const classifyMultiple = async (): Promise<ReadableStream<Uint8Array>> => { |
|
|
const response = await fetch('/classify_multiple', { |
|
|
method: 'POST', |
|
|
}); |
|
|
|
|
|
if (!response.ok || !response.body) { |
|
|
throw new Error(`Batch classification failed: ${response.statusText}`); |
|
|
} |
|
|
|
|
|
return response.body; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const clearUploads = async () => { |
|
|
const response = await fetch('/clear_uploads', { |
|
|
method: 'POST', |
|
|
}); |
|
|
return response.json(); |
|
|
}; |
|
|
|
|
|
export const getSamples = async () => { |
|
|
const response = await fetch('/api/samples'); |
|
|
return response.json(); |
|
|
}; |
|
|
|
|
|
export const useSample = async (filename: string, destination: 'single' | 'multiple') => { |
|
|
const response = await fetch('/api/use_sample', { |
|
|
method: 'POST', |
|
|
headers: { 'Content-Type': 'application/json' }, |
|
|
body: JSON.stringify({ filename, destination }) |
|
|
}); |
|
|
return response.json(); |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function* classifyMultipleStream(): AsyncGenerator<BatchStreamResult> { |
|
|
const stream = await classifyMultiple(); |
|
|
const reader = stream.getReader(); |
|
|
const decoder = new TextDecoder(); |
|
|
let buffer = ''; |
|
|
|
|
|
try { |
|
|
while (true) { |
|
|
const { done, value } = await reader.read(); |
|
|
if (done) break; |
|
|
|
|
|
buffer += decoder.decode(value, { stream: true }); |
|
|
|
|
|
|
|
|
const lines = buffer.split('\n'); |
|
|
buffer = lines.pop() || ''; |
|
|
|
|
|
for (const line of lines) { |
|
|
if (line.trim()) { |
|
|
try { |
|
|
const result = JSON.parse(line); |
|
|
yield result as BatchStreamResult; |
|
|
} catch (e) { |
|
|
console.warn("Failed to parse stream chunk", e); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} finally { |
|
|
reader.releaseLock(); |
|
|
} |
|
|
} |