nlp2sql 0.2.0rc6__tar.gz → 0.2.0rc8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nlp2sql-0.2.0rc8/.github/workflows/ci.yml +33 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.gitignore +1 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/CLAUDE.md +4 -1
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/PKG-INFO +84 -56
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/README.md +83 -55
- nlp2sql-0.2.0rc8/docs/API.md +385 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docs/ARCHITECTURE.md +74 -20
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/mcp_server/server.py +3 -2
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/pyproject.toml +3 -2
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/__init__.py +108 -39
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/anthropic_adapter.py +32 -16
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/gemini_adapter.py +33 -18
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/openai_adapter.py +31 -16
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/postgres_repository.py +36 -109
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/redshift_adapter.py +34 -89
- nlp2sql-0.2.0rc8/src/nlp2sql/adapters/regex_query_validator.py +80 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/cli.py +20 -7
- nlp2sql-0.2.0rc8/src/nlp2sql/client.py +189 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/config/settings.py +26 -5
- nlp2sql-0.2.0rc8/src/nlp2sql/core/database_prompts.py +48 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/core/entities.py +2 -0
- nlp2sql-0.2.0rc8/src/nlp2sql/core/provider_config.py +45 -0
- nlp2sql-0.2.0rc8/src/nlp2sql/core/result.py +44 -0
- nlp2sql-0.2.0rc8/src/nlp2sql/core/sql_keywords.py +19 -0
- nlp2sql-0.2.0rc8/src/nlp2sql/core/sql_safety.py +83 -0
- nlp2sql-0.2.0rc8/src/nlp2sql/ports/example_repository.py +55 -0
- nlp2sql-0.2.0rc8/src/nlp2sql/ports/query_safety.py +37 -0
- nlp2sql-0.2.0rc8/src/nlp2sql/ports/query_validator.py +26 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/analyzer.py +47 -18
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/embedding_manager.py +3 -48
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/example_store.py +52 -11
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/manager.py +17 -12
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/services/query_service.py +61 -42
- nlp2sql-0.2.0rc8/src/nlp2sql/utils/__init__.py +1 -0
- nlp2sql-0.2.0rc8/src/nlp2sql/utils/helpers.py +15 -0
- nlp2sql-0.2.0rc8/src/nlp2sql/utils/storage.py +63 -0
- nlp2sql-0.2.0rc8/tests/conftest.py +126 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/mcp/test_sql_security.py +2 -2
- nlp2sql-0.2.0rc8/tests/test_basic.py +249 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/test_batch_scoring.py +20 -41
- nlp2sql-0.2.0rc8/tests/test_column_validation.py +183 -0
- nlp2sql-0.2.0rc8/tests/test_database_prompts.py +64 -0
- nlp2sql-0.2.0rc8/tests/test_dsl_integration.py +228 -0
- nlp2sql-0.2.0rc8/tests/test_postgres_integration.py +120 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/uv.lock +1 -1
- nlp2sql-0.2.0rc6/docs/API.md +0 -472
- nlp2sql-0.2.0rc6/src/nlp2sql/utils/__init__.py +0 -0
- nlp2sql-0.2.0rc6/tests/test_basic.py +0 -53
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/commands/db.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/commands/quality.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/commands/test.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/rules/adapters.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/rules/architecture.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/rules/python-style.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/rules/testing.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/settings.json +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.github/workflows/publish-pypi.yml +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.github/workflows/publish-testpypi.yml +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.mcp.json.example +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.python-version +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/CONTRIBUTING.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/LICENSE +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/SECURITY.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/assets/nlp2sql-logo.png +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/benchmarks/enterprise_benchmark_results.json +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/.env.example +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/README.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/docker-compose.yml +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/get-db-urls.sh +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/init-schema.sql +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/large-schema.sql +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/localstack-init.sh +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/test-redshift.sh +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docs/CONFIGURATION.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docs/ENTERPRISE.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docs/Redshift.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/README.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/advanced/test_multiple_providers.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/advanced/test_simple_api.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/database_specific/test_odoo_integration.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/default_examples.json +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/documentation/real_world_example.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/getting_started/basic_usage.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/getting_started/simple_demo.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/getting_started/test_api_setup.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/schema_management/test_auto_schema.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/schema_management/test_schema_filters_comprehensive.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/.dockerignore +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/.env.example +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_README.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_SETUP.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_TESTING_SUMMARY.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/Dockerfile +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/INDEX.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/README.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/docker/init-ecommerce-schema.sql +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/docker-compose.yml +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/main.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/pyproject.toml +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/test-docker-endpoints.sh +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/install-dev.sh +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/mcp_server/README.md +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/mcp_server/__init__.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/mcp_server/example_config.json +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/mcp_server/pyproject.toml +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/__init__.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/local_embedding_adapter.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/openai_embedding_adapter.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/config/__init__.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/core/__init__.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/exceptions/__init__.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/factories/__init__.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/factories/repository_factory.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/__init__.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/ai_provider.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/cache.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/embedding_provider.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/query_optimizer.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/schema_repository.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/schema_strategy.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/__init__.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/example_loader.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/services/__init__.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/test_tmp/.gitignore +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/mcp/__init__.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/test_embedding_manager.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/test_integration.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/test_redshift_integration.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/test_repository_cache.py +0 -0
- {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/test_repository_factory.py +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, develop]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, develop]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Set up Python 3.12
|
|
18
|
+
uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: '3.12'
|
|
21
|
+
|
|
22
|
+
- name: Install uv
|
|
23
|
+
run: python -m pip install uv
|
|
24
|
+
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: |
|
|
27
|
+
uv pip install --system .
|
|
28
|
+
uv pip install --system ".[dev]"
|
|
29
|
+
|
|
30
|
+
- name: Unit tests
|
|
31
|
+
env:
|
|
32
|
+
PYTHONPATH: src
|
|
33
|
+
run: pytest -m "not integration and not llm" -q
|
|
@@ -51,6 +51,8 @@ The codebase follows Clean Architecture (Hexagonal/Ports & Adapters):
|
|
|
51
51
|
```
|
|
52
52
|
src/nlp2sql/
|
|
53
53
|
├── core/ # Business entities (pure Python, no external dependencies)
|
|
54
|
+
│ ├── entities.py # Query, SQLQuery, DatabaseType
|
|
55
|
+
│ └── database_prompts.py # SQL dialect hints for AI providers
|
|
54
56
|
├── ports/ # Interfaces/abstractions (contracts)
|
|
55
57
|
│ ├── ai_provider.py # AIProviderPort - interface for AI providers
|
|
56
58
|
│ ├── embedding_provider.py # EmbeddingProviderPort - interface for embeddings
|
|
@@ -69,7 +71,8 @@ src/nlp2sql/
|
|
|
69
71
|
├── schema/ # Schema management
|
|
70
72
|
│ ├── schema_manager.py # Coordinates filtering and strategies
|
|
71
73
|
│ ├── schema_analyzer.py # Scores schema relevance
|
|
72
|
-
│
|
|
74
|
+
│ ├── schema_embedding_manager.py # FAISS vector embeddings
|
|
75
|
+
│ └── example_store.py # ExampleStore - FAISS-indexed few-shot examples
|
|
73
76
|
├── config/ # Configuration (Pydantic Settings)
|
|
74
77
|
├── exceptions/ # Custom exceptions hierarchy
|
|
75
78
|
└── cli.py # Click-based CLI
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nlp2sql
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.0rc8
|
|
4
4
|
Summary: Enterprise-ready Natural Language to SQL converter with multi-provider support. Built for production scale (1000+ tables) with Clean Architecture.
|
|
5
5
|
Project-URL: Homepage, https://github.com/luiscarbonel1991/nlp2sql
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/luiscarbonel1991/nlp2sql/issues
|
|
@@ -133,85 +133,109 @@ pip install nlp2sql[embeddings-openai] # OpenAI embeddings
|
|
|
133
133
|
|
|
134
134
|
## Quick Start
|
|
135
135
|
|
|
136
|
-
### 1. Set
|
|
136
|
+
### 1. Set an API Key
|
|
137
137
|
|
|
138
138
|
```bash
|
|
139
|
-
# At least one AI provider key required
|
|
140
139
|
export OPENAI_API_KEY="your-openai-key"
|
|
141
|
-
#
|
|
142
|
-
# export GOOGLE_API_KEY="your-google-key"
|
|
140
|
+
# or ANTHROPIC_API_KEY, GOOGLE_API_KEY
|
|
143
141
|
```
|
|
144
142
|
|
|
145
|
-
### 2.
|
|
143
|
+
### 2. Connect and Ask
|
|
146
144
|
|
|
147
145
|
```python
|
|
148
146
|
import asyncio
|
|
149
|
-
import
|
|
150
|
-
from nlp2sql import
|
|
147
|
+
import nlp2sql
|
|
148
|
+
from nlp2sql import ProviderConfig
|
|
151
149
|
|
|
152
150
|
async def main():
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
ai_provider="openai",
|
|
157
|
-
api_key=os.getenv("OPENAI_API_KEY")
|
|
151
|
+
nlp = await nlp2sql.connect(
|
|
152
|
+
"postgresql://user:pass@localhost:5432/mydb",
|
|
153
|
+
provider=ProviderConfig(provider="openai", api_key="sk-..."),
|
|
158
154
|
)
|
|
159
|
-
|
|
160
|
-
|
|
155
|
+
|
|
156
|
+
result = await nlp.ask("Show me all active users")
|
|
157
|
+
print(result.sql)
|
|
158
|
+
print(result.confidence)
|
|
159
|
+
print(result.is_valid)
|
|
161
160
|
|
|
162
161
|
asyncio.run(main())
|
|
163
162
|
```
|
|
164
163
|
|
|
165
|
-
|
|
164
|
+
`connect()` auto-detects the database type from the URL, loads the schema, and builds the FAISS embedding index. Subsequent `ask()` calls reuse everything from disk cache.
|
|
166
165
|
|
|
167
|
-
|
|
168
|
-
from nlp2sql import create_and_initialize_service
|
|
166
|
+
### 3. Few-Shot Examples
|
|
169
167
|
|
|
170
|
-
|
|
171
|
-
# Initialize once
|
|
172
|
-
service = await create_and_initialize_service(
|
|
173
|
-
database_url="postgresql://user:pass@localhost:5432/mydb",
|
|
174
|
-
ai_provider="openai",
|
|
175
|
-
api_key=os.getenv("OPENAI_API_KEY")
|
|
176
|
-
)
|
|
168
|
+
Pass a list of dicts -- `connect()` handles embedding and indexing automatically:
|
|
177
169
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
170
|
+
```python
|
|
171
|
+
nlp = await nlp2sql.connect(
|
|
172
|
+
"redshift://user:pass@host:5439/db",
|
|
173
|
+
provider=ProviderConfig(provider="openai", api_key="sk-..."),
|
|
174
|
+
schema="dwh_data_share_llm",
|
|
175
|
+
examples=[
|
|
176
|
+
{
|
|
177
|
+
"question": "Total revenue last month?",
|
|
178
|
+
"sql": "SELECT SUM(revenue) FROM sales WHERE date >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month')",
|
|
179
|
+
"database_type": "redshift",
|
|
180
|
+
},
|
|
181
|
+
],
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
result = await nlp.ask("Show me total sales this quarter")
|
|
181
185
|
```
|
|
182
186
|
|
|
183
|
-
### 4.
|
|
187
|
+
### 4. Schema Filtering (Large Databases)
|
|
184
188
|
|
|
185
189
|
```python
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
database_url="postgresql://localhost/enterprise",
|
|
190
|
-
ai_provider="anthropic", # Best for large schemas (200K context)
|
|
191
|
-
api_key=os.getenv("ANTHROPIC_API_KEY"),
|
|
190
|
+
nlp = await nlp2sql.connect(
|
|
191
|
+
"postgresql://localhost/enterprise",
|
|
192
|
+
provider=ProviderConfig(provider="anthropic", api_key="sk-ant-..."),
|
|
192
193
|
schema_filters={
|
|
193
194
|
"include_schemas": ["sales", "finance"],
|
|
194
|
-
"exclude_system_tables": True
|
|
195
|
-
}
|
|
195
|
+
"exclude_system_tables": True,
|
|
196
|
+
},
|
|
196
197
|
)
|
|
198
|
+
```
|
|
197
199
|
|
|
198
|
-
|
|
200
|
+
### 5. Custom Model and Temperature
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
nlp = await nlp2sql.connect(
|
|
204
|
+
"postgresql://localhost/mydb",
|
|
205
|
+
provider=ProviderConfig(
|
|
206
|
+
provider="openai",
|
|
207
|
+
api_key="sk-...",
|
|
208
|
+
model="gpt-4o",
|
|
209
|
+
temperature=0.0,
|
|
210
|
+
max_tokens=4000,
|
|
211
|
+
),
|
|
212
|
+
)
|
|
199
213
|
```
|
|
200
214
|
|
|
201
|
-
###
|
|
215
|
+
### 6. CLI
|
|
202
216
|
|
|
203
217
|
```bash
|
|
204
|
-
# Generate SQL
|
|
205
218
|
nlp2sql query \
|
|
206
219
|
--database-url postgresql://user:pass@localhost:5432/mydb \
|
|
207
220
|
--question "Show all active users" \
|
|
208
221
|
--explain
|
|
209
222
|
|
|
210
|
-
# Inspect schema
|
|
211
223
|
nlp2sql inspect --database-url postgresql://localhost/mydb
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Advanced: Direct Service Access
|
|
212
227
|
|
|
213
|
-
|
|
214
|
-
|
|
228
|
+
For full control over the lifecycle, the lower-level API is still available:
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
from nlp2sql import create_and_initialize_service, ProviderConfig, DatabaseType
|
|
232
|
+
|
|
233
|
+
service = await create_and_initialize_service(
|
|
234
|
+
database_url="postgresql://localhost/mydb",
|
|
235
|
+
provider_config=ProviderConfig(provider="openai", api_key="sk-..."),
|
|
236
|
+
database_type=DatabaseType.POSTGRES,
|
|
237
|
+
)
|
|
238
|
+
result = await service.generate_sql("Count total users", database_type=DatabaseType.POSTGRES)
|
|
215
239
|
```
|
|
216
240
|
|
|
217
241
|
## How It Works
|
|
@@ -233,13 +257,13 @@ See [Architecture](docs/ARCHITECTURE.md) for the detailed flow with method refer
|
|
|
233
257
|
|
|
234
258
|
## Provider Comparison
|
|
235
259
|
|
|
236
|
-
| Provider | Context Size | Best For |
|
|
237
|
-
|
|
238
|
-
| OpenAI
|
|
239
|
-
| Anthropic
|
|
240
|
-
| Google Gemini | 1M | High volume
|
|
260
|
+
| Provider | Default Model | Context Size | Best For |
|
|
261
|
+
|----------|--------------|-------------|----------|
|
|
262
|
+
| OpenAI | gpt-4o-mini | 128K | Cost-effective, fast |
|
|
263
|
+
| Anthropic | claude-sonnet-4-20250514 | 200K | Large schemas |
|
|
264
|
+
| Google Gemini | gemini-2.0-flash | 1M | High volume |
|
|
241
265
|
|
|
242
|
-
See [Configuration](docs/CONFIGURATION.md) for
|
|
266
|
+
All models are configurable via `ProviderConfig(model="...")`. See [Configuration](docs/CONFIGURATION.md) for details.
|
|
243
267
|
|
|
244
268
|
## Architecture
|
|
245
269
|
|
|
@@ -247,13 +271,17 @@ Clean Architecture (Ports & Adapters) with three layers: core entities, port int
|
|
|
247
271
|
|
|
248
272
|
```
|
|
249
273
|
nlp2sql/
|
|
250
|
-
├──
|
|
251
|
-
├──
|
|
252
|
-
├──
|
|
253
|
-
|
|
254
|
-
├──
|
|
255
|
-
|
|
256
|
-
|
|
274
|
+
├── client.py # DSL: connect() + NLP2SQL class (recommended entry point)
|
|
275
|
+
├── core/ # Pure Python: entities, ProviderConfig, QueryResult, sql_safety, sql_keywords
|
|
276
|
+
├── ports/ # Interfaces: AIProviderPort, SchemaRepositoryPort, EmbeddingProviderPort,
|
|
277
|
+
│ # ExampleRepositoryPort, QuerySafetyPort, QueryValidatorPort, CachePort
|
|
278
|
+
├── adapters/ # Implementations: OpenAI, Anthropic, Gemini, PostgreSQL, Redshift,
|
|
279
|
+
│ # RegexQueryValidator
|
|
280
|
+
├── services/ # Orchestration: QueryGenerationService
|
|
281
|
+
├── schema/ # Schema management: SchemaManager, SchemaAnalyzer, SchemaEmbeddingManager,
|
|
282
|
+
│ # ExampleStore
|
|
283
|
+
├── config/ # Pydantic Settings (centralized defaults)
|
|
284
|
+
└── exceptions/ # Exception hierarchy (NLP2SQLException -> 8 subclasses)
|
|
257
285
|
```
|
|
258
286
|
|
|
259
287
|
See [Architecture](docs/ARCHITECTURE.md) for the full component diagram, data flow, and design decisions.
|
|
@@ -54,85 +54,109 @@ pip install nlp2sql[embeddings-openai] # OpenAI embeddings
|
|
|
54
54
|
|
|
55
55
|
## Quick Start
|
|
56
56
|
|
|
57
|
-
### 1. Set
|
|
57
|
+
### 1. Set an API Key
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
|
-
# At least one AI provider key required
|
|
61
60
|
export OPENAI_API_KEY="your-openai-key"
|
|
62
|
-
#
|
|
63
|
-
# export GOOGLE_API_KEY="your-google-key"
|
|
61
|
+
# or ANTHROPIC_API_KEY, GOOGLE_API_KEY
|
|
64
62
|
```
|
|
65
63
|
|
|
66
|
-
### 2.
|
|
64
|
+
### 2. Connect and Ask
|
|
67
65
|
|
|
68
66
|
```python
|
|
69
67
|
import asyncio
|
|
70
|
-
import
|
|
71
|
-
from nlp2sql import
|
|
68
|
+
import nlp2sql
|
|
69
|
+
from nlp2sql import ProviderConfig
|
|
72
70
|
|
|
73
71
|
async def main():
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
ai_provider="openai",
|
|
78
|
-
api_key=os.getenv("OPENAI_API_KEY")
|
|
72
|
+
nlp = await nlp2sql.connect(
|
|
73
|
+
"postgresql://user:pass@localhost:5432/mydb",
|
|
74
|
+
provider=ProviderConfig(provider="openai", api_key="sk-..."),
|
|
79
75
|
)
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
|
|
77
|
+
result = await nlp.ask("Show me all active users")
|
|
78
|
+
print(result.sql)
|
|
79
|
+
print(result.confidence)
|
|
80
|
+
print(result.is_valid)
|
|
82
81
|
|
|
83
82
|
asyncio.run(main())
|
|
84
83
|
```
|
|
85
84
|
|
|
86
|
-
|
|
85
|
+
`connect()` auto-detects the database type from the URL, loads the schema, and builds the FAISS embedding index. Subsequent `ask()` calls reuse everything from disk cache.
|
|
87
86
|
|
|
88
|
-
|
|
89
|
-
from nlp2sql import create_and_initialize_service
|
|
87
|
+
### 3. Few-Shot Examples
|
|
90
88
|
|
|
91
|
-
|
|
92
|
-
# Initialize once
|
|
93
|
-
service = await create_and_initialize_service(
|
|
94
|
-
database_url="postgresql://user:pass@localhost:5432/mydb",
|
|
95
|
-
ai_provider="openai",
|
|
96
|
-
api_key=os.getenv("OPENAI_API_KEY")
|
|
97
|
-
)
|
|
89
|
+
Pass a list of dicts -- `connect()` handles embedding and indexing automatically:
|
|
98
90
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
91
|
+
```python
|
|
92
|
+
nlp = await nlp2sql.connect(
|
|
93
|
+
"redshift://user:pass@host:5439/db",
|
|
94
|
+
provider=ProviderConfig(provider="openai", api_key="sk-..."),
|
|
95
|
+
schema="dwh_data_share_llm",
|
|
96
|
+
examples=[
|
|
97
|
+
{
|
|
98
|
+
"question": "Total revenue last month?",
|
|
99
|
+
"sql": "SELECT SUM(revenue) FROM sales WHERE date >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month')",
|
|
100
|
+
"database_type": "redshift",
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
result = await nlp.ask("Show me total sales this quarter")
|
|
102
106
|
```
|
|
103
107
|
|
|
104
|
-
### 4.
|
|
108
|
+
### 4. Schema Filtering (Large Databases)
|
|
105
109
|
|
|
106
110
|
```python
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
database_url="postgresql://localhost/enterprise",
|
|
111
|
-
ai_provider="anthropic", # Best for large schemas (200K context)
|
|
112
|
-
api_key=os.getenv("ANTHROPIC_API_KEY"),
|
|
111
|
+
nlp = await nlp2sql.connect(
|
|
112
|
+
"postgresql://localhost/enterprise",
|
|
113
|
+
provider=ProviderConfig(provider="anthropic", api_key="sk-ant-..."),
|
|
113
114
|
schema_filters={
|
|
114
115
|
"include_schemas": ["sales", "finance"],
|
|
115
|
-
"exclude_system_tables": True
|
|
116
|
-
}
|
|
116
|
+
"exclude_system_tables": True,
|
|
117
|
+
},
|
|
117
118
|
)
|
|
119
|
+
```
|
|
118
120
|
|
|
119
|
-
|
|
121
|
+
### 5. Custom Model and Temperature
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
nlp = await nlp2sql.connect(
|
|
125
|
+
"postgresql://localhost/mydb",
|
|
126
|
+
provider=ProviderConfig(
|
|
127
|
+
provider="openai",
|
|
128
|
+
api_key="sk-...",
|
|
129
|
+
model="gpt-4o",
|
|
130
|
+
temperature=0.0,
|
|
131
|
+
max_tokens=4000,
|
|
132
|
+
),
|
|
133
|
+
)
|
|
120
134
|
```
|
|
121
135
|
|
|
122
|
-
###
|
|
136
|
+
### 6. CLI
|
|
123
137
|
|
|
124
138
|
```bash
|
|
125
|
-
# Generate SQL
|
|
126
139
|
nlp2sql query \
|
|
127
140
|
--database-url postgresql://user:pass@localhost:5432/mydb \
|
|
128
141
|
--question "Show all active users" \
|
|
129
142
|
--explain
|
|
130
143
|
|
|
131
|
-
# Inspect schema
|
|
132
144
|
nlp2sql inspect --database-url postgresql://localhost/mydb
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Advanced: Direct Service Access
|
|
133
148
|
|
|
134
|
-
|
|
135
|
-
|
|
149
|
+
For full control over the lifecycle, the lower-level API is still available:
|
|
150
|
+
|
|
151
|
+
```python
|
|
152
|
+
from nlp2sql import create_and_initialize_service, ProviderConfig, DatabaseType
|
|
153
|
+
|
|
154
|
+
service = await create_and_initialize_service(
|
|
155
|
+
database_url="postgresql://localhost/mydb",
|
|
156
|
+
provider_config=ProviderConfig(provider="openai", api_key="sk-..."),
|
|
157
|
+
database_type=DatabaseType.POSTGRES,
|
|
158
|
+
)
|
|
159
|
+
result = await service.generate_sql("Count total users", database_type=DatabaseType.POSTGRES)
|
|
136
160
|
```
|
|
137
161
|
|
|
138
162
|
## How It Works
|
|
@@ -154,13 +178,13 @@ See [Architecture](docs/ARCHITECTURE.md) for the detailed flow with method refer
|
|
|
154
178
|
|
|
155
179
|
## Provider Comparison
|
|
156
180
|
|
|
157
|
-
| Provider | Context Size | Best For |
|
|
158
|
-
|
|
159
|
-
| OpenAI
|
|
160
|
-
| Anthropic
|
|
161
|
-
| Google Gemini | 1M | High volume
|
|
181
|
+
| Provider | Default Model | Context Size | Best For |
|
|
182
|
+
|----------|--------------|-------------|----------|
|
|
183
|
+
| OpenAI | gpt-4o-mini | 128K | Cost-effective, fast |
|
|
184
|
+
| Anthropic | claude-sonnet-4-20250514 | 200K | Large schemas |
|
|
185
|
+
| Google Gemini | gemini-2.0-flash | 1M | High volume |
|
|
162
186
|
|
|
163
|
-
See [Configuration](docs/CONFIGURATION.md) for
|
|
187
|
+
All models are configurable via `ProviderConfig(model="...")`. See [Configuration](docs/CONFIGURATION.md) for details.
|
|
164
188
|
|
|
165
189
|
## Architecture
|
|
166
190
|
|
|
@@ -168,13 +192,17 @@ Clean Architecture (Ports & Adapters) with three layers: core entities, port int
|
|
|
168
192
|
|
|
169
193
|
```
|
|
170
194
|
nlp2sql/
|
|
171
|
-
├──
|
|
172
|
-
├──
|
|
173
|
-
├──
|
|
174
|
-
|
|
175
|
-
├──
|
|
176
|
-
|
|
177
|
-
|
|
195
|
+
├── client.py # DSL: connect() + NLP2SQL class (recommended entry point)
|
|
196
|
+
├── core/ # Pure Python: entities, ProviderConfig, QueryResult, sql_safety, sql_keywords
|
|
197
|
+
├── ports/ # Interfaces: AIProviderPort, SchemaRepositoryPort, EmbeddingProviderPort,
|
|
198
|
+
│ # ExampleRepositoryPort, QuerySafetyPort, QueryValidatorPort, CachePort
|
|
199
|
+
├── adapters/ # Implementations: OpenAI, Anthropic, Gemini, PostgreSQL, Redshift,
|
|
200
|
+
│ # RegexQueryValidator
|
|
201
|
+
├── services/ # Orchestration: QueryGenerationService
|
|
202
|
+
├── schema/ # Schema management: SchemaManager, SchemaAnalyzer, SchemaEmbeddingManager,
|
|
203
|
+
│ # ExampleStore
|
|
204
|
+
├── config/ # Pydantic Settings (centralized defaults)
|
|
205
|
+
└── exceptions/ # Exception hierarchy (NLP2SQLException -> 8 subclasses)
|
|
178
206
|
```
|
|
179
207
|
|
|
180
208
|
See [Architecture](docs/ARCHITECTURE.md) for the full component diagram, data flow, and design decisions.
|