Skip to main content

A natural language to SQL query converter

Project description

nlseek

A natural language to Query converter.

nlseek_preview

Installation

# Using uv
uv pip install nlseek

# Or install from source
uv pip install -e .

Development

# Clone the repository
git clone https://github.com/leaninnovationlabs/nlseek.git
cd nlseek

# Create virtual environment and install dependencies
uv venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
uv pip install -e ".[dev]"

# Run tests
pytest

# Run linter
ruff check src tests
ruff format src tests

# Type checking
mypy src

Usage

Load domain from file

See examples/domains/ecommerce.yaml for a complete domain schema example.

from nlseek import DomainLoader, QueryResolver

# Load a domain schema from YAML files
loader = DomainLoader("/path/to/domains")
domain = loader.get_domain("ecommerce")

# Create a query resolver
resolver = QueryResolver(domain)

# Convert natural language to SQL
result = resolver.resolve("Show me all orders from last week")
print(result.query)        # The generated SQL query
print(result.explanation)  # Explanation of the query
print(result.tables_used)  # Tables referenced
print(result.entities)     # Entities identified from the question mapped to columns
print(result.filters)      # Filter conditions extracted from the WHERE clause

Load domain from JSON string

from nlseek import DomainLoader, QueryResolver

# Create a loader without a file path
loader = DomainLoader()

# Register a domain from a JSON string
loader.register_domain('''
{
    "name": "mydb",
    "database_type": "postgres",
    "tables": [
        {
            "name": "users",
            "columns": [
                {"name": "id", "type": "integer", "primary_key": true},
                {"name": "email", "type": "varchar(255)"}
            ]
        }
    ]
}
''')

# Use the registered domain
domain = loader.get_domain("mydb")
resolver = QueryResolver(domain)
result = resolver.resolve("List all users")

Generate domain from Pydantic models

from pydantic import BaseModel, Field
from nlseek import DomainLoader, QueryResolver

# Define your models (works with Pydantic, SQLModel, etc.)
class User(BaseModel):
    """User account information."""
    id: int
    email: str
    name: str | None = None

class Order(BaseModel):
    """Customer order."""
    id: int
    user_id: int  # Auto-detected as FK to users.id
    total: float = Field(description="Order total in USD")

# Generate domain from models
loader = DomainLoader()
loader.register_from_models(
    name="mydb",
    models=[User, Order],
    database_type="postgres",
)

# Use the generated domain
domain = loader.get_domain("mydb")
resolver = QueryResolver(domain)
result = resolver.resolve("Show orders for user with email john@example.com")

The generator automatically:

  • Converts class names to table names (User -> users, OrderItem -> order_items)
  • Maps Python types to SQL types (int -> integer, str -> varchar(255), etc.)
  • Detects primary keys (fields named id)
  • Infers relationships from foreign key columns (user_id -> users.id)
  • Extracts descriptions from docstrings and Field(description=...)

Configuring the AI Model

By default, QueryResolver uses Claude Opus 4. To use a different model, pass a ResolverConfig:

from nlseek import QueryResolver, ResolverConfig

config = ResolverConfig(model="anthropic:claude-sonnet-4-20250514")
resolver = QueryResolver(domain, config=config)

Any model identifier supported by pydantic-ai can be used but need to have the corresponding API key in the .env file.

Quick Demo

The demo loads the examples/domains/ecommerce.yaml schema (customers, products, orders, etc.) and prints the generated SQL, explanation, tables used, entities, and filters.

# More examples
uv run tests/demo.py "Top 5 customers by total spending"
uv run tests/demo.py "Revenue by category for delivered orders"

# Use a different model
uv run tests/demo.py --model "anthropic:claude-sonnet-4-20250514" "Products with low stock"

Response Fields

Each SQLQueryResult includes:

Field Type Description
query_id UUID Unique identifier for this query result
query str The generated SQL query
explanation str Brief explanation of what the query does
tables_used list[str] Tables referenced in the query
entities dict[str, list[str]] Entities from the question mapped to the columns they match
filters list[FilterCondition] Filter conditions extracted from the WHERE clause

Entities

Maps domain-specific values from the user's question to the database columns they were matched against. For example, for the question "Get me information about iphone under electronics":

{
  "iphone": ["products.name", "products.description"],
  "electronics": ["categories.name"]
}

Filters

Each FilterCondition contains:

Field Type Description
table str Table name (e.g. products)
attribute str Column name (e.g. name)
operator str SQL operator (e.g. LIKE, =, >, IN, BETWEEN)
value str The filter value (e.g. iphone, electronics)

For the same query above, the filters would be:

[
  {"table": "products", "attribute": "name", "operator": "LIKE", "value": "iphone"},
  {"table": "categories", "attribute": "name", "operator": "=", "value": "electronics"}
]

Database Support

Supports the following Query format right now

  • mysql
  • postgres
  • oracle
  • ansi sql

Environment Setup

Create a .env file with your Anthropic API key:

ANTHROPIC_API_KEY=your-api-key-here

License

MIT

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

nlseek-0.1.0.tar.gz (4.5 MB view details)

Uploaded Source

Built Distribution

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

nlseek-0.1.0-py3-none-any.whl (15.5 kB view details)

Uploaded Python 3

File details

Details for the file nlseek-0.1.0.tar.gz.

File metadata

  • Download URL: nlseek-0.1.0.tar.gz
  • Upload date:
  • Size: 4.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for nlseek-0.1.0.tar.gz
Algorithm Hash digest
SHA256 34fc5d087fa2c9cf72e2b18723fc714b8d41f875e38602034f9cf273c23da792
MD5 c0cc20fe51f541d459f22786e00802dd
BLAKE2b-256 c683664044a3bb39ef1572669b91018eb5eadf899a643b6a19a23863a7a5c5ea

See more details on using hashes here.

File details

Details for the file nlseek-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: nlseek-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for nlseek-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 33a28bd9f7eeddf926df4bdd3d2f82d1d9a9eadcdcb286ee14efc3c6847eaccc
MD5 2530f8eef3ddeefa2ad83840d2142a56
BLAKE2b-256 6ce371094a236d0411e83d2683b43734a52def7240f03ac67a813ab952133485

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