nlp2sql 0.2.0rc12__tar.gz → 0.2.0rc14__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 (170) hide show
  1. nlp2sql-0.2.0rc14/.github/workflows/ci.yml +84 -0
  2. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.gitignore +1 -0
  3. nlp2sql-0.2.0rc14/CHANGELOG.md +43 -0
  4. nlp2sql-0.2.0rc14/PKG-INFO +420 -0
  5. nlp2sql-0.2.0rc14/README.md +340 -0
  6. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/docker/docker-compose.yml +1 -1
  7. nlp2sql-0.2.0rc14/docker/init-schema.sql +313 -0
  8. nlp2sql-0.2.0rc14/docs/API.md +425 -0
  9. nlp2sql-0.2.0rc14/docs/ARCHITECTURE.md +366 -0
  10. nlp2sql-0.2.0rc14/docs/CONFIGURATION.md +269 -0
  11. nlp2sql-0.2.0rc14/docs/ENTERPRISE.md +244 -0
  12. nlp2sql-0.2.0rc14/docs/Redshift.md +166 -0
  13. nlp2sql-0.2.0rc14/examples/README.md +155 -0
  14. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/mcp_server/__init__.py +1 -1
  15. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/mcp_server/pyproject.toml +2 -2
  16. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/pyproject.toml +2 -1
  17. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/__init__.py +101 -16
  18. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/adapters/__init__.py +8 -0
  19. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/adapters/anthropic_adapter.py +31 -1
  20. nlp2sql-0.2.0rc14/src/nlp2sql/adapters/default_error_classifier.py +65 -0
  21. nlp2sql-0.2.0rc14/src/nlp2sql/adapters/default_repair_policy.py +41 -0
  22. nlp2sql-0.2.0rc14/src/nlp2sql/adapters/dict_semantic_resolver.py +27 -0
  23. nlp2sql-0.2.0rc14/src/nlp2sql/adapters/file_semantic_resolver.py +24 -0
  24. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/adapters/gemini_adapter.py +31 -1
  25. nlp2sql-0.2.0rc14/src/nlp2sql/adapters/noop_semantic_resolver.py +20 -0
  26. nlp2sql-0.2.0rc14/src/nlp2sql/adapters/noop_semantic_validator.py +19 -0
  27. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/adapters/openai_adapter.py +31 -1
  28. nlp2sql-0.2.0rc14/src/nlp2sql/adapters/pgvector_example_repository.py +489 -0
  29. nlp2sql-0.2.0rc14/src/nlp2sql/adapters/schema_repository_execution_adapter.py +20 -0
  30. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/cli.py +150 -19
  31. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/client.py +57 -2
  32. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/config/settings.py +2 -1
  33. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/core/database_prompts.py +3 -1
  34. nlp2sql-0.2.0rc14/src/nlp2sql/core/entities.py +332 -0
  35. nlp2sql-0.2.0rc14/src/nlp2sql/core/runtime.py +39 -0
  36. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/ports/ai_provider.py +1 -1
  37. nlp2sql-0.2.0rc14/src/nlp2sql/ports/error_classifier.py +19 -0
  38. nlp2sql-0.2.0rc14/src/nlp2sql/ports/query_execution.py +16 -0
  39. nlp2sql-0.2.0rc14/src/nlp2sql/ports/repair_policy.py +19 -0
  40. nlp2sql-0.2.0rc14/src/nlp2sql/ports/semantic_resolver.py +22 -0
  41. nlp2sql-0.2.0rc14/src/nlp2sql/ports/semantic_validator.py +21 -0
  42. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/schema/example_store.py +54 -15
  43. nlp2sql-0.2.0rc14/src/nlp2sql/services/example_selection_service.py +188 -0
  44. nlp2sql-0.2.0rc14/src/nlp2sql/services/prompt_assembly_service.py +64 -0
  45. nlp2sql-0.2.0rc14/src/nlp2sql/services/query_analysis_service.py +231 -0
  46. nlp2sql-0.2.0rc14/src/nlp2sql/services/query_repair_service.py +62 -0
  47. nlp2sql-0.2.0rc14/src/nlp2sql/services/query_service.py +653 -0
  48. nlp2sql-0.2.0rc14/src/nlp2sql/services/semantic_resolution_service.py +195 -0
  49. nlp2sql-0.2.0rc14/src/nlp2sql/services/semantic_validation_service.py +161 -0
  50. nlp2sql-0.2.0rc14/src/nlp2sql/services/sql_intent_planning_service.py +136 -0
  51. nlp2sql-0.2.0rc14/src/nlp2sql/utils/artifact_loader.py +202 -0
  52. nlp2sql-0.2.0rc14/src/nlp2sql/utils/semantic_prompt.py +186 -0
  53. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/conftest.py +26 -3
  54. nlp2sql-0.2.0rc14/tests/test_artifact_loader.py +65 -0
  55. nlp2sql-0.2.0rc14/tests/test_cli_semantic_support.py +138 -0
  56. nlp2sql-0.2.0rc14/tests/test_client_hooks.py +160 -0
  57. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/test_database_prompts.py +3 -0
  58. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/test_dsl_integration.py +174 -3
  59. nlp2sql-0.2.0rc14/tests/test_pgvector_example_repository.py +386 -0
  60. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/test_postgres_integration.py +51 -1
  61. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/test_redshift_integration.py +2 -2
  62. nlp2sql-0.2.0rc14/tests/test_retrieval_pipeline.py +489 -0
  63. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/uv.lock +20 -2
  64. nlp2sql-0.2.0rc12/.github/workflows/ci.yml +0 -33
  65. nlp2sql-0.2.0rc12/PKG-INFO +0 -342
  66. nlp2sql-0.2.0rc12/README.md +0 -264
  67. nlp2sql-0.2.0rc12/docker/init-schema.sql +0 -160
  68. nlp2sql-0.2.0rc12/docs/API.md +0 -385
  69. nlp2sql-0.2.0rc12/docs/ARCHITECTURE.md +0 -319
  70. nlp2sql-0.2.0rc12/docs/CONFIGURATION.md +0 -175
  71. nlp2sql-0.2.0rc12/docs/ENTERPRISE.md +0 -407
  72. nlp2sql-0.2.0rc12/docs/Redshift.md +0 -208
  73. nlp2sql-0.2.0rc12/examples/README.md +0 -168
  74. nlp2sql-0.2.0rc12/src/nlp2sql/core/entities.py +0 -92
  75. nlp2sql-0.2.0rc12/src/nlp2sql/services/query_service.py +0 -354
  76. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.claude/commands/db.md +0 -0
  77. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.claude/commands/quality.md +0 -0
  78. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.claude/commands/test.md +0 -0
  79. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.claude/rules/adapters.md +0 -0
  80. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.claude/rules/architecture.md +0 -0
  81. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.claude/rules/python-style.md +0 -0
  82. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.claude/rules/testing.md +0 -0
  83. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.claude/settings.json +0 -0
  84. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  85. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  86. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.github/workflows/publish-pypi.yml +0 -0
  87. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.github/workflows/publish-testpypi.yml +0 -0
  88. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.mcp.json.example +0 -0
  89. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/.python-version +0 -0
  90. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/CLAUDE.md +0 -0
  91. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/CONTRIBUTING.md +0 -0
  92. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/LICENSE +0 -0
  93. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/SECURITY.md +0 -0
  94. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/assets/nlp2sql-logo.png +0 -0
  95. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/benchmarks/enterprise_benchmark_results.json +0 -0
  96. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/docker/.env.example +0 -0
  97. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/docker/README.md +0 -0
  98. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/docker/get-db-urls.sh +0 -0
  99. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/docker/large-schema.sql +0 -0
  100. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/docker/localstack-init.sh +0 -0
  101. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/docker/test-redshift.sh +0 -0
  102. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/advanced/test_multiple_providers.py +0 -0
  103. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/advanced/test_simple_api.py +0 -0
  104. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/database_specific/test_odoo_integration.py +0 -0
  105. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/default_examples.json +0 -0
  106. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/documentation/real_world_example.py +0 -0
  107. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/getting_started/basic_usage.py +0 -0
  108. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/getting_started/simple_demo.py +0 -0
  109. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/getting_started/test_api_setup.py +0 -0
  110. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/schema_management/test_auto_schema.py +0 -0
  111. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/schema_management/test_schema_filters_comprehensive.py +0 -0
  112. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/.dockerignore +0 -0
  113. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/.env.example +0 -0
  114. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/DOCKER_README.md +0 -0
  115. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/DOCKER_SETUP.md +0 -0
  116. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/DOCKER_TESTING_SUMMARY.md +0 -0
  117. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/Dockerfile +0 -0
  118. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/INDEX.md +0 -0
  119. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/README.md +0 -0
  120. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/docker/init-ecommerce-schema.sql +0 -0
  121. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/docker-compose.yml +0 -0
  122. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/main.py +0 -0
  123. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/pyproject.toml +0 -0
  124. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/examples/strands-fastapi-agent/test-docker-endpoints.sh +0 -0
  125. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/install-dev.sh +0 -0
  126. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/mcp_server/README.md +0 -0
  127. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/mcp_server/example_config.json +0 -0
  128. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/mcp_server/server.py +0 -0
  129. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/adapters/local_embedding_adapter.py +0 -0
  130. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/adapters/openai_embedding_adapter.py +0 -0
  131. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/adapters/postgres_repository.py +0 -0
  132. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/adapters/redshift_adapter.py +0 -0
  133. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/adapters/regex_query_validator.py +0 -0
  134. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/config/__init__.py +0 -0
  135. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/core/__init__.py +0 -0
  136. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/core/provider_config.py +0 -0
  137. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/core/result.py +0 -0
  138. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/core/sql_keywords.py +0 -0
  139. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/core/sql_safety.py +0 -0
  140. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/exceptions/__init__.py +0 -0
  141. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/factories/__init__.py +0 -0
  142. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/factories/repository_factory.py +0 -0
  143. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/ports/__init__.py +0 -0
  144. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/ports/cache.py +0 -0
  145. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/ports/embedding_provider.py +0 -0
  146. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/ports/example_repository.py +0 -0
  147. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/ports/query_optimizer.py +0 -0
  148. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/ports/query_safety.py +0 -0
  149. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/ports/query_validator.py +0 -0
  150. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/ports/schema_repository.py +0 -0
  151. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/ports/schema_strategy.py +0 -0
  152. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/schema/__init__.py +0 -0
  153. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/schema/analyzer.py +0 -0
  154. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/schema/embedding_manager.py +0 -0
  155. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/schema/example_loader.py +0 -0
  156. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/schema/manager.py +0 -0
  157. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/services/__init__.py +0 -0
  158. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/utils/__init__.py +0 -0
  159. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/utils/helpers.py +0 -0
  160. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/src/nlp2sql/utils/storage.py +0 -0
  161. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/test_tmp/.gitignore +0 -0
  162. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/mcp/__init__.py +0 -0
  163. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/mcp/test_sql_security.py +0 -0
  164. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/test_basic.py +0 -0
  165. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/test_batch_scoring.py +0 -0
  166. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/test_column_validation.py +0 -0
  167. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/test_embedding_manager.py +0 -0
  168. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/test_integration.py +0 -0
  169. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/test_repository_cache.py +0 -0
  170. {nlp2sql-0.2.0rc12 → nlp2sql-0.2.0rc14}/tests/test_repository_factory.py +0 -0
