zaturn 0.2.0__py3-none-any.whl → 0.2.2__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.
zaturn/mcp/__init__.py CHANGED
@@ -1,10 +1,11 @@
1
1
  import argparse
2
+ import importlib.resources
2
3
  import os
3
4
  import platformdirs
4
- import pkg_resources
5
5
  import sys
6
6
 
7
7
  from fastmcp import FastMCP
8
+ from fastmcp.tools.tool import Tool
8
9
 
9
10
  from zaturn.tools import ZaturnTools
10
11
 
@@ -30,19 +31,17 @@ if not source_list:
30
31
  source_list = args.sources
31
32
 
32
33
  if not source_list:
33
- source_list = [
34
- pkg_resources.resource_filename(
35
- 'zaturn',
36
- os.path.join('mcp', 'example_data', 'all_pokemon_data.csv')
37
- )
38
- ]
34
+ with importlib.resources.path(
35
+ 'zaturn.tools.example_data', 'all_pokemon_data.csv'
36
+ ) as source_path:
37
+ source_list = [str(source_path)]
38
+
39
39
  print("No data sources provided. Loading example dataset for demonstration.")
40
40
  print(f"\nTo load your datasets, add them to {SOURCES_FILE} (one source URL or full file path per line)")
41
41
  print("\nOr use command line args to specify data sources:")
42
42
  print("zaturn_mcp sqlite:///path/to/mydata.db /path/to/my_file.csv")
43
43
  print(f"\nNOTE: Sources in command line args will be ignored if sources are found in {SOURCES_FILE}")
44
44
 
45
-
46
45
  SOURCES = {}
47
46
  for s in source_list:
48
47
  source = s.lower()
@@ -56,6 +55,10 @@ for s in source_list:
56
55
  source_type = 'mysql'
57
56
  s = s.replace('mysql://', 'mysql+pymysql://')
58
57
  source_name = source.split('/')[-1].split('?')[0]
58
+ elif source.startswith("mssql://"):
59
+ source_type = 'mssql'
60
+ s = s.replace('mssql://', 'mssql+pymssql://')
61
+ source_name = source.split('/')[-1].split('?')[0]
59
62
  elif source.startswith('clickhouse://'):
60
63
  source_type = 'clickhouse'
61
64
  source_name = source.split('/')[-1].split('?')[0]
@@ -86,8 +89,8 @@ for s in source_list:
86
89
  def ZaturnMCP(sources):
87
90
  zaturn_tools = ZaturnTools(sources)
88
91
  zaturn_mcp = FastMCP()
89
- for tool in zaturn_tools.tools:
90
- zaturn_mcp.add_tool(tool)
92
+ for tool_function in zaturn_tools.tools:
93
+ zaturn_mcp.add_tool(Tool.from_function(tool_function))
91
94
 
92
95
  return zaturn_mcp
93
96
 
zaturn/tools/config.py CHANGED
@@ -1,8 +1,5 @@
1
- import argparse
2
1
  import os
3
2
  import platformdirs
4
- import pkg_resources
5
- import sys
6
3
 
7
4
  # Basic Setup
8
5
  USER_DATA_DIR = platformdirs.user_data_dir('zaturn', 'zaturn')
@@ -13,83 +10,3 @@ SOURCES_FILE = os.path.join(USER_DATA_DIR, 'sources.txt')
13
10
  os.makedirs(QUERIES_DIR, exist_ok=True)
14
11
  os.makedirs(VISUALS_DIR, exist_ok=True)
15
12
 
