# 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
```bash
pip install rexa-search
```
## Configuration
Set the required API keys as environment variables:
```bash
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
```bash
rexa-search
```
Or using Python module:
```bash
python -m rexa
```
The server will start on port 8088 by default.
### Using Make
```bash
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:
```json
{
"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:
```json
{
"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:
```json
{
"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:**
```python
{
"html_answer": "<p>Rendered HTML...</p>",
"markdown_answer": "# Markdown response...",
"search_results": [...],
"search_type": "web" | "images",
"fallback": false
}
```
## Development
### Setup Development Environment
```bash
git clone https://github.com/retoor/rexa-search.git
cd rexa-search
make install
```
### Run with Auto-Reload
```bash
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