nl2sql-engine 0.1.0__py3-none-any.whl
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.
- nl2sql/__init__.py +38 -0
- nl2sql/adapters/__init__.py +0 -0
- nl2sql/adapters/duckdb/__init__.py +0 -0
- nl2sql/adapters/duckdb/adapter.py +71 -0
- nl2sql/adapters/mssql/__init__.py +0 -0
- nl2sql/adapters/mssql/adapter.py +122 -0
- nl2sql/adapters/mysql/__init__.py +0 -0
- nl2sql/adapters/mysql/adapter.py +123 -0
- nl2sql/adapters/postgres/__init__.py +0 -0
- nl2sql/adapters/postgres/adapter.py +115 -0
- nl2sql/adapters/sqlalchemy_base/__init__.py +17 -0
- nl2sql/adapters/sqlalchemy_base/adapter.py +476 -0
- nl2sql/adapters/sqlalchemy_base/models.py +36 -0
- nl2sql/adapters/sqlite/__init__.py +0 -0
- nl2sql/adapters/sqlite/adapter.py +88 -0
- nl2sql/aggregation/__init__.py +3 -0
- nl2sql/aggregation/aggregator.py +98 -0
- nl2sql/aggregation/engines/__init__.py +3 -0
- nl2sql/aggregation/engines/polars_duckdb.py +125 -0
- nl2sql/api/__init__.py +0 -0
- nl2sql/api/auth_api.py +60 -0
- nl2sql/api/benchmark_api.py +114 -0
- nl2sql/api/datasource_api.py +132 -0
- nl2sql/api/indexing_api.py +59 -0
- nl2sql/api/llm_api.py +82 -0
- nl2sql/api/policy_api.py +135 -0
- nl2sql/api/query_api.py +138 -0
- nl2sql/api/result_api.py +24 -0
- nl2sql/api/settings_api.py +65 -0
- nl2sql/auth/__init__.py +8 -0
- nl2sql/auth/models.py +36 -0
- nl2sql/auth/rbac.py +25 -0
- nl2sql/cli/__init__.py +0 -0
- nl2sql/cli/checks.py +53 -0
- nl2sql/cli/commands/__init__.py +0 -0
- nl2sql/cli/commands/benchmark.py +34 -0
- nl2sql/cli/commands/doctor.py +49 -0
- nl2sql/cli/commands/indexing.py +126 -0
- nl2sql/cli/commands/info.py +25 -0
- nl2sql/cli/commands/install.py +27 -0
- nl2sql/cli/commands/policy.py +57 -0
- nl2sql/cli/commands/run.py +166 -0
- nl2sql/cli/commands/setup.py +415 -0
- nl2sql/cli/commands/visualize.py +34 -0
- nl2sql/cli/common/decorators.py +34 -0
- nl2sql/cli/config.py +24 -0
- nl2sql/cli/console.py +52 -0
- nl2sql/cli/demo/__init__.py +1 -0
- nl2sql/cli/demo/data.py +87 -0
- nl2sql/cli/demo/defaults.py +122 -0
- nl2sql/cli/demo/factory.py +289 -0
- nl2sql/cli/demo/manager.py +230 -0
- nl2sql/cli/demo/schemas.py +336 -0
- nl2sql/cli/demo/writers/__init__.py +0 -0
- nl2sql/cli/demo/writers/docker.py +182 -0
- nl2sql/cli/demo/writers/sqlite.py +88 -0
- nl2sql/cli/generators/datasources/__init__.py +3 -0
- nl2sql/cli/generators/datasources/generator.py +24 -0
- nl2sql/cli/generators/datasources/templates.py +7 -0
- nl2sql/cli/generators/env/__init__.py +3 -0
- nl2sql/cli/generators/env/generator.py +46 -0
- nl2sql/cli/generators/env/templates.py +25 -0
- nl2sql/cli/generators/llm/__init__.py +3 -0
- nl2sql/cli/generators/llm/generator.py +24 -0
- nl2sql/cli/generators/llm/templates.py +4 -0
- nl2sql/cli/generators/policies/__init__.py +3 -0
- nl2sql/cli/generators/policies/generator.py +20 -0
- nl2sql/cli/generators/policies/templates.py +2 -0
- nl2sql/cli/main.py +195 -0
- nl2sql/cli/reporting.py +878 -0
- nl2sql/cli/types.py +13 -0
- nl2sql/common/__init__.py +1 -0
- nl2sql/common/cancellation.py +25 -0
- nl2sql/common/context.py +5 -0
- nl2sql/common/errors.py +109 -0
- nl2sql/common/event_logger.py +88 -0
- nl2sql/common/exceptions.py +3 -0
- nl2sql/common/logger.py +119 -0
- nl2sql/common/metrics.py +50 -0
- nl2sql/common/resilience.py +59 -0
- nl2sql/common/settings.py +195 -0
- nl2sql/configs/__init__.py +6 -0
- nl2sql/configs/datasources.py +10 -0
- nl2sql/configs/llm.py +36 -0
- nl2sql/configs/manager.py +176 -0
- nl2sql/configs/policies.py +14 -0
- nl2sql/configs/sample_questions.py +11 -0
- nl2sql/configs/secrets.py +11 -0
- nl2sql/context.py +106 -0
- nl2sql/datasources/__init__.py +21 -0
- nl2sql/datasources/discovery.py +28 -0
- nl2sql/datasources/models.py +21 -0
- nl2sql/datasources/protocols.py +3 -0
- nl2sql/datasources/registry.py +172 -0
- nl2sql/evaluation/__init__.py +6 -0
- nl2sql/evaluation/benchmark_runner.py +320 -0
- nl2sql/evaluation/evaluator.py +134 -0
- nl2sql/evaluation/types.py +22 -0
- nl2sql/execution/__init__.py +4 -0
- nl2sql/execution/artifacts/__init__.py +3 -0
- nl2sql/execution/artifacts/parquet.py +41 -0
- nl2sql/execution/artifacts/store.py +165 -0
- nl2sql/execution/contracts.py +57 -0
- nl2sql/execution/execution_store.py +25 -0
- nl2sql/execution/executor/__init__.py +3 -0
- nl2sql/execution/executor/sql_executor.py +116 -0
- nl2sql/indexing/__init__.py +7 -0
- nl2sql/indexing/chunk_builder.py +227 -0
- nl2sql/indexing/embeddings.py +180 -0
- nl2sql/indexing/enrichment_service.py +316 -0
- nl2sql/indexing/models.py +209 -0
- nl2sql/indexing/orchestrator.py +90 -0
- nl2sql/indexing/vector_store.py +422 -0
- nl2sql/llm/__init__.py +8 -0
- nl2sql/llm/models.py +10 -0
- nl2sql/llm/registry.py +214 -0
- nl2sql/pipeline/__init__.py +1 -0
- nl2sql/pipeline/graph.py +73 -0
- nl2sql/pipeline/graph_utils.py +141 -0
- nl2sql/pipeline/nodes/__init__.py +25 -0
- nl2sql/pipeline/nodes/aggregator/__init__.py +4 -0
- nl2sql/pipeline/nodes/aggregator/node.py +55 -0
- nl2sql/pipeline/nodes/aggregator/prompts.py +20 -0
- nl2sql/pipeline/nodes/aggregator/schemas.py +28 -0
- nl2sql/pipeline/nodes/answer_synthesizer/__init__.py +4 -0
- nl2sql/pipeline/nodes/answer_synthesizer/node.py +98 -0
- nl2sql/pipeline/nodes/answer_synthesizer/prompts.py +19 -0
- nl2sql/pipeline/nodes/answer_synthesizer/schemas.py +24 -0
- nl2sql/pipeline/nodes/ast_planner/__init__.py +4 -0
- nl2sql/pipeline/nodes/ast_planner/node.py +104 -0
- nl2sql/pipeline/nodes/ast_planner/prompts.py +138 -0
- nl2sql/pipeline/nodes/ast_planner/schemas.py +236 -0
- nl2sql/pipeline/nodes/datasource_resolver/__init__.py +4 -0
- nl2sql/pipeline/nodes/datasource_resolver/node.py +253 -0
- nl2sql/pipeline/nodes/datasource_resolver/schemas.py +21 -0
- nl2sql/pipeline/nodes/decomposer/__init__.py +3 -0
- nl2sql/pipeline/nodes/decomposer/node.py +219 -0
- nl2sql/pipeline/nodes/decomposer/prompts.py +96 -0
- nl2sql/pipeline/nodes/decomposer/schemas.py +143 -0
- nl2sql/pipeline/nodes/executor/__init__.py +3 -0
- nl2sql/pipeline/nodes/executor/node.py +107 -0
- nl2sql/pipeline/nodes/generator/__init__.py +4 -0
- nl2sql/pipeline/nodes/generator/node.py +267 -0
- nl2sql/pipeline/nodes/generator/schemas.py +13 -0
- nl2sql/pipeline/nodes/global_planner/__init__.py +4 -0
- nl2sql/pipeline/nodes/global_planner/node.py +186 -0
- nl2sql/pipeline/nodes/global_planner/schemas.py +101 -0
- nl2sql/pipeline/nodes/refiner/__init__.py +4 -0
- nl2sql/pipeline/nodes/refiner/node.py +132 -0
- nl2sql/pipeline/nodes/refiner/prompts.py +28 -0
- nl2sql/pipeline/nodes/refiner/schemas.py +13 -0
- nl2sql/pipeline/nodes/schema_retriever/__init__.py +3 -0
- nl2sql/pipeline/nodes/schema_retriever/node.py +252 -0
- nl2sql/pipeline/nodes/schema_retriever/schema.py +27 -0
- nl2sql/pipeline/nodes/validator/__init__.py +7 -0
- nl2sql/pipeline/nodes/validator/node.py +839 -0
- nl2sql/pipeline/nodes/validator/schemas.py +12 -0
- nl2sql/pipeline/pipeline_runner.py +72 -0
- nl2sql/pipeline/routes.py +72 -0
- nl2sql/pipeline/runtime.py +153 -0
- nl2sql/pipeline/state.py +92 -0
- nl2sql/pipeline/subgraphs/__init__.py +5 -0
- nl2sql/pipeline/subgraphs/schemas.py +23 -0
- nl2sql/pipeline/subgraphs/sql_agent.py +167 -0
- nl2sql/public_api.py +199 -0
- nl2sql/schema/__init__.py +37 -0
- nl2sql/schema/in_memory_store.py +173 -0
- nl2sql/schema/protocol.py +88 -0
- nl2sql/schema/sqlite_store.py +233 -0
- nl2sql/schema/store.py +29 -0
- nl2sql/secrets/__init__.py +14 -0
- nl2sql/secrets/factory.py +85 -0
- nl2sql/secrets/interfaces.py +16 -0
- nl2sql/secrets/manager.py +139 -0
- nl2sql/secrets/models.py +56 -0
- nl2sql/secrets/providers/aws.py +30 -0
- nl2sql/secrets/providers/azure.py +49 -0
- nl2sql/secrets/providers/env.py +8 -0
- nl2sql/secrets/providers/hashi.py +46 -0
- nl2sql/services/__init__.py +0 -0
- nl2sql/services/callbacks/__init__.py +0 -0
- nl2sql/services/callbacks/monitor.py +84 -0
- nl2sql/services/callbacks/node_context.py +7 -0
- nl2sql/services/callbacks/node_handlers.py +187 -0
- nl2sql/services/callbacks/node_metrics.py +14 -0
- nl2sql/services/callbacks/presenter.py +12 -0
- nl2sql/services/callbacks/token_handler.py +56 -0
- nl2sql_engine-0.1.0.dist-info/METADATA +295 -0
- nl2sql_engine-0.1.0.dist-info/RECORD +192 -0
- nl2sql_engine-0.1.0.dist-info/WHEEL +5 -0
- nl2sql_engine-0.1.0.dist-info/entry_points.txt +9 -0
- nl2sql_engine-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
|
|
2
|
+
# Templates for Demo Environment Generation
|
|
3
|
+
|
|
4
|
+
REF_SQL_POSTGRES = """
|
|
5
|
+
CREATE TABLE factories (
|
|
6
|
+
id SERIAL PRIMARY KEY,
|
|
7
|
+
name TEXT,
|
|
8
|
+
region TEXT,
|
|
9
|
+
capacity INTEGER
|
|
10
|
+
);
|
|
11
|
+
CREATE TABLE machine_types (
|
|
12
|
+
id SERIAL PRIMARY KEY,
|
|
13
|
+
model TEXT,
|
|
14
|
+
producer TEXT,
|
|
15
|
+
maintenance_interval_days INTEGER
|
|
16
|
+
);
|
|
17
|
+
CREATE TABLE shifts (
|
|
18
|
+
id SERIAL PRIMARY KEY,
|
|
19
|
+
name TEXT,
|
|
20
|
+
start_time TEXT,
|
|
21
|
+
end_time TEXT
|
|
22
|
+
);
|
|
23
|
+
CREATE TABLE departments (
|
|
24
|
+
id SERIAL PRIMARY KEY,
|
|
25
|
+
name TEXT
|
|
26
|
+
);
|
|
27
|
+
CREATE TABLE employee_roles (
|
|
28
|
+
id SERIAL PRIMARY KEY,
|
|
29
|
+
title TEXT,
|
|
30
|
+
department_id INTEGER
|
|
31
|
+
);
|
|
32
|
+
CREATE TABLE customer_segments (
|
|
33
|
+
id SERIAL PRIMARY KEY,
|
|
34
|
+
name TEXT
|
|
35
|
+
);
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
REF_SQL_SQLITE = """
|
|
39
|
+
CREATE TABLE factories (
|
|
40
|
+
id INTEGER PRIMARY KEY,
|
|
41
|
+
name TEXT,
|
|
42
|
+
region TEXT,
|
|
43
|
+
capacity INTEGER
|
|
44
|
+
);
|
|
45
|
+
CREATE TABLE machine_types (
|
|
46
|
+
id INTEGER PRIMARY KEY,
|
|
47
|
+
model TEXT,
|
|
48
|
+
producer TEXT,
|
|
49
|
+
maintenance_interval_days INTEGER
|
|
50
|
+
);
|
|
51
|
+
CREATE TABLE shifts (
|
|
52
|
+
id INTEGER PRIMARY KEY,
|
|
53
|
+
name TEXT,
|
|
54
|
+
start_time TEXT,
|
|
55
|
+
end_time TEXT
|
|
56
|
+
);
|
|
57
|
+
CREATE TABLE departments (
|
|
58
|
+
id INTEGER PRIMARY KEY,
|
|
59
|
+
name TEXT
|
|
60
|
+
);
|
|
61
|
+
CREATE TABLE employee_roles (
|
|
62
|
+
id INTEGER PRIMARY KEY,
|
|
63
|
+
title TEXT,
|
|
64
|
+
department_id INTEGER
|
|
65
|
+
);
|
|
66
|
+
CREATE TABLE customer_segments (
|
|
67
|
+
id INTEGER PRIMARY KEY,
|
|
68
|
+
name TEXT
|
|
69
|
+
);
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
OPS_SQL_POSTGRES = """
|
|
73
|
+
CREATE TABLE employees (
|
|
74
|
+
id SERIAL PRIMARY KEY,
|
|
75
|
+
name TEXT,
|
|
76
|
+
factory_id INTEGER,
|
|
77
|
+
shift_id INTEGER,
|
|
78
|
+
hire_date DATE,
|
|
79
|
+
role_id INTEGER,
|
|
80
|
+
department_id INTEGER,
|
|
81
|
+
status TEXT
|
|
82
|
+
);
|
|
83
|
+
CREATE TABLE machines (
|
|
84
|
+
id SERIAL PRIMARY KEY,
|
|
85
|
+
factory_id INTEGER,
|
|
86
|
+
type_id INTEGER,
|
|
87
|
+
status TEXT DEFAULT 'Active',
|
|
88
|
+
installation_date DATE,
|
|
89
|
+
last_maintenance_date DATE
|
|
90
|
+
);
|
|
91
|
+
CREATE TABLE maintenance_logs (
|
|
92
|
+
id SERIAL PRIMARY KEY,
|
|
93
|
+
machine_id INTEGER,
|
|
94
|
+
date DATE,
|
|
95
|
+
description TEXT,
|
|
96
|
+
technician_id INTEGER,
|
|
97
|
+
severity TEXT,
|
|
98
|
+
downtime_hours INTEGER
|
|
99
|
+
);
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
OPS_SQL_SQLITE = """
|
|
103
|
+
CREATE TABLE employees (
|
|
104
|
+
id INTEGER PRIMARY KEY,
|
|
105
|
+
name TEXT,
|
|
106
|
+
factory_id INTEGER,
|
|
107
|
+
shift_id INTEGER,
|
|
108
|
+
hire_date DATE,
|
|
109
|
+
role_id INTEGER,
|
|
110
|
+
department_id INTEGER,
|
|
111
|
+
status TEXT
|
|
112
|
+
);
|
|
113
|
+
CREATE TABLE machines (
|
|
114
|
+
id INTEGER PRIMARY KEY,
|
|
115
|
+
factory_id INTEGER,
|
|
116
|
+
type_id INTEGER,
|
|
117
|
+
status TEXT,
|
|
118
|
+
installation_date DATE,
|
|
119
|
+
last_maintenance_date DATE
|
|
120
|
+
);
|
|
121
|
+
CREATE TABLE maintenance_logs (
|
|
122
|
+
id INTEGER PRIMARY KEY,
|
|
123
|
+
machine_id INTEGER,
|
|
124
|
+
date DATE,
|
|
125
|
+
description TEXT,
|
|
126
|
+
technician_id INTEGER,
|
|
127
|
+
severity TEXT,
|
|
128
|
+
downtime_hours INTEGER
|
|
129
|
+
);
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
SUPPLY_SQL_MYSQL = """
|
|
133
|
+
CREATE TABLE products (
|
|
134
|
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
135
|
+
sku VARCHAR(255),
|
|
136
|
+
name TEXT,
|
|
137
|
+
base_cost DECIMAL(10,2),
|
|
138
|
+
category VARCHAR(100)
|
|
139
|
+
);
|
|
140
|
+
CREATE TABLE suppliers (
|
|
141
|
+
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
142
|
+
name TEXT,
|
|
143
|
+
country VARCHAR(100)
|
|
144
|
+
);
|
|
145
|
+
CREATE TABLE inventory (
|
|
146
|
+
product_id INT,
|
|
147
|
+
factory_id INT,
|
|
148
|
+
quantity INT,
|
|
149
|
+
last_updated DATE,
|
|
150
|
+
PRIMARY KEY (product_id, factory_id)
|
|
151
|
+
);
|
|
152
|
+
CREATE TABLE supplier_products (
|
|
153
|
+
supplier_id INT,
|
|
154
|
+
product_id INT,
|
|
155
|
+
PRIMARY KEY (supplier_id, product_id)
|
|
156
|
+
);
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
SUPPLY_SQL_SQLITE = """
|
|
160
|
+
CREATE TABLE products (
|
|
161
|
+
id INTEGER PRIMARY KEY,
|
|
162
|
+
sku TEXT,
|
|
163
|
+
name TEXT,
|
|
164
|
+
base_cost REAL,
|
|
165
|
+
category TEXT
|
|
166
|
+
);
|
|
167
|
+
CREATE TABLE suppliers (
|
|
168
|
+
id INTEGER PRIMARY KEY,
|
|
169
|
+
name TEXT,
|
|
170
|
+
country TEXT
|
|
171
|
+
);
|
|
172
|
+
CREATE TABLE inventory (
|
|
173
|
+
product_id INTEGER,
|
|
174
|
+
factory_id INTEGER,
|
|
175
|
+
quantity INTEGER,
|
|
176
|
+
last_updated DATE,
|
|
177
|
+
PRIMARY KEY (product_id, factory_id)
|
|
178
|
+
);
|
|
179
|
+
CREATE TABLE supplier_products (
|
|
180
|
+
supplier_id INTEGER,
|
|
181
|
+
product_id INTEGER,
|
|
182
|
+
PRIMARY KEY (supplier_id, product_id)
|
|
183
|
+
);
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
HISTORY_SQL_MSSQL = """
|
|
187
|
+
CREATE TABLE sales_orders (
|
|
188
|
+
id INT IDENTITY(1,1) PRIMARY KEY,
|
|
189
|
+
customer_name NVARCHAR(255),
|
|
190
|
+
order_date DATE,
|
|
191
|
+
total_amount DECIMAL(12,2),
|
|
192
|
+
status NVARCHAR(50),
|
|
193
|
+
customer_segment_id INT,
|
|
194
|
+
factory_id INT
|
|
195
|
+
);
|
|
196
|
+
CREATE TABLE sales_items (
|
|
197
|
+
id INT IDENTITY(1,1) PRIMARY KEY,
|
|
198
|
+
order_id INT,
|
|
199
|
+
product_id INT,
|
|
200
|
+
quantity INT,
|
|
201
|
+
unit_price DECIMAL(10,2),
|
|
202
|
+
discount_pct DECIMAL(5,2)
|
|
203
|
+
);
|
|
204
|
+
CREATE TABLE production_runs (
|
|
205
|
+
id INT IDENTITY(1,1) PRIMARY KEY,
|
|
206
|
+
factory_id INT,
|
|
207
|
+
date DATE,
|
|
208
|
+
output_quantity INT,
|
|
209
|
+
shift_id INT,
|
|
210
|
+
status NVARCHAR(50)
|
|
211
|
+
);
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
HISTORY_SQL_SQLITE = """
|
|
215
|
+
CREATE TABLE sales_orders (
|
|
216
|
+
id INTEGER PRIMARY KEY,
|
|
217
|
+
customer_name TEXT,
|
|
218
|
+
order_date DATE,
|
|
219
|
+
total_amount REAL,
|
|
220
|
+
status TEXT,
|
|
221
|
+
customer_segment_id INTEGER,
|
|
222
|
+
factory_id INTEGER
|
|
223
|
+
);
|
|
224
|
+
CREATE TABLE sales_items (
|
|
225
|
+
id INTEGER PRIMARY KEY,
|
|
226
|
+
order_id INTEGER,
|
|
227
|
+
product_id INTEGER,
|
|
228
|
+
quantity INTEGER,
|
|
229
|
+
unit_price REAL,
|
|
230
|
+
discount_pct REAL
|
|
231
|
+
);
|
|
232
|
+
CREATE TABLE production_runs (
|
|
233
|
+
id INTEGER PRIMARY KEY,
|
|
234
|
+
factory_id INTEGER,
|
|
235
|
+
date DATE,
|
|
236
|
+
output_quantity INTEGER,
|
|
237
|
+
shift_id INTEGER,
|
|
238
|
+
status TEXT
|
|
239
|
+
);
|
|
240
|
+
"""
|
|
241
|
+
|
|
242
|
+
DOCKER_COMPOSE_TEMPLATE = """version: '3.8'
|
|
243
|
+
|
|
244
|
+
services:
|
|
245
|
+
manufacturing_ref:
|
|
246
|
+
image: postgres:15
|
|
247
|
+
container_name: manufacturing_ref
|
|
248
|
+
ports:
|
|
249
|
+
- "5433:5432"
|
|
250
|
+
environment:
|
|
251
|
+
POSTGRES_USER: ${DEMO_POSTGRES_USER}
|
|
252
|
+
POSTGRES_PASSWORD: ${DEMO_POSTGRES_PASSWORD}
|
|
253
|
+
POSTGRES_DB: manufacturing_ref
|
|
254
|
+
# Env vars for Init Scripts
|
|
255
|
+
DEMO_REF_USER: ${DEMO_REF_USER}
|
|
256
|
+
DEMO_REF_PASSWORD: ${DEMO_REF_PASSWORD}
|
|
257
|
+
volumes:
|
|
258
|
+
- ./init_ref.sql:/docker-entrypoint-initdb.d/init.sql
|
|
259
|
+
healthcheck:
|
|
260
|
+
test: ["CMD-SHELL", "pg_isready -U ${DEMO_POSTGRES_USER}"]
|
|
261
|
+
interval: 5s
|
|
262
|
+
retries: 5
|
|
263
|
+
|
|
264
|
+
manufacturing_ops:
|
|
265
|
+
image: postgres:15
|
|
266
|
+
container_name: manufacturing_ops
|
|
267
|
+
ports:
|
|
268
|
+
- "5434:5432"
|
|
269
|
+
environment:
|
|
270
|
+
POSTGRES_USER: ${DEMO_POSTGRES_USER}
|
|
271
|
+
POSTGRES_PASSWORD: ${DEMO_POSTGRES_PASSWORD}
|
|
272
|
+
POSTGRES_DB: manufacturing_ops
|
|
273
|
+
# Env vars for Init Scripts
|
|
274
|
+
DEMO_OPS_USER: ${DEMO_OPS_USER}
|
|
275
|
+
DEMO_OPS_PASSWORD: ${DEMO_OPS_PASSWORD}
|
|
276
|
+
volumes:
|
|
277
|
+
- ./init_ops.sql:/docker-entrypoint-initdb.d/init.sql
|
|
278
|
+
healthcheck:
|
|
279
|
+
test: ["CMD-SHELL", "pg_isready -U ${DEMO_POSTGRES_USER}"]
|
|
280
|
+
interval: 5s
|
|
281
|
+
retries: 5
|
|
282
|
+
|
|
283
|
+
manufacturing_supply:
|
|
284
|
+
image: mysql:8
|
|
285
|
+
container_name: manufacturing_supply
|
|
286
|
+
ports:
|
|
287
|
+
- "3307:3306"
|
|
288
|
+
environment:
|
|
289
|
+
MYSQL_ROOT_PASSWORD: ${DEMO_MYSQL_ROOT_PASSWORD}
|
|
290
|
+
MYSQL_USER: ${DEMO_SUPPLY_USER}
|
|
291
|
+
MYSQL_PASSWORD: ${DEMO_SUPPLY_PASSWORD}
|
|
292
|
+
MYSQL_DATABASE: manufacturing_supply
|
|
293
|
+
volumes:
|
|
294
|
+
- ./init_supply.sql:/docker-entrypoint-initdb.d/init.sql
|
|
295
|
+
healthcheck:
|
|
296
|
+
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
|
297
|
+
interval: 5s
|
|
298
|
+
retries: 5
|
|
299
|
+
|
|
300
|
+
# Opt-in: `docker compose --profile mssql up`. The image is a ~1.6 GB pull, so
|
|
301
|
+
# the default stack leaves it out. Nothing outside this profile depends on it.
|
|
302
|
+
manufacturing_history:
|
|
303
|
+
image: mcr.microsoft.com/mssql/server:2022-latest
|
|
304
|
+
container_name: manufacturing_history
|
|
305
|
+
profiles: ["mssql"]
|
|
306
|
+
ports:
|
|
307
|
+
- "1434:1433"
|
|
308
|
+
environment:
|
|
309
|
+
ACCEPT_EULA: "Y"
|
|
310
|
+
MSSQL_SA_PASSWORD: "${DEMO_MSSQL_SA_PASSWORD}"
|
|
311
|
+
MSSQL_PID: "Express"
|
|
312
|
+
user: root # Needed to run the init script wrapper if we mount it
|
|
313
|
+
command: /bin/bash -c "/opt/mssql/bin/sqlservr & sleep 20 && /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P '${DEMO_MSSQL_SA_PASSWORD}' -i /init.sql -v HISTORY_USER='${DEMO_HISTORY_USER}' HISTORY_PASS='${DEMO_HISTORY_PASSWORD}' && wait"
|
|
314
|
+
volumes:
|
|
315
|
+
- ./init_history.sql:/init.sql
|
|
316
|
+
|
|
317
|
+
app:
|
|
318
|
+
build:
|
|
319
|
+
context: ..
|
|
320
|
+
dockerfile: packages/api/Dockerfile
|
|
321
|
+
container_name: nl2sql_app
|
|
322
|
+
ports:
|
|
323
|
+
- "8000:8000"
|
|
324
|
+
env_file:
|
|
325
|
+
- ../.env.demo
|
|
326
|
+
volumes:
|
|
327
|
+
- ../configs:/app/configs
|
|
328
|
+
- ../data:/app/data
|
|
329
|
+
depends_on:
|
|
330
|
+
manufacturing_ref:
|
|
331
|
+
condition: service_healthy
|
|
332
|
+
manufacturing_ops:
|
|
333
|
+
condition: service_healthy
|
|
334
|
+
manufacturing_supply:
|
|
335
|
+
condition: service_healthy
|
|
336
|
+
"""
|
|
File without changes
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
|
|
2
|
+
import pathlib
|
|
3
|
+
from typing import List, Dict, Any
|
|
4
|
+
from ..schemas import (
|
|
5
|
+
REF_SQL_POSTGRES,
|
|
6
|
+
OPS_SQL_POSTGRES,
|
|
7
|
+
SUPPLY_SQL_MYSQL,
|
|
8
|
+
HISTORY_SQL_MSSQL,
|
|
9
|
+
DOCKER_COMPOSE_TEMPLATE
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
class DockerWriter:
|
|
13
|
+
"""Writes Demo Artifacts (SQL, .env, docker-compose) for Docker environment."""
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def write_docker(output_dir: pathlib.Path,
|
|
17
|
+
secrets: Dict[str, str],
|
|
18
|
+
ref_data: tuple,
|
|
19
|
+
ops_data: tuple,
|
|
20
|
+
supply_data: tuple,
|
|
21
|
+
history_data: tuple):
|
|
22
|
+
"""Main entry point."""
|
|
23
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
24
|
+
|
|
25
|
+
# Unpack
|
|
26
|
+
factories, mtypes, shifts, departments, roles, segments = ref_data
|
|
27
|
+
employees, machines, logs = ops_data
|
|
28
|
+
products, suppliers, inventory, supplier_products = supply_data
|
|
29
|
+
orders, items, runs = history_data
|
|
30
|
+
|
|
31
|
+
# 1. SQL Scripts
|
|
32
|
+
DockerWriter._write_sql(output_dir / "init_ref.sql", REF_SQL_POSTGRES, secrets["DEMO_REF_PASSWORD"], "ref_admin", "manufacturing_ref", {
|
|
33
|
+
"factories": factories,
|
|
34
|
+
"machine_types": mtypes,
|
|
35
|
+
"shifts": shifts,
|
|
36
|
+
"departments": departments,
|
|
37
|
+
"employee_roles": roles,
|
|
38
|
+
"customer_segments": segments
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
DockerWriter._write_sql(output_dir / "init_ops.sql", OPS_SQL_POSTGRES, secrets["DEMO_OPS_PASSWORD"], "ops_admin", "manufacturing_ops", {
|
|
42
|
+
"employees": employees, "machines": machines, "maintenance_logs": logs
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
DockerWriter._write_mysql(output_dir / "init_supply.sql", SUPPLY_SQL_MYSQL, {
|
|
46
|
+
"products": products, "suppliers": suppliers, "inventory": inventory, "supplier_products": supplier_products
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
DockerWriter._write_mssql(output_dir / "init_history.sql", HISTORY_SQL_MSSQL, secrets, {
|
|
50
|
+
"sales_orders": orders, "sales_items": items, "production_runs": runs
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
# 2. .env
|
|
54
|
+
DockerWriter._write_env(output_dir / ".env", secrets)
|
|
55
|
+
|
|
56
|
+
# 3. docker-compose
|
|
57
|
+
(output_dir / "docker-compose.demo.yml").write_text(DOCKER_COMPOSE_TEMPLATE, encoding="utf-8")
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
def _to_insert(table: str, rows: List[Dict]) -> str:
|
|
61
|
+
if not rows:
|
|
62
|
+
return ""
|
|
63
|
+
|
|
64
|
+
columns = ", ".join(rows[0].keys())
|
|
65
|
+
values_list = []
|
|
66
|
+
for r in rows:
|
|
67
|
+
vals = []
|
|
68
|
+
for v in r.values():
|
|
69
|
+
if isinstance(v, str):
|
|
70
|
+
clean = v.replace("'", "''") # Basic HTML escape for SQL
|
|
71
|
+
vals.append(f"'{clean}'")
|
|
72
|
+
else:
|
|
73
|
+
vals.append(str(v))
|
|
74
|
+
values_list.append(f"({', '.join(vals)})")
|
|
75
|
+
|
|
76
|
+
# Bulk Insert
|
|
77
|
+
# Postgres supports multi-value INSERT
|
|
78
|
+
return f"INSERT INTO {table} ({columns}) VALUES\n" + ",\n".join(values_list) + ";"
|
|
79
|
+
|
|
80
|
+
@staticmethod
|
|
81
|
+
def _write_sql(path: pathlib.Path, schema: str, password: str, user: str, db: str, data: Dict[str, List[Dict]]):
|
|
82
|
+
inserts = []
|
|
83
|
+
for tbl, rows in data.items():
|
|
84
|
+
inserts.append(DockerWriter._to_insert(tbl, rows))
|
|
85
|
+
|
|
86
|
+
inserts_str = "\n\n".join(inserts)
|
|
87
|
+
|
|
88
|
+
script = f"""
|
|
89
|
+
-- Create User and Database
|
|
90
|
+
CREATE USER {user} WITH PASSWORD '{password}';
|
|
91
|
+
CREATE DATABASE {db} OWNER {user};
|
|
92
|
+
|
|
93
|
+
-- Connect and Populate
|
|
94
|
+
\\c {db};
|
|
95
|
+
|
|
96
|
+
{schema}
|
|
97
|
+
|
|
98
|
+
{inserts_str}
|
|
99
|
+
|
|
100
|
+
-- Grant Ownership
|
|
101
|
+
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO {user};
|
|
102
|
+
"""
|
|
103
|
+
path.write_text(script, encoding="utf-8")
|
|
104
|
+
|
|
105
|
+
@staticmethod
|
|
106
|
+
def _write_mysql(path: pathlib.Path, schema: str, data: Dict[str, List[Dict]]):
|
|
107
|
+
inserts = []
|
|
108
|
+
for tbl, rows in data.items():
|
|
109
|
+
inserts.append(DockerWriter._to_insert(tbl, rows))
|
|
110
|
+
|
|
111
|
+
inserts_str = "\n\n".join(inserts)
|
|
112
|
+
|
|
113
|
+
script = f"""
|
|
114
|
+
CREATE DATABASE IF NOT EXISTS manufacturing_supply;
|
|
115
|
+
USE manufacturing_supply;
|
|
116
|
+
|
|
117
|
+
{schema}
|
|
118
|
+
|
|
119
|
+
{inserts_str}
|
|
120
|
+
"""
|
|
121
|
+
path.write_text(script, encoding="utf-8")
|
|
122
|
+
|
|
123
|
+
@staticmethod
|
|
124
|
+
def _write_mssql(path: pathlib.Path, schema: str, secrets: Dict[str, str], data: Dict[str, List[Dict]]):
|
|
125
|
+
inserts = []
|
|
126
|
+
for tbl, rows in data.items():
|
|
127
|
+
inserts.append(DockerWriter._to_insert(tbl, rows))
|
|
128
|
+
|
|
129
|
+
inserts_str = "\nGO\n".join(inserts)
|
|
130
|
+
|
|
131
|
+
script = f"""
|
|
132
|
+
IF NOT EXISTS(SELECT * FROM sys.databases WHERE name = 'manufacturing_history')
|
|
133
|
+
BEGIN
|
|
134
|
+
CREATE DATABASE manufacturing_history
|
|
135
|
+
END
|
|
136
|
+
GO
|
|
137
|
+
USE manufacturing_history;
|
|
138
|
+
GO
|
|
139
|
+
|
|
140
|
+
-- Create User (Passed via sqlcmd -v vars)
|
|
141
|
+
CREATE LOGIN [$(HISTORY_USER)] WITH PASSWORD = '$(HISTORY_PASS)';
|
|
142
|
+
CREATE USER [$(HISTORY_USER)] FOR LOGIN [$(HISTORY_USER)];
|
|
143
|
+
ALTER ROLE [db_owner] ADD MEMBER [$(HISTORY_USER)];
|
|
144
|
+
GO
|
|
145
|
+
|
|
146
|
+
{schema}
|
|
147
|
+
GO
|
|
148
|
+
|
|
149
|
+
{inserts_str}
|
|
150
|
+
GO
|
|
151
|
+
"""
|
|
152
|
+
path.write_text(script, encoding="utf-8")
|
|
153
|
+
|
|
154
|
+
@staticmethod
|
|
155
|
+
def _write_env(path: pathlib.Path, secrets: Dict[str, str]):
|
|
156
|
+
# Matches the template we removed
|
|
157
|
+
content = f"""# NL2SQL Demo Environment Secrets
|
|
158
|
+
# Generated automatically. DO NOT COMMIT TO VERSION CONTROL.
|
|
159
|
+
|
|
160
|
+
# 1. Manufacturing Ref (Postgres)
|
|
161
|
+
DEMO_REF_USER=ref_admin
|
|
162
|
+
DEMO_REF_PASSWORD={secrets["DEMO_REF_PASSWORD"]}
|
|
163
|
+
|
|
164
|
+
# 2. Manufacturing Ops (Postgres)
|
|
165
|
+
DEMO_OPS_USER=ops_admin
|
|
166
|
+
DEMO_OPS_PASSWORD={secrets["DEMO_OPS_PASSWORD"]}
|
|
167
|
+
|
|
168
|
+
# Postgres Superuser (Container Root)
|
|
169
|
+
DEMO_POSTGRES_USER=postgres
|
|
170
|
+
DEMO_POSTGRES_PASSWORD={secrets["DEMO_POSTGRES_PASSWORD"]}
|
|
171
|
+
|
|
172
|
+
# 3. Manufacturing Supply (MySQL)
|
|
173
|
+
DEMO_SUPPLY_USER=supply_admin
|
|
174
|
+
DEMO_SUPPLY_PASSWORD={secrets["DEMO_SUPPLY_PASSWORD"]}
|
|
175
|
+
DEMO_MYSQL_ROOT_PASSWORD={secrets["DEMO_MYSQL_ROOT_PASSWORD"]}
|
|
176
|
+
|
|
177
|
+
# 4. Manufacturing History (MSSQL)
|
|
178
|
+
DEMO_HISTORY_USER=history_admin
|
|
179
|
+
DEMO_HISTORY_PASSWORD={secrets["DEMO_HISTORY_PASSWORD"]}
|
|
180
|
+
DEMO_MSSQL_SA_PASSWORD={secrets["DEMO_MSSQL_SA_PASSWORD"]}
|
|
181
|
+
"""
|
|
182
|
+
path.write_text(content, encoding="utf-8")
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
|
|
2
|
+
import sqlite3
|
|
3
|
+
import pathlib
|
|
4
|
+
from typing import List, Dict
|
|
5
|
+
from ..schemas import (
|
|
6
|
+
REF_SQL_SQLITE,
|
|
7
|
+
OPS_SQL_SQLITE,
|
|
8
|
+
SUPPLY_SQL_SQLITE,
|
|
9
|
+
HISTORY_SQL_SQLITE
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
class SQLiteWriter:
|
|
13
|
+
"""Writes Demo Data to SQLite databases."""
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def write_lite(output_dir: pathlib.Path,
|
|
17
|
+
ref_data: tuple,
|
|
18
|
+
ops_data: tuple,
|
|
19
|
+
supply_data: tuple,
|
|
20
|
+
history_data: tuple):
|
|
21
|
+
"""Main entry point to write all 4 databases."""
|
|
22
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
23
|
+
|
|
24
|
+
# Unpack Data
|
|
25
|
+
factories, mtypes, shifts, departments, roles, segments = ref_data
|
|
26
|
+
employees, machines, logs = ops_data
|
|
27
|
+
products, suppliers, inventory, supplier_products = supply_data
|
|
28
|
+
orders, items, runs = history_data
|
|
29
|
+
|
|
30
|
+
# 1. Ref
|
|
31
|
+
SQLiteWriter._create_db(output_dir / "manufacturing_ref.db", REF_SQL_SQLITE, {
|
|
32
|
+
"factories": factories,
|
|
33
|
+
"machine_types": mtypes,
|
|
34
|
+
"shifts": shifts,
|
|
35
|
+
"departments": departments,
|
|
36
|
+
"employee_roles": roles,
|
|
37
|
+
"customer_segments": segments
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
# 2. Ops
|
|
41
|
+
SQLiteWriter._create_db(output_dir / "manufacturing_ops.db", OPS_SQL_SQLITE, {
|
|
42
|
+
"employees": employees,
|
|
43
|
+
"machines": machines,
|
|
44
|
+
"maintenance_logs": logs
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
# 3. Supply
|
|
48
|
+
SQLiteWriter._create_db(output_dir / "manufacturing_supply.db", SUPPLY_SQL_SQLITE, {
|
|
49
|
+
"products": products,
|
|
50
|
+
"suppliers": suppliers,
|
|
51
|
+
"inventory": inventory,
|
|
52
|
+
"supplier_products": supplier_products
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
# 4. History
|
|
56
|
+
SQLiteWriter._create_db(output_dir / "manufacturing_history.db", HISTORY_SQL_SQLITE, {
|
|
57
|
+
"sales_orders": orders,
|
|
58
|
+
"sales_items": items,
|
|
59
|
+
"production_runs": runs
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
@staticmethod
|
|
63
|
+
def _create_db(path: pathlib.Path, schema_sql: str, data_map: Dict[str, List[Dict]]):
|
|
64
|
+
"""Creates a DB, runs schema, and inserts data."""
|
|
65
|
+
if path.exists():
|
|
66
|
+
path.unlink()
|
|
67
|
+
|
|
68
|
+
conn = sqlite3.connect(str(path))
|
|
69
|
+
cursor = conn.cursor()
|
|
70
|
+
|
|
71
|
+
# 1. Schema
|
|
72
|
+
cursor.executescript(schema_sql)
|
|
73
|
+
|
|
74
|
+
# 2. Data
|
|
75
|
+
for table_name, rows in data_map.items():
|
|
76
|
+
if not rows:
|
|
77
|
+
continue
|
|
78
|
+
|
|
79
|
+
# Assume all rows have same keys
|
|
80
|
+
keys = list(rows[0].keys())
|
|
81
|
+
cols = ", ".join(keys)
|
|
82
|
+
placeholders = ", ".join(f":{k}" for k in keys)
|
|
83
|
+
sql = f"INSERT INTO {table_name} ({cols}) VALUES ({placeholders})"
|
|
84
|
+
|
|
85
|
+
cursor.executemany(sql, rows)
|
|
86
|
+
|
|
87
|
+
conn.commit()
|
|
88
|
+
conn.close()
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import yaml
|
|
2
|
+
from nl2sql.configs import DatasourceFileConfig
|
|
3
|
+
|
|
4
|
+
class DatasourceGenerator:
|
|
5
|
+
"""Generates the content for datasources.yaml."""
|
|
6
|
+
|
|
7
|
+
HEADER = "# NL2SQL Datasource Configuration\n\n"
|
|
8
|
+
|
|
9
|
+
@staticmethod
|
|
10
|
+
def generate(config: DatasourceFileConfig) -> str:
|
|
11
|
+
"""
|
|
12
|
+
Generates YAML content for Datasource configuration.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
config: DatasourceFileConfig object (Envelope).
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
Formatted YAML string.
|
|
19
|
+
"""
|
|
20
|
+
dumped_config = config.model_dump(exclude_none=True)
|
|
21
|
+
|
|
22
|
+
yaml_block = yaml.safe_dump(dumped_config, sort_keys=False)
|
|
23
|
+
|
|
24
|
+
return DatasourceGenerator.HEADER + yaml_block
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from typing import Dict, Optional
|
|
2
|
+
from .templates import ENV_FILE_TEMPLATE, ENV_SECRETS_HEADER, ENV_SPECIFIC_SETTINGS
|
|
3
|
+
|
|
4
|
+
class EnvFileGenerator:
|
|
5
|
+
"""Standard generator for .env files complying with Universal Environment Protocol."""
|
|
6
|
+
|
|
7
|
+
@staticmethod
|
|
8
|
+
def generate(env: str, secrets: Optional[Dict[str, str]] = None) -> str:
|
|
9
|
+
"""Generates the content for a .env.<env> file.
|
|
10
|
+
|
|
11
|
+
This method constructs the standard configuration paths based on the
|
|
12
|
+
environment name and optionally appends provided secrets.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
env: The environment name (e.g., 'dev', 'demo', 'prod').
|
|
16
|
+
secrets: Optional dictionary of secret key-values to append.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
The formatted string content for the .env file.
|
|
20
|
+
"""
|
|
21
|
+
suffix = f".{env}" if env != "dev" else ""
|
|
22
|
+
|
|
23
|
+
# Populate template
|
|
24
|
+
content = ENV_FILE_TEMPLATE.format(env=env, suffix=suffix)
|
|
25
|
+
content += ENV_SPECIFIC_SETTINGS.get(env, "")
|
|
26
|
+
content += ENV_SECRETS_HEADER
|
|
27
|
+
|
|
28
|
+
used_keys = set()
|
|
29
|
+
|
|
30
|
+
if secrets:
|
|
31
|
+
for key, value in secrets.items():
|
|
32
|
+
content += f"{key}={value}\n"
|
|
33
|
+
used_keys.add(key)
|
|
34
|
+
|
|
35
|
+
critical_placeholders = ["OPENAI_API_KEY"]
|
|
36
|
+
appended_placeholders = False
|
|
37
|
+
|
|
38
|
+
for ph in critical_placeholders:
|
|
39
|
+
if ph not in used_keys:
|
|
40
|
+
content += f"{ph}=\n"
|
|
41
|
+
appended_placeholders = True
|
|
42
|
+
|
|
43
|
+
if appended_placeholders and not secrets:
|
|
44
|
+
content += "# Please fill in the required secrets above.\n"
|
|
45
|
+
|
|
46
|
+
return content
|