snowflake-switchboard-ai 0.1.0__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.
- snowflake_switchboard_ai-0.1.0/PKG-INFO +26 -0
- snowflake_switchboard_ai-0.1.0/README.md +12 -0
- snowflake_switchboard_ai-0.1.0/pyproject.toml +25 -0
- snowflake_switchboard_ai-0.1.0/setup.cfg +4 -0
- snowflake_switchboard_ai-0.1.0/snowflake_switchboard_ai.egg-info/PKG-INFO +26 -0
- snowflake_switchboard_ai-0.1.0/snowflake_switchboard_ai.egg-info/SOURCES.txt +9 -0
- snowflake_switchboard_ai-0.1.0/snowflake_switchboard_ai.egg-info/dependency_links.txt +1 -0
- snowflake_switchboard_ai-0.1.0/snowflake_switchboard_ai.egg-info/requires.txt +1 -0
- snowflake_switchboard_ai-0.1.0/snowflake_switchboard_ai.egg-info/top_level.txt +1 -0
- snowflake_switchboard_ai-0.1.0/switchboard/__init__.py +1 -0
- snowflake_switchboard_ai-0.1.0/switchboard/core.py +83 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: snowflake-switchboard-ai
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A dynamic, metadata-driven query router for Snowflake and Snowpark
|
|
5
|
+
Author-email: Murtaza Mohammed Rafiqi <murtuzarafiqui@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/mmar4/switchboard-ai
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: snowflake-snowpark-python>=1.0.0
|
|
14
|
+
|
|
15
|
+
# Switchboard AI 🚦
|
|
16
|
+
|
|
17
|
+
An intelligent query router that automatically optimizes your data workloads by routing lightweight queries to a local embedded engine (`DuckDB`) and heavy workloads to cloud warehouses (`Snowflake`).
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
- **Smart Routing:** Intercepts SQL queries and decides the most cost-effective compute engine.
|
|
21
|
+
- **Low Latency:** Executes minor lookups locally in-memory.
|
|
22
|
+
- **Seamless Snowflake Integration:** Native fallback to Snowflake cloud instances for heavy pipelines.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
```bash
|
|
26
|
+
pip install -e .
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Switchboard AI 🚦
|
|
2
|
+
|
|
3
|
+
An intelligent query router that automatically optimizes your data workloads by routing lightweight queries to a local embedded engine (`DuckDB`) and heavy workloads to cloud warehouses (`Snowflake`).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
- **Smart Routing:** Intercepts SQL queries and decides the most cost-effective compute engine.
|
|
7
|
+
- **Low Latency:** Executes minor lookups locally in-memory.
|
|
8
|
+
- **Seamless Snowflake Integration:** Native fallback to Snowflake cloud instances for heavy pipelines.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
```bash
|
|
12
|
+
pip install -e .
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "snowflake-switchboard-ai"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A dynamic, metadata-driven query router for Snowflake and Snowpark"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [
|
|
11
|
+
{ name = "Murtaza Mohammed Rafiqi", email = "murtuzarafiqui@gmail.com" }
|
|
12
|
+
]
|
|
13
|
+
license = { text = "MIT" }
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
]
|
|
19
|
+
requires-python = ">=3.8"
|
|
20
|
+
dependencies = [
|
|
21
|
+
"snowflake-snowpark-python>=1.0.0"
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
Homepage = "https://github.com/mmar4/switchboard-ai"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: snowflake-switchboard-ai
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A dynamic, metadata-driven query router for Snowflake and Snowpark
|
|
5
|
+
Author-email: Murtaza Mohammed Rafiqi <murtuzarafiqui@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/mmar4/switchboard-ai
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: snowflake-snowpark-python>=1.0.0
|
|
14
|
+
|
|
15
|
+
# Switchboard AI 🚦
|
|
16
|
+
|
|
17
|
+
An intelligent query router that automatically optimizes your data workloads by routing lightweight queries to a local embedded engine (`DuckDB`) and heavy workloads to cloud warehouses (`Snowflake`).
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
- **Smart Routing:** Intercepts SQL queries and decides the most cost-effective compute engine.
|
|
21
|
+
- **Low Latency:** Executes minor lookups locally in-memory.
|
|
22
|
+
- **Seamless Snowflake Integration:** Native fallback to Snowflake cloud instances for heavy pipelines.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
```bash
|
|
26
|
+
pip install -e .
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
snowflake_switchboard_ai.egg-info/PKG-INFO
|
|
4
|
+
snowflake_switchboard_ai.egg-info/SOURCES.txt
|
|
5
|
+
snowflake_switchboard_ai.egg-info/dependency_links.txt
|
|
6
|
+
snowflake_switchboard_ai.egg-info/requires.txt
|
|
7
|
+
snowflake_switchboard_ai.egg-info/top_level.txt
|
|
8
|
+
switchboard/__init__.py
|
|
9
|
+
switchboard/core.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
snowflake-snowpark-python>=1.0.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
switchboard
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .core import MultiTierSwitchboard
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from snowflake.snowpark import Session
|
|
3
|
+
from snowflake.snowpark.dataframe import DataFrame
|
|
4
|
+
|
|
5
|
+
class MultiTierSwitchboard:
|
|
6
|
+
def __init__(self, session: Session, warehouses: list = None, tiers: list = None):
|
|
7
|
+
self.session = session
|
|
8
|
+
|
|
9
|
+
if tiers:
|
|
10
|
+
self.tiers = sorted(tiers, key=lambda x: x["max_bytes"])
|
|
11
|
+
elif warehouses:
|
|
12
|
+
standard_limits = [
|
|
13
|
+
1_000_000_000, # 1 GB (XS limit)
|
|
14
|
+
5_000_000_000, # 5 GB (Small limit)
|
|
15
|
+
20_000_000_000, # 20 GB (Medium limit)
|
|
16
|
+
50_000_000_000, # 50 GB (Large limit)
|
|
17
|
+
100_000_000_000, # 100 GB (X-Large limit)
|
|
18
|
+
500_000_000_000 # 500 GB (2X-Large limit)
|
|
19
|
+
]
|
|
20
|
+
self.tiers = []
|
|
21
|
+
for i, wh in enumerate(warehouses):
|
|
22
|
+
if i == len(warehouses) - 1:
|
|
23
|
+
limit = float("inf")
|
|
24
|
+
else:
|
|
25
|
+
limit = standard_limits[i] if i < len(standard_limits) else float("inf")
|
|
26
|
+
self.tiers.append({"warehouse": wh, "max_bytes": limit})
|
|
27
|
+
else:
|
|
28
|
+
self.tiers = [
|
|
29
|
+
{"warehouse": "COMPUTE_WH", "max_bytes": 1_000_000_000},
|
|
30
|
+
{"warehouse": "PRACTICE", "max_bytes": float("inf")}
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
def run(self, query: str) -> DataFrame:
|
|
34
|
+
print(f"🤖 [Switchboard AI]: Analyzing query structure...")
|
|
35
|
+
|
|
36
|
+
estimated_bytes = 0
|
|
37
|
+
try:
|
|
38
|
+
explain_sql = f"SELECT SYSTEM$EXPLAIN_PLAN_JSON($${query}$$)"
|
|
39
|
+
explain_result = self.session.sql(explain_sql).collect()
|
|
40
|
+
plan_json_str = explain_result[0][0]
|
|
41
|
+
|
|
42
|
+
if plan_json_str:
|
|
43
|
+
plan_data = json.loads(plan_json_str)
|
|
44
|
+
estimated_bytes = self._extract_bytes_assigned(plan_data)
|
|
45
|
+
|
|
46
|
+
print(f"📊 [Switchboard AI]: Estimated telemetry payload -> {estimated_bytes:,} bytes assigned.")
|
|
47
|
+
|
|
48
|
+
except Exception as e:
|
|
49
|
+
print(f"⚠️ [Switchboard AI]: Pre-check skipped ({e}). Using baseline tier.")
|
|
50
|
+
|
|
51
|
+
target_wh = self.tiers[0]["warehouse"]
|
|
52
|
+
for tier in self.tiers:
|
|
53
|
+
if estimated_bytes <= tier["max_bytes"]:
|
|
54
|
+
target_wh = tier["warehouse"]
|
|
55
|
+
break
|
|
56
|
+
|
|
57
|
+
print(f"🚀 [Switchboard AI]: Routing query to optimal tier -> {target_wh}")
|
|
58
|
+
|
|
59
|
+
self.session.sql(f"USE WAREHOUSE {target_wh}").collect()
|
|
60
|
+
|
|
61
|
+
print(f"⚙️ [Switchboard AI]: Executing query...")
|
|
62
|
+
return self.session.sql(query)
|
|
63
|
+
|
|
64
|
+
def __call__(self, query: str, auto_show: bool = True) -> DataFrame:
|
|
65
|
+
df = self.run(query)
|
|
66
|
+
if auto_show:
|
|
67
|
+
df.show()
|
|
68
|
+
return df
|
|
69
|
+
|
|
70
|
+
def _extract_bytes_assigned(self, plan_node) -> int:
|
|
71
|
+
total_bytes = 0
|
|
72
|
+
if isinstance(plan_node, dict):
|
|
73
|
+
if "bytesAssigned" in plan_node:
|
|
74
|
+
try:
|
|
75
|
+
total_bytes += int(plan_node["bytesAssigned"])
|
|
76
|
+
except (ValueError, TypeError):
|
|
77
|
+
pass
|
|
78
|
+
for key, value in plan_node.items():
|
|
79
|
+
total_bytes += self._extract_bytes_assigned(value)
|
|
80
|
+
elif isinstance(plan_node, list):
|
|
81
|
+
for item in plan_node:
|
|
82
|
+
total_bytes += self._extract_bytes_assigned(item)
|
|
83
|
+
return total_bytes
|