A modular Python client library for hlquery, designed with a familiar and intuitive API structure.
- Modular Architecture: Clean separation of concerns with organized classes
- Intuitive API: Familiar and easy-to-use structure
- Authentication Support: Bearer token and X-API-Key authentication
- Flexible Parameters: Support for multiple parameter formats
- Auto-detection: Automatically detects searchable fields when not specified
- Type-safe Responses: Response objects with helper methods
- Comprehensive Validation: Input validation for all operations
- No External Dependencies: Uses Python's built-in
urllibandjsonmodules - Professional Structure: Well-organized and modular architecture
Core client usage has no dependencies beyond Python's standard library. PDF parsing uses the optional PyPDF2 package.
Simply import the client:
from lib import ClientOr install as a package:
pip install -e .Install the optional PDF parser when you want to index local PDF files directly through the Python client:
pip install PyPDF2CSV support is built in and does not require any extra package.
from lib import Client
# Initialize client
client = Client('http://localhost:9200')
# Health check
health = client.health()
print(f"Status: {health.get_status_code()}")
# List collections
collections = client.list_collections(0, 10)
if collections.is_success():
body = collections.get_body()
print(f"Found {len(body.get('collections', []))} collections")# Method 1: Set token in constructor
client = Client('http://localhost:9200', {
'token': 'your_token_here',
'auth_method': 'bearer' # or 'api-key'
})
# Method 2: Set token dynamically
client = Client('http://localhost:9200')
client.set_auth_token('your_token_here', 'bearer')
# Method 3: Use X-API-Key
client.set_auth_token('your_token_here', 'api-key')If the ai_search module is enabled, you can use the raw request helper to ask hlquery to summarize a stored document:
summary = client.execute_request(
"GET",
"/modules/ai_search/talk",
query_params={
"q": "summarize onboarding guide in docs",
"run": "true",
},
)
print(summary.get_body())Main client class that provides access to all API operations.
Handles HTTP requests, authentication, and error handling.
Response wrapper with helper methods:
get_status_code()- Get HTTP status codeget_body()- Get response bodyis_success()- Check if request was successfulis_error()- Check if request failedget_error()- Get error messageto_dict()- Convert to dictionary format (for backward compatibility)
Collections manages collections.
Documents handles document CRUD and import.
Search handles search requests and flexible parameter input.
Auth provides token helpers and validation.
Config handles defaults and URL/config normalization.
Validator validates request input before it is sent.
HlqueryException is the base type.
Use AuthenticationException, RequestException, ValidationException, CollectionException, DocumentException, and SearchException for specific failures.
Check server health status.
health = client.health()
if health.is_success():
body = health.get_body()
print(f"Status: {body.get('status')}")Get server statistics.
stats = client.stats()Get server information.
info = client.info()collections = client.collections_api()
# List collections
result = collections.list(0, 10)
# Get collection
result = collections.get('my_collection')
# Create collection
result = collections.create('new_collection', schema)
# Delete collection
result = collections.delete('collection_name')
# Get formatted fields
result = collections.get_fields('my_collection')# List collections
collections = client.list_collections(0, 10)
# Get collection details
collection = client.get_collection('my_collection')
# Get collection fields (formatted)
fields = client.get_collection_fields('my_collection')documents = client.documents_api()
# List documents
result = documents.list('collection', {'offset': 0, 'limit': 10})
# Get document
result = documents.get('collection', 'doc_id')
# Add document
result = documents.add('collection', document)
# Update document
result = documents.update('collection', 'doc_id', document)
# Delete document
result = documents.delete('collection', 'doc_id')
# Bulk import
result = documents.import_documents('collection', [doc1, doc2, doc3])
# Parse and add a local PDF file
result = documents.add_pdf('collection', './files/report.pdf')
# Parse and add a local CSV file
result = documents.add_csv('collection', './files/report.csv')documents.add_pdf(collection, file_path, options=None) parses a local PDF file, normalizes the extracted text, and submits it as a regular document to hlquery.
result = client.documents_api().add_pdf('reports', './files/q1-report.pdf', {
'id': 'report_q1',
'document': {
'source_type': 'pdf'
}
})The generated document includes:
titlecontentfile_namefile_pathmime_typepage_countfile_size_bytes- normalized PDF metadata fields such as
pdf_meta_author
Note: hlquery currently rejects commas in string field values. The PDF helper replaces commas with spaces before indexing so extracted text can be stored successfully.
documents.add_csv(collection, file_path, options=None) parses a local CSV file, flattens rows into normalized text, and submits it as a regular document to hlquery.
result = client.documents_api().add_csv('reports', './files/metrics.csv', {
'id': 'metrics_q1',
'document': {
'source_type': 'csv'
}
})The generated document includes:
titlecontentfile_namefile_pathmime_typerow_countcolumn_countcolumns
CSV parsing uses the Python standard library only. Cells are flattened into plain text, and commas are replaced with spaces before indexing to satisfy hlquery field restrictions.
search = client.search_api()
# Simple search
results = search.search('collection', {
'q': 'search query',
'query_by': 'title,content',
'limit': 10
})
# Multi-search
results = search.multi_search([
{'collection': 'col1', 'q': 'query1'},
{'collection': 'col2', 'q': 'query2'}
])# Search documents
results = client.search('collection', {
'q': 'search query',
'query_by': 'title,content',
'limit': 10
})hlquery.utils.ranker exposes a reusable compute_rank_signal helper (for rank_signal, popularity_score, hit_log) plus attach_rank_sort so you can sort by the boosted field across all clients.
from hlquery.utils import compute_rank_signal, attach_rank_sort
params = {'q': 'guide'}
signal = compute_rank_signal(popularity_score, hit_log)
params['rank_signal'] = signal
attach_rank_sort(params) # ensures sort_by=rank_signal:desc
results = client.search('collection', params)The search() method accepts flexible parameters:
q- Query string (supports field clauses,OR,NOT, phrases, and wildcards)- Examples:
q="title:laptop",q="title:laptop OR title:notebook",q="title:laptop NOT title:refurbished",q="\"wireless keyboard\"",q="laptop*"
- Examples:
query_by- Fields to search in (string or list)query- Structured query object
from/offset- Starting offsetsize/limit- Number of resultspage- Page number (alternative to offset)per_page- Results per page
filter_by- Filter conditions (string), for examplefilter_by="price:>100&&category:electronics"filter- Filter objectsort_by- Sort fields (string or list)sort- Sort specification
facet_by- Facet fields (string or list)facets- Facet specification
Alias for list_collections().
collections = client.indices({'offset': 0, 'limit': 10})Alias for get_collection() or get_document().
# Get document
doc = client.get({'index': 'collection', 'id': 'doc_id'})
# Get collection
collection = client.get({'index': 'collection'})Cat API for listing collections and system information.
indices = client.cat('indices', {'limit': 10})- Python >= 3.6
- No external dependencies (uses built-in
urllibandjson)
This package can be installed via pip:
pip install -e .Or add to your requirements.txt:
# No external dependencies required
For detailed information about the library architecture, design decisions, and internal structure, see STRUCTURE.md.
