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.
Files changed (132) hide show
  1. nlp2sql-0.2.0rc8/.github/workflows/ci.yml +33 -0
  2. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.gitignore +1 -0
  3. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/CLAUDE.md +4 -1
  4. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/PKG-INFO +84 -56
  5. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/README.md +83 -55
  6. nlp2sql-0.2.0rc8/docs/API.md +385 -0
  7. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docs/ARCHITECTURE.md +74 -20
  8. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/mcp_server/server.py +3 -2
  9. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/pyproject.toml +3 -2
  10. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/__init__.py +108 -39
  11. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/anthropic_adapter.py +32 -16
  12. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/gemini_adapter.py +33 -18
  13. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/openai_adapter.py +31 -16
  14. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/postgres_repository.py +36 -109
  15. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/redshift_adapter.py +34 -89
  16. nlp2sql-0.2.0rc8/src/nlp2sql/adapters/regex_query_validator.py +80 -0
  17. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/cli.py +20 -7
  18. nlp2sql-0.2.0rc8/src/nlp2sql/client.py +189 -0
  19. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/config/settings.py +26 -5
  20. nlp2sql-0.2.0rc8/src/nlp2sql/core/database_prompts.py +48 -0
  21. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/core/entities.py +2 -0
  22. nlp2sql-0.2.0rc8/src/nlp2sql/core/provider_config.py +45 -0
  23. nlp2sql-0.2.0rc8/src/nlp2sql/core/result.py +44 -0
  24. nlp2sql-0.2.0rc8/src/nlp2sql/core/sql_keywords.py +19 -0
  25. nlp2sql-0.2.0rc8/src/nlp2sql/core/sql_safety.py +83 -0
  26. nlp2sql-0.2.0rc8/src/nlp2sql/ports/example_repository.py +55 -0
  27. nlp2sql-0.2.0rc8/src/nlp2sql/ports/query_safety.py +37 -0
  28. nlp2sql-0.2.0rc8/src/nlp2sql/ports/query_validator.py +26 -0
  29. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/analyzer.py +47 -18
  30. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/embedding_manager.py +3 -48
  31. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/example_store.py +52 -11
  32. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/manager.py +17 -12
  33. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/services/query_service.py +61 -42
  34. nlp2sql-0.2.0rc8/src/nlp2sql/utils/__init__.py +1 -0
  35. nlp2sql-0.2.0rc8/src/nlp2sql/utils/helpers.py +15 -0
  36. nlp2sql-0.2.0rc8/src/nlp2sql/utils/storage.py +63 -0
  37. nlp2sql-0.2.0rc8/tests/conftest.py +126 -0
  38. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/mcp/test_sql_security.py +2 -2
  39. nlp2sql-0.2.0rc8/tests/test_basic.py +249 -0
  40. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/test_batch_scoring.py +20 -41
  41. nlp2sql-0.2.0rc8/tests/test_column_validation.py +183 -0
  42. nlp2sql-0.2.0rc8/tests/test_database_prompts.py +64 -0
  43. nlp2sql-0.2.0rc8/tests/test_dsl_integration.py +228 -0
  44. nlp2sql-0.2.0rc8/tests/test_postgres_integration.py +120 -0
  45. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/uv.lock +1 -1
  46. nlp2sql-0.2.0rc6/docs/API.md +0 -472
  47. nlp2sql-0.2.0rc6/src/nlp2sql/utils/__init__.py +0 -0
  48. nlp2sql-0.2.0rc6/tests/test_basic.py +0 -53
  49. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/commands/db.md +0 -0
  50. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/commands/quality.md +0 -0
  51. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/commands/test.md +0 -0
  52. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/rules/adapters.md +0 -0
  53. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/rules/architecture.md +0 -0
  54. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/rules/python-style.md +0 -0
  55. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/rules/testing.md +0 -0
  56. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.claude/settings.json +0 -0
  57. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  58. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  59. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.github/workflows/publish-pypi.yml +0 -0
  60. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.github/workflows/publish-testpypi.yml +0 -0
  61. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.mcp.json.example +0 -0
  62. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/.python-version +0 -0
  63. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/CONTRIBUTING.md +0 -0
  64. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/LICENSE +0 -0
  65. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/SECURITY.md +0 -0
  66. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/assets/nlp2sql-logo.png +0 -0
  67. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/benchmarks/enterprise_benchmark_results.json +0 -0
  68. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/.env.example +0 -0
  69. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/README.md +0 -0
  70. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/docker-compose.yml +0 -0
  71. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/get-db-urls.sh +0 -0
  72. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/init-schema.sql +0 -0
  73. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/large-schema.sql +0 -0
  74. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/localstack-init.sh +0 -0
  75. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docker/test-redshift.sh +0 -0
  76. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docs/CONFIGURATION.md +0 -0
  77. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docs/ENTERPRISE.md +0 -0
  78. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/docs/Redshift.md +0 -0
  79. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/README.md +0 -0
  80. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/advanced/test_multiple_providers.py +0 -0
  81. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/advanced/test_simple_api.py +0 -0
  82. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/database_specific/test_odoo_integration.py +0 -0
  83. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/default_examples.json +0 -0
  84. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/documentation/real_world_example.py +0 -0
  85. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/getting_started/basic_usage.py +0 -0
  86. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/getting_started/simple_demo.py +0 -0
  87. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/getting_started/test_api_setup.py +0 -0
  88. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/schema_management/test_auto_schema.py +0 -0
  89. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/schema_management/test_schema_filters_comprehensive.py +0 -0
  90. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/.dockerignore +0 -0
  91. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/.env.example +0 -0
  92. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_README.md +0 -0
  93. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_SETUP.md +0 -0
  94. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/DOCKER_TESTING_SUMMARY.md +0 -0
  95. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/Dockerfile +0 -0
  96. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/INDEX.md +0 -0
  97. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/README.md +0 -0
  98. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/docker/init-ecommerce-schema.sql +0 -0
  99. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/docker-compose.yml +0 -0
  100. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/main.py +0 -0
  101. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/pyproject.toml +0 -0
  102. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/examples/strands-fastapi-agent/test-docker-endpoints.sh +0 -0
  103. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/install-dev.sh +0 -0
  104. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/mcp_server/README.md +0 -0
  105. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/mcp_server/__init__.py +0 -0
  106. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/mcp_server/example_config.json +0 -0
  107. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/mcp_server/pyproject.toml +0 -0
  108. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/__init__.py +0 -0
  109. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/local_embedding_adapter.py +0 -0
  110. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/adapters/openai_embedding_adapter.py +0 -0
  111. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/config/__init__.py +0 -0
  112. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/core/__init__.py +0 -0
  113. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/exceptions/__init__.py +0 -0
  114. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/factories/__init__.py +0 -0
  115. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/factories/repository_factory.py +0 -0
  116. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/__init__.py +0 -0
  117. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/ai_provider.py +0 -0
  118. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/cache.py +0 -0
  119. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/embedding_provider.py +0 -0
  120. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/query_optimizer.py +0 -0
  121. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/schema_repository.py +0 -0
  122. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/ports/schema_strategy.py +0 -0
  123. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/__init__.py +0 -0
  124. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/schema/example_loader.py +0 -0
  125. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/src/nlp2sql/services/__init__.py +0 -0
  126. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/test_tmp/.gitignore +0 -0
  127. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/mcp/__init__.py +0 -0
  128. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/test_embedding_manager.py +0 -0
  129. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/test_integration.py +0 -0
  130. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/test_redshift_integration.py +0 -0
  131. {nlp2sql-0.2.0rc6 → nlp2sql-0.2.0rc8}/tests/test_repository_cache.py +0 -0
  132. {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
@@ -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/
@@ -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
- │ └── schema_embedding_manager.py # FAISS vector embeddings
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.0rc6
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 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)
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
- ```python
168
- from nlp2sql import create_and_initialize_service
166
+ ### 3. Few-Shot Examples
169
167
 
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
- )
168
+ Pass a list of dicts -- `connect()` handles embedding and indexing automatically:
177
169
 
178
- # Use multiple times
179
- result1 = await service.generate_sql("Count total users")
180
- result2 = await service.generate_sql("Show recent orders")
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. Large Database with Schema Filtering
187
+ ### 4. Schema Filtering (Large Databases)
184
188
 
185
189
  ```python
