HonestAI / EXPRESS_INTEGRATION_GUIDE.md
JatsTheAIGen's picture
Add Express.js integration guide with URL troubleshooting and input validation
91c95f0

Express.js Integration Guide

Quick Setup for Express Applications

1. Environment Variables

Add to your .env file or environment secrets:

# Hugging Face Spaces URL (use hyphens, not underscores)
HF_SPACE_URL=https://jatinautonomouslabs-research-ai-assistant-api.hf.space

# Alternative if hyphens don't work
# HF_SPACE_URL=https://jatinautonomouslabs-research_ai_assistant_api.hf.space

2. Express Code Example

const express = require('express');
const axios = require('axios');
const app = express();

app.use(express.json());

// Get HF Space URL from environment
const HF_SPACE_URL = process.env.HF_SPACE_URL || 
  'https://jatinautonomouslabs-research-ai-assistant-api.hf.space';

// Health check function
async function checkHFHealth() {
  try {
    const response = await axios.get(`${HF_SPACE_URL}/api/health`, {
      timeout: 5000
    });
    return {
      healthy: true,
      status: response.data.status,
      orchestratorReady: response.data.orchestrator_ready
    };
  } catch (error) {
    console.error('HF Space health check failed:', error.message);
    return {
      healthy: false,
      error: error.message
    };
  }
}

// Initialize HF Space connection
async function initializeHFConnection() {
  console.log('[Init] Using HuggingFace Spaces for AI backend...');
  console.log('[Init] Checking Flask API connection...');
  console.log(`[HFSpaces] Flask API: ${HF_SPACE_URL}`);
  
  const health = await checkHFHealth();
  
  if (health.healthy && health.orchestratorReady) {
    console.log('[Init] ✅ Flask API healthy and ready');
    return true;
  } else {
    console.log('[Init] ✗ Flask API unhealthy:', health.error || 'Orchestrator not ready');
    console.log('[Init] Make sure your HF Space is running');
    console.log(`[Init] URL: ${HF_SPACE_URL}`);
    return false;
  }
}

// Chat endpoint that proxies to HF Space
app.post('/api/chat', async (req, res) => {
  try {
    const { message, session_id, user_id, history } = req.body;
    
    // Validate input
    if (!message || typeof message !== 'string' || message.trim().length === 0) {
      return res.status(400).json({
        success: false,
        error: 'Message is required and must be a non-empty string'
      });
    }
    
    // Filter out CSS/HTML content (basic check)
    if (message.includes('{') && message.includes('}') && message.includes('color:')) {
      console.warn('[Chat] Detected potential CSS/HTML content, filtering...');
      return res.status(400).json({
        success: false,
        error: 'Please send text messages only, not code or CSS'
      });
    }
    
    // Call HF Space API
    const response = await axios.post(
      `${HF_SPACE_URL}/api/chat`,
      {
        message: message.trim(),
        session_id: session_id,
        user_id: user_id || 'anonymous',
        history: history || []
      },
      {
        timeout: 30000, // 30 second timeout
        headers: {
          'Content-Type': 'application/json'
        }
      }
    );
    
    res.json(response.data);
  } catch (error) {
    console.error('[Chat] Error:', error.message);
    
    if (error.response) {
      // HF Space returned an error
      res.status(error.response.status).json({
        success: false,
        error: error.response.data.error || error.response.data.message || 'HF Space API error',
        details: error.response.data
      });
    } else if (error.code === 'ECONNREFUSED' || error.code === 'ETIMEDOUT') {
      // Connection error
      res.status(503).json({
        success: false,
        error: 'HF Space is not reachable. Please check if the space is running.',
        url: HF_SPACE_URL
      });
    } else {
      // Other errors
      res.status(500).json({
        success: false,
        error: 'Internal server error',
        message: error.message
      });
    }
  }
});

// Start server
const PORT = process.env.PORT || 5000;