@@ -0,0 +1,84 @@
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
34
+
35
+ pgvector-integration:
36
+ runs-on: ubuntu-latest
37
+
38
+ services:
39
+ postgres:
40
+ image: pgvector/pgvector:pg16
41
+ env:
42
+ POSTGRES_USER: testuser
43
+ POSTGRES_PASSWORD: testpass
44
+ POSTGRES_DB: testdb
45
+ ports:
46
+ - 5432:5432
47
+ options: >-
48
+ --health-cmd "pg_isready -U testuser -d testdb"
49
+ --health-interval 10s
50
+ --health-timeout 5s
51
+ --health-retries 5
52
+
53
+ steps:
54
+ - name: Checkout
55
+ uses: actions/checkout@v4
56
+
57
+ - name: Set up Python 3.12
58
+ uses: actions/setup-python@v5
59
+ with:
60
+ python-version: '3.12'
61
+
62
+ - name: Install uv
63
+ run: python -m pip install uv
64
+
65
+ - name: Install dependencies (with pgvector extra)
66
+ run: |
67
+ uv pip install --system ".[dev]"
68
+ uv pip install --system ".[pgvector]"
69
+
70
+ # Scoped to the pgvector adapter suite so the job is self-contained (the
71
+ # broader integration suite needs init-schema.sql / LocalStack Redshift,
72
+ # which are out of scope for this lane). NLP2SQL_REQUIRE_INTEGRATION makes
73
+ # the fixtures FAIL instead of skip, so a misconfigured service goes red
74
+ # rather than green-via-skip (collection != execution).
75
+ - name: pgvector integration tests
76
+ env:
77
+ PYTHONPATH: src
78
+ NLP2SQL_REQUIRE_INTEGRATION: "1"
79
+ NLP2SQL_TEST_POSTGRES_HOST: localhost
80
+ NLP2SQL_TEST_POSTGRES_PORT: "5432"
81
+ NLP2SQL_TEST_POSTGRES_USER: testuser
82
+ NLP2SQL_TEST_POSTGRES_PASS: testpass
83
+ NLP2SQL_TEST_POSTGRES_DB: testdb
84
+ run: pytest tests/test_pgvector_example_repository.py -m integration -q
@@ -176,6 +176,7 @@ query_cache.db
176
176
  !README.md
