relationalai 1.0.0a3__py3-none-any.whl → 1.0.0a4__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.
- relationalai/config/shims.py +1 -0
- relationalai/semantics/__init__.py +7 -1
- relationalai/semantics/frontend/base.py +19 -13
- relationalai/semantics/frontend/core.py +30 -2
- relationalai/semantics/frontend/front_compiler.py +38 -11
- relationalai/semantics/frontend/pprint.py +1 -1
- relationalai/semantics/metamodel/rewriter.py +6 -2
- relationalai/semantics/metamodel/typer.py +70 -26
- relationalai/semantics/reasoners/__init__.py +11 -0
- relationalai/semantics/reasoners/graph/__init__.py +38 -0
- relationalai/semantics/reasoners/graph/core.py +9015 -0
- relationalai/shims/hoister.py +9 -0
- relationalai/shims/mm2v0.py +32 -24
- relationalai/tools/cli/cli.py +138 -0
- relationalai/tools/cli/docs.py +394 -0
- {relationalai-1.0.0a3.dist-info → relationalai-1.0.0a4.dist-info}/METADATA +5 -3
- {relationalai-1.0.0a3.dist-info → relationalai-1.0.0a4.dist-info}/RECORD +29 -24
- v0/relationalai/clients/exec_txn_poller.py +91 -0
- v0/relationalai/clients/resources/snowflake/__init__.py +2 -2
- v0/relationalai/clients/resources/snowflake/direct_access_resources.py +16 -10
- v0/relationalai/clients/resources/snowflake/snowflake.py +43 -14
- v0/relationalai/clients/resources/snowflake/use_index_poller.py +8 -0
- v0/relationalai/errors.py +18 -0
- v0/relationalai/semantics/lqp/executor.py +3 -1
- v0/relationalai/semantics/lqp/rewrite/extract_keys.py +25 -3
- v0/relationalai/semantics/reasoners/optimization/solvers_pb.py +335 -84
- {relationalai-1.0.0a3.dist-info → relationalai-1.0.0a4.dist-info}/WHEEL +0 -0
- {relationalai-1.0.0a3.dist-info → relationalai-1.0.0a4.dist-info}/entry_points.txt +0 -0
- {relationalai-1.0.0a3.dist-info → relationalai-1.0.0a4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Documentation generation and serving utilities.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import shutil
|
|
8
|
+
import subprocess
|
|
9
|
+
import webbrowser
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Optional
|
|
12
|
+
|
|
13
|
+
import click
|
|
14
|
+
from rich.console import Console
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def find_docs_dir() -> Path:
|
|
20
|
+
"""Find the documentation source directory."""
|
|
21
|
+
# Try multiple possible locations
|
|
22
|
+
possible_paths = [
|
|
23
|
+
Path("docs"), # Root level
|
|
24
|
+
Path(__file__).parent.parent.parent.parent / "docs", # From this file
|
|
25
|
+
Path.cwd() / "docs", # Current working directory
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
for path in possible_paths:
|
|
29
|
+
if path.exists() and (path / "package.json").exists():
|
|
30
|
+
return path.resolve()
|
|
31
|
+
|
|
32
|
+
raise click.ClickException(
|
|
33
|
+
"Documentation source directory not found. "
|
|
34
|
+
"Expected 'docs/' directory with package.json"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def has_nodejs() -> bool:
|
|
39
|
+
"""Check if Node.js is installed."""
|
|
40
|
+
try:
|
|
41
|
+
subprocess.run(
|
|
42
|
+
["node", "--version"],
|
|
43
|
+
capture_output=True,
|
|
44
|
+
text=True,
|
|
45
|
+
check=True,
|
|
46
|
+
)
|
|
47
|
+
return True
|
|
48
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def has_npm() -> bool:
|
|
53
|
+
"""Check if npm is installed."""
|
|
54
|
+
try:
|
|
55
|
+
subprocess.run(
|
|
56
|
+
["npm", "--version"],
|
|
57
|
+
capture_output=True,
|
|
58
|
+
text=True,
|
|
59
|
+
check=True,
|
|
60
|
+
)
|
|
61
|
+
return True
|
|
62
|
+
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def print_generation_success(output_path: Path) -> None:
|
|
67
|
+
"""
|
|
68
|
+
Print success message after documentation generation.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
output_path: Path to the generated documentation output directory
|
|
72
|
+
"""
|
|
73
|
+
console.print("[green]✓ Documentation generated")
|
|
74
|
+
console.print()
|
|
75
|
+
console.print("[cyan]The documentation site is ready to host![/cyan]")
|
|
76
|
+
console.print(f"[dim]Output location: {output_path}[/dim]")
|
|
77
|
+
console.print()
|
|
78
|
+
console.print("[yellow]You can serve it locally with:[/yellow]")
|
|
79
|
+
console.print(" [bold]rai docs serve[/bold]")
|
|
80
|
+
console.print()
|
|
81
|
+
console.print("[yellow]Or host the dist folder directly:[/yellow]")
|
|
82
|
+
console.print(
|
|
83
|
+
"[dim]The dist folder contains a complete static website. You can copy it to any "
|
|
84
|
+
"web server (Nginx, Apache, Flask, etc.), upload it to a CDN, or deploy it to "
|
|
85
|
+
"static hosting services like GitHub Pages, Netlify, or Vercel. All files use "
|
|
86
|
+
"relative paths, so it works regardless of where it's hosted.[/dim]"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def generate_docs(
|
|
91
|
+
output_dir: Optional[str] = None,
|
|
92
|
+
docs_dir: Optional[Path] = None,
|
|
93
|
+
) -> Path:
|
|
94
|
+
"""
|
|
95
|
+
Generate static documentation site.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
output_dir: Optional output directory (defaults to docs/dist)
|
|
99
|
+
docs_dir: Optional path to docs directory
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
Path to the generated output directory
|
|
103
|
+
"""
|
|
104
|
+
if docs_dir is None:
|
|
105
|
+
docs_dir = find_docs_dir()
|
|
106
|
+
|
|
107
|
+
# Check prerequisites
|
|
108
|
+
if not has_nodejs():
|
|
109
|
+
raise click.ClickException(
|
|
110
|
+
"Node.js is not installed. "
|
|
111
|
+
"Please install Node.js from https://nodejs.org/"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
if not has_npm():
|
|
115
|
+
raise click.ClickException(
|
|
116
|
+
"npm is not installed. "
|
|
117
|
+
"npm should come with Node.js installation."
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# Check if package.json exists
|
|
121
|
+
package_json = docs_dir / "package.json"
|
|
122
|
+
if not package_json.exists():
|
|
123
|
+
raise click.ClickException(
|
|
124
|
+
f"package.json not found in {docs_dir}. "
|
|
125
|
+
"This doesn't appear to be a valid SolidJS project."
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# Install dependencies if node_modules doesn't exist
|
|
129
|
+
node_modules = docs_dir / "node_modules"
|
|
130
|
+
if not node_modules.exists():
|
|
131
|
+
console.print("[blue]Installing dependencies...[/blue]")
|
|
132
|
+
try:
|
|
133
|
+
subprocess.run(
|
|
134
|
+
["npm", "install"],
|
|
135
|
+
cwd=docs_dir,
|
|
136
|
+
check=True,
|
|
137
|
+
stdout=subprocess.PIPE,
|
|
138
|
+
stderr=subprocess.PIPE,
|
|
139
|
+
)
|
|
140
|
+
console.print("[green]✓ Dependencies installed[/green]")
|
|
141
|
+
except subprocess.CalledProcessError as e:
|
|
142
|
+
error_msg = e.stderr.decode() if e.stderr else "Unknown error"
|
|
143
|
+
raise click.ClickException(
|
|
144
|
+
f"Failed to install dependencies: {error_msg}"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# Build the documentation
|
|
148
|
+
console.print("[blue]Building documentation site...[/blue]")
|
|
149
|
+
try:
|
|
150
|
+
subprocess.run(
|
|
151
|
+
["npm", "run", "build"],
|
|
152
|
+
cwd=docs_dir,
|
|
153
|
+
check=True,
|
|
154
|
+
capture_output=True,
|
|
155
|
+
text=True,
|
|
156
|
+
)
|
|
157
|
+
console.print("[green]✓ Build completed successfully[/green]")
|
|
158
|
+
except subprocess.CalledProcessError as e:
|
|
159
|
+
error_msg = e.stderr if e.stderr else e.stdout if e.stdout else "Unknown error"
|
|
160
|
+
console.print(f"[red]Build error output:[/red]\n{error_msg}")
|
|
161
|
+
raise click.ClickException(f"Build failed: {error_msg}")
|
|
162
|
+
|
|
163
|
+
# Determine output directory
|
|
164
|
+
build_output = docs_dir / "dist"
|
|
165
|
+
if not build_output.exists():
|
|
166
|
+
raise click.ClickException(
|
|
167
|
+
"Build output directory not found. "
|
|
168
|
+
"Build may have failed."
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
# Copy to custom output directory if specified
|
|
172
|
+
if output_dir:
|
|
173
|
+
output_path = Path(output_dir).resolve()
|
|
174
|
+
if output_path.exists():
|
|
175
|
+
console.print(f"[yellow]Output directory '{output_path}' exists. Cleaning...[/yellow]")
|
|
176
|
+
shutil.rmtree(output_path)
|
|
177
|
+
shutil.copytree(build_output, output_path)
|
|
178
|
+
print_generation_success(output_path)
|
|
179
|
+
return output_path
|
|
180
|
+
|
|
181
|
+
print_generation_success(build_output)
|
|
182
|
+
return build_output
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def serve_docs(
|
|
186
|
+
build_dir: str,
|
|
187
|
+
host: str = "127.0.0.1",
|
|
188
|
+
port: int = 8000,
|
|
189
|
+
open_browser: bool = True,
|
|
190
|
+
) -> None:
|
|
191
|
+
"""
|
|
192
|
+
Serve generated documentation site.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
build_dir: Directory containing built documentation
|
|
196
|
+
host: Host to bind to
|
|
197
|
+
port: Port to serve on
|
|
198
|
+
open_browser: Whether to open browser automatically
|
|
199
|
+
"""
|
|
200
|
+
build_path = Path(build_dir).resolve()
|
|
201
|
+
|
|
202
|
+
if not build_path.exists():
|
|
203
|
+
raise click.ClickException(
|
|
204
|
+
"Build directory does not exist. "
|
|
205
|
+
"Run 'rai docs generate' first."
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
index_html = build_path / "index.html"
|
|
209
|
+
if not index_html.exists():
|
|
210
|
+
raise click.ClickException(
|
|
211
|
+
"index.html not found. "
|
|
212
|
+
"This doesn't appear to be a valid build directory. "
|
|
213
|
+
"Run 'rai docs generate' first."
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
# Import FastAPI here to avoid requiring it if not using server
|
|
217
|
+
try:
|
|
218
|
+
from fastapi import FastAPI
|
|
219
|
+
from fastapi.staticfiles import StaticFiles
|
|
220
|
+
import uvicorn
|
|
221
|
+
except ImportError:
|
|
222
|
+
raise click.ClickException(
|
|
223
|
+
"FastAPI and uvicorn are required for serving documentation. "
|
|
224
|
+
"Install with: pip install fastapi uvicorn"
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
app = FastAPI(title="RAI Documentation")
|
|
228
|
+
app.mount("/", StaticFiles(directory=str(build_path), html=True), name="static")
|
|
229
|
+
|
|
230
|
+
url = f"http://{host}:{port}"
|
|
231
|
+
console.print(f"[green]✓ Documentation server running at {url}[/green]")
|
|
232
|
+
console.print("[yellow]Press Ctrl+C to stop the server[/yellow]")
|
|
233
|
+
|
|
234
|
+
if open_browser:
|
|
235
|
+
try:
|
|
236
|
+
webbrowser.open(url)
|
|
237
|
+
except Exception:
|
|
238
|
+
console.print(f"[yellow]Could not open browser automatically. Visit {url}[/yellow]")
|
|
239
|
+
|
|
240
|
+
try:
|
|
241
|
+
uvicorn.run(app, host=host, port=port, log_level="warning")
|
|
242
|
+
except KeyboardInterrupt:
|
|
243
|
+
console.print("\n[yellow]Server stopped[/yellow]")
|
|
244
|
+
except OSError as e:
|
|
245
|
+
if "Address already in use" in str(e):
|
|
246
|
+
raise click.ClickException(
|
|
247
|
+
f"Port {port} is already in use. "
|
|
248
|
+
"Try a different port with --port option."
|
|
249
|
+
)
|
|
250
|
+
raise
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def dev_docs(
|
|
254
|
+
docs_dir: Optional[Path] = None,
|
|
255
|
+
host: str = "127.0.0.1",
|
|
256
|
+
port: int = 5173,
|
|
257
|
+
open_browser: bool = True,
|
|
258
|
+
) -> None:
|
|
259
|
+
"""
|
|
260
|
+
Start development server with hot module replacement.
|
|
261
|
+
|
|
262
|
+
This runs Vite's dev server, which provides:
|
|
263
|
+
- Hot module replacement (HMR) - changes reflect instantly
|
|
264
|
+
- Fast refresh - no need to rebuild on every change
|
|
265
|
+
- Source maps for debugging
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
docs_dir: Optional path to docs directory
|
|
269
|
+
host: Host to bind to
|
|
270
|
+
port: Port to serve on (default: 5173, Vite's default)
|
|
271
|
+
open_browser: Whether to open browser automatically
|
|
272
|
+
"""
|
|
273
|
+
if docs_dir is None:
|
|
274
|
+
docs_dir = find_docs_dir()
|
|
275
|
+
|
|
276
|
+
# Check prerequisites
|
|
277
|
+
if not has_nodejs():
|
|
278
|
+
raise click.ClickException(
|
|
279
|
+
"Node.js is not installed. "
|
|
280
|
+
"Please install Node.js from https://nodejs.org/"
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
if not has_npm():
|
|
284
|
+
raise click.ClickException(
|
|
285
|
+
"npm is not installed. "
|
|
286
|
+
"npm should come with Node.js installation."
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
# Check if package.json exists
|
|
290
|
+
package_json = docs_dir / "package.json"
|
|
291
|
+
if not package_json.exists():
|
|
292
|
+
raise click.ClickException(
|
|
293
|
+
f"package.json not found in {docs_dir}. "
|
|
294
|
+
"This doesn't appear to be a valid SolidJS project."
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
# Install dependencies if node_modules doesn't exist
|
|
298
|
+
node_modules = docs_dir / "node_modules"
|
|
299
|
+
if not node_modules.exists():
|
|
300
|
+
console.print("[blue]Installing dependencies...[/blue]")
|
|
301
|
+
try:
|
|
302
|
+
subprocess.run(
|
|
303
|
+
["npm", "install"],
|
|
304
|
+
cwd=docs_dir,
|
|
305
|
+
check=True,
|
|
306
|
+
stdout=subprocess.PIPE,
|
|
307
|
+
stderr=subprocess.PIPE,
|
|
308
|
+
)
|
|
309
|
+
console.print("[green]✓ Dependencies installed[/green]")
|
|
310
|
+
except subprocess.CalledProcessError as e:
|
|
311
|
+
error_msg = e.stderr.decode() if e.stderr else "Unknown error"
|
|
312
|
+
raise click.ClickException(
|
|
313
|
+
f"Failed to install dependencies: {error_msg}"
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
# Start dev server
|
|
317
|
+
url = f"http://{host}:{port}"
|
|
318
|
+
console.print("[green]✓ Starting development server...[/green]")
|
|
319
|
+
console.print(f"[blue]Server will be available at {url}[/blue]")
|
|
320
|
+
console.print("[yellow]Press Ctrl+C to stop the server[/yellow]")
|
|
321
|
+
console.print(
|
|
322
|
+
"[dim]Note: Changes to files will automatically reload in the browser[/dim]"
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
if open_browser:
|
|
326
|
+
# Open browser after a short delay to let server start
|
|
327
|
+
import threading
|
|
328
|
+
import time
|
|
329
|
+
|
|
330
|
+
def open_browser_delayed():
|
|
331
|
+
time.sleep(1.5) # Give server time to start
|
|
332
|
+
try:
|
|
333
|
+
webbrowser.open(url)
|
|
334
|
+
except Exception:
|
|
335
|
+
console.print(f"[yellow]Could not open browser automatically. Visit {url}[/yellow]")
|
|
336
|
+
|
|
337
|
+
threading.Thread(target=open_browser_delayed, daemon=True).start()
|
|
338
|
+
|
|
339
|
+
try:
|
|
340
|
+
# Run npm run dev with custom host/port
|
|
341
|
+
# Vite accepts --host and --port flags directly
|
|
342
|
+
subprocess.run(
|
|
343
|
+
["npm", "run", "dev", "--", "--host", host, "--port", str(port)],
|
|
344
|
+
cwd=docs_dir,
|
|
345
|
+
check=True,
|
|
346
|
+
)
|
|
347
|
+
except KeyboardInterrupt:
|
|
348
|
+
console.print("\n[yellow]Development server stopped[/yellow]")
|
|
349
|
+
except subprocess.CalledProcessError as e:
|
|
350
|
+
error_msg = e.stderr.decode() if e.stderr else e.stdout.decode() if e.stdout else "Unknown error"
|
|
351
|
+
raise click.ClickException(f"Dev server failed: {error_msg}")
|
|
352
|
+
except OSError as e:
|
|
353
|
+
if "Address already in use" in str(e):
|
|
354
|
+
raise click.ClickException(
|
|
355
|
+
f"Port {port} is already in use. "
|
|
356
|
+
"Try a different port with --port option."
|
|
357
|
+
)
|
|
358
|
+
raise
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def cleanup_docs(docs_dir: Optional[Path] = None) -> None:
|
|
362
|
+
"""
|
|
363
|
+
Clean up generated files and dependencies.
|
|
364
|
+
|
|
365
|
+
Silently removes:
|
|
366
|
+
- node_modules/ directory
|
|
367
|
+
- dist/ directory (build output)
|
|
368
|
+
|
|
369
|
+
Args:
|
|
370
|
+
docs_dir: Optional path to docs directory
|
|
371
|
+
"""
|
|
372
|
+
if docs_dir is None:
|
|
373
|
+
docs_dir = find_docs_dir()
|
|
374
|
+
|
|
375
|
+
removed_items = []
|
|
376
|
+
|
|
377
|
+
# Remove node_modules
|
|
378
|
+
node_modules = docs_dir / "node_modules"
|
|
379
|
+
if node_modules.exists() and node_modules.is_dir():
|
|
380
|
+
try:
|
|
381
|
+
shutil.rmtree(node_modules)
|
|
382
|
+
removed_items.append("node_modules")
|
|
383
|
+
except Exception as e:
|
|
384
|
+
raise click.ClickException(f"Failed to remove node_modules: {e}")
|
|
385
|
+
|
|
386
|
+
# Remove dist
|
|
387
|
+
dist = docs_dir / "dist"
|
|
388
|
+
if dist.exists() and dist.is_dir():
|
|
389
|
+
try:
|
|
390
|
+
shutil.rmtree(dist)
|
|
391
|
+
removed_items.append("dist")
|
|
392
|
+
except Exception as e:
|
|
393
|
+
raise click.ClickException(f"Failed to remove dist: {e}")
|
|
394
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: relationalai
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.0a4
|
|
4
4
|
Summary: RelationalAI Library and CLI
|
|
5
5
|
Author-email: RelationalAI <support@relational.ai>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -15,10 +15,9 @@ Requires-Dist: numpy<2
|
|
|
15
15
|
Requires-Dist: pandas
|
|
16
16
|
Requires-Dist: colorama
|
|
17
17
|
Requires-Dist: inquirerpy
|
|
18
|
-
Requires-Dist: click
|
|
18
|
+
Requires-Dist: click
|
|
19
19
|
Requires-Dist: gravis
|
|
20
20
|
Requires-Dist: toml
|
|
21
|
-
Requires-Dist: tomlkit
|
|
22
21
|
Requires-Dist: requests
|
|
23
22
|
Requires-Dist: pyarrow
|
|
24
23
|
Requires-Dist: websockets
|
|
@@ -35,6 +34,9 @@ Requires-Dist: sqlglot
|
|
|
35
34
|
Requires-Dist: pyyaml
|
|
36
35
|
Requires-Dist: pydantic<2.12.0,>=2.0.0
|
|
37
36
|
Requires-Dist: pydantic-settings<2.11.0,>=2.0.0
|
|
37
|
+
Requires-Dist: tomlkit
|
|
38
|
+
Requires-Dist: fastapi
|
|
39
|
+
Requires-Dist: uvicorn[standard]
|
|
38
40
|
Provides-Extra: dev
|
|
39
41
|
Requires-Dist: pytest; extra == "dev"
|
|
40
42
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -2,7 +2,7 @@ relationalai/__init__.py,sha256=hHhZc1h-IDj0pzPF67763g0a4Pdh7W-4GQpyqL60dec,152
|
|
|
2
2
|
relationalai/config/__init__.py,sha256=QL7MxBN7xy50h4Sqg3jotuyg-6EisCEtJCHCWQrL1ME,1524
|
|
3
3
|
relationalai/config/config.py,sha256=CUBkOYWu3IgCAa4oHVwEozfMbZgAX3hENo-Va2gsdIs,10477
|
|
4
4
|
relationalai/config/config_fields.py,sha256=Gskc1Ugsi4xowepDlma1HNaYdQ_wS2RiMpUaG6aNdv4,4081
|
|
5
|
-
relationalai/config/shims.py,sha256=
|
|
5
|
+
relationalai/config/shims.py,sha256=YM3rtPNpRSrQomRw5xNSekU5Da3dcYbxxzGryQt7RME,41
|
|
6
6
|
relationalai/config/connections/__init__.py,sha256=5709qbuJxqg2WedSoejpdDrXpvwowG_xDS8adoexeOA,1171
|
|
7
7
|
relationalai/config/connections/base.py,sha256=9DkPLosMc9yb6uFFks_FP_e-47K5wMD14tW_cJ05s_A,759
|
|
8
8
|
relationalai/config/connections/duckdb.py,sha256=PhhJXARTJf2ObQa9CYMJlZMGohMNCg879cKHvUr1M5Q,891
|
|
@@ -13,22 +13,25 @@ relationalai/config/external/dbt_models.py,sha256=Px_C5nID_3te3o1wfsYJjrKkZcTPUY
|
|
|
13
13
|
relationalai/config/external/snowflake_converter.py,sha256=Vnaqgazd-XwZybqbOU2YK3qYf0if-KwdTORaP0xTff4,1280
|
|
14
14
|
relationalai/config/external/snowflake_models.py,sha256=6hCaVMdhESxbW-HF0-s51Z4WIc97bS1FrZRKZ4DXE6A,2681
|
|
15
15
|
relationalai/config/external/utils.py,sha256=IJsZUCLI4Y2erETERQKcd-Alo4wNMTi1AHkdb92Z-n0,422
|
|
16
|
-
relationalai/semantics/__init__.py,sha256=
|
|
16
|
+
relationalai/semantics/__init__.py,sha256=Td5zPCjwRbYV-UA05kXwnuL1BW-iRxiWEV6sJksrzTY,4640
|
|
17
17
|
relationalai/semantics/backends/lqp/annotations.py,sha256=TUk_fuXyBWs7H4BHx-4jZGonSD8MdgPswt-D2k7QC-4,390
|
|
18
18
|
relationalai/semantics/backends/sql/sql_compiler.py,sha256=p_1YjROlcmu0kwvI32qUWAmMQntp_A6H3_vgGDDLiQk,10628
|
|
19
19
|
relationalai/semantics/frontend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
-
relationalai/semantics/frontend/base.py,sha256=
|
|
21
|
-
relationalai/semantics/frontend/core.py,sha256=
|
|
22
|
-
relationalai/semantics/frontend/front_compiler.py,sha256=
|
|
23
|
-
relationalai/semantics/frontend/pprint.py,sha256=
|
|
20
|
+
relationalai/semantics/frontend/base.py,sha256=xxs0udBqK4ErwA9pPAtFXV-Ky4keEOJQ0k4gsOKrMUQ,66007
|
|
21
|
+
relationalai/semantics/frontend/core.py,sha256=nTFDsF18WemplUmxOeCbUTHGhrCmxWIeRjC5amKkdDE,8399
|
|
22
|
+
relationalai/semantics/frontend/front_compiler.py,sha256=RIa12ifKoWJ0HqwrBSiDniKF5K-AGEJ1L8VC4wOyuck,58615
|
|
23
|
+
relationalai/semantics/frontend/pprint.py,sha256=mc2i4MlmPpsjXWx6bO_J7lMrxUeDfO2du4eaPZi6pFU,14982
|
|
24
24
|
relationalai/semantics/metamodel/__init__.py,sha256=mISE8niHeEAD6QjX8pi_apFfMIVCZ7dGeCXFGtFPTvk,364
|
|
25
25
|
relationalai/semantics/metamodel/builtins.py,sha256=rmeVdjw3kDSsx7TjpnFpy8W6OrHuUV1GQwazWhaWrG0,7009
|
|
26
26
|
relationalai/semantics/metamodel/metamodel.py,sha256=TgIufxJslJZkf5_RleTU19i2h0DTW6CodSYqwyVcLEc,13899
|
|
27
27
|
relationalai/semantics/metamodel/metamodel_analyzer.py,sha256=tusDRO2az1yiF951SDg-cHOaNQ1M7qw1HG1cxV3YuxU,16228
|
|
28
28
|
relationalai/semantics/metamodel/metamodel_compiler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
29
|
relationalai/semantics/metamodel/pprint.py,sha256=65t7tZTfBP2qOlKShYM8nwrbsiS3gKaCYkUJepu0a2o,15684
|
|
30
|
-
relationalai/semantics/metamodel/rewriter.py,sha256=
|
|
31
|
-
relationalai/semantics/metamodel/typer.py,sha256=
|
|
30
|
+
relationalai/semantics/metamodel/rewriter.py,sha256=14T2fzoBLMvYZNOy8VjRq_NS7rwU9EECbkQXJxfdvDw,8436
|
|
31
|
+
relationalai/semantics/metamodel/typer.py,sha256=Acc1NiS9oCrqt9ZP_uI4GyT0sduOwmu1tS5U-3Irndo,57654
|
|
32
|
+
relationalai/semantics/reasoners/__init__.py,sha256=T1ysWgmX85pULUqdxZroPexY45DvfzsV3J2xJQHr3nQ,377
|
|
33
|
+
relationalai/semantics/reasoners/graph/__init__.py,sha256=1hFTc-a8tj4LJv7bYUSGqRCKAuSygbhqwFH25lebWDs,1356
|
|
34
|
+
relationalai/semantics/reasoners/graph/core.py,sha256=prUtjt8nb87Xp9z38Y6bD_iqFaYWCZLwBGhWOmCs20I,399827
|
|
32
35
|
relationalai/semantics/std/__init__.py,sha256=_cbDmeCT634GtdGJ0CqgfJw6pFaJR0ajR3B_bWCr_9A,2627
|
|
33
36
|
relationalai/semantics/std/aggregates.py,sha256=uCwoBLmuRBBq9lTf5ACD3yosvtp5Wi8IQUCF_dKWS80,6259
|
|
34
37
|
relationalai/semantics/std/common.py,sha256=raWuvX2u4juKPU0BKtqF5xvJSDjKHF1BWQVFioBmOf8,1658
|
|
@@ -44,14 +47,15 @@ relationalai/semantics/std/strings.py,sha256=w0k06gDfyMS6GODPjhG0gl2SkJ0aH5aYezS
|
|
|
44
47
|
relationalai/shims/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
48
|
relationalai/shims/executor.py,sha256=LtpBx74mhbJ1bCUVvetDlk5iDAEi_x-wNZ6iq5WPW2s,7531
|
|
46
49
|
relationalai/shims/helpers.py,sha256=1v6D-wDq3nCwDz4egdGUeleRC0fK6wfo9fIQIeQCfZA,4508
|
|
47
|
-
relationalai/shims/hoister.py,sha256=
|
|
48
|
-
relationalai/shims/mm2v0.py,sha256=
|
|
50
|
+
relationalai/shims/hoister.py,sha256=maebjwse3GvOFCHJWgBXBTwpiqeny8DAyoFW6HtUzI8,9423
|
|
51
|
+
relationalai/shims/mm2v0.py,sha256=G1Gct9rtH6KF1z0yN6yZj0WFTACfeJhcbRCZTyc1eRU,64436
|
|
49
52
|
relationalai/tools/debugger.py,sha256=B8QIE1-WFdfkiPoFFn1yztr9t6yf5PI32Y9Y9XzQOJk,10798
|
|
50
53
|
relationalai/tools/typer_debugger.py,sha256=__oLODEBwgt6pYIn1jgIPlenFmiK7iqXfTY_mozHxXA,3182
|
|
51
54
|
relationalai/tools/cli/__init__.py,sha256=jkIlp7wftUuSIlczwZD4_siT5cs6mzpsNGrQ_kMkLZ4,74
|
|
52
|
-
relationalai/tools/cli/cli.py,sha256=
|
|
55
|
+
relationalai/tools/cli/cli.py,sha256=N2quQWjcgq7qqiW1WhkDGOVZZL0nfNfUc59zsUj95pY,5958
|
|
53
56
|
relationalai/tools/cli/config_template.py,sha256=l52KOI3ZBkhtM9V7EQSUOEddHVdMnjl21hPnnQSwdBE,949
|
|
54
57
|
relationalai/tools/cli/dev.py,sha256=1GjfjTLi4BXbV5fXKlF5g1bc8-YsA9oKOBSntquBd8g,340
|
|
58
|
+
relationalai/tools/cli/docs.py,sha256=GSUMHVqHMzrpYw1wOHTKfbkZW-dozRfzoKpgb2o4wvQ,12648
|
|
55
59
|
relationalai/tools/cli/components/__init__.py,sha256=H91hUt3lohr6kAVGOHgTKpDgwRc2Ka4a-iw2domfm5o,143
|
|
56
60
|
relationalai/tools/cli/components/progress_reader.py,sha256=mrAFI4p1T7tgDNd_S9QAF9QXuF5RlWGSg5fzQY1_MRY,56767
|
|
57
61
|
relationalai/tools/cli/components/utils.py,sha256=n_st7K3B8bDLsi8rjYgilPtx7TJRcU5xZlauGUrjyv8,1700
|
|
@@ -72,7 +76,7 @@ v0/relationalai/debugging.py,sha256=AuzbwLT1s71tctuIbYNhfWY2vR_opB7ItbmlqFVHgrY,
|
|
|
72
76
|
v0/relationalai/dependencies.py,sha256=tL113efcISkJUiDXYHmRdU_usdD7gmee-VRHA7N4EFA,16574
|
|
73
77
|
v0/relationalai/docutils.py,sha256=1gVv9mk0ytdMB2W7_NvslJefmSQtTOg8LHTCDcGCjyE,1554
|
|
74
78
|
v0/relationalai/dsl.py,sha256=9BdpqzDNcW4717GyxVAYIMZ7ctE_bvXS-5sNLIbXQZ0,66128
|
|
75
|
-
v0/relationalai/errors.py,sha256=
|
|
79
|
+
v0/relationalai/errors.py,sha256=bwKNODY5aROWRRW-Df2zxHk5ACxWnR0zOhOdOHO9Yi0,96831
|
|
76
80
|
v0/relationalai/metagen.py,sha256=o10PNvR_myr_61DC8g6lkB093bFo9qXGUkZKgKyfXiE,26821
|
|
77
81
|
v0/relationalai/metamodel.py,sha256=P1hliwHd1nYxbXON4LZeaYZD6T6pZm97HgmFBFrWyCk,32886
|
|
78
82
|
v0/relationalai/rel.py,sha256=ePmAXx4NxOdsPcHNHyGH3Jkp_cB3QzfKu5p_EQSHPh0,38293
|
|
@@ -90,6 +94,7 @@ v0/relationalai/clients/__init__.py,sha256=LQ_yHsutRMpoW2mOTmOPGF8mrbP0OiV5E68t8
|
|
|
90
94
|
v0/relationalai/clients/client.py,sha256=gk_V9KS7_MM2dLL2OCO7EPLHD9dsRwR6R-30SW8lDwU,35759
|
|
91
95
|
v0/relationalai/clients/config.py,sha256=PriDlD0_VZFV0fEQng6U-F5xjGwz5gC2F5_lM159AjM,24481
|
|
92
96
|
v0/relationalai/clients/direct_access_client.py,sha256=p3hqjwdiXQQytRke1wIeNRM-HlZLAxH1U6-yPhsPOdQ,6454
|
|
97
|
+
v0/relationalai/clients/exec_txn_poller.py,sha256=veEHerCeKIJe9X7Yjnxab-lXUI4lWBW8tmY-tgMwKwQ,3123
|
|
93
98
|
v0/relationalai/clients/hash_util.py,sha256=NXVtUFgRokZz-45CwV-r5Z5KvmEXD2dh4ypNOrEWAwY,1501
|
|
94
99
|
v0/relationalai/clients/local.py,sha256=vo5ikSWg38l3xQAh9yL--4sMAj_T5Tn7YEZiw7TCH08,23504
|
|
95
100
|
v0/relationalai/clients/profile_polling.py,sha256=c1ixxAOKvy-dDfVqkKENwfcsvBB8jhLA1oT9RIFIrY8,2571
|
|
@@ -98,15 +103,15 @@ v0/relationalai/clients/types.py,sha256=VU2LRtlnFsBRYdokxUccrsUkEYLE9N62EUiWtA_q
|
|
|
98
103
|
v0/relationalai/clients/util.py,sha256=Vrw_kr-Oqp_DKTkJ_rTbzpDm4_Z4h8w10T8GUyGLxbA,12323
|
|
99
104
|
v0/relationalai/clients/resources/__init__.py,sha256=pymn8gB86Q3C2bVoFei0KAL8pX_U04uDY9TE4TKzTBs,260
|
|
100
105
|
v0/relationalai/clients/resources/azure/azure.py,sha256=TDapfM5rLoHrPrXg5cUe827m3AO0gSqQjNid1VUlUFo,20631
|
|
101
|
-
v0/relationalai/clients/resources/snowflake/__init__.py,sha256=
|
|
106
|
+
v0/relationalai/clients/resources/snowflake/__init__.py,sha256=Ofyf1RZu9GLQdvsjpHDUHEQHHVODb9vKYI4hMOxczH4,923
|
|
102
107
|
v0/relationalai/clients/resources/snowflake/cache_store.py,sha256=A-qd11wcwN3TkIqvlN0_iFUU3aEjJal3T2pqFBwkkzQ,3966
|
|
103
108
|
v0/relationalai/clients/resources/snowflake/cli_resources.py,sha256=xTIcCzvgbkxuNAEvzZoRpj0n-js0hZCK30q7IZXztbI,3252
|
|
104
|
-
v0/relationalai/clients/resources/snowflake/direct_access_resources.py,sha256=
|
|
109
|
+
v0/relationalai/clients/resources/snowflake/direct_access_resources.py,sha256=a_vfArYM8IAd7gAwx4VEis0KOOr2Vej7vMwY3csxGmQ,30134
|
|
105
110
|
v0/relationalai/clients/resources/snowflake/engine_state_handlers.py,sha256=SQBu4GfbyABU6xrEV-koivC-ubsVrfCBTF0FEQgJM5g,12054
|
|
106
111
|
v0/relationalai/clients/resources/snowflake/error_handlers.py,sha256=581G2xOihUoiPlucC_Z2FOzhKu_swdIc3uORd0yJQuA,8805
|
|
107
112
|
v0/relationalai/clients/resources/snowflake/resources_factory.py,sha256=4LGd4IQ6z8hGeGlO1TIjSFJEeUNHutaB7j9q1a9rYfQ,3385
|
|
108
|
-
v0/relationalai/clients/resources/snowflake/snowflake.py,sha256=
|
|
109
|
-
v0/relationalai/clients/resources/snowflake/use_index_poller.py,sha256=
|
|
113
|
+
v0/relationalai/clients/resources/snowflake/snowflake.py,sha256=buPPwLR9_gX5zo9sN90rGD1qIkn1qX4yOcaXmNlOP4U,134362
|
|
114
|
+
v0/relationalai/clients/resources/snowflake/use_index_poller.py,sha256=AE7z2pL4QioPRDL7-O9J4KHSuxbYbRAvd886mZPpCQI,48871
|
|
110
115
|
v0/relationalai/clients/resources/snowflake/use_index_resources.py,sha256=69PNWHI_uf-Aw_evfwC6j8HLVdjhp84vs8hLkjnhwbg,6462
|
|
111
116
|
v0/relationalai/clients/resources/snowflake/util.py,sha256=BEnm1B1-nqqHdm41RNxblbb-zqXbtqEGGZmTdAYeN_M,13841
|
|
112
117
|
v0/relationalai/early_access/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -372,7 +377,7 @@ v0/relationalai/semantics/lqp/__init__.py,sha256=XgcQZxK-zz_LqPDVtwREhsIvjTuUIt4
|
|
|
372
377
|
v0/relationalai/semantics/lqp/builtins.py,sha256=Xst9-UxkCAwDqL-hFOby8B3GKh705oidFUjEozxn71Y,585
|
|
373
378
|
v0/relationalai/semantics/lqp/compiler.py,sha256=xpGIQAqTMwLi3Vrbe79Yal7O_mfNxpBLioZjqeV2hzc,955
|
|
374
379
|
v0/relationalai/semantics/lqp/constructors.py,sha256=x7G85vbJzLIXzUCMKVdJVsr4PrcUsAOzCCfvimHLMVU,2366
|
|
375
|
-
v0/relationalai/semantics/lqp/executor.py,sha256=
|
|
380
|
+
v0/relationalai/semantics/lqp/executor.py,sha256=OkxegnEp4_U7uslhDS0cBi8OQOg499NPYEYomWpEqlI,21550
|
|
376
381
|
v0/relationalai/semantics/lqp/intrinsics.py,sha256=8kgH4ndYKBCNnoNOn7iWOU0wnMTSiov0kYaKocQ45RY,880
|
|
377
382
|
v0/relationalai/semantics/lqp/ir.py,sha256=6W9mUH0W7u5eIfF1S3o33uSOfQuM3UcqEkxrxpr1X_8,1867
|
|
378
383
|
v0/relationalai/semantics/lqp/model2lqp.py,sha256=J_QofcYgq_Yb5dhOOP4lXvxsxFMEGHVnaNXoCMK_ak8,38639
|
|
@@ -387,7 +392,7 @@ v0/relationalai/semantics/lqp/rewrite/__init__.py,sha256=V9ERED9qdh4VvY9Ud_M8Zn8
|
|
|
387
392
|
v0/relationalai/semantics/lqp/rewrite/annotate_constraints.py,sha256=zOm-OUzWBhk2iMc_eURII1-okIGJ-teDbEcJ30WDjUU,2325
|
|
388
393
|
v0/relationalai/semantics/lqp/rewrite/cdc.py,sha256=cx_fpQrzkzkeAGHE_kV10nd1-0Jduws6yiIRq650f4c,10412
|
|
389
394
|
v0/relationalai/semantics/lqp/rewrite/extract_common.py,sha256=johHGsS9SDDVbonMIE8Ck9rCuidllwdeJZDruW_5kQs,14705
|
|
390
|
-
v0/relationalai/semantics/lqp/rewrite/extract_keys.py,sha256=
|
|
395
|
+
v0/relationalai/semantics/lqp/rewrite/extract_keys.py,sha256=8C5te8XWU5JiLpc7WojIVKg0_wyMM-gdlxmJdHQSnQQ,22165
|
|
391
396
|
v0/relationalai/semantics/lqp/rewrite/function_annotations.py,sha256=WAHpqRVBqpUIDL2MA1aBmyOTvcpH_yfdeWBS1vAEtzA,4675
|
|
392
397
|
v0/relationalai/semantics/lqp/rewrite/functional_dependencies.py,sha256=LTwMvU19FMdgCG8nJwV2wyiW8Hu9oCj-hIKKSMOYZYE,12727
|
|
393
398
|
v0/relationalai/semantics/lqp/rewrite/quantify_vars.py,sha256=3l_pDMc4r-izuE274MP_ffNgZ6g7Rk5ysg3CXqKKlBU,12016
|
|
@@ -420,7 +425,7 @@ v0/relationalai/semantics/reasoners/graph/core.py,sha256=Bth2oe5ulItBChZCoFTgP-o
|
|
|
420
425
|
v0/relationalai/semantics/reasoners/optimization/__init__.py,sha256=HZlyy3Od7ArXI_HMhWrxrQPnyZGScgiVdmMul51lx7Q,2218
|
|
421
426
|
v0/relationalai/semantics/reasoners/optimization/common.py,sha256=gmJrJAPNyaBqik2_QaxjCoFPZKqdroxmNXUeoDGwOtY,3130
|
|
422
427
|
v0/relationalai/semantics/reasoners/optimization/solvers_dev.py,sha256=MqCvdDk1l_XSBlHd5-XpHVfcvD8INjCNbCttaomv6SY,24517
|
|
423
|
-
v0/relationalai/semantics/reasoners/optimization/solvers_pb.py,sha256=
|
|
428
|
+
v0/relationalai/semantics/reasoners/optimization/solvers_pb.py,sha256=MbubEIDJbXpe1gJ3lT_yBhVSDzA_EVuDvxRU4bLOjUk,60159
|
|
424
429
|
v0/relationalai/semantics/rel/__init__.py,sha256=pMlVTC_TbQ45mP1LpzwFBBgPxpKc0H3uJDvvDXEWzvs,55
|
|
425
430
|
v0/relationalai/semantics/rel/builtins.py,sha256=0M9r5GQb9CnkkbdhO8Psw9TgiZk5CC3z5RMncUa6uuM,1571
|
|
426
431
|
v0/relationalai/semantics/rel/compiler.py,sha256=t7gitonfRewTk8IQ53DTqPegytwax1jGu43VgQOqBWA,43062
|
|
@@ -491,8 +496,8 @@ v0/relationalai/util/span_tracker.py,sha256=7vyvEBdI9uCj1dxVZCQT_W5vPMxIzxewrlRR
|
|
|
491
496
|
v0/relationalai/util/spans_file_handler.py,sha256=w34WVw19ubtrjPBkKmg0Hb-9MldICmowF1OW85KCJN0,3209
|
|
492
497
|
v0/relationalai/util/timeout.py,sha256=2o6BVNFnFc-B2j-i1pEkZcQbMRto9ps2emci0XwiA4I,783
|
|
493
498
|
v0/relationalai/util/tracing_handler.py,sha256=wJQN52PRw8R2XB1_qd-POgfGZStrj9OFL7wa5Xr6SEM,1732
|
|
494
|
-
relationalai-1.0.
|
|
495
|
-
relationalai-1.0.
|
|
496
|
-
relationalai-1.0.
|
|
497
|
-
relationalai-1.0.
|
|
498
|
-
relationalai-1.0.
|
|
499
|
+
relationalai-1.0.0a4.dist-info/METADATA,sha256=IBtzvgqfMTby0BJHn885Ub5UgZ9O3f_flCGqY84qCWM,1417
|
|
500
|
+
relationalai-1.0.0a4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
501
|
+
relationalai-1.0.0a4.dist-info/entry_points.txt,sha256=u_anMN5_VCOQNA5E2mTLT2LWc9r1i-F9yQmy3ZNAAck,91
|
|
502
|
+
relationalai-1.0.0a4.dist-info/top_level.txt,sha256=Y9cfzWf-p2omqqmVy_98m287xf0OJbj6OB5RRdkGql4,16
|
|
503
|
+
relationalai-1.0.0a4.dist-info/RECORD,,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
from typing import Dict, Optional, TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
from v0.relationalai import debugging
|
|
7
|
+
from v0.relationalai.clients.util import poll_with_specified_overhead
|
|
8
|
+
from v0.relationalai.tools.cli_controls import create_progress
|
|
9
|
+
from v0.relationalai.util.format import format_duration
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from v0.relationalai.clients.resources.snowflake import Resources
|
|
13
|
+
|
|
14
|
+
# Polling behavior constants
|
|
15
|
+
POLL_OVERHEAD_RATE = 0.1 # Overhead rate for exponential backoff
|
|
16
|
+
|
|
17
|
+
# Text color constants
|
|
18
|
+
GREEN_COLOR = '\033[92m'
|
|
19
|
+
GRAY_COLOR = '\033[90m'
|
|
20
|
+
ENDC = '\033[0m'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ExecTxnPoller:
|
|
24
|
+
"""
|
|
25
|
+
Encapsulates the polling logic for exec_async transaction completion.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
resource: "Resources",
|
|
31
|
+
txn_id: str,
|
|
32
|
+
headers: Optional[Dict] = None,
|
|
33
|
+
txn_start_time: Optional[float] = None,
|
|
34
|
+
):
|
|
35
|
+
self.res = resource
|
|
36
|
+
self.txn_id = txn_id
|
|
37
|
+
self.headers = headers or {}
|
|
38
|
+
self.txn_start_time = txn_start_time or time.time()
|
|
39
|
+
|
|
40
|
+
def poll(self) -> bool:
|
|
41
|
+
"""
|
|
42
|
+
Poll for transaction completion with interactive progress display.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
True if transaction completed successfully, False otherwise
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
# Don't show duration summary - we handle our own completion message
|
|
49
|
+
with create_progress(
|
|
50
|
+
description="Evaluating Query...",
|
|
51
|
+
success_message="", # We'll handle this ourselves
|
|
52
|
+
leading_newline=False,
|
|
53
|
+
trailing_newline=False,
|
|
54
|
+
show_duration_summary=False,
|
|
55
|
+
) as progress:
|
|
56
|
+
def check_status() -> bool:
|
|
57
|
+
"""Check if transaction is complete."""
|
|
58
|
+
elapsed = time.time() - self.txn_start_time
|
|
59
|
+
# Update the main status with elapsed time
|
|
60
|
+
progress.update_main_status(
|
|
61
|
+
query_progress_message(self.txn_id, elapsed)
|
|
62
|
+
)
|
|
63
|
+
return self.res._check_exec_async_status(self.txn_id, headers=self.headers)
|
|
64
|
+
|
|
65
|
+
with debugging.span("wait", txn_id=self.txn_id):
|
|
66
|
+
poll_with_specified_overhead(check_status, overhead_rate=POLL_OVERHEAD_RATE)
|
|
67
|
+
|
|
68
|
+
# Calculate final duration
|
|
69
|
+
total_duration = time.time() - self.txn_start_time
|
|
70
|
+
|
|
71
|
+
# Update to success message with duration
|
|
72
|
+
progress.update_main_status(
|
|
73
|
+
query_complete_message(self.txn_id, total_duration)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
return True
|
|
77
|
+
|
|
78
|
+
def query_progress_message(id: str, duration: float) -> str:
|
|
79
|
+
return (
|
|
80
|
+
# Print with whitespace to align with the end of the transaction ID
|
|
81
|
+
f"Evaluating Query... {format_duration(duration):>18}\n" +
|
|
82
|
+
f"{GRAY_COLOR}Query: {id}{ENDC}"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def query_complete_message(id: str, duration: float, status_header: bool = False) -> str:
|
|
86
|
+
return (
|
|
87
|
+
(f"{GREEN_COLOR}✅ " if status_header else "") +
|
|
88
|
+
# Print with whitespace to align with the end of the transaction ID
|
|
89
|
+
f"Query Complete: {format_duration(duration):>24}\n" +
|
|
90
|
+
f"{GRAY_COLOR}Query: {id}{ENDC}"
|
|
91
|
+
)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Snowflake resources module.
|
|
3
3
|
"""
|
|
4
4
|
# Import order matters - Resources must be imported first since other classes depend on it
|
|
5
|
-
from .snowflake import Resources, Provider, Graph, SnowflakeClient, APP_NAME, PYREL_ROOT_DB, ExecContext, INTERNAL_ENGINE_SIZES, ENGINE_SIZES_AWS, ENGINE_SIZES_AZURE, PrimaryKey
|
|
5
|
+
from .snowflake import Resources, Provider, Graph, SnowflakeClient, APP_NAME, PYREL_ROOT_DB, ExecContext, INTERNAL_ENGINE_SIZES, ENGINE_SIZES_AWS, ENGINE_SIZES_AZURE, PrimaryKey, PRINT_TXN_PROGRESS_FLAG
|
|
6
6
|
|
|
7
7
|
# These imports depend on Resources, so they come after
|
|
8
8
|
from .cli_resources import CLIResources
|
|
@@ -14,7 +14,7 @@ __all__ = [
|
|
|
14
14
|
'Resources', 'DirectAccessResources', 'Provider', 'Graph', 'SnowflakeClient',
|
|
15
15
|
'APP_NAME', 'PYREL_ROOT_DB', 'CLIResources', 'UseIndexResources', 'ExecContext',
|
|
16
16
|
'INTERNAL_ENGINE_SIZES', 'ENGINE_SIZES_AWS', 'ENGINE_SIZES_AZURE', 'PrimaryKey',
|
|
17
|
-
'create_resources_instance',
|
|
17
|
+
'PRINT_TXN_PROGRESS_FLAG', 'create_resources_instance',
|
|
18
18
|
]
|
|
19
19
|
|
|
20
20
|
|