async function startServer() {
  // Check HF Space connection on startup
  const hfReady = await initializeHFConnection();
  
  if (!hfReady) {
    console.warn('[Init] ⚠ HF Space not reachable');
    console.warn('[Init] Check HF_SPACE_URL in Secrets');
    console.warn('[Init] Make sure your HF Space is running');
  }
  
  app.listen(PORT, () => {
    console.log(`[express] serving on port ${PORT}`);
  });
}

startServer();

3. Testing the Connection

// Test script
const axios = require('axios');

async function testConnection() {
  const HF_SPACE_URL = process.env.HF_SPACE_URL || 
    'https://jatinautonomouslabs-research-ai-assistant-api.hf.space';
  
  console.log('Testing HF Space connection...');
  console.log(`URL: ${HF_SPACE_URL}`);
  
  // Test 1: Root endpoint
  try {
    const root = await axios.get(`${HF_SPACE_URL}/`, { timeout: 5000 });
    console.log('✅ Root endpoint:', root.status, root.data);
  } catch (e) {
    console.log('❌ Root endpoint failed:', e.message);
  }
  
  // Test 2: Health endpoint
  try {
    const health = await axios.get(`${HF_SPACE_URL}/api/health`, { timeout: 5000 });
    console.log('✅ Health endpoint:', health.status, health.data);
  } catch (e) {
    console.log('❌ Health endpoint failed:', e.message);
  }
  
  // Test 3: Chat endpoint
  try {
    const chat = await axios.post(
      `${HF_SPACE_URL}/api/chat`,
      { message: 'Hello, test message' },
      { timeout: 10000 }
    );
    console.log('✅ Chat endpoint:', chat.status, chat.data.message);
  } catch (e) {
    console.log('❌ Chat endpoint failed:', e.message);
  }
}

testConnection();

4. Common Issues and Solutions

Issue: 404 Not Found

Causes:

  • Space is still building (wait 5-15 minutes)
  • Wrong URL format (use hyphens, not underscores)
  • Space is not public

Solutions:

  1. Check Space status: https://huggingface.co/spaces/JatinAutonomousLabs/Research_AI_Assistant_API
  2. Verify URL format: Use - (hyphens) not _ (underscores)
  3. Test both URL formats:
    # With hyphens (recommended)
    curl https://jatinautonomouslabs-research-ai-assistant-api.hf.space/
    
    # With underscores (if hyphens don't work)
    curl https://jatinautonomouslabs-research_ai_assistant_api.hf.space/
    

Issue: 503 Service Unavailable

Cause: Space is running but API is initializing

Solution: Wait 30-60 seconds and retry

Issue: CSS/HTML Content in Messages

Solution: Add input validation in your Express app:

function isValidMessage(message) {
  // Check for CSS patterns
  if (message.includes('{') && message.includes('}') && 
      (message.includes('color:') || message.includes('background:'))) {
    return false;
  }
  
  // Check for HTML tags
  if (/<[^>]+>/.test(message)) {
    return false;
  }
  
  return true;
}

// Use in your endpoint
if (!isValidMessage(message)) {
  return res.status(400).json({
    success: false,
    error: 'Please send text messages only, not code or markup'
  });
}

5. Environment Variables Checklist

Make sure these are set in your Express app's environment:

# Required
HF_SPACE_URL=https://jatinautonomouslabs-research-ai-assistant-api.hf.space

# Optional
PORT=5000
NODE_ENV=production

6. Monitoring and Logging

Add logging to track HF Space connectivity:

// Periodic health check
setInterval(async () => {
  const health = await checkHFHealth();
  if (!health.healthy) {
    console.warn('[Monitor] HF Space is down:', health.error);
  }
}, 60000); // Check every minute

Quick Reference

Correct URL Format:

https://jatinautonomouslabs-research-ai-assistant-api.hf.space

Endpoints:

  • GET / - API information
  • GET /api/health - Health check
  • POST /api/chat - Chat endpoint

Test Command:

curl https://jatinautonomouslabs-research-ai-assistant-api.hf.space/api/health