Spaces:
Paused
Paused
File size: 4,287 Bytes
bcf46c3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | /**
* official TypeScript/JavaScript SDK client for the Opticparse Vision-Scrape API.
* Compatible with Node.js environments and modern web browsers.
*/
export interface ScrapeRequest {
targetUrl: string;
extractionQuery: string;
viewportWidth?: number;
viewportHeight?: number;
waitUntil?: 'networkidle' | 'load' | 'domcontentloaded';
timeout?: number;
}
export interface ClientConfig {
/**
* The API Key for authorization.
* Maps to X-API-Key header for direct server connection.
*/
apiKey?: string;
/**
* Custom target URL for the Opticparse service.
* Defaults to http://localhost:8000.
*/
apiUrl?: string;
}
export class OpticparseError extends Error {
statusCode?: number;
details?: string;
constructor(message: string, statusCode?: number, details?: string) {
super(message);
this.name = 'OpticparseError';
this.statusCode = statusCode;
this.details = details;
}
}
export class OpticparseClient {
private apiKey: string;
private apiUrl: string;
constructor(config: ClientConfig = {}) {
// Attempt to load from Node.js environment if not provided explicitly
const getEnv = (key: string): string => {
return (typeof process !== 'undefined' && process.env ? process.env[key] : '') || '';
};
this.apiKey = config.apiKey || getEnv('OPTICPARSE_API_KEY');
this.apiUrl = config.apiUrl || getEnv('OPTICPARSE_API_URL') || 'http://localhost:8000';
}
/**
* Performs an AI-driven visual scraping operation against the target webpage.
*
* @param request Target site details and desired JSON format instructions
* @returns The parsed JSON object containing target details
* @throws {OpticparseError} on HTTP authorization issues, network timeout, or server failure.
*/
async scrape<T = any>(request: ScrapeRequest): Promise<T> {
if (!this.apiKey) {
throw new OpticparseError(
'Client misconfigured: API Key is missing. Configure via the constructor or OPTICPARSE_API_KEY environment variable.'
);
}
const payload = {
target_url: request.targetUrl,
extraction_query: request.extractionQuery,
viewport_width: request.viewportWidth ?? 1280,
viewport_height: request.viewportHeight ?? 800,
wait_until: request.waitUntil ?? 'networkidle',
timeout: request.timeout ?? 90000,
};
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'X-API-Key': this.apiKey,
};
const controller = new AbortController();
const requestTimeout = request.timeout ?? 90000; // default 90s maximum duration
const timeoutId = setTimeout(() => controller.abort(), requestTimeout);
// Normalize URL pathing
const endpoint = `${this.apiUrl.replace(/\/+$/, '')}/api/vision-scrape`;
try {
const response = await fetch(endpoint, {
method: 'POST',
headers,
body: JSON.stringify(payload),
signal: controller.signal,
});
clearTimeout(timeoutId);
if (!response.ok) {
let errorDetails = '';
try {
errorDetails = await response.text();
} catch {
// ignore parsing error
}
if (response.status === 401 || response.status === 403) {
throw new OpticparseError(
'Unauthorized: Invalid or missing API key credential.',
response.status,
errorDetails
);
}
if (response.status === 400) {
throw new OpticparseError(
'Bad Request: Scraper endpoint rejected configuration options.',
400,
errorDetails
);
}
throw new OpticparseError(
`Request failed with HTTP status ${response.status}`,
response.status,
errorDetails
);
}
const data = await response.json();
return data as T;
} catch (error: any) {
clearTimeout(timeoutId);
if (error.name === 'AbortError') {
throw new OpticparseError(`Request timed out after limit of ${requestTimeout}ms`);
}
if (error instanceof OpticparseError) {
throw error;
}
throw new OpticparseError(`Network request failure: ${error.message || error}`);
}
}
}
|