ABTestPredictor / API_JAVASCRIPT_EXAMPLE.js
nitish-spz's picture
build error - fix 1
e93a798
/**
* 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:
// <input type="file" id="controlImage" accept="image/*">
// <input type="file" id="variantImage" accept="image/*">
// <button onclick="predictFromBrowser()">Predict</button>
// <div id="results"></div>
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 = `
<h3>Prediction Results</h3>
<p>Win Probability: ${data.predictionResults.probability}</p>
<p>Model Confidence: ${data.predictionResults.modelConfidence}%</p>
<p>Training Samples: ${data.predictionResults.trainingDataSamples}</p>
<p>Total Predictions: ${data.predictionResults.totalPredictions}</p>
`;
}
// ============================================================================
// 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');
});