Skip to main content

RediSearch client library for kiarina namespace

Project description

kiarina-lib-redisearch

A comprehensive Python client library for RediSearch with advanced configuration management, schema definition, and both full-text and vector search capabilities.

Features

  • Full-Text Search: Advanced text search with stemming, phonetic matching, and fuzzy search
  • Vector Search: Similarity search using FLAT and HNSW algorithms with multiple distance metrics
  • Schema Management: Type-safe schema definition with automatic migration support
  • Configuration Management: Flexible configuration using pydantic-settings-manager
  • Sync & Async: Support for both synchronous and asynchronous operations
  • Advanced Filtering: Intuitive query builder with type-safe filter expressions
  • Index Management: Complete index lifecycle management (create, migrate, reset, drop)
  • Type Safety: Full type hints and Pydantic validation throughout

Installation

pip install kiarina-lib-redisearch

Quick Start

Basic Usage (Sync)

import redis
from kiarina.lib.redisearch import create_redisearch_client, settings_manager

# Define your schema (part of your application code)
schema = [
    {"type": "tag", "name": "category"},
    {"type": "text", "name": "title"},
    {"type": "numeric", "name": "price", "sortable": True},
    {"type": "vector", "name": "embedding", "algorithm": "FLAT", "dims": 1536}
]

# Configure settings (infrastructure configuration)
settings_manager.user_config = {
    "default": {
        "key_prefix": "products:",
        "index_name": "products_index"
    }
}

# Create Redis connection (decode_responses=False is required)
redis_client = redis.Redis(host="localhost", port=6379, decode_responses=False)

# Create RediSearch client with schema
client = create_redisearch_client(
    "default",
    field_dicts=schema,
    redis=redis_client,
)

# Create index
client.create_index()

# Add documents
client.set({
    "category": "electronics",
    "title": "Wireless Headphones",
    "price": 99.99,
    "embedding": [0.1, 0.2, 0.3, ...]
}, id="product_1")

# Full-text search
results = client.find(
    filter=[["category", "==", "electronics"]],
    return_fields=["title", "price"]
)

# Vector similarity search
results = client.search(
    vector=[0.1, 0.2, 0.3, ...],
    limit=10
)

Async Usage

import redis.asyncio
from kiarina.lib.redisearch.asyncio import create_redisearch_client

schema = [
    {"type": "text", "name": "title"},
    {"type": "numeric", "name": "price", "sortable": True}
]

async def main():
    redis_client = redis.asyncio.Redis(host="localhost", port=6379, decode_responses=False)
    client = create_redisearch_client(field_dicts=schema, redis=redis_client)
    
    await client.create_index()
    await client.set({"title": "Example", "price": 99.99}, id="doc_1")
    results = await client.find()

Schema Definition

Define your search schema with type-safe field definitions:

Field Types

# Tag field
{"type": "tag", "name": "category", "separator": ",", "sortable": True}

# Text field
{"type": "text", "name": "description", "weight": 2.0, "no_stem": False}

# Numeric field
{"type": "numeric", "name": "price", "sortable": True}

# Vector field (FLAT)
{
    "type": "vector",
    "name": "embedding",
    "algorithm": "FLAT",
    "dims": 1536,
    "datatype": "FLOAT32",
    "distance_metric": "COSINE"
}

# Vector field (HNSW)
{
    "type": "vector",
    "name": "embedding",
    "algorithm": "HNSW",
    "dims": 1536,
    "datatype": "FLOAT32",
    "distance_metric": "COSINE",
    "m": 16,
    "ef_construction": 200
}

Configuration

Environment Variables

export KIARINA_LIB_REDISEARCH_KEY_PREFIX="myapp:"
export KIARINA_LIB_REDISEARCH_INDEX_NAME="main_index"
export KIARINA_LIB_REDISEARCH_PROTECT_INDEX_DELETION="true"

YAML Configuration

# config.yaml
redisearch:
  development:
    key_prefix: "dev:"
    index_name: "dev_index"
    protect_index_deletion: false
  production:
    key_prefix: "prod:"
    index_name: "prod_index"
    protect_index_deletion: true
import yaml
from kiarina.lib.redisearch import settings_manager

with open("config.yaml") as f:
    config = yaml.safe_load(f)
    settings_manager.user_config = config["redisearch"]

