nlp2sql 0.2.0rc7__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.0rc7 → nlp2sql-0.2.0rc8}/.gitignore +1 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/PKG-INFO +82 -80
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/README.md +81 -79
- nlp2sql-0.2.0rc8/docs/API.md +385 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docs/ARCHITECTURE.md +72 -20
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/mcp_server/server.py +3 -2
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/pyproject.toml +3 -2
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/__init__.py +102 -40
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/anthropic_adapter.py +25 -7
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/gemini_adapter.py +26 -9
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/openai_adapter.py +24 -7
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/postgres_repository.py +2 -81
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/redshift_adapter.py +2 -63
- nlp2sql-0.2.0rc8/src/nlp2sql/adapters/regex_query_validator.py +80 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/cli.py +18 -7
- nlp2sql-0.2.0rc8/src/nlp2sql/client.py +189 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/config/settings.py +26 -5
- {nlp2sql-0.2.0rc7 → 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.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/analyzer.py +5 -1
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/embedding_manager.py +3 -48
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/example_store.py +52 -11
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/manager.py +13 -8
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/services/query_service.py +34 -126
- 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.0rc7 → 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.0rc7 → nlp2sql-0.2.0rc8}/tests/test_column_validation.py +6 -3
- 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.0rc7 → nlp2sql-0.2.0rc8}/uv.lock +1 -1
- nlp2sql-0.2.0rc7/docs/API.md +0 -510
- nlp2sql-0.2.0rc7/src/nlp2sql/utils/__init__.py +0 -0
- nlp2sql-0.2.0rc7/tests/test_basic.py +0 -53
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/commands/db.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/commands/quality.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/commands/test.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/rules/adapters.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/rules/architecture.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/rules/python-style.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/rules/testing.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/settings.json +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.github/workflows/publish-pypi.yml +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.github/workflows/publish-testpypi.yml +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.mcp.json.example +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.python-version +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/CLAUDE.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/CONTRIBUTING.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/LICENSE +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/SECURITY.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/assets/nlp2sql-logo.png +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/benchmarks/enterprise_benchmark_results.json +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/.env.example +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/README.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/docker-compose.yml +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/get-db-urls.sh +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/init-schema.sql +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/large-schema.sql +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/localstack-init.sh +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/test-redshift.sh +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docs/CONFIGURATION.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docs/ENTERPRISE.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docs/Redshift.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/README.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/advanced/test_multiple_providers.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/advanced/test_simple_api.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/database_specific/test_odoo_integration.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/default_examples.json +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/documentation/real_world_example.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/getting_started/basic_usage.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/getting_started/simple_demo.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/getting_started/test_api_setup.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/schema_management/test_auto_schema.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/schema_management/test_schema_filters_comprehensive.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/.dockerignore +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/.env.example +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_README.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_SETUP.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_TESTING_SUMMARY.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/Dockerfile +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/INDEX.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/README.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/docker/init-ecommerce-schema.sql +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/docker-compose.yml +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/main.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/pyproject.toml +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/test-docker-endpoints.sh +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/install-dev.sh +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/mcp_server/README.md +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/mcp_server/__init__.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/mcp_server/example_config.json +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/mcp_server/pyproject.toml +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/__init__.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/local_embedding_adapter.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/openai_embedding_adapter.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/config/__init__.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/core/__init__.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/core/database_prompts.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/exceptions/__init__.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/factories/__init__.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/factories/repository_factory.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/__init__.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/ai_provider.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/cache.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/embedding_provider.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/query_optimizer.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/schema_repository.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/schema_strategy.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/__init__.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/example_loader.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/services/__init__.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/test_tmp/.gitignore +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/mcp/__init__.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_batch_scoring.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_database_prompts.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_embedding_manager.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_integration.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_redshift_integration.py +0 -0
- {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_repository_cache.py +0 -0
- {nlp2sql-0.2.0rc7 → 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
|
|
@@ -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,111 +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
|
-
|
|
166
|
-
|
|
167
|
-
```python
|
|
168
|
-
from nlp2sql import create_and_initialize_service
|
|
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.
|
|
169
165
|
|
|
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
|
-
)
|
|
177
|
-
|
|
178
|
-
# Use multiple times
|
|
179
|
-
result1 = await service.generate_sql("Count total users")
|
|
180
|
-
result2 = await service.generate_sql("Show recent orders")
|
|
181
|
-
```
|
|
166
|
+
### 3. Few-Shot Examples
|
|
182
167
|
|
|
183
|
-
|
|
168
|
+
Pass a list of dicts -- `connect()` handles embedding and indexing automatically:
|
|
184
169
|
|
|
185
170
|
```python
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
198
|
-
])
|
|
199
|
-
|
|
200
|
-
service = await create_and_initialize_service(
|
|
201
|
-
database_url="redshift://user:pass@host:5439/db",
|
|
202
|
-
ai_provider="openai",
|
|
203
|
-
api_key=os.getenv("OPENAI_API_KEY"),
|
|
204
|
-
example_store=example_store
|
|
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
|
+
],
|
|
205
182
|
)
|
|
206
|
-
|
|
183
|
+
|
|
184
|
+
result = await nlp.ask("Show me total sales this quarter")
|
|
207
185
|
```
|
|
208
186
|
|
|
209
|
-
###
|
|
187
|
+
### 4. Schema Filtering (Large Databases)
|
|
210
188
|
|
|
211
189
|
```python
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
database_url="postgresql://localhost/enterprise",
|
|
216
|
-
ai_provider="anthropic", # Best for large schemas (200K context)
|
|
217
|
-
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-..."),
|
|
218
193
|
schema_filters={
|
|
219
194
|
"include_schemas": ["sales", "finance"],
|
|
220
|
-
"exclude_system_tables": True
|
|
221
|
-
}
|
|
195
|
+
"exclude_system_tables": True,
|
|
196
|
+
},
|
|
222
197
|
)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 5. Custom Model and Temperature
|
|
223
201
|
|
|
224
|
-
|
|
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
|
+
)
|
|
225
213
|
```
|
|
226
214
|
|
|
227
|
-
###
|
|
215
|
+
### 6. CLI
|
|
228
216
|
|
|
229
217
|
```bash
|
|
230
|
-
# Generate SQL
|
|
231
218
|
nlp2sql query \
|
|
232
219
|
--database-url postgresql://user:pass@localhost:5432/mydb \
|
|
233
220
|
--question "Show all active users" \
|
|
234
221
|
--explain
|
|
235
222
|
|
|
236
|
-
# Inspect schema
|
|
237
223
|
nlp2sql inspect --database-url postgresql://localhost/mydb
|
|
224
|
+
```
|
|
238
225
|
|
|
239
|
-
|
|
240
|
-
|
|
226
|
+
### Advanced: Direct Service Access
|
|
227
|
+
|
|
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)
|
|
241
239
|
```
|
|
242
240
|
|
|
243
241
|
## How It Works
|
|
@@ -259,13 +257,13 @@ See [Architecture](docs/ARCHITECTURE.md) for the detailed flow with method refer
|
|
|
259
257
|
|
|
260
258
|
## Provider Comparison
|
|
261
259
|
|
|
262
|
-
| Provider | Context Size | Best For |
|
|
263
|
-
|
|
264
|
-
| OpenAI
|
|
265
|
-
| Anthropic
|
|
266
|
-
| 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 |
|
|
267
265
|
|
|
268
|
-
See [Configuration](docs/CONFIGURATION.md) for
|
|
266
|
+
All models are configurable via `ProviderConfig(model="...")`. See [Configuration](docs/CONFIGURATION.md) for details.
|
|
269
267
|
|
|
270
268
|
## Architecture
|
|
271
269
|
|
|
@@ -273,13 +271,17 @@ Clean Architecture (Ports & Adapters) with three layers: core entities, port int
|
|
|
273
271
|
|
|
274
272
|
```
|
|
275
273
|
nlp2sql/
|
|
276
|
-
├──
|
|
277
|
-
├──
|
|
278
|
-
├──
|
|
279
|
-
|
|
280
|
-
├──
|
|
281
|
-
|
|
282
|
-
|
|
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)
|
|
283
285
|
```
|
|
284
286
|
|
|
285
287
|
See [Architecture](docs/ARCHITECTURE.md) for the full component diagram, data flow, and design decisions.
|
|
@@ -54,111 +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
|
-
|
|
87
|
-
|
|
88
|
-
```python
|
|
89
|
-
from nlp2sql import create_and_initialize_service
|
|
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.
|
|
90
86
|
|
|
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
|
-
)
|
|
98
|
-
|
|
99
|
-
# Use multiple times
|
|
100
|
-
result1 = await service.generate_sql("Count total users")
|
|
101
|
-
result2 = await service.generate_sql("Show recent orders")
|
|
102
|
-
```
|
|
87
|
+
### 3. Few-Shot Examples
|
|
103
88
|
|
|
104
|
-
|
|
89
|
+
Pass a list of dicts -- `connect()` handles embedding and indexing automatically:
|
|
105
90
|
|
|
106
91
|
```python
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
])
|
|
120
|
-
|
|
121
|
-
service = await create_and_initialize_service(
|
|
122
|
-
database_url="redshift://user:pass@host:5439/db",
|
|
123
|
-
ai_provider="openai",
|
|
124
|
-
api_key=os.getenv("OPENAI_API_KEY"),
|
|
125
|
-
example_store=example_store
|
|
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
|
+
],
|
|
126
103
|
)
|
|
127
|
-
|
|
104
|
+
|
|
105
|
+
result = await nlp.ask("Show me total sales this quarter")
|
|
128
106
|
```
|
|
129
107
|
|
|
130
|
-
###
|
|
108
|
+
### 4. Schema Filtering (Large Databases)
|
|
131
109
|
|
|
132
110
|
```python
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
database_url="postgresql://localhost/enterprise",
|
|
137
|
-
ai_provider="anthropic", # Best for large schemas (200K context)
|
|
138
|
-
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-..."),
|
|
139
114
|
schema_filters={
|
|
140
115
|
"include_schemas": ["sales", "finance"],
|
|
141
|
-
"exclude_system_tables": True
|
|
142
|
-
}
|
|
116
|
+
"exclude_system_tables": True,
|
|
117
|
+
},
|
|
143
118
|
)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 5. Custom Model and Temperature
|
|
144
122
|
|
|
145
|
-
|
|
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
|
+
)
|
|
146
134
|
```
|
|
147
135
|
|
|
148
|
-
###
|
|
136
|
+
### 6. CLI
|
|
149
137
|
|
|
150
138
|
```bash
|
|
151
|
-
# Generate SQL
|
|
152
139
|
nlp2sql query \
|
|
153
140
|
--database-url postgresql://user:pass@localhost:5432/mydb \
|
|
154
141
|
--question "Show all active users" \
|
|
155
142
|
--explain
|
|
156
143
|
|
|
157
|
-
# Inspect schema
|
|
158
144
|
nlp2sql inspect --database-url postgresql://localhost/mydb
|
|
145
|
+
```
|
|
159
146
|
|
|
160
|
-
|
|
161
|
-
|
|
147
|
+
### Advanced: Direct Service Access
|
|
148
|
+
|
|
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)
|
|
162
160
|
```
|
|
163
161
|
|
|
164
162
|
## How It Works
|
|
@@ -180,13 +178,13 @@ See [Architecture](docs/ARCHITECTURE.md) for the detailed flow with method refer
|
|
|
180
178
|
|
|
181
179
|
## Provider Comparison
|
|
182
180
|
|
|
183
|
-
| Provider | Context Size | Best For |
|
|
184
|
-
|
|
185
|
-
| OpenAI
|
|
186
|
-
| Anthropic
|
|
187
|
-
| 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 |
|
|
188
186
|
|
|
189
|
-
See [Configuration](docs/CONFIGURATION.md) for
|
|
187
|
+
All models are configurable via `ProviderConfig(model="...")`. See [Configuration](docs/CONFIGURATION.md) for details.
|
|
190
188
|
|
|
191
189
|
## Architecture
|
|
192
190
|
|
|
@@ -194,13 +192,17 @@ Clean Architecture (Ports & Adapters) with three layers: core entities, port int
|
|
|
194
192
|
|
|
195
193
|
```
|
|
196
194
|
nlp2sql/
|
|
197
|
-
├──
|
|
198
|
-
├──
|
|
199
|
-
├──
|
|
200
|
-
|
|
201
|
-
├──
|
|
202
|
-
|
|
203
|
-
|
|
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)
|
|
204
206
|
```
|
|
205
207
|
|
|
206
208
|
See [Architecture](docs/ARCHITECTURE.md) for the full component diagram, data flow, and design decisions.
|