zaturn 0.1.4__tar.gz → 0.1.6__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.
- zaturn-0.1.6/CHANGELOG.md +6 -0
- {zaturn-0.1.4/zaturn.egg-info → zaturn-0.1.6}/PKG-INFO +16 -3
- {zaturn-0.1.4 → zaturn-0.1.6}/README.md +12 -2
- {zaturn-0.1.4 → zaturn-0.1.6}/pyproject.toml +4 -1
- {zaturn-0.1.4 → zaturn-0.1.6}/uv.lock +192 -1
- {zaturn-0.1.4 → zaturn-0.1.6}/zaturn/config.py +3 -0
- {zaturn-0.1.4 → zaturn-0.1.6}/zaturn/core.py +2 -2
- {zaturn-0.1.4 → zaturn-0.1.6}/zaturn/query_utils.py +6 -0
- zaturn-0.1.6/zaturn/visualizations.py +155 -0
- {zaturn-0.1.4 → zaturn-0.1.6/zaturn.egg-info}/PKG-INFO +16 -3
- {zaturn-0.1.4 → zaturn-0.1.6}/zaturn.egg-info/SOURCES.txt +2 -1
- {zaturn-0.1.4 → zaturn-0.1.6}/zaturn.egg-info/requires.txt +3 -0
- zaturn-0.1.4/zaturn/visualizations.py +0 -203
- {zaturn-0.1.4 → zaturn-0.1.6}/.gitignore +0 -0
- {zaturn-0.1.4 → zaturn-0.1.6}/LICENSE +0 -0
- {zaturn-0.1.4 → zaturn-0.1.6}/brand/logo.png +0 -0
- {zaturn-0.1.4 → zaturn-0.1.6}/brand/logo.svg +0 -0
- /zaturn-0.1.4/debug_server.py → /zaturn-0.1.6/run_sse_server.py +0 -0
- {zaturn-0.1.4 → zaturn-0.1.6}/setup.cfg +0 -0
- {zaturn-0.1.4 → zaturn-0.1.6}/zaturn/__init__.py +0 -0
- {zaturn-0.1.4 → zaturn-0.1.6}/zaturn/example_data/all_pokemon_data.csv +0 -0
- {zaturn-0.1.4 → zaturn-0.1.6}/zaturn.egg-info/dependency_links.txt +0 -0
- {zaturn-0.1.4 → zaturn-0.1.6}/zaturn.egg-info/entry_points.txt +0 -0
- {zaturn-0.1.4 → zaturn-0.1.6}/zaturn.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: zaturn
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.6
|
4
4
|
Summary: AI Data Analysis MCP
|
5
5
|
Author-email: Karthik Devan <krtdvn@gmail.com>
|
6
6
|
Maintainer-email: Karthik Devan <krtdvn@gmail.com>
|
@@ -9,11 +9,14 @@ Project-URL: Issues, https://github.com/kdqed/zaturn/issues
|
|
9
9
|
Requires-Python: >=3.11
|
10
10
|
Description-Content-Type: text/markdown
|
11
11
|
License-File: LICENSE
|
12
|
+
Requires-Dist: clickhouse-connect>=0.8.17
|
12
13
|
Requires-Dist: cryptography>=44.0.2
|
13
14
|
Requires-Dist: duckdb>=1.2.1
|
14
15
|
Requires-Dist: fastmcp>=0.4.1
|
16
|
+
Requires-Dist: kaleido==0.2.1
|
15
17
|
Requires-Dist: pandas>=2.2.3
|
16
18
|
Requires-Dist: platformdirs>=4.3.7
|
19
|
+
Requires-Dist: plotly[express]>=6.0.1
|
17
20
|
Requires-Dist: psycopg2-binary>=2.9.10
|
18
21
|
Requires-Dist: pyarrow>=19.0.1
|
19
22
|
Requires-Dist: pymysql>=1.1.1
|
@@ -54,7 +57,7 @@ https://github.com/user-attachments/assets/d42dc433-e5ec-4b3e-bef0-5cfc097396ab
|
|
54
57
|
|
55
58
|
### Multiple Data Sources
|
56
59
|
Zaturn can currently connect to the following data sources:
|
57
|
-
- SQL Databases: PostgreSQL, SQLite, DuckDB, MySQL
|
60
|
+
- SQL Databases: PostgreSQL, SQLite, DuckDB, MySQL, ClickHouse
|
58
61
|
- Files: CSV, Parquet
|
59
62
|
|
60
63
|
Connectors for more data sources are being added.
|
@@ -103,6 +106,7 @@ OR add a `sources.txt` to the Zaturn config directory:
|
|
103
106
|
```
|
104
107
|
postgresql://username:password@host:port/dbname
|
105
108
|
mysql+pymysql://username:password@host:3306/dbname
|
109
|
+
clickhouse://username:password@host:port/dbname
|
106
110
|
sqlite:////full/path/to/sample_dbs/northwind.db
|
107
111
|
/full/path/to/sample_dbs/titanic.parquet
|
108
112
|
/full/path/to/sample_dbs/ny_aq.csv
|
@@ -158,11 +162,20 @@ Analyst:
|
|
158
162
|
```
|
159
163
|
- A native notebook interface
|
160
164
|
|
161
|
-
##
|
165
|
+
## Help And Feedback
|
162
166
|
|
163
167
|
[Raise an issue](https://github.com/kdqed/zaturn/issues) or [join the Discord](https://discord.gg/K8mECeVzpQ).
|
164
168
|
|
165
169
|
|
170
|
+
## Support The Project
|
171
|
+
|
172
|
+
If you find Zaturn useful, please support this project by:
|
173
|
+
- Starring the Project
|
174
|
+
- Spreading the word
|
175
|
+
- [Pledging $9/month on Patreon](https://www.patreon.com/kdqed?utm_medium=github&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink)
|
176
|
+
|
177
|
+
Your support will enable me to dedicate more of my time to Zaturn.
|
178
|
+
|
166
179
|
## Example Dataset Credits
|
167
180
|
|
168
181
|
The [pokemon dataset compiled by Sarah Taha and PokéAPI](https://www.kaggle.com/datasets/sarahtaha/1025-pokemon) has been included under the [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) license for demonstration purposes.
|
@@ -28,7 +28,7 @@ https://github.com/user-attachments/assets/d42dc433-e5ec-4b3e-bef0-5cfc097396ab
|
|
28
28
|
|
29
29
|
### Multiple Data Sources
|
30
30
|
Zaturn can currently connect to the following data sources:
|
31
|
-
- SQL Databases: PostgreSQL, SQLite, DuckDB, MySQL
|
31
|
+
- SQL Databases: PostgreSQL, SQLite, DuckDB, MySQL, ClickHouse
|
32
32
|
- Files: CSV, Parquet
|
33
33
|
|
34
34
|
Connectors for more data sources are being added.
|
@@ -77,6 +77,7 @@ OR add a `sources.txt` to the Zaturn config directory:
|
|
77
77
|
```
|
78
78
|
postgresql://username:password@host:port/dbname
|
79
79
|
mysql+pymysql://username:password@host:3306/dbname
|
80
|
+
clickhouse://username:password@host:port/dbname
|
80
81
|
sqlite:////full/path/to/sample_dbs/northwind.db
|
81
82
|
/full/path/to/sample_dbs/titanic.parquet
|
82
83
|
/full/path/to/sample_dbs/ny_aq.csv
|
@@ -132,11 +133,20 @@ Analyst:
|
|
132
133
|
```
|
133
134
|
- A native notebook interface
|
134
135
|
|
135
|
-
##
|
136
|
+
## Help And Feedback
|
136
137
|
|
137
138
|
[Raise an issue](https://github.com/kdqed/zaturn/issues) or [join the Discord](https://discord.gg/K8mECeVzpQ).
|
138
139
|
|
139
140
|
|
141
|
+
## Support The Project
|
142
|
+
|
143
|
+
If you find Zaturn useful, please support this project by:
|
144
|
+
- Starring the Project
|
145
|
+
- Spreading the word
|
146
|
+
- [Pledging $9/month on Patreon](https://www.patreon.com/kdqed?utm_medium=github&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink)
|
147
|
+
|
148
|
+
Your support will enable me to dedicate more of my time to Zaturn.
|
149
|
+
|
140
150
|
## Example Dataset Credits
|
141
151
|
|
142
152
|
The [pokemon dataset compiled by Sarah Taha and PokéAPI](https://www.kaggle.com/datasets/sarahtaha/1025-pokemon) has been included under the [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) license for demonstration purposes.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "zaturn"
|
3
|
-
version = "0.1.
|
3
|
+
version = "0.1.6"
|
4
4
|
description = "AI Data Analysis MCP"
|
5
5
|
authors = [
|
6
6
|
{name = "Karthik Devan", email = "krtdvn@gmail.com"},
|
@@ -11,11 +11,14 @@ maintainers = [
|
|
11
11
|
readme = "README.md"
|
12
12
|
requires-python = ">=3.11"
|
13
13
|
dependencies = [
|
14
|
+
"clickhouse-connect>=0.8.17",
|
14
15
|
"cryptography>=44.0.2",
|
15
16
|
"duckdb>=1.2.1",
|
16
17
|
"fastmcp>=0.4.1",
|
18
|
+
"kaleido==0.2.1",
|
17
19
|
"pandas>=2.2.3",
|
18
20
|
"platformdirs>=4.3.7",
|
21
|
+
"plotly[express]>=6.0.1",
|
19
22
|
"psycopg2-binary>=2.9.10",
|
20
23
|
"pyarrow>=19.0.1",
|
21
24
|
"pymysql>=1.1.1",
|
@@ -95,6 +95,51 @@ wheels = [
|
|
95
95
|
{ url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 },
|
96
96
|
]
|
97
97
|
|
98
|
+
[[package]]
|
99
|
+
name = "clickhouse-connect"
|
100
|
+
version = "0.8.17"
|
101
|
+
source = { registry = "https://pypi.org/simple" }
|
102
|
+
dependencies = [
|
103
|
+
{ name = "certifi" },
|
104
|
+
{ name = "lz4" },
|
105
|
+
{ name = "pytz" },
|
106
|
+
{ name = "urllib3" },
|
107
|
+
{ name = "zstandard" },
|
108
|
+
]
|
109
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c2/c2/e46db00486e02007551ff9ba8880ebee9f6d564b26b9323bc9f83f961849/clickhouse_connect-0.8.17.tar.gz", hash = "sha256:16405a37f8229a83956fbc372598d03b876537ee3acf2a5ad2f660336879b3fa", size = 91247 }
|
110
|
+
wheels = [
|
111
|
+
{ url = "https://files.pythonhosted.org/packages/cb/31/2077ded60a46f7a4ac16ab23b73be1e817975e45dcfef4d8c1803f4e84cc/clickhouse_connect-0.8.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d292a4c73ec863115875b91533003427ef4cdd4931e899064488ce2c75d22d4e", size = 258605 },
|
112
|
+
{ url = "https://files.pythonhosted.org/packages/6d/b6/744f7f9664d9611b5835cc9b8c5d27ae2c6e826bd974712dccd8be4c31ec/clickhouse_connect-0.8.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:45f3d55bf17ff69f63ca0150cdd77436d35f5cf85e672056798befe06651b78c", size = 251649 },
|
113
|
+
{ url = "https://files.pythonhosted.org/packages/63/53/b03dfd20fd8fa090c4d6d70f96b2e2e44574408de2561d6b68fbb6dd371e/clickhouse_connect-0.8.17-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ecc8539cdbcde71394d242665329ad3d32477a9a8d21449876f4a841def0a2d", size = 1061626 },
|
114
|
+
{ url = "https://files.pythonhosted.org/packages/33/3f/c1f80477ab5b90d8e50480410d1f384ca1fdbf800c6e5b72a029699cffb6/clickhouse_connect-0.8.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab35c6eec3758c65d61fe6f96bd13e242f7a7cd27dcb6fbe527db0285011f400", size = 1072472 },
|
115
|
+
{ url = "https://files.pythonhosted.org/packages/22/08/076fa97e065ac5b5bc8d50c5ea24f9ac852c5b6d2f60ee2f54b57eb230b2/clickhouse_connect-0.8.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2227650d3cf34f3b1bafc207ec113697e58b7b08f0947014e5d66f2687d702", size = 1034338 },
|
116
|
+
{ url = "https://files.pythonhosted.org/packages/f2/01/5218d78c97683fd4789030287fcc7f239003e93bad71634c5c58b3535afc/clickhouse_connect-0.8.17-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c25c76a07ab2d4188b9923d76a61bf6f6e7a1a9e702ec1124cff4478e4bc3b7", size = 1066617 },
|
117
|
+
{ url = "https://files.pythonhosted.org/packages/0d/bb/3916a0a675245598d52ea4f72eb2ba2e1f79cc45aee632a48fd757c18a19/clickhouse_connect-0.8.17-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f257922b32949f18013bb52e71f50f2eb4667458d73d5782861b46e22081221f", size = 1072619 },
|
118
|
+
{ url = "https://files.pythonhosted.org/packages/78/8c/5feb108128ca33b687bb03bcc8ff52be35d26cbba291af9504f6aed55fd6/clickhouse_connect-0.8.17-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8b59c22ed333f20d547aaf9b1dbd5fd475b2861da8acbb59633503b41b51fdf2", size = 1103629 },
|
119
|
+
{ url = "https://files.pythonhosted.org/packages/58/c1/ce42d2381c29cd2b6a08ae7810639de95bc53051240ca87ab1c59f3da9ab/clickhouse_connect-0.8.17-cp311-cp311-win32.whl", hash = "sha256:6613e1b863535a94b438b946e0dc4619fe83d8a021d99f947d88eee95568838e", size = 229555 },
|
120
|
+
{ url = "https://files.pythonhosted.org/packages/4a/dd/050a2c10856ef08dce5c188c26c750881b6a2a7dd5be829eaab334cb0fb0/clickhouse_connect-0.8.17-cp311-cp311-win_amd64.whl", hash = "sha256:d6879fa613128229a397ea5f31612bc1731dad72759a7b566ee684c600e61c90", size = 247119 },
|
121
|
+
{ url = "https://files.pythonhosted.org/packages/3d/18/da233967602118f985088ae29ed7fa8b24a6893178ccce35ff6b09261606/clickhouse_connect-0.8.17-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ca0a9d39af57c269f2c26a3142ca31812bde82a5a176d89c2ee1b9500d1e471d", size = 262090 },
|
122
|
+
{ url = "https://files.pythonhosted.org/packages/61/cf/9a2efb2cc72bb2312bc3ca5464239b31388c537aef60278cbfbf8a0134ff/clickhouse_connect-0.8.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cac30623ed9ca51c3619751b23567901e8a85025e8c4fde11dc64292f68a3dee", size = 253789 },
|
123
|
+
{ url = "https://files.pythonhosted.org/packages/f7/75/7b083fcbc9e5b4e92a56c08a5eb943412d1a6e5c01b137bd62e06d56525d/clickhouse_connect-0.8.17-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e0f7f3dde0c9ffae210a402574bb3ea30a9fef1b6d1fbc81d95e67a8ac7799d", size = 1058039 },
|
124
|
+
{ url = "https://files.pythonhosted.org/packages/1a/58/339bd60c3d0a16eb793badd6a67bfdcbc13c10b0232ea7e6feae2390ba10/clickhouse_connect-0.8.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a85d11ff8d115a707ee91c86b96ef1d8e92e2c34ab3f3ce41241ec0ebae78d5", size = 1076405 },
|
125
|
+
{ url = "https://files.pythonhosted.org/packages/dd/e8/26dac5044f197f985c52263861f6771c39449e642fcad83374dbce1c70b0/clickhouse_connect-0.8.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32cfe3a81b8b3d58af62948c0cdfd3fe0aaab6e35299ddfe6a556c9c3c00c37d", size = 1031665 },
|
126
|
+
{ url = "https://files.pythonhosted.org/packages/81/39/dd7977f111e77f16a4d7e7249104ef9a4a7c86c0569a3b792352c560a15e/clickhouse_connect-0.8.17-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ba1e360fa7a28f6dcfa584c82e0a03db26a71e91e14c115a2d70603eea43cbac", size = 1057311 },
|
127
|
+
{ url = "https://files.pythonhosted.org/packages/3d/68/a46278e295658cc508ffc33b008491a8e14d85ebd60873167aaf0f8c9cc1/clickhouse_connect-0.8.17-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4ea849c2dcb1712fd209d8b58fe3fcf016b65b30ff6aadae444194f470bbd800", size = 1073995 },
|
128
|
+
{ url = "https://files.pythonhosted.org/packages/12/9e/095de494d63ebf0f90369b4f3ef9c50de0488a0e2771e84aa767ee99f743/clickhouse_connect-0.8.17-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d0a34eb004e0dcbc1583d4fc31918e665794cdcc242150f1e699c75a7aa46b7d", size = 1099316 },
|
129
|
+
{ url = "https://files.pythonhosted.org/packages/87/35/3c1335dab9184985b5e73b6f31dda60ba56ab7d05b6c43bf89339eda031b/clickhouse_connect-0.8.17-cp312-cp312-win32.whl", hash = "sha256:b77f5c8aca4d7ed87649afbda1eea62cd16406c74029e85f28512b24c2165106", size = 229349 },
|
130
|
+
{ url = "https://files.pythonhosted.org/packages/10/3c/e507a6bd392c6618c90deb634a7447a9e11af41dc66e9f141c117d8de232/clickhouse_connect-0.8.17-cp312-cp312-win_amd64.whl", hash = "sha256:01903b8989afc3cf60f959695d56e38c20033a3dbb88aae42af857eb16e028b0", size = 247420 },
|
131
|
+
{ url = "https://files.pythonhosted.org/packages/83/17/918d5c2396426502ad4ed84b314f3699b8d0834f9741823ba59362aa8205/clickhouse_connect-0.8.17-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f0772cc3de3df5a460c2a5a4ef5b3737da7bfbc93b91e88000cf712f5a7ab5f9", size = 259327 },
|
132
|
+
{ url = "https://files.pythonhosted.org/packages/43/ce/fb6374bab859d145c403d49cb270998c2fa92f8eac1291fb2dad963e27d6/clickhouse_connect-0.8.17-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dffcb1767c684eac1ae9f2fb5c40cc98e23bd3b57f9fb090cd31f4fd2add898b", size = 250996 },
|
133
|
+
{ url = "https://files.pythonhosted.org/packages/67/e4/b749f0b402781140702775e2b9d7674679f104b8701034252d51f1fc5194/clickhouse_connect-0.8.17-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b1bd03750e69b2f278fff6e041a5d8b059656735e4d8c60ee82d647645481f1", size = 1041001 },
|
134
|
+
{ url = "https://files.pythonhosted.org/packages/9f/ec/84745d52d9e15449234debee0b90789113bd057347f87cee582ce59100d0/clickhouse_connect-0.8.17-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:030395cbd6e64e467f004fe481346849e482d38a87004103df7a806835851171", size = 1059424 },
|
135
|
+
{ url = "https://files.pythonhosted.org/packages/71/d2/8e55c77aad1882ac210a8ec0924bd4bc771a03f390991d4768f42992ea16/clickhouse_connect-0.8.17-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e44328e12997d361e02d1f8208e1f151133d372f8ef85a524fc622385e69096", size = 1015033 },
|
136
|
+
{ url = "https://files.pythonhosted.org/packages/6c/ae/b37a84923675437e88d8974bf15e75368a781767fd556861205dbd9d2a43/clickhouse_connect-0.8.17-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44a00808be2c72754e0c0c76005a9ecdb9ef08cb5490f82c45224455ccb47b1c", size = 1042049 },
|
137
|
+
{ url = "https://files.pythonhosted.org/packages/0c/46/214b8bd87b6a56c2d7bf31edc48c5ea2ffa0b1485ced97f198befd1d232e/clickhouse_connect-0.8.17-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4ab8ea92a2b48dd09f26a491989628244a29231d56731aa53e29b10a8fcabe7e", size = 1057463 },
|
138
|
+
{ url = "https://files.pythonhosted.org/packages/fc/e1/551af37d606b4ae39ddc254bc1348787dc02d1af53748f9a4d522653e61c/clickhouse_connect-0.8.17-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a6b2111c0b5cecef6f63f57af4e882fe7289918d5f61fd16068b721878e8610f", size = 1084897 },
|
139
|
+
{ url = "https://files.pythonhosted.org/packages/88/e7/b5059eb293e4d1968385854471fe50c7f1196085bc99e9a439a8798fa367/clickhouse_connect-0.8.17-cp313-cp313-win32.whl", hash = "sha256:8430adebbbb401a80357a81c55c8cf42ff1c6f272c12130c22046c0f4225c399", size = 228640 },
|
140
|
+
{ url = "https://files.pythonhosted.org/packages/b7/8f/a9be019232982608cf9619a746d46215951d62a4aecbdc3241219c523251/clickhouse_connect-0.8.17-cp313-cp313-win_amd64.whl", hash = "sha256:097209544de81c8c4a5e659c50089066bd92ebfb4a0c96cc7853f7c98bbf7487", size = 246393 },
|
141
|
+
]
|
142
|
+
|
98
143
|
[[package]]
|
99
144
|
name = "colorama"
|
100
145
|
version = "0.4.6"
|
@@ -445,6 +490,19 @@ wheels = [
|
|
445
490
|
{ url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 },
|
446
491
|
]
|
447
492
|
|
493
|
+
[[package]]
|
494
|
+
name = "kaleido"
|
495
|
+
version = "0.2.1"
|
496
|
+
source = { registry = "https://pypi.org/simple" }
|
497
|
+
wheels = [
|
498
|
+
{ url = "https://files.pythonhosted.org/packages/e0/f7/0ccaa596ec341963adbb4f839774c36d5659e75a0812d946732b927d480e/kaleido-0.2.1-py2.py3-none-macosx_10_11_x86_64.whl", hash = "sha256:ca6f73e7ff00aaebf2843f73f1d3bacde1930ef5041093fe76b83a15785049a7", size = 85153681 },
|
499
|
+
{ url = "https://files.pythonhosted.org/packages/45/8e/4297556be5a07b713bb42dde0f748354de9a6918dee251c0e6bdcda341e7/kaleido-0.2.1-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:bb9a5d1f710357d5d432ee240ef6658a6d124c3e610935817b4b42da9c787c05", size = 85808197 },
|
500
|
+
{ url = "https://files.pythonhosted.org/packages/ae/b3/a0f0f4faac229b0011d8c4a7ee6da7c2dca0b6fd08039c95920846f23ca4/kaleido-0.2.1-py2.py3-none-manylinux1_x86_64.whl", hash = "sha256:aa21cf1bf1c78f8fa50a9f7d45e1003c387bd3d6fe0a767cfbbf344b95bdc3a8", size = 79902476 },
|
501
|
+
{ url = "https://files.pythonhosted.org/packages/a1/2b/680662678a57afab1685f0c431c2aba7783ce4344f06ec162074d485d469/kaleido-0.2.1-py2.py3-none-manylinux2014_aarch64.whl", hash = "sha256:845819844c8082c9469d9c17e42621fbf85c2b237ef8a86ec8a8527f98b6512a", size = 83711746 },
|
502
|
+
{ url = "https://files.pythonhosted.org/packages/88/89/4b6f8bb3f9ab036fd4ad1cb2d628ab5c81db32ac9aa0641d7b180073ba43/kaleido-0.2.1-py2.py3-none-win32.whl", hash = "sha256:ecc72635860be616c6b7161807a65c0dbd9b90c6437ac96965831e2e24066552", size = 62312480 },
|
503
|
+
{ url = "https://files.pythonhosted.org/packages/f7/9a/0408b02a4bcb3cf8b338a2b074ac7d1b2099e2b092b42473def22f7b625f/kaleido-0.2.1-py2.py3-none-win_amd64.whl", hash = "sha256:4670985f28913c2d063c5734d125ecc28e40810141bdb0a46f15b76c1d45f23c", size = 65945521 },
|
504
|
+
]
|
505
|
+
|
448
506
|
[[package]]
|
449
507
|
name = "kiwisolver"
|
450
508
|
version = "1.4.8"
|
@@ -511,6 +569,38 @@ wheels = [
|
|
511
569
|
{ url = "https://files.pythonhosted.org/packages/4c/fa/be89a49c640930180657482a74970cdcf6f7072c8d2471e1babe17a222dc/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:be4816dc51c8a471749d664161b434912eee82f2ea66bd7628bd14583a833e85", size = 2349213 },
|
512
570
|
]
|
513
571
|
|
572
|
+
[[package]]
|
573
|
+
name = "lz4"
|
574
|
+
version = "4.4.4"
|
575
|
+
source = { registry = "https://pypi.org/simple" }
|
576
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c6/5a/945f5086326d569f14c84ac6f7fcc3229f0b9b1e8cc536b951fd53dfb9e1/lz4-4.4.4.tar.gz", hash = "sha256:070fd0627ec4393011251a094e08ed9fdcc78cb4e7ab28f507638eee4e39abda", size = 171884 }
|
577
|
+
wheels = [
|
578
|
+
{ url = "https://files.pythonhosted.org/packages/28/e8/63843dc5ecb1529eb38e1761ceed04a0ad52a9ad8929ab8b7930ea2e4976/lz4-4.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ddfc7194cd206496c445e9e5b0c47f970ce982c725c87bd22de028884125b68f", size = 220898 },
|
579
|
+
{ url = "https://files.pythonhosted.org/packages/e4/94/c53de5f07c7dc11cf459aab2a1d754f5df5f693bfacbbe1e4914bfd02f1e/lz4-4.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:714f9298c86f8e7278f1c6af23e509044782fa8220eb0260f8f8f1632f820550", size = 189685 },
|
580
|
+
{ url = "https://files.pythonhosted.org/packages/fe/59/c22d516dd0352f2a3415d1f665ccef2f3e74ecec3ca6a8f061a38f97d50d/lz4-4.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8474c91de47733856c6686df3c4aca33753741da7e757979369c2c0d32918ba", size = 1239225 },
|
581
|
+
{ url = "https://files.pythonhosted.org/packages/81/af/665685072e71f3f0e626221b7922867ec249cd8376aca761078c8f11f5da/lz4-4.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80dd27d7d680ea02c261c226acf1d41de2fd77af4fb2da62b278a9376e380de0", size = 1265881 },
|
582
|
+
{ url = "https://files.pythonhosted.org/packages/90/04/b4557ae381d3aa451388a29755cc410066f5e2f78c847f66f154f4520a68/lz4-4.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b7d6dddfd01b49aedb940fdcaf32f41dc58c926ba35f4e31866aeec2f32f4f4", size = 1185593 },
|
583
|
+
{ url = "https://files.pythonhosted.org/packages/7b/e4/03636979f4e8bf92c557f998ca98ee4e6ef92e92eaf0ed6d3c7f2524e790/lz4-4.4.4-cp311-cp311-win32.whl", hash = "sha256:4134b9fd70ac41954c080b772816bb1afe0c8354ee993015a83430031d686a4c", size = 88259 },
|
584
|
+
{ url = "https://files.pythonhosted.org/packages/07/f0/9efe53b4945441a5d2790d455134843ad86739855b7e6199977bf6dc8898/lz4-4.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:f5024d3ca2383470f7c4ef4d0ed8eabad0b22b23eeefde1c192cf1a38d5e9f78", size = 99916 },
|
585
|
+
{ url = "https://files.pythonhosted.org/packages/87/c8/1675527549ee174b9e1db089f7ddfbb962a97314657269b1e0344a5eaf56/lz4-4.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:6ea715bb3357ea1665f77874cf8f55385ff112553db06f3742d3cdcec08633f7", size = 89741 },
|
586
|
+
{ url = "https://files.pythonhosted.org/packages/f7/2d/5523b4fabe11cd98f040f715728d1932eb7e696bfe94391872a823332b94/lz4-4.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:23ae267494fdd80f0d2a131beff890cf857f1b812ee72dbb96c3204aab725553", size = 220669 },
|
587
|
+
{ url = "https://files.pythonhosted.org/packages/91/06/1a5bbcacbfb48d8ee5b6eb3fca6aa84143a81d92946bdb5cd6b005f1863e/lz4-4.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fff9f3a1ed63d45cb6514bfb8293005dc4141341ce3500abdfeb76124c0b9b2e", size = 189661 },
|
588
|
+
{ url = "https://files.pythonhosted.org/packages/fa/08/39eb7ac907f73e11a69a11576a75a9e36406b3241c0ba41453a7eb842abb/lz4-4.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ea7f07329f85a8eda4d8cf937b87f27f0ac392c6400f18bea2c667c8b7f8ecc", size = 1238775 },
|
589
|
+
{ url = "https://files.pythonhosted.org/packages/e9/26/05840fbd4233e8d23e88411a066ab19f1e9de332edddb8df2b6a95c7fddc/lz4-4.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ccab8f7f7b82f9fa9fc3b0ba584d353bd5aa818d5821d77d5b9447faad2aaad", size = 1265143 },
|
590
|
+
{ url = "https://files.pythonhosted.org/packages/b7/5d/5f2db18c298a419932f3ab2023deb689863cf8fd7ed875b1c43492479af2/lz4-4.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43e9d48b2daf80e486213128b0763deed35bbb7a59b66d1681e205e1702d735", size = 1185032 },
|
591
|
+
{ url = "https://files.pythonhosted.org/packages/c4/e6/736ab5f128694b0f6aac58343bcf37163437ac95997276cd0be3ea4c3342/lz4-4.4.4-cp312-cp312-win32.whl", hash = "sha256:33e01e18e4561b0381b2c33d58e77ceee850a5067f0ece945064cbaac2176962", size = 88284 },
|
592
|
+
{ url = "https://files.pythonhosted.org/packages/40/b8/243430cb62319175070e06e3a94c4c7bd186a812e474e22148ae1290d47d/lz4-4.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:d21d1a2892a2dcc193163dd13eaadabb2c1b803807a5117d8f8588b22eaf9f12", size = 99918 },
|
593
|
+
{ url = "https://files.pythonhosted.org/packages/6c/e1/0686c91738f3e6c2e1a243e0fdd4371667c4d2e5009b0a3605806c2aa020/lz4-4.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:2f4f2965c98ab254feddf6b5072854a6935adab7bc81412ec4fe238f07b85f62", size = 89736 },
|
594
|
+
{ url = "https://files.pythonhosted.org/packages/3b/3c/d1d1b926d3688263893461e7c47ed7382a969a0976fc121fc678ec325fc6/lz4-4.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ed6eb9f8deaf25ee4f6fad9625d0955183fdc90c52b6f79a76b7f209af1b6e54", size = 220678 },
|
595
|
+
{ url = "https://files.pythonhosted.org/packages/26/89/8783d98deb058800dabe07e6cdc90f5a2a8502a9bad8c5343c641120ace2/lz4-4.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:18ae4fe3bafb344dbd09f976d45cbf49c05c34416f2462828f9572c1fa6d5af7", size = 189670 },
|
596
|
+
{ url = "https://files.pythonhosted.org/packages/22/ab/a491ace69a83a8914a49f7391e92ca0698f11b28d5ce7b2ececa2be28e9a/lz4-4.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57fd20c5fc1a49d1bbd170836fccf9a338847e73664f8e313dce6ac91b8c1e02", size = 1238746 },
|
597
|
+
{ url = "https://files.pythonhosted.org/packages/97/12/a1f2f4fdc6b7159c0d12249456f9fe454665b6126e98dbee9f2bd3cf735c/lz4-4.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9cb387c33f014dae4db8cb4ba789c8d2a0a6d045ddff6be13f6c8d9def1d2a6", size = 1265119 },
|
598
|
+
{ url = "https://files.pythonhosted.org/packages/50/6e/e22e50f5207649db6ea83cd31b79049118305be67e96bec60becf317afc6/lz4-4.4.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0be9f68240231e1e44118a4ebfecd8a5d4184f0bdf5c591c98dd6ade9720afd", size = 1184954 },
|
599
|
+
{ url = "https://files.pythonhosted.org/packages/4c/c4/2a458039645fcc6324ece731d4d1361c5daf960b553d1fcb4261ba07d51c/lz4-4.4.4-cp313-cp313-win32.whl", hash = "sha256:e9ec5d45ea43684f87c316542af061ef5febc6a6b322928f059ce1fb289c298a", size = 88289 },
|
600
|
+
{ url = "https://files.pythonhosted.org/packages/00/96/b8e24ea7537ab418074c226279acfcaa470e1ea8271003e24909b6db942b/lz4-4.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:a760a175b46325b2bb33b1f2bbfb8aa21b48e1b9653e29c10b6834f9bb44ead4", size = 99925 },
|
601
|
+
{ url = "https://files.pythonhosted.org/packages/a5/a5/f9838fe6aa132cfd22733ed2729d0592259fff074cefb80f19aa0607367b/lz4-4.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:f4c21648d81e0dda38b4720dccc9006ae33b0e9e7ffe88af6bf7d4ec124e2fba", size = 89743 },
|
602
|
+
]
|
603
|
+
|
514
604
|
[[package]]
|
515
605
|
name = "markdown-it-py"
|
516
606
|
version = "3.0.0"
|
@@ -594,6 +684,15 @@ wheels = [
|
|
594
684
|
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 },
|
595
685
|
]
|
596
686
|
|
687
|
+
[[package]]
|
688
|
+
name = "narwhals"
|
689
|
+
version = "1.35.0"
|
690
|
+
source = { registry = "https://pypi.org/simple" }
|
691
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ee/6a/a98fa5e9d530a428a0cd79d27f059ed65efd3a07aad61a8c93e323c9c20b/narwhals-1.35.0.tar.gz", hash = "sha256:07477d18487fbc940243b69818a177ed7119b737910a8a254fb67688b48a7c96", size = 265784 }
|
692
|
+
wheels = [
|
693
|
+
{ url = "https://files.pythonhosted.org/packages/80/b3/5781eb874f04cb1e882a7d93cf30abcb00362a3205c5f3708a7434a1a2ac/narwhals-1.35.0-py3-none-any.whl", hash = "sha256:7562af132fa3f8aaaf34dc96d7ec95bdca29d1c795e8fcf14e01edf1d32122bc", size = 325708 },
|
694
|
+
]
|
695
|
+
|
597
696
|
[[package]]
|
598
697
|
name = "numpy"
|
599
698
|
version = "2.2.4"
|
@@ -781,6 +880,24 @@ wheels = [
|
|
781
880
|
{ url = "https://files.pythonhosted.org/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94", size = 18499 },
|
782
881
|
]
|
783
882
|
|
883
|
+
[[package]]
|
884
|
+
name = "plotly"
|
885
|
+
version = "6.0.1"
|
886
|
+
source = { registry = "https://pypi.org/simple" }
|
887
|
+
dependencies = [
|
888
|
+
{ name = "narwhals" },
|
889
|
+
{ name = "packaging" },
|
890
|
+
]
|
891
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c7/cc/e41b5f697ae403f0b50e47b7af2e36642a193085f553bf7cc1169362873a/plotly-6.0.1.tar.gz", hash = "sha256:dd8400229872b6e3c964b099be699f8d00c489a974f2cfccfad5e8240873366b", size = 8094643 }
|
892
|
+
wheels = [
|
893
|
+
{ url = "https://files.pythonhosted.org/packages/02/65/ad2bc85f7377f5cfba5d4466d5474423a3fb7f6a97fd807c06f92dd3e721/plotly-6.0.1-py3-none-any.whl", hash = "sha256:4714db20fea57a435692c548a4eb4fae454f7daddf15f8d8ba7e1045681d7768", size = 14805757 },
|
894
|
+
]
|
895
|
+
|
896
|
+
[package.optional-dependencies]
|
897
|
+
express = [
|
898
|
+
{ name = "numpy" },
|
899
|
+
]
|
900
|
+
|
784
901
|
[[package]]
|
785
902
|
name = "pluggy"
|
786
903
|
version = "1.5.0"
|
@@ -1272,6 +1389,15 @@ wheels = [
|
|
1272
1389
|
{ url = "https://files.pythonhosted.org/packages/d7/72/6cb6728e2738c05bbe9bd522d6fc79f86b9a28402f38663e85a28fddd4a0/ujson-5.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:4573fd1695932d4f619928fd09d5d03d917274381649ade4328091ceca175539", size = 42212 },
|
1273
1390
|
]
|
1274
1391
|
|
1392
|
+
[[package]]
|
1393
|
+
name = "urllib3"
|
1394
|
+
version = "2.4.0"
|
1395
|
+
source = { registry = "https://pypi.org/simple" }
|
1396
|
+
sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672 }
|
1397
|
+
wheels = [
|
1398
|
+
{ url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680 },
|
1399
|
+
]
|
1400
|
+
|
1275
1401
|
[[package]]
|
1276
1402
|
name = "uvicorn"
|
1277
1403
|
version = "0.34.0"
|
@@ -1329,14 +1455,17 @@ wheels = [
|
|
1329
1455
|
|
1330
1456
|
[[package]]
|
1331
1457
|
name = "zaturn"
|
1332
|
-
version = "0.1.
|
1458
|
+
version = "0.1.5"
|
1333
1459
|
source = { editable = "." }
|
1334
1460
|
dependencies = [
|
1461
|
+
{ name = "clickhouse-connect" },
|
1335
1462
|
{ name = "cryptography" },
|
1336
1463
|
{ name = "duckdb" },
|
1337
1464
|
{ name = "fastmcp" },
|
1465
|
+
{ name = "kaleido" },
|
1338
1466
|
{ name = "pandas" },
|
1339
1467
|
{ name = "platformdirs" },
|
1468
|
+
{ name = "plotly", extra = ["express"] },
|
1340
1469
|
{ name = "psycopg2-binary" },
|
1341
1470
|
{ name = "pyarrow" },
|
1342
1471
|
{ name = "pymysql" },
|
@@ -1349,11 +1478,14 @@ dependencies = [
|
|
1349
1478
|
|
1350
1479
|
[package.metadata]
|
1351
1480
|
requires-dist = [
|
1481
|
+
{ name = "clickhouse-connect", specifier = ">=0.8.17" },
|
1352
1482
|
{ name = "cryptography", specifier = ">=44.0.2" },
|
1353
1483
|
{ name = "duckdb", specifier = ">=1.2.1" },
|
1354
1484
|
{ name = "fastmcp", specifier = ">=0.4.1" },
|
1485
|
+
{ name = "kaleido", specifier = "==0.2.1" },
|
1355
1486
|
{ name = "pandas", specifier = ">=2.2.3" },
|
1356
1487
|
{ name = "platformdirs", specifier = ">=4.3.7" },
|
1488
|
+
{ name = "plotly", extras = ["express"], specifier = ">=6.0.1" },
|
1357
1489
|
{ name = "psycopg2-binary", specifier = ">=2.9.10" },
|
1358
1490
|
{ name = "pyarrow", specifier = ">=19.0.1" },
|
1359
1491
|
{ name = "pymysql", specifier = ">=1.1.1" },
|
@@ -1375,3 +1507,62 @@ sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e
|
|
1375
1507
|
wheels = [
|
1376
1508
|
{ url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630 },
|
1377
1509
|
]
|
1510
|
+
|
1511
|
+
[[package]]
|
1512
|
+
name = "zstandard"
|
1513
|
+
version = "0.23.0"
|
1514
|
+
source = { registry = "https://pypi.org/simple" }
|
1515
|
+
dependencies = [
|
1516
|
+
{ name = "cffi", marker = "platform_python_implementation == 'PyPy'" },
|
1517
|
+
]
|
1518
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ed/f6/2ac0287b442160a89d726b17a9184a4c615bb5237db763791a7fd16d9df1/zstandard-0.23.0.tar.gz", hash = "sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09", size = 681701 }
|
1519
|
+
wheels = [
|
1520
|
+
{ url = "https://files.pythonhosted.org/packages/9e/40/f67e7d2c25a0e2dc1744dd781110b0b60306657f8696cafb7ad7579469bd/zstandard-0.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e", size = 788699 },
|
1521
|
+
{ url = "https://files.pythonhosted.org/packages/e8/46/66d5b55f4d737dd6ab75851b224abf0afe5774976fe511a54d2eb9063a41/zstandard-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23", size = 633681 },
|
1522
|
+
{ url = "https://files.pythonhosted.org/packages/63/b6/677e65c095d8e12b66b8f862b069bcf1f1d781b9c9c6f12eb55000d57583/zstandard-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a", size = 4944328 },
|
1523
|
+
{ url = "https://files.pythonhosted.org/packages/59/cc/e76acb4c42afa05a9d20827116d1f9287e9c32b7ad58cc3af0721ce2b481/zstandard-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db", size = 5311955 },
|
1524
|
+
{ url = "https://files.pythonhosted.org/packages/78/e4/644b8075f18fc7f632130c32e8f36f6dc1b93065bf2dd87f03223b187f26/zstandard-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2", size = 5344944 },
|
1525
|
+
{ url = "https://files.pythonhosted.org/packages/76/3f/dbafccf19cfeca25bbabf6f2dd81796b7218f768ec400f043edc767015a6/zstandard-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca", size = 5442927 },
|
1526
|
+
{ url = "https://files.pythonhosted.org/packages/0c/c3/d24a01a19b6733b9f218e94d1a87c477d523237e07f94899e1c10f6fd06c/zstandard-0.23.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c", size = 4864910 },
|
1527
|
+
{ url = "https://files.pythonhosted.org/packages/1c/a9/cf8f78ead4597264f7618d0875be01f9bc23c9d1d11afb6d225b867cb423/zstandard-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e", size = 4935544 },
|
1528
|
+
{ url = "https://files.pythonhosted.org/packages/2c/96/8af1e3731b67965fb995a940c04a2c20997a7b3b14826b9d1301cf160879/zstandard-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5", size = 5467094 },
|
1529
|
+
{ url = "https://files.pythonhosted.org/packages/ff/57/43ea9df642c636cb79f88a13ab07d92d88d3bfe3e550b55a25a07a26d878/zstandard-0.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48", size = 4860440 },
|
1530
|
+
{ url = "https://files.pythonhosted.org/packages/46/37/edb78f33c7f44f806525f27baa300341918fd4c4af9472fbc2c3094be2e8/zstandard-0.23.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c", size = 4700091 },
|
1531
|
+
{ url = "https://files.pythonhosted.org/packages/c1/f1/454ac3962671a754f3cb49242472df5c2cced4eb959ae203a377b45b1a3c/zstandard-0.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003", size = 5208682 },
|
1532
|
+
{ url = "https://files.pythonhosted.org/packages/85/b2/1734b0fff1634390b1b887202d557d2dd542de84a4c155c258cf75da4773/zstandard-0.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78", size = 5669707 },
|
1533
|
+
{ url = "https://files.pythonhosted.org/packages/52/5a/87d6971f0997c4b9b09c495bf92189fb63de86a83cadc4977dc19735f652/zstandard-0.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473", size = 5201792 },
|
1534
|
+
{ url = "https://files.pythonhosted.org/packages/79/02/6f6a42cc84459d399bd1a4e1adfc78d4dfe45e56d05b072008d10040e13b/zstandard-0.23.0-cp311-cp311-win32.whl", hash = "sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160", size = 430586 },
|
1535
|
+
{ url = "https://files.pythonhosted.org/packages/be/a2/4272175d47c623ff78196f3c10e9dc7045c1b9caf3735bf041e65271eca4/zstandard-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0", size = 495420 },
|
1536
|
+
{ url = "https://files.pythonhosted.org/packages/7b/83/f23338c963bd9de687d47bf32efe9fd30164e722ba27fb59df33e6b1719b/zstandard-0.23.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094", size = 788713 },
|
1537
|
+
{ url = "https://files.pythonhosted.org/packages/5b/b3/1a028f6750fd9227ee0b937a278a434ab7f7fdc3066c3173f64366fe2466/zstandard-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8", size = 633459 },
|
1538
|
+
{ url = "https://files.pythonhosted.org/packages/26/af/36d89aae0c1f95a0a98e50711bc5d92c144939efc1f81a2fcd3e78d7f4c1/zstandard-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1", size = 4945707 },
|
1539
|
+
{ url = "https://files.pythonhosted.org/packages/cd/2e/2051f5c772f4dfc0aae3741d5fc72c3dcfe3aaeb461cc231668a4db1ce14/zstandard-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072", size = 5306545 },
|
1540
|
+
{ url = "https://files.pythonhosted.org/packages/0a/9e/a11c97b087f89cab030fa71206963090d2fecd8eb83e67bb8f3ffb84c024/zstandard-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20", size = 5337533 },
|
1541
|
+
{ url = "https://files.pythonhosted.org/packages/fc/79/edeb217c57fe1bf16d890aa91a1c2c96b28c07b46afed54a5dcf310c3f6f/zstandard-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373", size = 5436510 },
|
1542
|
+
{ url = "https://files.pythonhosted.org/packages/81/4f/c21383d97cb7a422ddf1ae824b53ce4b51063d0eeb2afa757eb40804a8ef/zstandard-0.23.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db", size = 4859973 },
|
1543
|
+
{ url = "https://files.pythonhosted.org/packages/ab/15/08d22e87753304405ccac8be2493a495f529edd81d39a0870621462276ef/zstandard-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772", size = 4936968 },
|
1544
|
+
{ url = "https://files.pythonhosted.org/packages/eb/fa/f3670a597949fe7dcf38119a39f7da49a8a84a6f0b1a2e46b2f71a0ab83f/zstandard-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105", size = 5467179 },
|
1545
|
+
{ url = "https://files.pythonhosted.org/packages/4e/a9/dad2ab22020211e380adc477a1dbf9f109b1f8d94c614944843e20dc2a99/zstandard-0.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba", size = 4848577 },
|
1546
|
+
{ url = "https://files.pythonhosted.org/packages/08/03/dd28b4484b0770f1e23478413e01bee476ae8227bbc81561f9c329e12564/zstandard-0.23.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd", size = 4693899 },
|
1547
|
+
{ url = "https://files.pythonhosted.org/packages/2b/64/3da7497eb635d025841e958bcd66a86117ae320c3b14b0ae86e9e8627518/zstandard-0.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a", size = 5199964 },
|
1548
|
+
{ url = "https://files.pythonhosted.org/packages/43/a4/d82decbab158a0e8a6ebb7fc98bc4d903266bce85b6e9aaedea1d288338c/zstandard-0.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90", size = 5655398 },
|
1549
|
+
{ url = "https://files.pythonhosted.org/packages/f2/61/ac78a1263bc83a5cf29e7458b77a568eda5a8f81980691bbc6eb6a0d45cc/zstandard-0.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35", size = 5191313 },
|
1550
|
+
{ url = "https://files.pythonhosted.org/packages/e7/54/967c478314e16af5baf849b6ee9d6ea724ae5b100eb506011f045d3d4e16/zstandard-0.23.0-cp312-cp312-win32.whl", hash = "sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d", size = 430877 },
|
1551
|
+
{ url = "https://files.pythonhosted.org/packages/75/37/872d74bd7739639c4553bf94c84af7d54d8211b626b352bc57f0fd8d1e3f/zstandard-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b", size = 495595 },
|
1552
|
+
{ url = "https://files.pythonhosted.org/packages/80/f1/8386f3f7c10261fe85fbc2c012fdb3d4db793b921c9abcc995d8da1b7a80/zstandard-0.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9", size = 788975 },
|
1553
|
+
{ url = "https://files.pythonhosted.org/packages/16/e8/cbf01077550b3e5dc86089035ff8f6fbbb312bc0983757c2d1117ebba242/zstandard-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a", size = 633448 },
|
1554
|
+
{ url = "https://files.pythonhosted.org/packages/06/27/4a1b4c267c29a464a161aeb2589aff212b4db653a1d96bffe3598f3f0d22/zstandard-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2", size = 4945269 },
|
1555
|
+
{ url = "https://files.pythonhosted.org/packages/7c/64/d99261cc57afd9ae65b707e38045ed8269fbdae73544fd2e4a4d50d0ed83/zstandard-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5", size = 5306228 },
|
1556
|
+
{ url = "https://files.pythonhosted.org/packages/7a/cf/27b74c6f22541f0263016a0fd6369b1b7818941de639215c84e4e94b2a1c/zstandard-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f", size = 5336891 },
|
1557
|
+
{ url = "https://files.pythonhosted.org/packages/fa/18/89ac62eac46b69948bf35fcd90d37103f38722968e2981f752d69081ec4d/zstandard-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed", size = 5436310 },
|
1558
|
+
{ url = "https://files.pythonhosted.org/packages/a8/a8/5ca5328ee568a873f5118d5b5f70d1f36c6387716efe2e369010289a5738/zstandard-0.23.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea", size = 4859912 },
|
1559
|
+
{ url = "https://files.pythonhosted.org/packages/ea/ca/3781059c95fd0868658b1cf0440edd832b942f84ae60685d0cfdb808bca1/zstandard-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847", size = 4936946 },
|
1560
|
+
{ url = "https://files.pythonhosted.org/packages/ce/11/41a58986f809532742c2b832c53b74ba0e0a5dae7e8ab4642bf5876f35de/zstandard-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171", size = 5466994 },
|
1561
|
+
{ url = "https://files.pythonhosted.org/packages/83/e3/97d84fe95edd38d7053af05159465d298c8b20cebe9ccb3d26783faa9094/zstandard-0.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840", size = 4848681 },
|
1562
|
+
{ url = "https://files.pythonhosted.org/packages/6e/99/cb1e63e931de15c88af26085e3f2d9af9ce53ccafac73b6e48418fd5a6e6/zstandard-0.23.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690", size = 4694239 },
|
1563
|
+
{ url = "https://files.pythonhosted.org/packages/ab/50/b1e703016eebbc6501fc92f34db7b1c68e54e567ef39e6e59cf5fb6f2ec0/zstandard-0.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b", size = 5200149 },
|
1564
|
+
{ url = "https://files.pythonhosted.org/packages/aa/e0/932388630aaba70197c78bdb10cce2c91fae01a7e553b76ce85471aec690/zstandard-0.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057", size = 5655392 },
|
1565
|
+
{ url = "https://files.pythonhosted.org/packages/02/90/2633473864f67a15526324b007a9f96c96f56d5f32ef2a56cc12f9548723/zstandard-0.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33", size = 5191299 },
|
1566
|
+
{ url = "https://files.pythonhosted.org/packages/b0/4c/315ca5c32da7e2dc3455f3b2caee5c8c2246074a61aac6ec3378a97b7136/zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd", size = 430862 },
|
1567
|
+
{ url = "https://files.pythonhosted.org/packages/a2/bf/c6aaba098e2d04781e8f4f7c0ba3c7aa73d00e4c436bcc0cf059a66691d1/zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b", size = 495578 },
|
1568
|
+
]
|
@@ -62,6 +62,9 @@ for s in source_list:
|
|
62
62
|
elif source.startswith("mysql+pymysql://"):
|
63
63
|
source_type = 'mysql'
|
64
64
|
source_name = source.split('/')[-1].split('?')[0]
|
65
|
+
elif source.startswith('clickhouse://'):
|
66
|
+
source_type = 'clickhouse'
|
67
|
+
source_name = source.split('/')[-1].split('?')[0]
|
65
68
|
elif source.endswith(".duckdb"):
|
66
69
|
source_type = "duckdb"
|
67
70
|
source_name = source.split('/')[-1].split('.')[0]
|
@@ -62,7 +62,7 @@ def _list_tables(source_id: str):
|
|
62
62
|
if col.startswith("Tables_in_"):
|
63
63
|
return result[col].to_list()
|
64
64
|
|
65
|
-
case "duckdb" | "csv" | "parquet":
|
65
|
+
case "duckdb" | "csv" | "parquet" | "clickhouse":
|
66
66
|
result = query_utils.execute_query(source, "SHOW TABLES")
|
67
67
|
return result['name'].to_list()
|
68
68
|
|
@@ -96,7 +96,7 @@ def describe_table(source_id: str, table_name: str) -> str:
|
|
96
96
|
)
|
97
97
|
return result.to_markdown(index=False)
|
98
98
|
|
99
|
-
case "mysql" | "duckdb" | "csv" | "parquet":
|
99
|
+
case "mysql" | "duckdb" | "csv" | "parquet" | "clickhouse":
|
100
100
|
result = query_utils.execute_query(source,
|
101
101
|
f"DESCRIBE {table_name};"
|
102
102
|
)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import clickhouse_connect
|
1
2
|
import duckdb
|
2
3
|
import numpy as np
|
3
4
|
import os
|
@@ -46,6 +47,11 @@ def execute_query(source: dict, query: str):
|
|
46
47
|
result = conn.execute(sqlalchemy.text(query))
|
47
48
|
return pd.DataFrame(result)
|
48
49
|
|
50
|
+
case "clickhouse":
|
51
|
+
client = clickhouse_connect.get_client(dsn=url)
|
52
|
+
client.query('SET readonly=1;')
|
53
|
+
return client.query_df(query, use_extended_dtypes=False)
|
54
|
+
|
49
55
|
case "duckdb":
|
50
56
|
conn = duckdb.connect(url, read_only=True)
|
51
57
|
return conn.execute(query).df()
|
@@ -0,0 +1,155 @@
|
|
1
|
+
from fastmcp import FastMCP, Image
|
2
|
+
import math
|
3
|
+
import os
|
4
|
+
import plotly.express as px
|
5
|
+
import time
|
6
|
+
from typing import Any, Union, Optional
|
7
|
+
from zaturn import config, query_utils
|
8
|
+
|
9
|
+
|
10
|
+
mcp = FastMCP("Zaturn Visualizations")
|
11
|
+
|
12
|
+
|
13
|
+
def _fig_to_image(fig) -> Union[str, Image]:
|
14
|
+
filepath = os.path.join(config.VISUALS_DIR, str(int(time.time())) + '.png')
|
15
|
+
fig.write_image(filepath)
|
16
|
+
if config.RETURN_IMAGES:
|
17
|
+
return Image(path=filepath)
|
18
|
+
else:
|
19
|
+
return filepath
|
20
|
+
|
21
|
+
|
22
|
+
# Relationships
|
23
|
+
|
24
|
+
@mcp.tool()
|
25
|
+
def scatter_plot(
|
26
|
+
query_id: str,
|
27
|
+
x: str,
|
28
|
+
y: str,
|
29
|
+
color: str = None
|
30
|
+
):
|
31
|
+
"""
|
32
|
+
Make a scatter plot with the dataframe obtained from running SQL Query against source
|
33
|
+
If this returns an image, display it. If it returns a file path, mention it.
|
34
|
+
Args:
|
35
|
+
query_id: Previously run query to use for plotting
|
36
|
+
x: Column name from SQL result to use for x-axis
|
37
|
+
y: Column name from SQL result to use for y-axis
|
38
|
+
color: Optional; column name from SQL result to use for coloring the points, with color representing another dimension
|
39
|
+
"""
|
40
|
+
df = query_utils.load_query(query_id)
|
41
|
+
fig = px.scatter(df, x=x, y=y, color=color)
|
42
|
+
fig.update_xaxes(autotickangles=[0, 45, 60, 90])
|
43
|
+
return _fig_to_image(fig)
|
44
|
+
|
45
|
+
|
46
|
+
@mcp.tool()
|
47
|
+
def line_plot(
|
48
|
+
query_id: str,
|
49
|
+
x: str,
|
50
|
+
y: str,
|
51
|
+
color: str = None
|
52
|
+
):
|
53
|
+
"""
|
54
|
+
Make a line plot with the dataframe obtained from running SQL Query against source
|
55
|
+
Args:
|
56
|
+
query_id: Previously run query to use for plotting
|
57
|
+
x: Column name from SQL result to use for x-axis
|
58
|
+
y: Column name from SQL result to use for y-axis
|
59
|
+
color: Optional; column name from SQL result to use for drawing multiple colored lines representing another dimension
|
60
|
+
"""
|
61
|
+
df = query_utils.load_query(query_id)
|
62
|
+
fig = px.line(df, x=x, y=y, color=color)
|
63
|
+
fig.update_xaxes(autotickangles=[0, 45, 60, 90])
|
64
|
+
return _fig_to_image(fig)
|
65
|
+
|
66
|
+
|
67
|
+
# Distributions
|
68
|
+
|
69
|
+
@mcp.tool()
|
70
|
+
def histogram(
|
71
|
+
query_id: str,
|
72
|
+
column: str,
|
73
|
+
color: str = None,
|
74
|
+
nbins: int = None
|
75
|
+
):
|
76
|
+
"""
|
77
|
+
Make a histogram with a column of the dataframe obtained from running SQL Query against source
|
78
|
+
Args:
|
79
|
+
query_id: Previously run query to use for plotting
|
80
|
+
column: Column name from SQL result to use for the histogram
|
81
|
+
color: Optional; column name from SQL result to use for drawing multiple colored histograms representing another dimension
|
82
|
+
nbins: Optional; number of bins
|
83
|
+
"""
|
84
|
+
df = query_utils.load_query(query_id)
|
85
|
+
fig = px.histogram(df, x=column, color=color, nbins=nbins)
|
86
|
+
fig.update_xaxes(autotickangles=[0, 45, 60, 90])
|
87
|
+
return _fig_to_image(fig)
|
88
|
+
|
89
|
+
# Categorical
|
90
|
+
|
91
|
+
@mcp.tool()
|
92
|
+
def strip_plot(
|
93
|
+
query_id: str,
|
94
|
+
x: str,
|
95
|
+
y: str = None,
|
96
|
+
color: str = None
|
97
|
+
):
|
98
|
+
"""
|
99
|
+
Make a strip plot with the dataframe obtained from running SQL Query against source
|
100
|
+
Args:
|
101
|
+
query_id: Previously run query to use for plotting
|
102
|
+
x: Column name from SQL result to use for x axis
|
103
|
+
y: Optional; column name from SQL result to use for y axis
|
104
|
+
color: Optional column name from SQL result to show multiple colored strips representing another dimension
|
105
|
+
"""
|
106
|
+
df = query_utils.load_query(query_id)
|
107
|
+
fig = px.strip(df, x=x, y=y, color=color)
|
108
|
+
fig.update_xaxes(autotickangles=[0, 45, 60, 90])
|
109
|
+
return _fig_to_image(fig)
|
110
|
+
|
111
|
+
|
112
|
+
@mcp.tool()
|
113
|
+
def box_plot(
|
114
|
+
query_id: str,
|
115
|
+
y: str,
|
116
|
+
x: str = None,
|
117
|
+
color: str = None
|
118
|
+
):
|
119
|
+
"""
|
120
|
+
Make a box plot with the dataframe obtained from running SQL Query against source
|
121
|
+
Args:
|
122
|
+
query_id: Previously run query to use for plotting
|
123
|
+
y: Column name from SQL result to use for y axis
|
124
|
+
x: Optional; Column name from SQL result to use for x axis
|
125
|
+
color: Optional column name from SQL result to show multiple colored bars representing another dimension
|
126
|
+
"""
|
127
|
+
df = query_utils.load_query(query_id)
|
128
|
+
fig = px.box(df, x=x, y=y, color=color)
|
129
|
+
fig.update_xaxes(autotickangles=[0, 45, 60, 90])
|
130
|
+
return _fig_to_image(fig)
|
131
|
+
|
132
|
+
|
133
|
+
@mcp.tool()
|
134
|
+
def bar_plot(
|
135
|
+
query_id: str,
|
136
|
+
x: str,
|
137
|
+
y: str = None,
|
138
|
+
color: str = None,
|
139
|
+
orientation: str = 'v'
|
140
|
+
):
|
141
|
+
"""
|
142
|
+
Make a bar plot with the dataframe obtained from running SQL Query against source
|
143
|
+
Args:
|
144
|
+
query_id: Previously run query to use for plotting
|
145
|
+
x: Column name from SQL result to use for x axis
|
146
|
+
y: Optional; column name from SQL result to use for y axis
|
147
|
+
color: Optional column name from SQL result to use as a 3rd dimension by splitting each bar into colored sections
|
148
|
+
orientation: Orientation of the box plot, use 'v' for vertical (default) and 'h' for horizontal. Be mindful of choosing the correct X and Y columns as per orientation
|
149
|
+
"""
|
150
|
+
df = query_utils.load_query(query_id)
|
151
|
+
fig = px.bar(df, x=x, y=y, color=color, orientation=orientation)
|
152
|
+
fig.update_xaxes(autotickangles=[0, 45, 60, 90])
|
153
|
+
return _fig_to_image(fig)
|
154
|
+
|
155
|
+
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: zaturn
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.6
|
4
4
|
Summary: AI Data Analysis MCP
|
5
5
|
Author-email: Karthik Devan <krtdvn@gmail.com>
|
6
6
|
Maintainer-email: Karthik Devan <krtdvn@gmail.com>
|
@@ -9,11 +9,14 @@ Project-URL: Issues, https://github.com/kdqed/zaturn/issues
|
|
9
9
|
Requires-Python: >=3.11
|
10
10
|
Description-Content-Type: text/markdown
|
11
11
|
License-File: LICENSE
|
12
|
+
Requires-Dist: clickhouse-connect>=0.8.17
|
12
13
|
Requires-Dist: cryptography>=44.0.2
|
13
14
|
Requires-Dist: duckdb>=1.2.1
|
14
15
|
Requires-Dist: fastmcp>=0.4.1
|
16
|
+
Requires-Dist: kaleido==0.2.1
|
15
17
|
Requires-Dist: pandas>=2.2.3
|
16
18
|
Requires-Dist: platformdirs>=4.3.7
|
19
|
+
Requires-Dist: plotly[express]>=6.0.1
|
17
20
|
Requires-Dist: psycopg2-binary>=2.9.10
|
18
21
|
Requires-Dist: pyarrow>=19.0.1
|
19
22
|
Requires-Dist: pymysql>=1.1.1
|
@@ -54,7 +57,7 @@ https://github.com/user-attachments/assets/d42dc433-e5ec-4b3e-bef0-5cfc097396ab
|
|
54
57
|
|
55
58
|
### Multiple Data Sources
|
56
59
|
Zaturn can currently connect to the following data sources:
|
57
|
-
- SQL Databases: PostgreSQL, SQLite, DuckDB, MySQL
|
60
|
+
- SQL Databases: PostgreSQL, SQLite, DuckDB, MySQL, ClickHouse
|
58
61
|
- Files: CSV, Parquet
|
59
62
|
|
60
63
|
Connectors for more data sources are being added.
|
@@ -103,6 +106,7 @@ OR add a `sources.txt` to the Zaturn config directory:
|
|
103
106
|
```
|
104
107
|
postgresql://username:password@host:port/dbname
|
105
108
|
mysql+pymysql://username:password@host:3306/dbname
|
109
|
+
clickhouse://username:password@host:port/dbname
|
106
110
|
sqlite:////full/path/to/sample_dbs/northwind.db
|
107
111
|
/full/path/to/sample_dbs/titanic.parquet
|
108
112
|
/full/path/to/sample_dbs/ny_aq.csv
|
@@ -158,11 +162,20 @@ Analyst:
|
|
158
162
|
```
|
159
163
|
- A native notebook interface
|
160
164
|
|
161
|
-
##
|
165
|
+
## Help And Feedback
|
162
166
|
|
163
167
|
[Raise an issue](https://github.com/kdqed/zaturn/issues) or [join the Discord](https://discord.gg/K8mECeVzpQ).
|
164
168
|
|
165
169
|
|
170
|
+
## Support The Project
|
171
|
+
|
172
|
+
If you find Zaturn useful, please support this project by:
|
173
|
+
- Starring the Project
|
174
|
+
- Spreading the word
|
175
|
+
- [Pledging $9/month on Patreon](https://www.patreon.com/kdqed?utm_medium=github&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink)
|
176
|
+
|
177
|
+
Your support will enable me to dedicate more of my time to Zaturn.
|
178
|
+
|
166
179
|
## Example Dataset Credits
|
167
180
|
|
168
181
|
The [pokemon dataset compiled by Sarah Taha and PokéAPI](https://www.kaggle.com/datasets/sarahtaha/1025-pokemon) has been included under the [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) license for demonstration purposes.
|
@@ -1,203 +0,0 @@
|
|
1
|
-
from fastmcp import FastMCP, Image
|
2
|
-
import math
|
3
|
-
import matplotlib.pyplot as plt
|
4
|
-
import os
|
5
|
-
import seaborn as sns
|
6
|
-
import time
|
7
|
-
from typing import Any, Union, Optional
|
8
|
-
from zaturn import config, query_utils
|
9
|
-
|
10
|
-
sns.set_theme()
|
11
|
-
sns.set_style('ticks')
|
12
|
-
|
13
|
-
mcp = FastMCP("Zaturn Visualizations")
|
14
|
-
|
15
|
-
|
16
|
-
def _plot_to_image(plot) -> Union[str, Image]:
|
17
|
-
figure = plot.get_figure()
|
18
|
-
filepath = os.path.join(config.VISUALS_DIR, str(int(time.time())) + '.png')
|
19
|
-
figure.savefig(filepath, bbox_inches='tight')
|
20
|
-
plt.clf()
|
21
|
-
if config.RETURN_IMAGES:
|
22
|
-
return Image(path=filepath)
|
23
|
-
else:
|
24
|
-
return filepath
|
25
|
-
|
26
|
-
|
27
|
-
def _fix_x_labels(plot, labels):
|
28
|
-
max_label_length = max(list(labels.map(lambda x: len(str(x)))))
|
29
|
-
|
30
|
-
LABEL_HIDE_FACTOR = 1
|
31
|
-
if len(labels) > 20:
|
32
|
-
LABEL_HIDE_FACTOR = math.ceil(len(labels)/20)
|
33
|
-
|
34
|
-
labels_to_show = list(labels)
|
35
|
-
ticks = list(plot.get_xticks())
|
36
|
-
if LABEL_HIDE_FACTOR > 1:
|
37
|
-
ticks = ticks[::LABEL_HIDE_FACTOR]
|
38
|
-
labels_to_show = labels_to_show[::LABEL_HIDE_FACTOR]
|
39
|
-
|
40
|
-
plot.set_xticks(ticks, labels_to_show)
|
41
|
-
cutoff = 2 # for rotation
|
42
|
-
|
43
|
-
if max_label_length >= 12:
|
44
|
-
cutoff = 3
|
45
|
-
elif max_label_length >= 10:
|
46
|
-
cutoff = 4
|
47
|
-
elif max_label_length >= 8:
|
48
|
-
cutoff = 5
|
49
|
-
elif max_label_length >= 7:
|
50
|
-
cutoff = 5
|
51
|
-
elif max_label_length >= 6:
|
52
|
-
cutoff = 6
|
53
|
-
elif max_label_length >= 5:
|
54
|
-
cutoff = 7
|
55
|
-
elif max_label_length >= 4:
|
56
|
-
cutoff = 9
|
57
|
-
elif max_label_length >= 3:
|
58
|
-
cutoff = 13
|
59
|
-
else:
|
60
|
-
cutoff = 15
|
61
|
-
|
62
|
-
if len(labels)>cutoff:
|
63
|
-
plot.set_xticklabels(plot.get_xticklabels(), rotation=-45, ha='left', va='top')
|
64
|
-
|
65
|
-
return plot
|
66
|
-
|
67
|
-
|
68
|
-
# Relationships
|
69
|
-
|
70
|
-
@mcp.tool()
|
71
|
-
def scatter_plot(
|
72
|
-
query_id: str,
|
73
|
-
x: str,
|
74
|
-
y: str,
|
75
|
-
hue: str = None
|
76
|
-
):
|
77
|
-
"""
|
78
|
-
Make a scatter plot with the dataframe obtained from running SQL Query against source
|
79
|
-
If this returns an image, display it. If it returns a file path, mention it.
|
80
|
-
Args:
|
81
|
-
query_id: Previously run query to use for plotting
|
82
|
-
x: Column name from SQL result to use for x-axis
|
83
|
-
y: Column name from SQL result to use for y-axis
|
84
|
-
hue: Optional String; Column name from SQL result to use for coloring the points
|
85
|
-
"""
|
86
|
-
df = query_utils.load_query(query_id)
|
87
|
-
plot = sns.scatterplot(df, x=x, y=y, hue=hue)
|
88
|
-
plot = _fix_x_labels(plot, df[x])
|
89
|
-
return _plot_to_image(plot)
|
90
|
-
|
91
|
-
|
92
|
-
@mcp.tool()
|
93
|
-
def line_plot(
|
94
|
-
query_id: str,
|
95
|
-
x: str,
|
96
|
-
y: str,
|
97
|
-
hue: str = None
|
98
|
-
):
|
99
|
-
"""
|
100
|
-
Make a line plot with the dataframe obtained from running SQL Query against source
|
101
|
-
Args:
|
102
|
-
query_id: Previously run query to use for plotting
|
103
|
-
x: Column name from SQL result to use for x-axis
|
104
|
-
y: Column name from SQL result to use for y-axis
|
105
|
-
hue: Optional; column name from SQL result to use for drawing multiple colored lines
|
106
|
-
"""
|
107
|
-
df = query_utils.load_query(query_id)
|
108
|
-
plot = sns.lineplot(df, x=x, y=y, hue=hue)
|
109
|
-
plot = _fix_x_labels(plot, df[x])
|
110
|
-
return _plot_to_image(plot)
|
111
|
-
|
112
|
-
|
113
|
-
# Distributions
|
114
|
-
|
115
|
-
@mcp.tool()
|
116
|
-
def histogram(
|
117
|
-
query_id: str,
|
118
|
-
column: str,
|
119
|
-
hue: str = None,
|
120
|
-
bins: int = None
|
121
|
-
):
|
122
|
-
"""
|
123
|
-
Make a histogram with a column of the dataframe obtained from running SQL Query against source
|
124
|
-
Args:
|
125
|
-
query_id: Previously run query to use for plotting
|
126
|
-
column: Column name from SQL result to use for the histogram
|
127
|
-
hue: Optional; column name from SQL result to use for drawing multiple colored histograms
|
128
|
-
bins: Optional; number of bins
|
129
|
-
"""
|
130
|
-
df = query_utils.load_query(query_id)
|
131
|
-
plot = sns.histplot(df, x=column, hue=hue, bins=bins)
|
132
|
-
return _plot_to_image(plot)
|
133
|
-
|
134
|
-
|
135
|
-
# Categorical
|
136
|
-
|
137
|
-
@mcp.tool()
|
138
|
-
def strip_plot(
|
139
|
-
query_id: str,
|
140
|
-
x: str,
|
141
|
-
y: str = None,
|
142
|
-
hue: str = None,
|
143
|
-
legend: bool = False
|
144
|
-
):
|
145
|
-
"""
|
146
|
-
Make a strip plot with the dataframe obtained from running SQL Query against source
|
147
|
-
Args:
|
148
|
-
query_id: Previously run query to use for plotting
|
149
|
-
x: Column name from SQL result to use for x axis
|
150
|
-
y: Optional; column name from SQL result to use for y axis
|
151
|
-
hue: Optional; column name from SQL result to use for coloring the points
|
152
|
-
legend: Whether to draw a legend for the hue
|
153
|
-
"""
|
154
|
-
df = query_utils.load_query(query_id)
|
155
|
-
plot = sns.stripplot(df, x=x, y=y, hue=hue, legend=legend)
|
156
|
-
plot = _fix_x_labels(plot, df[x])
|
157
|
-
return _plot_to_image(plot)
|
158
|
-
|
159
|
-
|
160
|
-
@mcp.tool()
|
161
|
-
def box_plot(
|
162
|
-
query_id: str,
|
163
|
-
x: str,
|
164
|
-
y: str = None,
|
165
|
-
hue: str = None
|
166
|
-
):
|
167
|
-
"""
|
168
|
-
Make a box plot with the dataframe obtained from running SQL Query against source
|
169
|
-
Args:
|
170
|
-
query_id: Previously run query to use for plotting
|
171
|
-
x: Column name from SQL result to use for x axis
|
172
|
-
y: Optional; column name from SQL result to use for y axis
|
173
|
-
hue: Optional column name from SQL result to use for coloring the points
|
174
|
-
"""
|
175
|
-
df = query_utils.load_query(query_id)
|
176
|
-
plot = sns.boxplot(df, x=x, y=y, hue=hue)
|
177
|
-
plot = _fix_x_labels(plot, df[x])
|
178
|
-
return _plot_to_image(plot)
|
179
|
-
|
180
|
-
|
181
|
-
@mcp.tool()
|
182
|
-
def bar_plot(
|
183
|
-
query_id: str,
|
184
|
-
x: str,
|
185
|
-
y: str = None,
|
186
|
-
hue: str = None,
|
187
|
-
orient: str = 'v'
|
188
|
-
):
|
189
|
-
"""
|
190
|
-
Make a bar plot with the dataframe obtained from running SQL Query against source
|
191
|
-
Args:
|
192
|
-
query_id: Previously run query to use for plotting
|
193
|
-
x: Column name from SQL result to use for x axis
|
194
|
-
y: Optional; column name from SQL result to use for y axis
|
195
|
-
hue: Optional column name from SQL result to use for coloring the bars
|
196
|
-
orient: Orientation of the box plot, use 'v' for vertical and 'h' for horizontal
|
197
|
-
"""
|
198
|
-
df = query_utils.load_query(query_id)
|
199
|
-
plot = sns.barplot(df, x=x, y=y, hue=hue, orient=orient)
|
200
|
-
plot = _fix_x_labels(plot, df[x])
|
201
|
-
return _plot_to_image(plot)
|
202
|
-
|
203
|
-
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|