vizro-mcp 0.1.3__py3-none-any.whl → 0.1.4__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.
- vizro_mcp/__init__.py +1 -1
- vizro_mcp/_schemas/schemas.py +2 -2
- vizro_mcp/_utils/__init__.py +0 -2
- vizro_mcp/_utils/configs.py +2 -2
- vizro_mcp/_utils/prompts.py +12 -35
- vizro_mcp/_utils/utils.py +2 -2
- vizro_mcp/server.py +8 -8
- {vizro_mcp-0.1.3.dist-info → vizro_mcp-0.1.4.dist-info}/METADATA +2 -1
- vizro_mcp-0.1.4.dist-info/RECORD +14 -0
- {vizro_mcp-0.1.3.dist-info → vizro_mcp-0.1.4.dist-info}/WHEEL +1 -1
- vizro_mcp-0.1.3.dist-info/RECORD +0 -14
- {vizro_mcp-0.1.3.dist-info → vizro_mcp-0.1.4.dist-info}/entry_points.txt +0 -0
- {vizro_mcp-0.1.3.dist-info → vizro_mcp-0.1.4.dist-info}/licenses/LICENSE.txt +0 -0
vizro_mcp/__init__.py
CHANGED
vizro_mcp/_schemas/schemas.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Schema defining pydantic models for usage in the MCP server."""
|
|
2
2
|
|
|
3
|
-
from typing import Annotated, Any
|
|
3
|
+
from typing import Annotated, Any
|
|
4
4
|
|
|
5
5
|
import vizro.figures as vf
|
|
6
6
|
import vizro.models as vm
|
|
@@ -153,7 +153,7 @@ class ChartPlan(BaseModel):
|
|
|
153
153
|
imports = [imp for imp in imports if "vizro" not in imp]
|
|
154
154
|
return "\n".join(imports) + "\n"
|
|
155
155
|
|
|
156
|
-
def get_chart_code(self, chart_name:
|
|
156
|
+
def get_chart_code(self, chart_name: str | None = None, vizro: bool = False):
|
|
157
157
|
chart_code = self.chart_code
|
|
158
158
|
if vizro:
|
|
159
159
|
chart_code = chart_code.replace(f"def {self.chart_name}", f"@capture('graph')\ndef {self.chart_name}")
|
vizro_mcp/_utils/__init__.py
CHANGED
|
@@ -7,7 +7,6 @@ from .configs import (
|
|
|
7
7
|
)
|
|
8
8
|
from .prompts import (
|
|
9
9
|
CHART_INSTRUCTIONS,
|
|
10
|
-
LAYOUT_INSTRUCTIONS,
|
|
11
10
|
get_chart_prompt,
|
|
12
11
|
get_dashboard_instructions,
|
|
13
12
|
get_dashboard_prompt,
|
|
@@ -34,7 +33,6 @@ __all__ = [ # noqa: RUF022
|
|
|
34
33
|
"VizroCodeAndPreviewLink",
|
|
35
34
|
# Constants
|
|
36
35
|
"CHART_INSTRUCTIONS",
|
|
37
|
-
"LAYOUT_INSTRUCTIONS",
|
|
38
36
|
"GAPMINDER",
|
|
39
37
|
"IRIS",
|
|
40
38
|
"SAMPLE_DASHBOARD_CONFIG",
|
vizro_mcp/_utils/configs.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Pre-set configs for the Vizro MCP."""
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from typing import Any, Literal
|
|
4
|
+
from typing import Any, Literal
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
@dataclass
|
|
@@ -10,7 +10,7 @@ class DFMetaData:
|
|
|
10
10
|
file_path_or_url: str
|
|
11
11
|
file_location_type: Literal["local", "remote"]
|
|
12
12
|
read_function_string: Literal["pd.read_csv", "pd.read_json", "pd.read_html", "pd.read_parquet", "pd.read_excel"]
|
|
13
|
-
column_names_types:
|
|
13
|
+
column_names_types: dict[str, str] | None = None
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
@dataclass
|
vizro_mcp/_utils/prompts.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Prompts for the Vizro MCP."""
|
|
2
2
|
# ruff: noqa: E501 #Ignore line length only in prompts
|
|
3
3
|
|
|
4
|
-
from typing import Literal,
|
|
4
|
+
from typing import Literal, Protocol
|
|
5
5
|
|
|
6
6
|
import vizro
|
|
7
7
|
import vizro.actions as va
|
|
@@ -32,7 +32,7 @@ IMPORTANT:
|
|
|
32
32
|
- IF the user has no plan (ie no components or pages), use the config at the bottom of this prompt, OTHERWISE:
|
|
33
33
|
- make a plan of what components you would like to use, then request all necessary schemas using the `get_model_json_schema` tool
|
|
34
34
|
- start with `Dashboard`, don't forget `Graph`,
|
|
35
|
-
- MUST explicitly
|
|
35
|
+
- MUST explicitly set layout (layout setting is NOT optional, contrary to what schema says)
|
|
36
36
|
- assemble your components into a page, then add the page or pages to a dashboard, DO NOT show config or code to the user until you have validated the solution
|
|
37
37
|
- ALWAYS validate the dashboard configuration using the `validate_dashboard_config` tool
|
|
38
38
|
- using `custom_chart` is encouraged for advanced visualizations, no need to call the planner tool in advanced mode
|
|
@@ -61,11 +61,12 @@ class HasNameAndDoc(Protocol):
|
|
|
61
61
|
"""Protocol for objects that have a name and a docstring."""
|
|
62
62
|
|
|
63
63
|
__name__: str
|
|
64
|
-
__doc__:
|
|
64
|
+
__doc__: str | None
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
# This dict is used to give the model and overview of what is available in the vizro.models namespace.
|
|
68
68
|
# It helps it to narrow down the choices when asking for a model.
|
|
69
|
+
# Intentionally omitted: Accordion, Action, Table, Layout and VizroBaseModel
|
|
69
70
|
MODEL_GROUPS: dict[str, list[type[HasNameAndDoc]]] = {
|
|
70
71
|
"main": [vm.Dashboard, vm.Page],
|
|
71
72
|
"static components": [
|
|
@@ -75,10 +76,10 @@ MODEL_GROUPS: dict[str, list[type[HasNameAndDoc]]] = {
|
|
|
75
76
|
vm.Container,
|
|
76
77
|
vm.Tabs,
|
|
77
78
|
],
|
|
78
|
-
"dynamic components": [vm.Figure, vm.Graph, vm.AgGrid],
|
|
79
|
+
"dynamic components - ie reactive to controls": [vm.Figure, vm.Graph, vm.AgGrid],
|
|
79
80
|
"layouts": [vm.Grid, vm.Flex],
|
|
80
|
-
"controls": [vm.Filter, vm.Parameter],
|
|
81
|
-
"selectors": [
|
|
81
|
+
"controls - control display of dynamic components": [vm.Filter, vm.Parameter],
|
|
82
|
+
"selectors - input mechanisms for controls": [
|
|
82
83
|
vm.Dropdown,
|
|
83
84
|
vm.RadioItems,
|
|
84
85
|
vm.Checklist,
|
|
@@ -88,37 +89,13 @@ MODEL_GROUPS: dict[str, list[type[HasNameAndDoc]]] = {
|
|
|
88
89
|
vm.Switch,
|
|
89
90
|
],
|
|
90
91
|
"navigation": [vm.Navigation, vm.NavBar, vm.NavLink],
|
|
91
|
-
"additional_info": [vm.Tooltip],
|
|
92
|
+
"additional_info - info about the component": [vm.Tooltip],
|
|
92
93
|
"actions available for the actions argument of a model": [
|
|
93
|
-
va.
|
|
94
|
-
va.set_control,
|
|
94
|
+
getattr(va, func) for func in va.__all__ if not hasattr(getattr(va, func), "__deprecated__")
|
|
95
95
|
],
|
|
96
|
-
"functions available for vm.Figure(...,figure=...) model": [vf
|
|
96
|
+
"functions available for vm.Figure(...,figure=...) model": [getattr(vf, func) for func in vf.__all__],
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
LAYOUT_INSTRUCTIONS = """Some extra information about Layout in Vizro:
|
|
100
|
-
Overall:
|
|
101
|
-
- Use Flex for most dashboards, use Grid only for cases below
|
|
102
|
-
- Great tip: group elements in a `Container` and decide on appropriate layout inside the container and
|
|
103
|
-
outside the container
|
|
104
|
-
|
|
105
|
-
Flex (Recommended in ALMOST ALL cases, definitely as default unless asked otherwise!):
|
|
106
|
-
- use wrap=True if direction="row" to avoid horizontal scroll
|
|
107
|
-
- Sizing of components: use min/max widths only to prevent items from shrinking too small
|
|
108
|
-
- Graph example: vm.Graph(figure=px.violin(..., width=900)).
|
|
109
|
-
- AgGrid example: vm.AgGrid(figure=dash_ag_grid(tips, style={"width": 900})).
|
|
110
|
-
|
|
111
|
-
Grid (Use only if asked):
|
|
112
|
-
- Use when:
|
|
113
|
-
- you need precise alignment across both rows and columns
|
|
114
|
-
- you want a component (often charts) to fill a concrete part of the page, e.g. when asked to fill one row, or a column
|
|
115
|
-
- ALWAYS opt for `Grid` to make components fill space instead of playing with `width` and `height`
|
|
116
|
-
- NEVER use collapsible containers inside `Grid`
|
|
117
|
-
- IMPORTANT: you must use integers to refer to the elements, starting from 0, every element must be referenced,
|
|
118
|
-
elements can't overlap and must be rectangular, and you must use the same number of columns and rows for each row
|
|
119
|
-
|
|
120
|
-
Do NOT forget to call `validate_dashboard_config` after each iteration."""
|
|
121
|
-
|
|
122
99
|
|
|
123
100
|
def get_overview_vizro_models() -> dict[str, list[dict[str, str]]]:
|
|
124
101
|
"""Get all available models in the vizro.models namespace.
|
|
@@ -183,7 +160,7 @@ Create a super simple Vizro dashboard with one page and one chart and one filter
|
|
|
183
160
|
"""
|
|
184
161
|
|
|
185
162
|
|
|
186
|
-
def get_dashboard_prompt(file_path_or_url: str, user_context:
|
|
163
|
+
def get_dashboard_prompt(file_path_or_url: str, user_context: str | None = None) -> str:
|
|
187
164
|
"""Get a prompt for creating a Vizro dashboard."""
|
|
188
165
|
USER_INSTRUCTIONS = f"""
|
|
189
166
|
3. Create a Vizro dashboard that follows the user context:
|
|
@@ -214,7 +191,7 @@ Create a dashboard based on the following dataset: `{file_path_or_url}`. Proceed
|
|
|
214
191
|
"""
|
|
215
192
|
|
|
216
193
|
|
|
217
|
-
def get_chart_prompt(file_path_or_url: str, user_context:
|
|
194
|
+
def get_chart_prompt(file_path_or_url: str, user_context: str | None = None) -> str:
|
|
218
195
|
"""Get a prompt for creating a Vizro chart."""
|
|
219
196
|
FALLBACK_INSTRUCTIONS = """
|
|
220
197
|
- Think what chart could reflect this data-set best, ideally the chart shows some insights about the data-set
|
vizro_mcp/_utils/utils.py
CHANGED
|
@@ -7,7 +7,7 @@ import json
|
|
|
7
7
|
import re
|
|
8
8
|
from dataclasses import dataclass
|
|
9
9
|
from pathlib import Path
|
|
10
|
-
from typing import TYPE_CHECKING, Literal
|
|
10
|
+
from typing import TYPE_CHECKING, Literal
|
|
11
11
|
from urllib.parse import quote, urlencode
|
|
12
12
|
|
|
13
13
|
import pandas as pd
|
|
@@ -44,7 +44,7 @@ def convert_github_url_to_raw(path_or_url: str) -> str:
|
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
def load_dataframe_by_format(
|
|
47
|
-
path_or_url:
|
|
47
|
+
path_or_url: str | Path, mime_type: str | None = None
|
|
48
48
|
) -> tuple[pd.DataFrame, Literal["pd.read_csv", "pd.read_json", "pd.read_html", "pd.read_excel", "pd.read_parquet"]]:
|
|
49
49
|
"""Load a dataframe based on file format determined by MIME type or file extension."""
|
|
50
50
|
file_path_str_lower = str(path_or_url).lower()
|
vizro_mcp/server.py
CHANGED
|
@@ -4,7 +4,7 @@ import mimetypes
|
|
|
4
4
|
import webbrowser
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import Any, Literal
|
|
7
|
+
from typing import Any, Literal
|
|
8
8
|
|
|
9
9
|
import vizro
|
|
10
10
|
import vizro.models as vm
|
|
@@ -22,7 +22,6 @@ from vizro_mcp._utils import (
|
|
|
22
22
|
CHART_INSTRUCTIONS,
|
|
23
23
|
GAPMINDER,
|
|
24
24
|
IRIS,
|
|
25
|
-
LAYOUT_INSTRUCTIONS,
|
|
26
25
|
STOCKS,
|
|
27
26
|
TIPS,
|
|
28
27
|
DFInfo,
|
|
@@ -48,7 +47,7 @@ class ValidateResults:
|
|
|
48
47
|
valid: bool
|
|
49
48
|
message: str
|
|
50
49
|
python_code: str
|
|
51
|
-
pycafe_url:
|
|
50
|
+
pycafe_url: str | None
|
|
52
51
|
browser_opened: bool
|
|
53
52
|
|
|
54
53
|
|
|
@@ -58,8 +57,8 @@ class DataAnalysisResults:
|
|
|
58
57
|
|
|
59
58
|
valid: bool
|
|
60
59
|
message: str
|
|
61
|
-
df_info:
|
|
62
|
-
df_metadata:
|
|
60
|
+
df_info: DFInfo | None
|
|
61
|
+
df_metadata: DFMetaData | None
|
|
63
62
|
|
|
64
63
|
|
|
65
64
|
@dataclass
|
|
@@ -149,7 +148,8 @@ that model if necessary. Do NOT forget to call `validate_dashboard_config` after
|
|
|
149
148
|
return ModelJsonSchemaResults(
|
|
150
149
|
model_name=model_name,
|
|
151
150
|
json_schema=model_class.model_json_schema(schema_generator=NoDefsGenerateJsonSchema),
|
|
152
|
-
additional_info=
|
|
151
|
+
additional_info="""Grid layout: use integers starting from 0 to reference elements.
|
|
152
|
+
Elements can't overlap, must be rectangular, and rows must have equal column counts.""",
|
|
153
153
|
)
|
|
154
154
|
|
|
155
155
|
return ModelJsonSchemaResults(
|
|
@@ -315,7 +315,7 @@ def create_starter_dashboard():
|
|
|
315
315
|
@mcp.prompt()
|
|
316
316
|
def create_dashboard(
|
|
317
317
|
file_path_or_url: str = Field(description="The absolute path or URL to the data file you want to use."),
|
|
318
|
-
context:
|
|
318
|
+
context: str | None = Field(default=None, description="(Optional) Describe the dashboard you want to create."),
|
|
319
319
|
) -> str:
|
|
320
320
|
"""Prompt template for creating an EDA dashboard based on one dataset."""
|
|
321
321
|
return get_dashboard_prompt(file_path_or_url, context)
|
|
@@ -372,7 +372,7 @@ def validate_chart_code(
|
|
|
372
372
|
@mcp.prompt()
|
|
373
373
|
def create_vizro_chart(
|
|
374
374
|
file_path_or_url: str = Field(description="The absolute path or URL to the data file you want to use."),
|
|
375
|
-
context:
|
|
375
|
+
context: str | None = Field(default=None, description="(Optional) Describe the chart you want to create."),
|
|
376
376
|
) -> str:
|
|
377
377
|
"""Prompt template for creating a Vizro chart."""
|
|
378
378
|
return get_chart_prompt(file_path_or_url, context)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vizro-mcp
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: MCP server to help create Vizro dashboards and charts
|
|
5
5
|
Author: Vizro Team
|
|
6
6
|
License-File: LICENSE.txt
|
|
@@ -9,6 +9,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
12
13
|
Requires-Python: >=3.10
|
|
13
14
|
Requires-Dist: click>=8.1.7
|
|
14
15
|
Requires-Dist: httpx>=0.28.1
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
vizro_mcp/__init__.py,sha256=b07rnAb9ypm8N9O4fLH5LYOeVC48ncU5k_xesNH0zmc,379
|
|
2
|
+
vizro_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
vizro_mcp/server.py,sha256=DoD1B_-EeHcTJSAog6lyaAi-_AA4u1dXAsHLgq0ku3Y,13689
|
|
4
|
+
vizro_mcp/_schemas/__init__.py,sha256=0lk_CiNjo4QFyX0i-VuSeL7EMM6sD_2p836y-ftM3Gs,196
|
|
5
|
+
vizro_mcp/_schemas/schemas.py,sha256=6XCNSTag7RL0xL3SkRVMlJ2GOW0nbm73drhcKRpNfOU,8795
|
|
6
|
+
vizro_mcp/_utils/__init__.py,sha256=ucPbfXe8kEFT7chz6ed_BeqAw71MnoWlZTYyCp4tPYY,1130
|
|
7
|
+
vizro_mcp/_utils/configs.py,sha256=DH5B-RbtLuAkq6cgVL7oBOg3J-T_Mi4ovU430h5iUus,3614
|
|
8
|
+
vizro_mcp/_utils/prompts.py,sha256=TJ--Tpv_tw2L8Tbt6PtaCA435HhUPpqUibNoEryKu94,10767
|
|
9
|
+
vizro_mcp/_utils/utils.py,sha256=1CAD1U27Uca_9KmR3SolimFqMrWVlWApKOFSWDvpeRY,8173
|
|
10
|
+
vizro_mcp-0.1.4.dist-info/METADATA,sha256=3iHwiGkUAQpUM0zX0X47G5_0F6sSQARAcLa-eetlgXU,12413
|
|
11
|
+
vizro_mcp-0.1.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
12
|
+
vizro_mcp-0.1.4.dist-info/entry_points.txt,sha256=iSUzPHvx4Ogsn91tK2C0OHxI44SNCHT1F1zUqbTj5O0,45
|
|
13
|
+
vizro_mcp-0.1.4.dist-info/licenses/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
14
|
+
vizro_mcp-0.1.4.dist-info/RECORD,,
|
vizro_mcp-0.1.3.dist-info/RECORD
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
vizro_mcp/__init__.py,sha256=9_2ffpEe97JqIlmGOJszrMrDv2N8f9VyPpVmZ7s9C4k,379
|
|
2
|
-
vizro_mcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
vizro_mcp/server.py,sha256=ydjjwhyyr983_nHlA7uOAvZcdQyJ4x5KiXj4hPIaiWk,13603
|
|
4
|
-
vizro_mcp/_schemas/__init__.py,sha256=0lk_CiNjo4QFyX0i-VuSeL7EMM6sD_2p836y-ftM3Gs,196
|
|
5
|
-
vizro_mcp/_schemas/schemas.py,sha256=gwDJL_9OK_S0NrZTk1rmJCVP6LLqsMIbVh-s-nZmBrw,8808
|
|
6
|
-
vizro_mcp/_utils/__init__.py,sha256=r57TYaklMaV5TYD8HUG6uv-whvMFfyuULs4cqEZXGkg,1182
|
|
7
|
-
vizro_mcp/_utils/configs.py,sha256=28ALgRgKYzRnPunSTjZxHFz2kyQy8yW4ZLhDgCUkE0s,3627
|
|
8
|
-
vizro_mcp/_utils/prompts.py,sha256=c4q6m9RvQIAWXuEpAgP5giDEAprdgpR23GDpyAQ5ekA,11922
|
|
9
|
-
vizro_mcp/_utils/utils.py,sha256=ZzBp6_jHMI6VsaptWC6WFMf1S4QCnrbo2Iq1-O4QH0A,8199
|
|
10
|
-
vizro_mcp-0.1.3.dist-info/METADATA,sha256=9GUwdMqHFWoQYnmTTU0rD0OPujYgU9EONC60ZAdV9Qs,12362
|
|
11
|
-
vizro_mcp-0.1.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
12
|
-
vizro_mcp-0.1.3.dist-info/entry_points.txt,sha256=iSUzPHvx4Ogsn91tK2C0OHxI44SNCHT1F1zUqbTj5O0,45
|
|
13
|
-
vizro_mcp-0.1.3.dist-info/licenses/LICENSE.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
14
|
-
vizro_mcp-0.1.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|