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
- EXA_API_KEY: For web and image search (https://dashboard.exa.ai/api-keys)
- OPENROUTER_API_KEY: For AI answer formatting with markdown and syntax highlighting (https://openrouter.ai/keys)
- OPENROUTER_MODEL: Optional, defaults to
x-ai/grok-code-fast-1
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 highlightingGET /search?q=query&num=10- Web search results pageGET /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
- Returns:
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