settings_manager.active_key = "production"

API Reference

Index Operations

# Check if index exists
exists = client.exists_index()

# Create index
client.create_index()

# Drop index
client.drop_index(delete_documents=True)

# Reset index (drop and recreate)
client.reset_index()

# Migrate index (auto-detect schema changes)
client.migrate_index()

# Get index information
info = client.get_info()

Document Operations

# Set document
client.set({"title": "Example", "price": 99.99}, id="doc_1")

# Get document
doc = client.get("doc_1")

# Delete document
client.delete("doc_1")

# Get Redis key
key = client.get_key("doc_1")  # Returns "prefix:doc_1"

Search Operations

# Count documents
count_result = client.count(filter=[["category", "==", "electronics"]])

# Full-text search
results = client.find(
    filter=[["category", "==", "electronics"], ["price", "<", 500]],
    sort_by="price",
    sort_desc=False,
    offset=0,
    limit=20,
    return_fields=["title", "price"]
)

# Vector similarity search
results = client.search(
    vector=[0.1, 0.2, ...],
    filter=[["category", "==", "electronics"]],
    offset=0,
    limit=10,
    return_fields=["title", "distance"]
)

Advanced Filtering

import kiarina.lib.redisearch_filter as rf

# Using filter API
filter_expr = (
    (rf.Tag("category") == "electronics") &
    (rf.Numeric("price") < 500) &
    (rf.Text("title") % "*wireless*")
)
results = client.find(filter=filter_expr)

# Using condition lists
conditions = [
    ["category", "==", "electronics"],
    ["price", "<", 500],
    ["title", "like", "*wireless*"]
]
results = client.find(filter=conditions)

Filter Operators

Tag filters:

  • == or in: Match tags
  • != or not in: Exclude tags

Numeric filters:

  • ==, !=, >, <, >=, <=: Numeric comparisons

Text filters:

  • ==: Exact match
  • !=: Not equal
  • % or like: Pattern matching (wildcards, fuzzy search)

Schema Migration

# Update schema in code
new_schema = [
    {"type": "tag", "name": "category"},
    {"type": "text", "name": "title"},
    {"type": "numeric", "name": "rating", "sortable": True},  # New field
]

# Create client with new schema
client = create_redisearch_client(field_dicts=new_schema, redis=redis_client)

# Migrate (auto-detects changes and recreates index)
client.migrate_index()

Testing

Prerequisites

  • Python 3.12+
  • Redis with RediSearch module
  • Docker (for running Redis in tests)

Running Tests

# Start Redis with RediSearch
docker compose up -d redis

# Run all tests for this package
mise run package:test kiarina-lib-redisearch

# Run with coverage
mise run package:test kiarina-lib-redisearch --coverage

Dependencies

License

This project is licensed under the MIT License - see the LICENSE file for details.

Related Projects

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

kiarina_lib_redisearch-1.22.1.tar.gz (26.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kiarina_lib_redisearch-1.22.1-py3-none-any.whl (46.1 kB view details)

Uploaded Python 3

File details

Details for the file kiarina_lib_redisearch-1.22.1.tar.gz.

File metadata

  • Download URL: kiarina_lib_redisearch-1.22.1.tar.gz
  • Upload date:
  • Size: 26.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for kiarina_lib_redisearch-1.22.1.tar.gz
Algorithm Hash digest
SHA256 f8d9870a06a74d5701cee1dac18e85a8b8e04eaf41008937b4bbbc9d428bf7c5
MD5 61e63778706ee8ac426e3f5afe2a6578
BLAKE2b-256 1113a229a9a51e5ea86eb89eb2ea47b356e91f1135b3f96023d2b6a3c375172f

See more details on using hashes here.

File details

Details for the file kiarina_lib_redisearch-1.22.1-py3-none-any.whl.

File metadata

File hashes

Hashes for kiarina_lib_redisearch-1.22.1-py3-none-any.whl
Algorithm Hash digest
SHA256 48b8c51fe63c67f0eaa5bf23fd94f24fcde27b7725f31af6ff76eebf3f212cc6
MD5 a9ab834347e5454b82c316513714a826
BLAKE2b-256 3543c7cf0bb9152b80f9407293bba8e56c16d918c83198b5e62bb4b3f6b58b0b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page