186
- from nlp2sql import create_and_initialize_service
187
-
188
- service = await create_and_initialize_service(
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
- result = await service.generate_sql("Show revenue by month")
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
- ### 5. CLI Usage
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
- # Benchmark providers
214
- nlp2sql benchmark --database-url postgresql://localhost/mydb
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 GPT-4 | 128K | Complex reasoning |
239
- | Anthropic Claude | 200K | Large schemas |
240
- | 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 |
241
265
 
242
- See [Configuration](docs/CONFIGURATION.md) for detailed provider setup.
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
- ├── core/ # Business entities (pure Python, no dependencies)
251
- ├── ports/ # Interfaces (AIProviderPort, SchemaRepositoryPort, EmbeddingProviderPort)
252
- ├── adapters/ # Implementations (OpenAI, Anthropic, Gemini, PostgreSQL, Redshift)
253
- ├── services/ # Orchestration (QueryGenerationService)
254
- ├── schema/ # Schema management (SchemaManager, SchemaAnalyzer, SchemaEmbeddingManager)
255
- ├── config/ # Pydantic Settings configuration
256
- └── 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)
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 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)
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
- ```python
89
- from nlp2sql import create_and_initialize_service
87
+ ### 3. Few-Shot Examples
90
88
 
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
- )
89
+ Pass a list of dicts -- `connect()` handles embedding and indexing automatically:
98
90
 
99
- # Use multiple times
100
- result1 = await service.generate_sql("Count total users")
101
- result2 = await service.generate_sql("Show recent orders")
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. Large Database with Schema Filtering
108
+ ### 4. Schema Filtering (Large Databases)
105
109
 
106
110
  ```python
107
- from nlp2sql import create_and_initialize_service
108
-
109
- service = await create_and_initialize_service(
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
- result = await service.generate_sql("Show revenue by month")
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
- ### 5. CLI Usage
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
- # Benchmark providers
135
- nlp2sql benchmark --database-url postgresql://localhost/mydb
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 GPT-4 | 128K | Complex reasoning |
160
- | Anthropic Claude | 200K | Large schemas |
161
- | 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 |
162
186
 
163
- See [Configuration](docs/CONFIGURATION.md) for detailed provider setup.
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
- ├── core/ # Business entities (pure Python, no dependencies)
172
- ├── ports/ # Interfaces (AIProviderPort, SchemaRepositoryPort, EmbeddingProviderPort)
173
- ├── adapters/ # Implementations (OpenAI, Anthropic, Gemini, PostgreSQL, Redshift)
174
- ├── services/ # Orchestration (QueryGenerationService)
175
- ├── schema/ # Schema management (SchemaManager, SchemaAnalyzer, SchemaEmbeddingManager)
176
- ├── config/ # Pydantic Settings configuration
177
- └── 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)
178
206
  ```
179
207
 
180
208
  See [Architecture](docs/ARCHITECTURE.md) for the full component diagram, data flow, and design decisions.