Rexa Search

A classic Google-style search engine (2005-2010 era) powered by Exa API and OpenRouter. Features AI-powered search with markdown formatting, web search, and image search with thumbnail display, complete with a REST API and 24-hour result caching.

Features

  • Classic Google interface (2005-2010 era)
  • AI Search - Perform Exa web/image search, format with OpenRouter in markdown with syntax highlighting (default option)
  • Web search with Exa API
  • Image search with thumbnail grid layout
  • 24-hour caching for entire search pipeline (Exa results + OpenRouter formatted answers)
  • Progressive Web App (PWA) support
  • Fully responsive design
  • REST API for programmatic access
  • Installable Python package
  • SQLite-based caching with dataset library

Installation

pip install rexa-search

Configuration

Set the required API keys as environment variables:

export EXA_API_KEY=your_exa_api_key_here
export OPENROUTER_API_KEY=your_openrouter_api_key_here

API Keys

Usage

Start the Server

rexa-search

Or using Python module:

python -m rexa

The server will start on port 8088 by default.

Using Make

make install
make run

API Endpoints

Web Interface

  • GET / - Homepage (AI search is default)
  • GET /ai?q=query - AI search with markdown formatting and syntax highlighting
  • GET /search?q=query&num=10 - Web search results page
  • GET /images?q=query&num=20 - Image search results page

REST API

  • GET /api/ai?q=query&num=10 - AI search with markdown formatted answer (JSON)
    • Returns: html_answer, markdown_answer, search_results, search_type, cached
    • Auto-detects web vs image search based on query keywords
  • GET /api/search?q=query&num=10 - Web search (JSON)
  • GET /api/images?q=query&num=20 - Image search (JSON)
  • GET /api/mixed?q=query&num=10 - Combined web and images (JSON)

Response Format

AI Search:

{
  "html_answer": "<p>Formatted HTML with syntax highlighting</p>",
  "markdown_answer": "# Answer in **markdown** format",
  "search_results": [...],
  "search_type": "web" | "images",
  "cached": false,
  "fallback": false
}

Features:

  • Query type auto-detection (web vs images based on keywords)
  • Markdown formatting with OpenRouter (x-ai/grok-code-fast-1)
  • Syntax highlighting for code blocks
  • Fallback to markdown-formatted Exa results if OpenRouter fails
  • Entire pipeline cached for 24 hours

Web Search:

{
  "results": [
    {
      "title": "Page Title",
      "url": "https://example.com",
      "image": "https://example.com/image.jpg",
      "favicon": "https://example.com/favicon.ico",
      "text": "Page content snippet...",
      "highlights": ["Important text..."],
      "published_date": "2025-01-01",
      "author": "Author Name"
    }
  ],
  "cached": false
}

Mixed Search:

{
  "web": [...],
  "images": [...]
}

Caching

All API requests are cached for 24 hours in a local SQLite database (cache.db in the working directory). This reduces API calls and improves performance.

Cached data includes:

  • AI search results (Exa web/images search + OpenRouter formatted markdown answer)
  • Web search results
  • Image search results
  • Mixed search results

Cache structure:

{
    "html_answer": "<p>Rendered HTML...</p>",
    "markdown_answer": "# Markdown response...",
    "search_results": [...],
    "search_type": "web" | "images",
    "fallback": false
}

Development

Setup Development Environment

git clone https://github.com/retoor/rexa-search.git
cd rexa-search
make install

Run with Auto-Reload

make dev

Project Structure

rexa/
├── rexa/
│   ├── main.py              # Application entry point
│   ├── api/
│   │   ├── router.py       # FastAPI routes
│   │   └── endpoints.py     # Search endpoints
│   ├── core/
│   │   ├── config.py       # Configuration
│   │   ├── cache.py        # 24h caching logic
│   │   └── exa_client.py   # Exa API wrapper
│   ├── templates/
│   │   ├── base.html
│   │   ├── home.html
│   │   ├── results_web.html
│   │   └── results_images.html
│   └── static/
│       ├── css/
│       │   └── style.css
│       └── js/
├── setup.py
├── pyproject.toml
├── Makefile
└── README.md

Configuration Options

Environment variables:

  • EXA_API_KEY - Your Exa API key (required)
  • PORT - Server port (default: 8088)
  • HOST - Server host (default: 0.0.0.0)
  • CACHE_TTL_HOURS - Cache time-to-live in hours (default: 24)

License

MIT License - See LICENSE file for details.

Author

retoor retoor@molodetz.nl

Acknowledgments

  • Powered by Exa API - https://exa.ai
  • Classic Google design inspiration