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
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c447c970e419b8d635ba6572b72fef36e60b4f6d469f45cd550b73bc4559987
|
|
| MD5 |
ebe7509ebda330cdaac691613ac03dac
|
|
| BLAKE2b-256 |
76de26155c1a89f6ef4744d68b93dd6e2c2e526bdd8d1c75d80ada19f437b556
|
Provenance
The following attestation bundles were made for pynlqe-0.1.6.tar.gz:
Publisher:
publish.yml on iMuto-Software-Solutions-LLC/nlqe
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pynlqe-0.1.6.tar.gz -
Subject digest:
5c447c970e419b8d635ba6572b72fef36e60b4f6d469f45cd550b73bc4559987 - Sigstore transparency entry: 1208653571
- Sigstore integration time:
-
Permalink:
iMuto-Software-Solutions-LLC/nlqe@3d52d462aea8b97940ecc5808d96841f41be276c -
Branch / Tag:
refs/tags/v0.1.6 - Owner: https://github.com/iMuto-Software-Solutions-LLC
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3d52d462aea8b97940ecc5808d96841f41be276c -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8adc3d2b9296660ff0ae25a2166ff333266f65e43197c4dc1890d76ca6ce28b3
|
|
| MD5 |
4708fec8ceb08abb480c5bdcac35664a
|
|
| BLAKE2b-256 |
fa200d282f0facf1540e485e7014265a4220d469d1d8c371cedcf53a2aa01df6
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pynlqe-0.1.6-py3-none-any.whl -
Subject digest:
8adc3d2b9296660ff0ae25a2166ff333266f65e43197c4dc1890d76ca6ce28b3 - Sigstore transparency entry: 1208653824
- Sigstore integration time:
-
Permalink:
iMuto-Software-Solutions-LLC/nlqe@3d52d462aea8b97940ecc5808d96841f41be276c -
Branch / Tag:
refs/tags/v0.1.6 - Owner: https://github.com/iMuto-Software-Solutions-LLC
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3d52d462aea8b97940ecc5808d96841f41be276c -
Trigger Event:
push
-
Statement type: