Skip to content

Latest commit

 

History

History
169 lines (131 loc) · 4.69 KB

File metadata and controls

169 lines (131 loc) · 4.69 KB

AioHTTP Server Migration

This document describes the migration from the custom asyncio-based HTTP server to aiohttp.

Overview

The NLWeb application has been migrated to use aiohttp, a modern asynchronous HTTP framework for Python. This migration provides:

  • Better HTTP/1.1 compliance
  • Built-in WebSocket support (for future features)
  • More robust request/response handling
  • Better performance and security
  • Simplified codebase
  • Built-in features for streaming, keep-alive, and connection management

Running the Server

Using the new aiohttp server (default):

# Using the startup script
./startup_aiohttp.sh

# Or directly with Python
cd code/python
python -m webserver.aiohttp_server

# Or using the app file
python app-aiohttp.py

Switching between servers:

# Use aiohttp server (default)
export USE_AIOHTTP=true
./startup_aiohttp.sh

# Use legacy server
export USE_AIOHTTP=false
./startup_aiohttp.sh

Architecture Changes

1. Middleware System

The new server uses aiohttp's middleware system located in /code/python/webserver/middleware/:

  • cors.py - CORS handling with proper preflight support
  • error_handler.py - Centralized error handling and formatting
  • logging_middleware.py - Request/response logging
  • auth.py - Authentication handling for protected endpoints
  • streaming.py - SSE streaming support detection and headers

2. Route Organization

Routes are now organized by functionality in /code/python/webserver/routes/:

  • static.py - Static file serving (/, /static/, /html/)
  • api.py - Core API endpoints (/ask, /who, /sites)
  • health.py - Health check endpoints (/health, /ready)
  • oauth.py - OAuth endpoints (to be implemented)
  • mcp.py - Model Context Protocol endpoints (to be implemented)
  • conversation.py - Conversation management (to be implemented)

3. Streaming Implementation

The streaming implementation now uses aiohttp's built-in features:

  • StreamResponse for SSE (Server-Sent Events)
  • Built-in chunked encoding
  • Automatic keep-alive handling
  • Connection state management via transport.is_closing()

4. Key Features Utilized

Built-in Keep-Alive

# Configured in AppRunner
runner = web.AppRunner(app, keepalive_timeout=75)

Streaming Response

response = web.StreamResponse(
    headers={
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'X-Accel-Buffering': 'no'
    }
)
await response.prepare(request)
await response.write(b'data: {"message": "hello"}\n\n')

Graceful Shutdown

app.on_shutdown.append(shutdown_handler)
app.on_cleanup.append(cleanup_handler)

Compatibility

Backward Compatibility

The migration maintains full backward compatibility:

  • All existing endpoints work the same way
  • Request/response formats are unchanged
  • SSE streaming format is preserved
  • Query parameters and headers are handled identically

Handler Compatibility

A compatibility layer (AioHttpStreamingWrapper) ensures existing handlers work without modification:

  • NLWebHandler works unchanged
  • GenerateAnswer works unchanged
  • WhoHandler works unchanged

Benefits

  1. Performance: Better connection handling and resource utilization
  2. Reliability: Battle-tested framework with proper HTTP compliance
  3. Features: Access to aiohttp ecosystem (sessions, WebSockets, etc.)
  4. Maintainability: Less custom code to maintain
  5. Security: Regular security updates from aiohttp team

Migration Status

Completed:

  • ✅ Core server infrastructure
  • ✅ Middleware system (CORS, error handling, logging, auth, streaming)
  • ✅ Static file serving
  • ✅ Basic API endpoints (/ask, /who, /sites)
  • ✅ SSE streaming support
  • ✅ Health check endpoints
  • ✅ Compatibility layer for existing handlers

TODO:

  • ⏳ OAuth endpoints migration
  • ⏳ MCP endpoints migration
  • ⏳ Conversation management endpoints
  • ⏳ Performance testing and optimization
  • ⏳ Full integration testing
  • ⏳ Update deployment scripts for production

Testing

To test the new server:

  1. Start the server:

    cd code/python
    python -m webserver.aiohttp_server
  2. Test endpoints:

    # Health check
    curl http://localhost:8000/health
    
    # Static files
    curl http://localhost:8000/
    
    # API endpoints
    curl http://localhost:8000/who
    curl http://localhost:8000/sites
    
    # SSE streaming
    curl -H "Accept: text/event-stream" http://localhost:8000/ask?q=test

Configuration

The server uses the same configuration file (config/config_webserver.yaml) as the legacy server. All configuration options are preserved and work identically.