/** * A/B Test Predictor - JavaScript/Node.js API Examples */ // ============================================================================ // Option 1: Using Fetch API (Browser/Node.js) // ============================================================================ async function predictABTest(controlImagePath, variantImagePath, categories) { const apiUrl = 'http://localhost:7860/api/predict'; // Change to your deployment URL // Read and encode images to base64 const fs = require('fs').promises; const controlImage = await fs.readFile(controlImagePath); const variantImage = await fs.readFile(variantImagePath); const controlB64 = `data:image/jpeg;base64,${controlImage.toString('base64')}`; const variantB64 = `data:image/jpeg;base64,${variantImage.toString('base64')}`; // Prepare request payload const payload = { data: [ controlB64, variantB64, categories.businessModel, categories.customerType, categories.conversionType, categories.industry, categories.pageType ] }; // Send POST request const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) { throw new Error(`API request failed: ${response.status} ${response.statusText}`); } const result = await response.json(); return result.data[0]; // Gradio wraps response in 'data' array } // Example usage (async () => { try { const result = await predictABTest( 'control.jpg', 'variant.jpg', { businessModel: 'SaaS', customerType: 'B2B', conversionType: 'High-Intent Lead Gen', industry: 'B2B Software & Tech', pageType: 'Awareness & Discovery' } ); console.log('Prediction Results:'); console.log(JSON.stringify(result, null, 2)); console.log('\nWin Probability:', result.predictionResults.probability); console.log('Model Confidence:', result.predictionResults.modelConfidence + '%'); } catch (error) { console.error('Error:', error.message); } })(); // ============================================================================ // Option 2: Using Axios (More Robust) // ============================================================================ const axios = require('axios'); const fs = require('fs').promises; class ABTestPredictorClient { constructor(apiUrl = 'http://localhost:7860') { this.apiUrl = apiUrl; this.endpoint = `${apiUrl}/api/predict`; } async encodeImage(imagePath) { const imageBuffer = await fs.readFile(imagePath); return `data:image/jpeg;base64,${imageBuffer.toString('base64')}`; } async predict(controlImagePath, variantImagePath, categories) { try { // Encode images const controlB64 = await this.encodeImage(controlImagePath); const variantB64 = await this.encodeImage(variantImagePath); // Validate categories this.validateCategories(categories); // Prepare payload const payload = { data: [ controlB64, variantB64, categories.businessModel, categories.customerType, categories.conversionType, categories.industry, categories.pageType ] }; // Make API call const response = await axios.post(this.endpoint, payload, { headers: { 'Content-Type': 'application/json' }, timeout: 30000 // 30 second timeout }); return { success: true, data: response.data.data[0] }; } catch (error) { return { success: false, error: error.message, details: error.response?.data }; } } validateCategories(categories) { const validCategories = { businessModel: ['E-Commerce', 'Lead Generation', 'Other*', 'SaaS'], customerType: ['B2B', 'B2C', 'Both', 'Other*'], conversionType: [ 'Direct Purchase', 'High-Intent Lead Gen', 'Info/Content Lead Gen', 'Location Search', 'Non-Profit/Community', 'Other Conversion' ], industry: [ 'Automotive & Transportation', 'B2B Services', 'B2B Software & Tech', 'Consumer Services', 'Consumer Software & Apps', 'Education', 'Finance, Insurance & Real Estate', 'Food, Hospitality & Travel', 'Health & Wellness', 'Industrial & Manufacturing', 'Media & Entertainment', 'Non-Profit & Government', 'Other', 'Retail & E-commerce' ], pageType: [ 'Awareness & Discovery', 'Consideration & Evaluation', 'Conversion', 'Internal & Navigation', 'Post-Conversion & Other' ] }; // Validate each category for (const [key, value] of Object.entries(categories)) { if (!validCategories[key]?.includes(value)) { throw new Error(`Invalid ${key}: ${value}`); } } return true; } async batchPredict(testCases) { const results = []; for (let i = 0; i < testCases.length; i++) { console.log(`Processing test ${i + 1}/${testCases.length}...`); const testCase = testCases[i]; const result = await this.predict( testCase.controlImage, testCase.variantImage, testCase.categories ); results.push({ testId: i + 1, input: testCase, result: result }); // Rate limiting await new Promise(resolve => setTimeout(resolve, 1000)); } return results; } } // Example usage (async () => { const client = new ABTestPredictorClient('http://localhost:7860'); // Single prediction const result = await client.predict( 'control.jpg', 'variant.jpg', { businessModel: 'SaaS', customerType: 'B2B', conversionType: 'High-Intent Lead Gen', industry: 'B2B Software & Tech', pageType: 'Awareness & Discovery' } ); if (result.success) { console.log('Prediction successful!'); console.log('Win Probability:', result.data.predictionResults.probability); console.log('Confidence:', result.data.predictionResults.modelConfidence + '%'); } else { console.error('Prediction failed:', result.error); } // Batch predictions const testCases = [ { controlImage: 'test1_control.jpg', variantImage: 'test1_variant.jpg', categories: { businessModel: 'SaaS', customerType: 'B2B', conversionType: 'High-Intent Lead Gen', industry: 'B2B Software & Tech', pageType: 'Awareness & Discovery' } }, // Add more test cases... ]; const batchResults = await client.batchPredict(testCases); console.log('Batch results:', JSON.stringify(batchResults, null, 2)); })(); // ============================================================================ // Option 3: Browser Example (Using File Input) // ============================================================================ // HTML: // // // //
async function predictFromBrowser() { const controlFile = document.getElementById('controlImage').files[0]; const variantFile = document.getElementById('variantImage').files[0]; if (!controlFile || !variantFile) { alert('Please select both images'); return; } // Convert files to base64 const controlB64 = await fileToBase64(controlFile); const variantB64 = await fileToBase64(variantFile); // Prepare payload const payload = { data: [ controlB64, variantB64, 'SaaS', 'B2B', 'High-Intent Lead Gen', 'B2B Software & Tech', 'Awareness & Discovery' ] }; try { const response = await fetch('http://localhost:7860/api/predict', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const result = await response.json(); displayResults(result.data[0]); } catch (error) { alert('Error: ' + error.message); } } function fileToBase64(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = reject; reader.readAsDataURL(file); }); } function displayResults(data) { const resultsDiv = document.getElementById('results'); resultsDiv.innerHTML = `

Prediction Results

Win Probability: ${data.predictionResults.probability}

Model Confidence: ${data.predictionResults.modelConfidence}%

Training Samples: ${data.predictionResults.trainingDataSamples}

Total Predictions: ${data.predictionResults.totalPredictions}

`; } // ============================================================================ // Option 4: Express.js Server Example // ============================================================================ const express = require('express'); const multer = require('multer'); const upload = multer({ dest: 'uploads/' }); const app = express(); const client = new ABTestPredictorClient('http://localhost:7860'); app.post('/predict', upload.fields([ { name: 'control', maxCount: 1 }, { name: 'variant', maxCount: 1 } ]), async (req, res) => { try { const controlPath = req.files['control'][0].path; const variantPath = req.files['variant'][0].path; const categories = { businessModel: req.body.businessModel, customerType: req.body.customerType, conversionType: req.body.conversionType, industry: req.body.industry, pageType: req.body.pageType }; const result = await client.predict(controlPath, variantPath, categories); // Clean up uploaded files const fs = require('fs'); fs.unlinkSync(controlPath); fs.unlinkSync(variantPath); res.json(result); } catch (error) { res.status(500).json({ success: false, error: error.message }); } }); app.listen(3000, () => { console.log('Proxy server running on port 3000'); });