16
- # Parse command line args
17
- parser = argparse.ArgumentParser(
18
- description="Zaturn: A read-only BI tool for analyzing various data sources"
19
- )
20
- parser.add_argument('--noimg', action='store_const',
21
- const=True, default=False,
22
- help='Return image file paths instead of images for visuals. Use when MCP client cannot render images.',
23
- )
24
- parser.add_argument('sources', nargs=argparse.REMAINDER, default=[],
25
- help='Data source (can be specified multiple times). Can be SQLite, MySQL, PostgreSQL connection string, or a path to CSV, Parquet, or DuckDB file.'
26
- )
27
- args = parser.parse_args()
28
-
29
- # Read and parse sources
30
- source_list = []
31
- if os.path.exists(SOURCES_FILE):
32
- with open(SOURCES_FILE) as f:
33
- source_list = [line.strip('\n') for line in f.readlines() if line.strip('\n')]
34
-
35
- if not source_list:
36
- source_list = args.sources
37
-
38
- if not source_list:
39
- source_list = [
40
- pkg_resources.resource_filename(
41
- 'zaturn',
42
- os.path.join('mcp', 'example_data', 'all_pokemon_data.csv')
43
- )
44
- ]
45
- print("No data sources provided. Loading example dataset for demonstration.")
46
- print(f"\nTo load your datasets, add them to {SOURCES_FILE} (one source URL or full file path per line)")
47
- print("\nOr use command line args to specify data sources:")
48
- print("zaturn_mcp sqlite:///path/to/mydata.db /path/to/my_file.csv")
49
- print(f"\nNOTE: Sources in command line args will be ignored if sources are found in {SOURCES_FILE}")
50
-
51
- CLI_SOURCES = {}
52
- for s in source_list:
53
- source = s.lower()
54
- if source.startswith('sqlite://'):
55
- source_type = 'sqlite'
56
- source_name = source.split('/')[-1].split('?')[0].split('.db')[0]
57
- elif source.startswith('postgresql://'):
58
- source_type = 'postgresql'
59
- source_name = source.split('/')[-1].split('?')[0]
60
- elif source.startswith("mysql://") or source.startswith("mysql+pymysql://"):
61
- source_type = 'mysql'
62
- s = s.replace('mysql://', 'mysql+pymysql://')
63
- source_name = source.split('/')[-1].split('?')[0]
64
- elif source.startswith('clickhouse://'):
65
- source_type = 'clickhouse'
66
- source_name = source.split('/')[-1].split('?')[0]
67
- elif source.endswith(".duckdb"):
68
- source_type = "duckdb"
69
- source_name = source.split('/')[-1].split('.')[0]
70
- elif source.endswith(".csv"):
71
- source_type = "csv"
72
- source_name = source.split('/')[-1].split('.')[0]
73
- elif source.endswith(".parquet") or source.endswith(".pq"):
74
- source_type = "parquet"
75
- source_name = source.split('/')[-1].split('.')[0]
76
- else:
77
- continue
78
-
79
- source_id = f'{source_name}-{source_type}'
80
- if source_id in CLI_SOURCES:
81
- i = 2
82
- while True:
83
- source_id = f'{source_name}{i}-{source_type}'
84
- if source_id not in SOURCES:
85
- break
86
- i += 1
87
-
88
- CLI_SOURCES[source_id] = {'url': s, 'type': source_type}
89
-
90
-
91
- # Other Settings
92
- CLI_RETURN_IMAGES = not args.noimg
93
-
94
-
95
-
@@ -30,6 +30,10 @@ def list_tables(source):
30
30
  for col in list(result):
31
31
  if col.startswith("Tables_in_"):
32
32
  return result[col].to_list()
33
+
34
+ case "mssql":
35
+ result = execute_query(source, "SELECT name FROM sys.tables")
36
+ return result['name'].to_list()
33
37
 
34
38
  case "duckdb" | "csv" | "parquet" | "clickhouse":
35
39
  result = execute_query(source, "SHOW TABLES")
@@ -46,7 +50,7 @@ def describe_table(source, table_name):
46
50
  f'PRAGMA table_info("{table_name}");'
47
51
  )
48
52
 
49
- case 'postgresql':
53
+ case 'postgresql' | 'mssql':
50
54
  return execute_query(source,
51
55
  f"SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '{table_name}';"
52
56
  )
@@ -81,6 +85,14 @@ def execute_query(source: dict, query: str):
81
85
  result = session.execute(sqlalchemy.text(query))
82
86
  return pd.DataFrame(result)
83
87
 
88
+ case "mssql":
89
+ engine = sqlalchemy.create_engine(url)
90
+ with Session(engine) as session:
91
+ # no known way to ensure read-only here
92
+ # please use read-only credentials
93
+ result = session.execute(sqlalchemy.text(query))
94
+ return pd.DataFrame(result)
95
+
84
96
  case "postgresql":
85
97
  engine = sqlalchemy.create_engine(url)
86
98
  with engine.connect() as conn:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zaturn
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: AI Data Analysis MCP & Studio
5
5
  Author-email: Karthik Devan <krtdvn@gmail.com>
6
6
  Maintainer-email: Karthik Devan <krtdvn@gmail.com>
@@ -25,6 +25,7 @@ Requires-Dist: platformdirs>=4.3.7
25
25
  Requires-Dist: plotly[express]>=6.0.1
26
26
  Requires-Dist: psycopg2-binary>=2.9.10
27
27
  Requires-Dist: pyarrow>=19.0.1
28
+ Requires-Dist: pymssql>=2.3.7
28
29
  Requires-Dist: pymysql>=1.1.1
29
30
  Requires-Dist: python-lsp-server>=1.12.2
30
31
  Requires-Dist: python-slugify>=8.0.4
@@ -58,7 +59,7 @@ https://github.com/user-attachments/assets/d42dc433-e5ec-4b3e-bef0-5cfc097396ab
58
59
  ### Multiple Data Sources
59
60
 
60
61
  Zaturn can currently connect to the following data sources:
61
- - SQL Databases: PostgreSQL, SQLite, DuckDB, MySQL, ClickHouse
62
+ - SQL Databases: PostgreSQL, SQLite, DuckDB, MySQL, ClickHouse, SQL Server
62
63
  - Files: CSV, Parquet
63
64
 
64
65
  Connectors for more data sources are being added.
@@ -77,7 +78,7 @@ More visualization capabilities are being added.
77
78
 
78
79
  ## Installation & Setup
79
80
 