177
177
  !CONTRIBUTING.md
178
178
  !SECURITY.md
179
+ !CHANGELOG.md
179
180
  !docs/*.md
180
181
  !**/README.md
181
182
  !.github/**/*.md
@@ -0,0 +1,43 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## Versioning policy
9
+
10
+ - **MAJOR** — incompatible public API changes (removing/renaming a public symbol
11
+ or changing a port/ABC contract in a non-backward-compatible way).
12
+ - **MINOR** — backward-compatible functionality (new adapters, new optional
13
+ parameters, new optional extras).
14
+ - **PATCH** — backward-compatible bug fixes.
15
+
16
+ Pre-1.0 the project ships release candidates (e.g. `0.2.0rcN`). Public surface
17
+ changes — moving/renaming exported symbols, or adding methods to a published
18
+ port such as `ExampleRepositoryPort` — MUST be recorded under `Unreleased`
19
+ before release and called out as **Breaking** if they affect external
20
+ implementers. Backward-compatible shims are preferred over hard breaks while
21
+ pre-1.0.
22
+
23
+ ## [Unreleased]
24
+
25
+ ## [0.2.0rc14] - 2026-09-16
26
+
27
+ ### Added
28
+ - `PgvectorExampleRepository`: a Postgres + `pgvector` implementation of
29
+ `ExampleRepositoryPort`, an alternative to the on-disk FAISS `ExampleStore`
30
+ for storing and semantically searching few-shot examples. Stores examples in
31
+ a single table with a `namespace` column (per-database isolation via
32
+ `md5(database_url:schema_name)`, byte-identical to `ExampleStore`), cosine
33
+ distance search over an HNSW index, and idempotent `auto_migrate` DDL.
34
+ - Optional `pgvector` extra: `pip install 'nlp2sql[pgvector]'`.
35
+ - CI: a `pgvector-integration` job that runs the adapter's integration tests
36
+ against a `pgvector/pgvector:pg16` service. The job fails (rather than skips)
37
+ when the database or `vector` extension is unavailable
38
+ (`NLP2SQL_REQUIRE_INTEGRATION`).
39
+
40
+ ### Changed
41
+ - `docker/docker-compose.yml`: the `postgres` service image is now
42
+ `pgvector/pgvector:pg16` (drop-in replacement for `postgres:16`, adds the
43
+ `vector` extension) so integration tests run out of the box.
@@ -0,0 +1,420 @@
1
+ Metadata-Version: 2.5
2
+ Name: nlp2sql
3
+ Version: 0.2.0rc14
4
+ Summary: Enterprise-ready Natural Language to SQL converter with multi-provider support. Built for production scale (1000+ tables) with Clean Architecture.
5
+ Project-URL: Homepage, https://github.com/luiscarbonel1991/nlp2sql
6
+ Project-URL: Bug Tracker, https://github.com/luiscarbonel1991/nlp2sql/issues
7
+ Project-URL: Documentation, https://nlp2sql.readthedocs.io
8
+ Author-email: luiscarbonel1991 <devhighlevel@gmail.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: ai,clean-architecture,database,enterprise,llm,multi-provider,mysql,natural-language,nlp,postgres,production,query-generation,schema-filtering,sql
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Database
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.9
24
+ Requires-Dist: anthropic>=0.18.0
25
+ Requires-Dist: azure-identity>=1.15.0
26
+ Requires-Dist: boto3>=1.34.0
27
+ Requires-Dist: click>=8.0.0
28
+ Requires-Dist: faiss-cpu>=1.7.4
29
+ Requires-Dist: google-generativeai>=0.3.0
30
+ Requires-Dist: greenlet>=3.2.3
31
+ Requires-Dist: httpx>=0.25.0
32
+ Requires-Dist: numpy>=1.24.0
33
+ Requires-Dist: openai>=1.0.0
34
+ Requires-Dist: pandas>=2.0.0
35
+ Requires-Dist: psycopg2-binary>=2.9.0
36
+ Requires-Dist: psycopg[binary]>=3.2.13
37
+ Requires-Dist: pydantic-settings>=2.0.0
38
+ Requires-Dist: pydantic>=2.5.0
39
+ Requires-Dist: redis>=5.0.0
40
+ Requires-Dist: scikit-learn>=1.3.0
41
+ Requires-Dist: sqlalchemy-redshift>=0.7.0
42
+ Requires-Dist: sqlalchemy>=2.0.0
43
+ Requires-Dist: structlog>=24.1.0
44
+ Requires-Dist: tenacity>=8.2.0
45
+ Requires-Dist: tiktoken>=0.5.0
46
+ Provides-Extra: all-embeddings
47
+ Requires-Dist: sentence-transformers>=2.5.0; extra == 'all-embeddings'
48
+ Provides-Extra: all-providers
49
+ Requires-Dist: anthropic>=0.18.0; extra == 'all-providers'
50
+ Requires-Dist: google-generativeai>=0.3.0; extra == 'all-providers'
51
+ Provides-Extra: anthropic
52
+ Requires-Dist: anthropic>=0.18.0; extra == 'anthropic'
53
+ Provides-Extra: dev
54
+ Requires-Dist: black>=23.7.0; extra == 'dev'
55
+ Requires-Dist: isort>=5.12.0; extra == 'dev'
56
+ Requires-Dist: mypy>=1.7.0; extra == 'dev'
57
+ Requires-Dist: myst-parser>=2.0.0; extra == 'dev'
58
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
59
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
60
+ Requires-Dist: pytest-mock>=3.11.0; extra == 'dev'
61
+ Requires-Dist: pytest>=7.4.0; extra == 'dev'
62
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
63
+ Requires-Dist: sphinx-rtd-theme>=1.3.0; extra == 'dev'
64
+ Requires-Dist: sphinx>=7.0.0; extra == 'dev'
65
+ Provides-Extra: embeddings-local
66
+ Requires-Dist: sentence-transformers>=2.5.0; extra == 'embeddings-local'
67
+ Provides-Extra: embeddings-openai
68
+ Provides-Extra: gemini
69
+ Requires-Dist: google-generativeai>=0.3.0; extra == 'gemini'
70
+ Provides-Extra: mssql
71
+ Requires-Dist: pymssql>=2.2.0; extra == 'mssql'
72
+ Provides-Extra: mysql
73
+ Requires-Dist: mysql-connector-python>=8.0.0; extra == 'mysql'
74
+ Requires-Dist: pymysql>=1.1.0; extra == 'mysql'
75
+ Provides-Extra: oracle
76
+ Requires-Dist: oracledb>=2.0.0; extra == 'oracle'
77
+ Provides-Extra: pgvector
78
+ Requires-Dist: pgvector>=0.2.5; extra == 'pgvector'
79
+ Description-Content-Type: text/markdown
80
+
81
+ <p align="center">
82
+ <img src="assets/nlp2sql-logo.png" alt="nlp2sql logo" width="400">
83
+ </p>
84
+
85
+ <p align="center">
86
+ <a href="https://pepy.tech/projects/nlp2sql"><img src="https://static.pepy.tech/personalized-badge/nlp2sql?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads" alt="PyPI Downloads"></a>
87
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
88
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.9+-blue.svg" alt="Python 3.9+"></a>
89
+ <a href="https://github.com/psf/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code style: black"></a>
90
+ </p>
91
+
92
+ # nlp2sql
93
+
94
+ **DSL-first natural language to SQL for PostgreSQL and Redshift**
95
+
96
+ `nlp2sql` turns a natural language question into SQL through a reusable Python DSL:
97
+
98
+ - `await connect(...)`
99
+ - `await nlp.ask(...)`
100
+ - optional few-shot examples
101
+ - optional semantic context
102
+ - optional validation and repair
103
+
104
+ The library is designed for both simple schemas and large warehouses, but all public examples in this repository use the local e-commerce domain shipped with the project itself.
105
+
106
+ ## Features
107
+
108
+ - **DSL-first API**: `connect()` returns an `NLP2SQL` client with `ask()`, `validate()`, `explain()`, and `suggest()`
109
+ - **Business-aware generation**: optional `SemanticContext` adds canonical tables, metrics, dimensions, rules, and mappings
110
+ - **Execution modes**: generate only, generate plus validate, and generate plus validate plus repair
111
+ - **Few-shot examples**: pass example lists directly or use an example repository implementation
112
+ - **Large schema support**: FAISS plus TF-IDF hybrid retrieval, schema filters, and disk-backed caches
113
+ - **Multiple providers**: OpenAI, Anthropic, and Gemini
114
+ - **Database support**: PostgreSQL and Amazon Redshift
115
+ - **Async by default**: built for services, APIs, notebooks, and workers
116
+
117
+ ## Documentation
118
+
119
+ | Document | Description |
120
+ |----------|-------------|
121
+ | [Architecture](docs/ARCHITECTURE.md) | Runtime flow, services, ports, and diagrams |
122
+ | [API Reference](docs/API.md) | Python API, CLI, hooks, and metadata reference |
123
+ | [Configuration](docs/CONFIGURATION.md) | Environment variables, examples, semantic context, cache behavior |
124
+ | [Enterprise Guide](docs/ENTERPRISE.md) | Governed usage, scale, and deployment patterns |
125
+ | [Redshift Support](docs/Redshift.md) | Redshift-specific notes using public examples |
126
+ | [Examples](examples/README.md) | Safe public examples based on the local e-commerce domain |
127
+ | [Contributing](CONTRIBUTING.md) | Contribution guidelines |
128
+
129
+ ## Installation
130
+
131
+ ```bash
132
+ # With UV (recommended)
133
+ uv add nlp2sql
134
+
135
+ # With pip
136
+ pip install nlp2sql
137
+
138
+ # With specific providers
139
+ pip install nlp2sql[anthropic,gemini]
140
+ pip install nlp2sql[all-providers]
141
+
142
+ # With embeddings
143
+ pip install nlp2sql[embeddings-local]
144
+ pip install nlp2sql[embeddings-openai]
145
+ ```
146
+
147
+ ## Quick Start
148
+
149
+ ### 1. Set a Provider Key
150
+
151
+ ```bash
152
+ export OPENAI_API_KEY="your-openai-key"
153
+ # or ANTHROPIC_API_KEY / GOOGLE_API_KEY
154
+ ```
155
+
156
+ ### 2. Use the DSL
157
+
158
+ ```python
159
+ import asyncio
160
+
161
+ import nlp2sql
162
+ from nlp2sql import ProviderConfig
163
+
164
+
165
+ async def main():
166
+ nlp = await nlp2sql.connect(
167
+ "postgresql://testuser:testpass@localhost:5432/testdb",
168
+ provider=ProviderConfig(provider="openai", api_key="sk-..."),
169
+ )
170
+
171
+ result = await nlp.ask("Show active users by region")
172
+ print(result.sql)
173
+ print(result.confidence)
174
+ print(result.metadata["sql_intent_plan"])
175
+
176
+
177
+ asyncio.run(main())
178
+ ```
179
+
180
+ `connect()` loads the schema, initializes retrieval indexes, and returns a reusable `NLP2SQL` client. `ask()` returns a typed `QueryResult`.
181
+
182
+ ### 3. Add Few-Shot Examples
183
+
184
+ Pass examples directly to `connect()`. The library handles indexing for you.
185
+
186
+ ```python
187
+ nlp = await nlp2sql.connect(
188
+ "postgresql://testuser:testpass@localhost:5432/testdb",
189
+ provider=ProviderConfig(provider="openai", api_key="sk-..."),
190
+ examples=[
191
+ {
192
+ "question": "Show revenue by source category for the flagship store",
193
+ "sql": (
194
+ "SELECT d.metric_date, mc.source_category, SUM(d.revenue) AS revenue "
195
+ "FROM daily_channel_metrics d "
196
+ "JOIN stores s ON d.store_id = s.id "
197
+ "JOIN marketing_channels mc ON d.channel_id = mc.id "
198
+ "WHERE s.code = 'na_flagship' "
199
+ "GROUP BY d.metric_date, mc.source_category"
200
+ ),
201
+ "database_type": "postgres",
202
+ }
203
+ ],
204
+ )
205
+ ```
206
+
207
+ ### 4. Add In-Memory Semantic Context
208
+
209
+ Use semantic context when the same question could map to multiple plausible tables or dimensions.
210
+
211
+ ```python
212
+ from nlp2sql import (
213
+ DimensionDefinition,
214
+ DomainRule,
215
+ MetricDefinition,
216
+ SemanticContext,
217
+ SemanticEntityMapping,
218
+ )
219
+
220
+ semantic_context = SemanticContext(
221
+ domain="ecommerce_channel_performance",
222
+ canonical_tables=["daily_channel_metrics"],
223
+ required_filters=["s.code = 'na_flagship'", "s.region = 'North America'"],
224
+ entity_mappings=[
225
+ SemanticEntityMapping(
226
+ source_term="North America flagship store",
227
+ target="store_scope",
228
+ resolved_value="na_flagship / North America",
229
+ filter_expression="s.code = 'na_flagship' AND s.region = 'North America'",
230
+ )
231
+ ],
232
+ metric_definitions=[
233
+ MetricDefinition(name="revenue", description="Revenue by day and source category."),
234
+ MetricDefinition(name="orders_count", description="Orders by day and source category."),
235
+ ],
236
+ dimension_definitions=[
237
+ DimensionDefinition(name="metric_date", description="Daily grain."),
238
+ DimensionDefinition(name="source_category", description="Channel grouping."),
239
+ ],
240
+ rules=[
241
+ DomainRule(
242
+ name="preserve_source_breakdown",
243
+ description="Keep source_category when the question asks for a source breakdown.",
244
+ required_dimensions=["source_category"],
245
+ preferred_tables=["daily_channel_metrics"],
246
+ )
247
+ ],
248
+ )
249
+
250
+ result = await nlp.ask(
251
+ "Show daily revenue and order count by source category for the North America flagship store",
252
+ semantic_context=semantic_context,
253
+ )
254
+ ```
255
+
256
+ ### 5. Validate and Repair
257
+
258
+ `ask()` supports execution-aware modes directly.
259
+
260
+ ```python
261
+ result = await nlp.ask(
262
+ "Show revenue by source category for the flagship store",
263
+ validate=True,
264
+ repair=True,
265
+ )
266
+ ```
267
+
268
+ - `generate_only`: generate SQL only
269
+ - `generate_and_validate`: execute readonly validation when execution is wired
270
+ - `generate_validate_repair`: retry on semantic or execution failures when repair hooks are available
271
+
272
+ ### 6. CLI Parity
273
+
274
+ The CLI exposes the same concepts:
275
+
276
+ ```bash
277
+ nlp2sql query \
278
+ --database-url postgresql://testuser:testpass@localhost:5432/testdb \
279
+ --question "Show daily revenue by source category for the North America flagship store" \
280
+ --examples-file examples.json \
281
+ --semantic-context-file semantic-context.json \
282
+ --validate \
283
+ --repair \
284
+ --show-semantic-context \
285
+ --show-sql-intent-plan \
286
+ --show-selected-examples
287
+ ```
288
+
289
+ ## How It Works
290
+
291
+ ```mermaid
292
+ flowchart TD
293
+ userCode[UserCodeOrCLI] --> dsl[connectAndAskDSL]
294
+ dsl --> analysis[QueryAnalysisService]
295
+ analysis --> semantic[SemanticResolutionService]
296
+ semantic --> retrieval[SchemaRetrievalAndExampleSelection]
297
+ retrieval --> intent[SqlIntentPlanningService]
298
+ intent --> prompt[PromptAssemblyAndAdapters]
299
+ prompt --> llm[LLMGeneration]
300
+ llm --> semval[SemanticValidation]
301
+ semval --> exec[OptionalExecutionAndRepair]
302
+ exec --> result[QueryResultMetadata]
303
+ ```
304
+
305
+ At runtime the library:
306
+
307
+ 1. analyzes the question
308
+ 2. optionally resolves and merges semantic context
309
+ 3. retrieves relevant schema and examples
310
+ 4. builds a structured SQL intent plan
311
+ 5. assembles the prompt
312
+ 6. generates SQL
313
+ 7. optionally validates, executes, and repairs
314
+ 8. returns a `QueryResult` with debug metadata
315
+
316
+ See [Architecture](docs/ARCHITECTURE.md) for the full breakdown.
317
+
318
+ ## Public Example Domain
319
+
320
+ This repository ships a local e-commerce integration domain used in tests and docs. It includes:
321
+
322
+ - `stores`
323
+ - `marketing_channels`
324
+ - `users`
325
+ - `products`
326
+ - `orders`
327
+ - `order_items`
328
+ - `daily_channel_metrics`
329
+
330
+ The public examples intentionally stay inside that domain to avoid leaking any private warehouse schema.
331
+
332
+ To start it locally:
333
+
334
+ ```bash
335
+ cd docker
336
+ docker compose up -d postgres
337
+ ```
338
+
339
+ The default URL is:
340
+
341
+ ```bash
342
+ postgresql://testuser:testpass@localhost:5432/testdb
343
+ ```
344
+
345
+ ## Provider Comparison
346
+
347
+ | Provider | Default Model | Context Size | Best For |
348
+ |----------|---------------|--------------|----------|
349
+ | OpenAI | `gpt-4o-mini` | 128K | Fast general purpose usage |
350
+ | Anthropic | `claude-sonnet-4-20250514` | 200K | Larger schemas and long prompts |
351
+ | Gemini | `gemini-2.0-flash` | 1M | High-volume and very large contexts |
352
+
353
+ All models are configurable through `ProviderConfig`.
354
+
355
+ ## Lower-Level API
356
+
357
+ `connect()` is the recommended path. Lower-level entry points still exist for advanced wiring:
358
+
359
+ ```python
360
+ from nlp2sql import DatabaseType, ProviderConfig, create_and_initialize_service
361
+
362
+ service = await create_and_initialize_service(
363
+ database_url="postgresql://testuser:testpass@localhost:5432/testdb",
364
+ provider_config=ProviderConfig(provider="openai", api_key="sk-..."),
365
+ database_type=DatabaseType.POSTGRES,
366
+ )
367
+
368
+ result = await service.generate_sql(
369
+ "Count active users by region",
370
+ database_type=DatabaseType.POSTGRES,
371
+ )
372
+ print(result["sql"])
373
+ ```
374
+
375
+ ## Development
376
+
377
+ ```bash
378
+ git clone https://github.com/luiscarbonel1991/nlp2sql.git
379
+ cd nlp2sql
380
+ uv sync
381
+
382
+ # Start the local public e-commerce database
383
+ cd docker && docker compose up -d postgres
384
+
385
+ # Integration tests without llm
386
+ cd ..
387
+ uv run pytest -m "integration and not llm"
388
+
389
+ # Optional llm integration tests
390
+ uv run pytest -m "integration and llm"
391
+ ```
392
+
393
+ ## MCP Server
394
+
395
+ `nlp2sql` includes a Model Context Protocol server for assistant integration.
396
+
397
+ ```json
398
+ {
399
+ "mcpServers": {
400
+ "nlp2sql": {
401
+ "command": "python",
402
+ "args": ["/path/to/nlp2sql/mcp_server/server.py"],
403
+ "env": {
404
+ "OPENAI_API_KEY": "${OPENAI_API_KEY}",
405
+ "NLP2SQL_DEFAULT_DB_URL": "postgresql://testuser:testpass@localhost:5432/testdb"
406
+ }
407
+ }
408
+ }
409
+ }
410
+ ```
411
+
412
+ See [mcp_server/README.md](mcp_server/README.md) for details.
413
+
414
+ ## Contributing
415
+
416
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
417
+
418
+ ## License
419
+
420
+ MIT License. See [LICENSE](LICENSE).