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.
Files changed (132) hide show
  1. nlp2sql-0.2.0rc8/.github/workflows/ci.yml +33 -0
  2. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.gitignore +1 -0
  3. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/PKG-INFO +82 -80
  4. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/README.md +81 -79
  5. nlp2sql-0.2.0rc8/docs/API.md +385 -0
  6. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docs/ARCHITECTURE.md +72 -20
  7. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/mcp_server/server.py +3 -2
  8. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/pyproject.toml +3 -2
  9. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/__init__.py +102 -40
  10. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/anthropic_adapter.py +25 -7
  11. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/gemini_adapter.py +26 -9
  12. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/openai_adapter.py +24 -7
  13. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/postgres_repository.py +2 -81
  14. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/redshift_adapter.py +2 -63
  15. nlp2sql-0.2.0rc8/src/nlp2sql/adapters/regex_query_validator.py +80 -0
  16. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/cli.py +18 -7
  17. nlp2sql-0.2.0rc8/src/nlp2sql/client.py +189 -0
  18. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/config/settings.py +26 -5
  19. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/core/entities.py +2 -0
  20. nlp2sql-0.2.0rc8/src/nlp2sql/core/provider_config.py +45 -0
  21. nlp2sql-0.2.0rc8/src/nlp2sql/core/result.py +44 -0
  22. nlp2sql-0.2.0rc8/src/nlp2sql/core/sql_keywords.py +19 -0
  23. nlp2sql-0.2.0rc8/src/nlp2sql/core/sql_safety.py +83 -0
  24. nlp2sql-0.2.0rc8/src/nlp2sql/ports/example_repository.py +55 -0
  25. nlp2sql-0.2.0rc8/src/nlp2sql/ports/query_safety.py +37 -0
  26. nlp2sql-0.2.0rc8/src/nlp2sql/ports/query_validator.py +26 -0
  27. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/analyzer.py +5 -1
  28. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/embedding_manager.py +3 -48
  29. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/example_store.py +52 -11
  30. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/manager.py +13 -8
  31. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/services/query_service.py +34 -126
  32. nlp2sql-0.2.0rc8/src/nlp2sql/utils/__init__.py +1 -0
  33. nlp2sql-0.2.0rc8/src/nlp2sql/utils/helpers.py +15 -0
  34. nlp2sql-0.2.0rc8/src/nlp2sql/utils/storage.py +63 -0
  35. nlp2sql-0.2.0rc8/tests/conftest.py +126 -0
  36. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/mcp/test_sql_security.py +2 -2
  37. nlp2sql-0.2.0rc8/tests/test_basic.py +249 -0
  38. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_column_validation.py +6 -3
  39. nlp2sql-0.2.0rc8/tests/test_dsl_integration.py +228 -0
  40. nlp2sql-0.2.0rc8/tests/test_postgres_integration.py +120 -0
  41. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/uv.lock +1 -1
  42. nlp2sql-0.2.0rc7/docs/API.md +0 -510
  43. nlp2sql-0.2.0rc7/src/nlp2sql/utils/__init__.py +0 -0
  44. nlp2sql-0.2.0rc7/tests/test_basic.py +0 -53
  45. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/commands/db.md +0 -0
  46. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/commands/quality.md +0 -0
  47. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/commands/test.md +0 -0
  48. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/rules/adapters.md +0 -0
  49. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/rules/architecture.md +0 -0
  50. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/rules/python-style.md +0 -0
  51. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/rules/testing.md +0 -0
  52. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.claude/settings.json +0 -0
  53. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  54. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  55. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.github/workflows/publish-pypi.yml +0 -0
  56. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.github/workflows/publish-testpypi.yml +0 -0
  57. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.mcp.json.example +0 -0
  58. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/.python-version +0 -0
  59. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/CLAUDE.md +0 -0
  60. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/CONTRIBUTING.md +0 -0
  61. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/LICENSE +0 -0
  62. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/SECURITY.md +0 -0
  63. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/assets/nlp2sql-logo.png +0 -0
  64. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/benchmarks/enterprise_benchmark_results.json +0 -0
  65. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/.env.example +0 -0
  66. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/README.md +0 -0
  67. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/docker-compose.yml +0 -0
  68. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/get-db-urls.sh +0 -0
  69. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/init-schema.sql +0 -0
  70. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/large-schema.sql +0 -0
  71. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/localstack-init.sh +0 -0
  72. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docker/test-redshift.sh +0 -0
  73. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docs/CONFIGURATION.md +0 -0
  74. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docs/ENTERPRISE.md +0 -0
  75. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/docs/Redshift.md +0 -0
  76. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/README.md +0 -0
  77. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/advanced/test_multiple_providers.py +0 -0
  78. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/advanced/test_simple_api.py +0 -0
  79. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/database_specific/test_odoo_integration.py +0 -0
  80. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/default_examples.json +0 -0
  81. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/documentation/real_world_example.py +0 -0
  82. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/getting_started/basic_usage.py +0 -0
  83. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/getting_started/simple_demo.py +0 -0
  84. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/getting_started/test_api_setup.py +0 -0
  85. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/schema_management/test_auto_schema.py +0 -0
  86. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/schema_management/test_schema_filters_comprehensive.py +0 -0
  87. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/.dockerignore +0 -0
  88. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/.env.example +0 -0
  89. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_README.md +0 -0
  90. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_SETUP.md +0 -0
  91. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_TESTING_SUMMARY.md +0 -0
  92. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/Dockerfile +0 -0
  93. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/INDEX.md +0 -0
  94. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/README.md +0 -0
  95. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/docker/init-ecommerce-schema.sql +0 -0
  96. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/docker-compose.yml +0 -0
  97. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/main.py +0 -0
  98. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/pyproject.toml +0 -0
  99. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/test-docker-endpoints.sh +0 -0
  100. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/install-dev.sh +0 -0
  101. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/mcp_server/README.md +0 -0
  102. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/mcp_server/__init__.py +0 -0
  103. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/mcp_server/example_config.json +0 -0
  104. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/mcp_server/pyproject.toml +0 -0
  105. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/__init__.py +0 -0
  106. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/local_embedding_adapter.py +0 -0
  107. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/openai_embedding_adapter.py +0 -0
  108. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/config/__init__.py +0 -0
  109. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/core/__init__.py +0 -0
  110. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/core/database_prompts.py +0 -0
  111. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/exceptions/__init__.py +0 -0
  112. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/factories/__init__.py +0 -0
  113. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/factories/repository_factory.py +0 -0
  114. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/__init__.py +0 -0
  115. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/ai_provider.py +0 -0
  116. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/cache.py +0 -0
  117. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/embedding_provider.py +0 -0
  118. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/query_optimizer.py +0 -0
  119. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/schema_repository.py +0 -0
  120. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/schema_strategy.py +0 -0
  121. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/__init__.py +0 -0
  122. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/example_loader.py +0 -0
  123. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/src/nlp2sql/services/__init__.py +0 -0
  124. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/test_tmp/.gitignore +0 -0
  125. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/mcp/__init__.py +0 -0
  126. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_batch_scoring.py +0 -0
  127. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_database_prompts.py +0 -0
  128. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_embedding_manager.py +0 -0
  129. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_integration.py +0 -0
  130. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_redshift_integration.py +0 -0
  131. {nlp2sql-0.2.0rc7 → nlp2sql-0.2.0rc8}/tests/test_repository_cache.py +0 -0
  132. {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
@@ -166,6 +166,7 @@ cython_debug/
166
166
  nplsql.toml
167
167
  embeddings/
168
168
  embeddings
169
+ examples_index/
169
170
  query_cache.db
170
171
  *.iml
171
172
  *.idea/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nlp2sql
3
- Version: 0.2.0rc7
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 Environment Variables
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
- # export ANTHROPIC_API_KEY="your-anthropic-key"
142
- # export GOOGLE_API_KEY="your-google-key"
140
+ # or ANTHROPIC_API_KEY, GOOGLE_API_KEY
143
141
  ```
144
142
 
145
- ### 2. One-Line Usage
143
+ ### 2. Connect and Ask
146
144
 
147
145
  ```python
148
146
  import asyncio
149
- import os
150
- from nlp2sql import generate_sql_from_db
147
+ import nlp2sql
148
+ from nlp2sql import ProviderConfig
151
149
 
152
150
  async def main():
153
- result = await generate_sql_from_db(
154
- database_url="postgresql://user:pass@localhost:5432/mydb",
155
- question="Show me all active users",
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
- print(result['sql'])
160
- print(f"Confidence: {result['confidence']}")
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
- ### 3. Pre-Initialized Service (Better Performance)
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
- async def main():
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
- ### 4. Few-Shot Examples (Improved Accuracy)
168
+ Pass a list of dicts -- `connect()` handles embedding and indexing automatically:
184
169
 
185
170
  ```python
186
- from nlp2sql import ExampleStore, create_embedding_provider, create_and_initialize_service
187
-
188
- # Create example store with domain-specific examples
189
- embedding_provider = create_embedding_provider("openai", api_key=os.getenv("OPENAI_API_KEY"))
190
- example_store = ExampleStore(embedding_provider=embedding_provider)
191
- await example_store.add_examples([
192
- {
193
- "question": "What was the total revenue last month?",
194
- "sql": "SELECT SUM(gross_revenue) FROM sales WHERE date >= DATE_TRUNC('month', DATEADD(month, -1, CURRENT_DATE))",
195
- "database_type": "redshift",
196
- "metadata": {"category": "aggregation"}
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
- result = await service.generate_sql("Show me total sales this quarter")
183
+
184
+ result = await nlp.ask("Show me total sales this quarter")
207
185
  ```
208
186
 
209
- ### 5. Large Database with Schema Filtering
187
+ ### 4. Schema Filtering (Large Databases)
210
188
 
211
189
  ```python
212
- from nlp2sql import create_and_initialize_service
213
-
214
- service = await create_and_initialize_service(
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
- result = await service.generate_sql("Show revenue by month")
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
- ### 5. CLI Usage
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
- # Benchmark providers
240
- nlp2sql benchmark --database-url postgresql://localhost/mydb
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 GPT-4 | 128K | Complex reasoning |
265
- | Anthropic Claude | 200K | Large schemas |
266
- | Google Gemini | 1M | High volume, cost efficiency |
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 detailed provider setup.
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
- ├── core/ # Business entities (pure Python, no dependencies)
277
- ├── ports/ # Interfaces (AIProviderPort, SchemaRepositoryPort, EmbeddingProviderPort)
278
- ├── adapters/ # Implementations (OpenAI, Anthropic, Gemini, PostgreSQL, Redshift)
279
- ├── services/ # Orchestration (QueryGenerationService)
280
- ├── schema/ # Schema management (SchemaManager, SchemaAnalyzer, SchemaEmbeddingManager)
281
- ├── config/ # Pydantic Settings configuration
282
- └── exceptions/ # Custom exception hierarchy
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 Environment Variables
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
- # export ANTHROPIC_API_KEY="your-anthropic-key"
63
- # export GOOGLE_API_KEY="your-google-key"
61
+ # or ANTHROPIC_API_KEY, GOOGLE_API_KEY
64
62
  ```
65
63
 
66
- ### 2. One-Line Usage
64
+ ### 2. Connect and Ask
67
65
 
68
66
  ```python
69
67
  import asyncio
70
- import os
71
- from nlp2sql import generate_sql_from_db
68
+ import nlp2sql
69
+ from nlp2sql import ProviderConfig
72
70
 
73
71
  async def main():
74
- result = await generate_sql_from_db(
75
- database_url="postgresql://user:pass@localhost:5432/mydb",
76
- question="Show me all active users",
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
- print(result['sql'])
81
- print(f"Confidence: {result['confidence']}")
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
- ### 3. Pre-Initialized Service (Better Performance)
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
- async def main():
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
- ### 4. Few-Shot Examples (Improved Accuracy)
89
+ Pass a list of dicts -- `connect()` handles embedding and indexing automatically:
105
90
 
106
91
  ```python
107
- from nlp2sql import ExampleStore, create_embedding_provider, create_and_initialize_service
108
-
109
- # Create example store with domain-specific examples
110
- embedding_provider = create_embedding_provider("openai", api_key=os.getenv("OPENAI_API_KEY"))
111
- example_store = ExampleStore(embedding_provider=embedding_provider)
112
- await example_store.add_examples([
113
- {
114
- "question": "What was the total revenue last month?",
115
- "sql": "SELECT SUM(gross_revenue) FROM sales WHERE date >= DATE_TRUNC('month', DATEADD(month, -1, CURRENT_DATE))",
116
- "database_type": "redshift",
117
- "metadata": {"category": "aggregation"}
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
- result = await service.generate_sql("Show me total sales this quarter")
104
+
105
+ result = await nlp.ask("Show me total sales this quarter")
128
106
  ```
129
107
 
130
- ### 5. Large Database with Schema Filtering
108
+ ### 4. Schema Filtering (Large Databases)
131
109
 
132
110
  ```python
133
- from nlp2sql import create_and_initialize_service
134
-
135
- service = await create_and_initialize_service(
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
- result = await service.generate_sql("Show revenue by month")
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
- ### 5. CLI Usage
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
- # Benchmark providers
161
- nlp2sql benchmark --database-url postgresql://localhost/mydb
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 GPT-4 | 128K | Complex reasoning |
186
- | Anthropic Claude | 200K | Large schemas |
187
- | Google Gemini | 1M | High volume, cost efficiency |
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 detailed provider setup.
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
- ├── core/ # Business entities (pure Python, no dependencies)
198
- ├── ports/ # Interfaces (AIProviderPort, SchemaRepositoryPort, EmbeddingProviderPort)
199
- ├── adapters/ # Implementations (OpenAI, Anthropic, Gemini, PostgreSQL, Redshift)
200
- ├── services/ # Orchestration (QueryGenerationService)
201
- ├── schema/ # Schema management (SchemaManager, SchemaAnalyzer, SchemaEmbeddingManager)
202
- ├── config/ # Pydantic Settings configuration
203
- └── exceptions/ # Custom exception hierarchy
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.