Turn Elasticsearch into a smart search engine in 5 minutes with ZeroEntropy's LLM-powered reranking.
Project description
elastic-zeroentropy
Turn Elasticsearch into a smart search engine in 5 minutes with ZeroEntropy's LLM-powered reranking.
elastic-zeroentropy is a lightweight Python library that seamlessly integrates ZeroEntropy's state-of-the-art rerankers with Elasticsearch to provide intelligent search result reranking. Boost your search relevance by up to 28% NDCG@10 with just a few lines of code.
๐ Quick Start
import asyncio
from elastic_zeroentropy import ElasticZeroEntropyReranker
async def main():
# Initialize with environment variables or pass config directly
async with ElasticZeroEntropyReranker() as reranker:
response = await reranker.search(
query="machine learning applications",
index="my_documents"
)
for result in response.results:
print(f"๐ {result.document.title}")
print(f" ๐ Score: {result.score:.4f}")
print(f" ๐ {result.document.text[:100]}...")
print()
asyncio.run(main())
โจ Features
- ๐ฏ State-of-the-art reranking: Powered by ZeroEntropy's zerank-1 and zerank-1-small models
- โก High performance: Async HTTP requests with connection pooling and retry logic
- ๐ง Easy configuration: Environment variables, configuration files, or programmatic setup
- ๐ก๏ธ Robust error handling: Graceful failures with detailed error messages
- ๐ Comprehensive monitoring: Health checks, debug info, and performance metrics
- ๐๏ธ Flexible scoring: Combine Elasticsearch and reranking scores with custom weights
- ๐ Rich CLI: Command-line interface for testing and debugging
- ๐ Full type safety: Complete type hints and Pydantic models
- ๐งช Well tested: Comprehensive test suite with >95% coverage
๐ฆ Installation
Install the base package:
pip install elastic-zeroentropy
Or with optional CLI dependencies:
pip install "elastic-zeroentropy[cli]"
For development:
pip install "elastic-zeroentropy[dev]"
โ๏ธ Configuration
Environment Variables
Create a .env file or set environment variables:
# Required: ZeroEntropy API key
ZEROENTROPY_API_KEY=your_api_key_here
# Optional: ZeroEntropy settings
ZEROENTROPY_BASE_URL=https://api.zeroentropy.dev/v1
ZEROENTROPY_MODEL=zerank-1
# Optional: Elasticsearch settings
ELASTICSEARCH_URL=http://localhost:9200
ELASTICSEARCH_USERNAME=your_username
ELASTICSEARCH_PASSWORD=your_password
# Optional: Search behavior
DEFAULT_TOP_K_INITIAL=100
DEFAULT_TOP_K_RERANK=20
DEFAULT_TOP_K_FINAL=10
DEFAULT_ELASTICSEARCH_WEIGHT=0.3
DEFAULT_RERANK_WEIGHT=0.7
Generate a complete template:
elastic-zeroentropy config-template
Programmatic Configuration
from elastic_zeroentropy import ElasticZeroEntropyConfig
config = ElasticZeroEntropyConfig(
zeroentropy_api_key="your_api_key",
elasticsearch_url="http://localhost:9200",
default_top_k_final=15
)
๐ฏ Usage Examples
Basic Search with Reranking
import asyncio
from elastic_zeroentropy import ElasticZeroEntropyReranker
async def search_example():
async with ElasticZeroEntropyReranker() as reranker:
response = await reranker.search(
query="artificial intelligence applications",
index="research_papers"
)
print(f"Found {response.total_hits} total hits")
print(f"Search took {response.took_ms}ms")
if response.reranking_enabled:
print(f"Reranking took {response.reranking_took_ms}ms")
print(f"Model used: {response.model_used}")
for result in response.results:
print(f"\n๐ {result.document.title or result.document.id}")
print(f"Score: {result.score:.4f} (ES: {result.elasticsearch_score:.4f}, Rerank: {result.rerank_score:.4f})")
print(f"Text: {result.document.text[:200]}...")
asyncio.run(search_example())
Advanced Configuration
from elastic_zeroentropy import ElasticZeroEntropyReranker, RerankerConfig
async def advanced_search():
# Custom reranking configuration
reranker_config = RerankerConfig(
top_k_initial=50, # Retrieve 50 docs from Elasticsearch
top_k_rerank=15, # Send top 15 to reranker
top_k_final=5, # Return top 5 final results
model="zerank-1-small", # Use smaller/faster model
combine_scores=True, # Combine ES and rerank scores
score_weights={
"elasticsearch": 0.2,
"rerank": 0.8
}
)
async with ElasticZeroEntropyReranker() as reranker:
response = await reranker.search(
query="deep learning neural networks",
index="ai_papers",
reranker_config=reranker_config,
filters={"category": "machine-learning", "year": {"gte": 2020}},
return_debug_info=True
)
# Access debug information
if response.debug_info:
print("Debug Info:", response.debug_info)
asyncio.run(advanced_search())
Batch Processing
from elastic_zeroentropy import ElasticZeroEntropyReranker, SearchRequest
async def batch_search():
requests = [
SearchRequest(query="machine learning", index="papers"),
SearchRequest(query="natural language processing", index="papers"),
SearchRequest(query="computer vision", index="papers"),
]
async with ElasticZeroEntropyReranker() as reranker:
responses = await reranker.search_batch(requests, max_concurrent=2)
for i, response in enumerate(responses):
print(f"\nQuery {i+1}: {response.query}")
print(f"Results: {len(response.results)}")
asyncio.run(batch_search())
Custom Elasticsearch Queries
from elastic_zeroentropy import ElasticZeroEntropyReranker, ElasticsearchQuery
async def custom_query_search():
# Define custom Elasticsearch query
es_query = ElasticsearchQuery(
index="documents",
query={
"bool": {
"must": [
{"match": {"title": "artificial intelligence"}},
{"range": {"publication_date": {"gte": "2023-01-01"}}}
],
"should": [
{"match": {"abstract": "machine learning"}}
]
}
},
size=50,
sort=[{"_score": {"order": "desc"}}]
)
async with ElasticZeroEntropyReranker() as reranker:
response = await reranker.search(
query="AI and ML research", # Used for reranking
index="documents", # Will be overridden by es_query.index
elasticsearch_query=es_query
)
asyncio.run(custom_query_search())
Search Without Reranking
async def elasticsearch_only():
async with ElasticZeroEntropyReranker() as reranker:
response = await reranker.search(
query="information retrieval",
index="documents",
enable_reranking=False # Skip reranking step
)
print(f"Elasticsearch-only results: {len(response.results)}")
asyncio.run(elasticsearch_only())
๐ฅ๏ธ Command Line Interface
The library includes a powerful CLI for testing and debugging:
Basic Search
elastic-zeroentropy search "machine learning" my_index --top-k 5
Advanced Search with Filters
elastic-zeroentropy search \
"deep learning" \
research_papers \
--top-k-initial 100 \
--top-k-rerank 20 \
--top-k 10 \
--model zerank-1-small \
--filters '{"category": "AI", "year": {"gte": 2020}}' \
--debug-info
Health Check
elastic-zeroentropy health
Configuration Management
# Show current configuration
elastic-zeroentropy config-show
# Generate template .env file
elastic-zeroentropy config-template
# Inspect Elasticsearch index
elastic-zeroentropy inspect my_index --limit 3
Output Formats
# Table format (default)
elastic-zeroentropy search "AI" papers --output table
# JSON format
elastic-zeroentropy search "AI" papers --output json
# Simple text format
elastic-zeroentropy search "AI" papers --output simple
๐ฅ Health Monitoring
Monitor the health of your Elasticsearch and ZeroEntropy connections:
async def monitor_health():
async with ElasticZeroEntropyReranker() as reranker:
health = await reranker.health_check()
print(f"Overall Status: {health.status}")
print(f"Elasticsearch: {health.elasticsearch['status']}")
print(f"ZeroEntropy API: {health.zeroentropy['status']}")
if health.status != "healthy":
print("Issues detected - check your configuration")
asyncio.run(monitor_health())
โ ๏ธ Error Handling
The library provides specific exceptions for different error conditions:
from elastic_zeroentropy import (
ElasticZeroEntropyReranker,
ConfigurationError,
ZeroEntropyAPIError,
ElasticsearchError,
RerankingError
)
async def robust_search():
try:
async with ElasticZeroEntropyReranker() as reranker:
response = await reranker.search("test query", "test_index")
except ConfigurationError as e:
print(f"Configuration issue: {e.message}")
print(f"Details: {e.details}")
except ZeroEntropyAPIError as e:
print(f"ZeroEntropy API error: {e.message}")
if e.status_code == 429:
print("Rate limit exceeded - consider reducing request frequency")
except ElasticsearchError as e:
print(f"Elasticsearch error: {e.message}")
print(f"Index: {e.details.get('index')}")
except RerankingError as e:
print(f"Reranking failed: {e.message}")
print(f"Stage: {e.details.get('stage')}")
asyncio.run(robust_search())
๐๏ธ Advanced Features
Score Combination Strategies
# Rerank scores only
config = RerankerConfig(combine_scores=False)
# Custom weight combination
config = RerankerConfig(
combine_scores=True,
score_weights={"elasticsearch": 0.4, "rerank": 0.6}
)
# Elasticsearch scores only (no reranking)
response = await reranker.search(
query="test",
index="docs",
enable_reranking=False
)
Rate Limiting and Performance
from elastic_zeroentropy import ElasticZeroEntropyConfig
config = ElasticZeroEntropyConfig(
zeroentropy_api_key="your_key",
max_concurrent_requests=5, # Limit concurrent requests
requests_per_minute=500, # Rate limiting
connection_pool_size=20, # HTTP connection pooling
zeroentropy_timeout=30.0, # Request timeout
zeroentropy_max_retries=3 # Retry attempts
)
Custom Document Processing
from elastic_zeroentropy.models import Document
# Create documents with metadata
documents = [
Document(
id="doc1",
text="Document content here",
title="Document Title",
metadata={"category": "research", "author": "John Doe"},
source="database"
)
]
๐ง Development
Setup Development Environment
git clone https://github.com/houssamouaziz/elastic-zeroentropy-reranker.git
cd elastic-zeroentropy-reranker
# Install with development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run with coverage
pytest --cov=elastic_zeroentropy --cov-report=html
# Type checking
mypy src/
# Code formatting
black src/ tests/
isort src/ tests/
Project Structure
elastic-zeroentropy-reranker/
โโโ src/elastic_zeroentropy/ # Main package
โ โโโ __init__.py # Public API
โ โโโ config.py # Configuration management
โ โโโ models.py # Pydantic data models
โ โโโ exceptions.py # Custom exceptions
โ โโโ zeroentropy_client.py # ZeroEntropy API client
โ โโโ elasticsearch_client.py # Elasticsearch client
โ โโโ reranker.py # Main reranker class
โ โโโ cli.py # Command-line interface
โโโ tests/ # Test suite
โโโ examples/ # Usage examples
โโโ docs/ # Documentation
โโโ pyproject.toml # Package configuration
โโโ README.md # This file
๐ Performance
Based on ZeroEntropy's benchmarks, you can expect:
- Accuracy: Up to 28% improvement in NDCG@10 over baseline search
- Speed: ~150ms latency for small payloads, ~315ms for large payloads
- Cost: $0.025 per million tokens (50% less than competitors)
- Throughput: Supports high concurrent request volumes with rate limiting
๐ค Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- ZeroEntropy for their excellent reranking models
- Elasticsearch for the search engine
- The Python community for amazing libraries like
httpx,pydantic, andclick
๐ Links
- ZeroEntropy: Website | Documentation | GitHub
- Elasticsearch: Website | Python Client
- Documentation: API Reference | Examples
Made with โค๏ธ by the elastic-zeroentropy team
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file elastic_zeroentropy-0.1.0.tar.gz.
File metadata
- Download URL: elastic_zeroentropy-0.1.0.tar.gz
- Upload date:
- Size: 35.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d967e58429605ecd4a5aa26603cec11cd88aa62170fa2d445b252c722a5fb2a
|
|
| MD5 |
27faa33662d971b2bf027b2e18c83732
|
|
| BLAKE2b-256 |
954e27fc7e478d1c29aa36e50b14e97119d64aa1cdd831f3ad3ddfc6657d4818
|
File details
Details for the file elastic_zeroentropy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: elastic_zeroentropy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 31.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
806e37ca08ffb49882c24c2fa413c725898c5623018c81b3ad9fb30be29ef495
|
|
| MD5 |
fb250b8d029d4fe05ea1bd3114b56d3a
|
|
| BLAKE2b-256 |
dd791265690d6ac91ee9be0ead7b6194dcc93dcfe624e1a990e7b1873895c67e
|