Skip to main content

Natural language to SQL query engine powered by LangChain and DuckDB

Project description

NLQE (Natural Language NLQE)

A natural language to SQL query engine powered by LangChain and DuckDB. Ask questions about your data in plain English — works with OpenAI, Anthropic, or any LangChain-compatible model.

Version: v0.1.0 | Python: 3.11+ | License: MIT


Examples

Single query

from nlqe import QueryEngine, QueryEngineConfig

# Reads NLQE_OPENAI_API_KEY from environment or .env
config = QueryEngineConfig()
engine = QueryEngine(config)
engine.load_datasource("transactions.parquet")

response = engine.query("What was total revenue by region last month?")
print(response.answer)
# "North America led with $1.2M, followed by Europe at $890K ..."

print(f"SQL: {response.generated_sql}")
print(f"Rows: {len(response.data)}  Confidence: {response.confidence_score:.0%}")

Querying External Databases (PostgreSQL, MySQL, MSSQL)

from nlqe import QueryEngine, QueryEngineConfig
from nlqe.types import PostgresConfig

# Reads NLQE_POSTGRES_URI from environment
db_config = PostgresConfig() 

engine = QueryEngine(QueryEngineConfig())

# Introspect only the specified tables to save LLM context
engine.load_datasource(db_config, allowlist=["users", "orders"])

response = engine.query("How many active users placed an order last week?")
print(response.generated_sql)
# SELECT COUNT(DISTINCT u.id) FROM ext_db.users u JOIN ext_db.orders o ON ...

Querying Remote Files (S3, HTTP, Azure)

from nlqe import QueryEngine, QueryEngineConfig

# Configure S3 credentials (if using S3)
import os
os.environ["AWS_ACCESS_KEY_ID"] = "your_key"
os.environ["AWS_SECRET_ACCESS_KEY"] = "your_secret"
os.environ["AWS_REGION"] = "us-east-1"

engine = QueryEngine(QueryEngineConfig())

# Query directly from an S3 bucket
engine.load_datasource("s3://my-bucket/data/sales.parquet")

# Or from a public URL
# engine.load_datasource("https://example.com/data.csv")

response = engine.query("What are the total sales by category?")
print(response.answer)

Multi-turn conversation

conv = engine.start_conversation()

r1 = conv.query("Show me the top 5 products by revenue")
r2 = conv.query("Which of those had the highest return rate?")  # uses context from r1
r3 = conv.query("Compare that to last month")

print(r3.answer)

Switch to LLM Providers

from langchain_anthropic import ChatAnthropic
from nlqe import QueryEngine, QueryEngineConfig
from nlqe.llm import LLMClient

# Anthropic
llm = ChatAnthropic(model="claude-3-5-sonnet-20241022")
engine = QueryEngine(QueryEngineConfig(), custom_llm_client=LLMClient(llm))

# Ollama (Local)
from langchain_ollama import ChatOllama
engine = QueryEngine(QueryEngineConfig(), custom_llm_client=LLMClient(ChatOllama(model="llama3")))

Installation

# Install core package
pip install pynlqe

# Install with development tools
pip install "pynlqe[dev]"

Generate the sample dataset for testing:

python create_sample_data.py

Configuration

Copy .env.example to .env and fill in your credentials:

cp .env.example .env
NLQE_LLM_PROVIDER=openai
NLQE_OPENAI_API_KEY=sk-...
NLQE_LLM_MODEL=gpt-4o

Overview

NLQE translates plain English into SQL executed against structured data (Parquet, CSV) via DuckDB. It uses an iterative debug loop to automatically recover from SQL errors.

Key features:

  • Swappable LLM providers (OpenAI, Anthropic, Ollama, etc.)
  • Multi-turn conversations with context preservation
  • Automatic SQL error recovery (Iterative Debug Loop)
  • Robust evaluation framework with "golden datasets"
  • High test coverage and strict type safety

Architecture Overview

Component Location Purpose
QueryEngine engine.py Main entry point
LLMClient llm/client.py SQL generation, debugging, and synthesis
DuckDBExecutor duckdb/executor.py Safe SQL execution via DuckDB
QueryLoop query/loop.py Orchestration logic
ConversationManager conversation/manager.py Multi-turn history tracking

For more details see ARCHITECTURE.md.


Development

Use the provided Makefile for common development tasks:

make install    # Install dependencies
make lint       # Run ruff and mypy
make format     # Format code with ruff
make test       # Run all tests
make build      # Build distribution packages

Running the Evaluation Suite

Evaluate the engine against standardized test cases:

python -m nlqe.testing.cli evaluate --dataset fixtures/golden_datasets.yaml

Documentation

Document Description
API.md Public API reference and detailed usage
ARCHITECTURE.md Technical design and component data flows
DESIGN.md High-level goals and philosophy
TESTING.md Evaluation strategy and accuracy metrics
FAQ.md Design decisions and common questions

Future Roadmap

  • v0.2.0: Support for PostgreSQL and Snowflake datasources, result caching, and custom synthesizers.
  • v1.0.0: Cloud-native API, fine-tuning support, and advanced production monitoring.

License

This project is licensed under the MIT License.

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

pynlqe-0.1.6.tar.gz (473.2 kB view details)

Uploaded Source

Built Distribution

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

pynlqe-0.1.6-py3-none-any.whl (43.0 kB view details)

Uploaded Python 3

File details

Details for the file pynlqe-0.1.6.tar.gz.

File metadata

  • Download URL: pynlqe-0.1.6.tar.gz
  • Upload date:
  • Size: 473.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pynlqe-0.1.6.tar.gz
Algorithm Hash digest
SHA256 5c447c970e419b8d635ba6572b72fef36e60b4f6d469f45cd550b73bc4559987
MD5 ebe7509ebda330cdaac691613ac03dac
BLAKE2b-256 76de26155c1a89f6ef4744d68b93dd6e2c2e526bdd8d1c75d80ada19f437b556

See more details on using hashes here.

Provenance

The following attestation bundles were made for pynlqe-0.1.6.tar.gz:

Publisher: publish.yml on iMuto-Software-Solutions-LLC/nlqe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pynlqe-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: pynlqe-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 43.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pynlqe-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 8adc3d2b9296660ff0ae25a2166ff333266f65e43197c4dc1890d76ca6ce28b3
MD5 4708fec8ceb08abb480c5bdcac35664a
BLAKE2b-256 fa200d282f0facf1540e485e7014265a4220d469d1d8c371cedcf53a2aa01df6

See more details on using hashes here.

Provenance

The following attestation bundles were made for pynlqe-0.1.6-py3-none-any.whl:

Publisher: publish.yml on iMuto-Software-Solutions-LLC/nlqe

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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