80
- See [https://zaturn.pro/install](https://zaturn.pro/install)
81
+ See [https://zaturn.pro/docs/install](https://zaturn.pro/docs/install)
81
82
 
82
83
 
83
84
  ## Roadmap
@@ -97,7 +98,6 @@ Analyst:
97
98
  I can get it done right now. Actually, you can do it right now.
98
99
  You know what? The boss can do it right now.
99
100
  ```
100
- - A native notebook interface
101
101
 
102
102
  ## Help And Feedback
103
103
 
@@ -1,4 +1,4 @@
1
- zaturn/mcp/__init__.py,sha256=-fyROX8LHX1UXiLYE3kk17pXIILW-DVrFviechA57Pg,3213
1
+ zaturn/mcp/__init__.py,sha256=8pTcOyJ3tK7TJcP4HBDVQA_MVuMrfYJwa8sWKfCvXIE,3466
2
2
  zaturn/studio/__init__.py,sha256=A1QxWydtsE0VmsJlvF7O9Fx1-WKjV3MBPje7knFSDzw,83
3
3
  zaturn/studio/agent_wrapper.py,sha256=4mEMRfE1Tfv63D7OIabqUbEJdIgO2yo8UXO6PKvNrmI,4603
4
4
  zaturn/studio/app.py,sha256=LEoSjs5wpZGX1B7pcJ2e_6CaxOFjbO6JitxlkJv__30,9208
@@ -26,14 +26,14 @@ zaturn/studio/templates/setup_prompt.html,sha256=K8l3ewlEyrUFiMmw2qPyDFbFNkq1RCB
26
26
  zaturn/studio/templates/user_message.html,sha256=WbvdVr4AVzVx6MG0eQ_ulMeHB9rpScZc-EZlCoYFEgw,90
27
27
  zaturn/studio/templates/css/style.css,sha256=cKImLAjLp6XjHdT16v9yJS0DHG2wWx8djR18SHfMqvE,6264
28
28
  zaturn/tools/__init__.py,sha256=vOcHneRuZll9k-2e3sra7m8qfdc4IoAFYc2g_xK79HE,262
29
- zaturn/tools/config.py,sha256=8YCwFp1emhEfbbJd_KTQ_Nrl4yt9tJoDZHgMXatJGjk,3382
29
+ zaturn/tools/config.py,sha256=Ia-WzK_G6vQqB7norvaffb3fKLjtmXupVqAWsxdu6Gs,354
30
30
  zaturn/tools/core.py,sha256=4fHxSIbO22cTIejJk02GzUBfWimh1Ql9mZ3JgI1qLBY,2893
31
- zaturn/tools/query_utils.py,sha256=x769ZrpbnpxHwdQf6PbAUx6-qMGWuqfMOTA3kVjRUcE,4808
31
+ zaturn/tools/query_utils.py,sha256=OnXbONmEgsHcScrJ76b7P3BRLOKgi8TMkhxBcLQK9cY,5306
32
32
  zaturn/tools/visualizations.py,sha256=aPXCN1YIjCz6uiwJjduKCiLLtnBFX92hTvjy5EqQYk8,9509
33
33
  zaturn/tools/example_data/all_pokemon_data.csv,sha256=SUlGHHWbehuLg-ch1YUrQ6-xBtqHGw6rIkyn70fAgCk,130893
34
- zaturn-0.2.0.dist-info/licenses/LICENSE,sha256=mZSuFlbEBZGl0-8ULRMLdRDbhau5hrWRNQOjytYeaug,1070
35
- zaturn-0.2.0.dist-info/METADATA,sha256=9_odOtbZ5NNo5nu5hDOXIEWG1TlIlxr39DdDVakp_pg,3957
36
- zaturn-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
- zaturn-0.2.0.dist-info/entry_points.txt,sha256=MWMWX0dE_ZQM4StGKCLxJym_D91F82RcBi2LBj0hEho,82
38
- zaturn-0.2.0.dist-info/top_level.txt,sha256=KLUnwQwVZkfd5YCnnqR35MOOs8KLhanPGelvmRo2MVA,7
39
- zaturn-0.2.0.dist-info/RECORD,,
34
+ zaturn-0.2.2.dist-info/licenses/LICENSE,sha256=mZSuFlbEBZGl0-8ULRMLdRDbhau5hrWRNQOjytYeaug,1070
35
+ zaturn-0.2.2.dist-info/METADATA,sha256=BSnrqH9k7MNfqmRVPEO6q3884y-8Ym1X6ctklZz6NZc,3978
36
+ zaturn-0.2.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ zaturn-0.2.2.dist-info/entry_points.txt,sha256=MWMWX0dE_ZQM4StGKCLxJym_D91F82RcBi2LBj0hEho,82
38
+ zaturn-0.2.2.dist-info/top_level.txt,sha256=KLUnwQwVZkfd5YCnnqR35MOOs8KLhanPGelvmRo2MVA,7
39
+ zaturn-0.2.2.dist-info/RECORD,,
File without changes