apix/lib/api.ts
Khoa.vo 0ef7e5475c
Some checks are pending
CI / build (18.x) (push) Waiting to run
CI / build (20.x) (push) Waiting to run
v3.0.0: Add FastAPI backend
- Add Python FastAPI backend with Pydantic validation
- Port WhiskClient and MetaAIClient to Python
- Create API routers for all endpoints
- Add Swagger/ReDoc documentation at /docs
- Update Dockerfile for multi-service container
- Add lib/api.ts frontend client
- Update README for V3
2026-01-13 07:46:32 +07:00

236 lines
5.8 KiB
TypeScript

/**
* API Client for FastAPI Backend
*
* Centralized API calls to the FastAPI backend.
* Used by frontend components to call the new Python backend.
*/
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
// Types
export interface GenerateParams {
prompt: string;
aspectRatio?: string;
refs?: { subject?: string | string[]; scene?: string | string[]; style?: string | string[] };
preciseMode?: boolean;
imageCount?: number;
cookies: string;
}
export interface GeneratedImage {
data: string;
index?: number;
prompt: string;
aspectRatio: string;
}
export interface VideoParams {
prompt: string;
imageBase64?: string;
imageGenerationId?: string;
cookies: string;
}
export interface ReferenceUploadParams {
imageBase64: string;
mimeType: string;
category: string;
cookies: string;
}
export interface MetaGenerateParams {
prompt: string;
cookies?: string;
imageCount?: number;
aspectRatio?: string;
useMetaFreeWrapper?: boolean;
metaFreeWrapperUrl?: string;
}
// Helper to handle API responses
async function handleResponse<T>(response: Response): Promise<T> {
if (!response.ok) {
const error = await response.json().catch(() => ({ error: 'Request failed' }));
throw new Error(error.error || error.detail || `HTTP ${response.status}`);
}
return response.json();
}
/**
* Generate images using Whisk API
*/
export async function generateImages(params: GenerateParams): Promise<{ images: GeneratedImage[] }> {
const response = await fetch(`${API_BASE}/generate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params)
});
return handleResponse(response);
}
/**
* Generate video using Whisk API
*/
export async function generateVideo(params: VideoParams): Promise<{
success: boolean;
id?: string;
url?: string;
status?: string;
}> {
const response = await fetch(`${API_BASE}/video/generate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params)
});
return handleResponse(response);
}
/**
* Upload reference image
*/
export async function uploadReference(params: ReferenceUploadParams): Promise<{
success: boolean;
id: string;
}> {
const response = await fetch(`${API_BASE}/references/upload`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params)
});
return handleResponse(response);
}
/**
* Generate images using Meta AI
*/
export async function generateMetaImages(params: MetaGenerateParams): Promise<{
success: boolean;
images: Array<{
data?: string;
url?: string;
prompt: string;
model: string;
aspectRatio: string;
}>;
}> {
const response = await fetch(`${API_BASE}/meta/generate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params)
});
return handleResponse(response);
}
/**
* Get prompts from library
*/
export async function getPrompts(): Promise<{
prompts: any[];
last_updated: string | null;
lastSync: number | null;
categories: Record<string, string[]>;
total_count: number;
sources: string[];
}> {
const response = await fetch(`${API_BASE}/prompts`);
return handleResponse(response);
}
/**
* Sync prompts from sources
*/
export async function syncPrompts(): Promise<{
success: boolean;
count: number;
added: number;
}> {
const response = await fetch(`${API_BASE}/prompts/sync`, {
method: 'POST'
});
return handleResponse(response);
}
/**
* Track prompt usage
*/
export async function trackPromptUse(promptId: number): Promise<{
success: boolean;
promptId: number;
useCount: number;
lastUsedAt: number;
}> {
const response = await fetch(`${API_BASE}/prompts/use`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ promptId })
});
return handleResponse(response);
}
/**
* Get upload history
*/
export async function getHistory(category?: string): Promise<{
history: Array<{
id: string;
url: string;
originalName: string;
category: string;
mediaId?: string;
createdAt?: number;
}>;
}> {
const url = category ? `${API_BASE}/history?category=${category}` : `${API_BASE}/history`;
const response = await fetch(url);
return handleResponse(response);
}
/**
* Upload to history
*/
export async function uploadToHistory(file: File, category: string, cookies?: string): Promise<{
id: string;
url: string;
originalName: string;
category: string;
mediaId?: string;
}> {
const formData = new FormData();
formData.append('file', file);
formData.append('category', category);
if (cookies) formData.append('cookies', cookies);
const response = await fetch(`${API_BASE}/history`, {
method: 'POST',
body: formData
});
return handleResponse(response);
}
/**
* Delete history item
*/
export async function deleteHistoryItem(itemId: string): Promise<{ success: boolean }> {
const response = await fetch(`${API_BASE}/history/${itemId}`, {
method: 'DELETE'
});
return handleResponse(response);
}
/**
* Clear all history
*/
export async function clearHistory(): Promise<{ success: boolean }> {
const response = await fetch(`${API_BASE}/history`, {
method: 'DELETE'
});
return handleResponse(response);
}
/**
* Health check
*/
export async function healthCheck(): Promise<{ status: string; service: string; version: string }> {
const response = await fetch(`${API_BASE}/health`);
return handleResponse(response);
}