vizro-mcp 0.1.0__py3-none-any.whl → 0.1.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.
- vizro_mcp/__init__.py +1 -1
- vizro_mcp/_schemas/__init__.py +0 -18
- vizro_mcp/_schemas/schemas.py +50 -133
- vizro_mcp/_utils/__init__.py +24 -5
- vizro_mcp/_utils/configs.py +142 -0
- vizro_mcp/_utils/prompts.py +180 -0
- vizro_mcp/_utils/utils.py +63 -146
- vizro_mcp/server.py +167 -203
- {vizro_mcp-0.1.0.dist-info → vizro_mcp-0.1.2.dist-info}/METADATA +87 -43
- vizro_mcp-0.1.2.dist-info/RECORD +14 -0
- vizro_mcp-0.1.0.dist-info/RECORD +0 -12
- {vizro_mcp-0.1.0.dist-info → vizro_mcp-0.1.2.dist-info}/WHEEL +0 -0
- {vizro_mcp-0.1.0.dist-info → vizro_mcp-0.1.2.dist-info}/entry_points.txt +0 -0
- {vizro_mcp-0.1.0.dist-info → vizro_mcp-0.1.2.dist-info}/licenses/LICENSE.txt +0 -0
vizro_mcp/server.py
CHANGED
|
@@ -8,45 +8,39 @@ from typing import Any, Literal, Optional
|
|
|
8
8
|
|
|
9
9
|
import vizro.models as vm
|
|
10
10
|
from mcp.server.fastmcp import FastMCP
|
|
11
|
-
from pydantic import ValidationError
|
|
11
|
+
from pydantic import Field, ValidationError
|
|
12
12
|
from vizro import Vizro
|
|
13
13
|
|
|
14
14
|
from vizro_mcp._schemas import (
|
|
15
15
|
AgGridEnhanced,
|
|
16
16
|
ChartPlan,
|
|
17
|
-
ContainerSimplified,
|
|
18
|
-
DashboardSimplified,
|
|
19
|
-
FilterSimplified,
|
|
20
17
|
GraphEnhanced,
|
|
21
|
-
PageSimplified,
|
|
22
|
-
ParameterSimplified,
|
|
23
|
-
TabsSimplified,
|
|
24
|
-
get_overview_vizro_models,
|
|
25
|
-
get_simple_dashboard_config,
|
|
26
18
|
)
|
|
27
19
|
from vizro_mcp._utils import (
|
|
20
|
+
CHART_INSTRUCTIONS,
|
|
28
21
|
GAPMINDER,
|
|
29
22
|
IRIS,
|
|
30
|
-
SAMPLE_DASHBOARD_CONFIG,
|
|
31
23
|
STOCKS,
|
|
32
24
|
TIPS,
|
|
33
25
|
DFInfo,
|
|
34
26
|
DFMetaData,
|
|
27
|
+
NoDefsGenerateJsonSchema,
|
|
35
28
|
convert_github_url_to_raw,
|
|
36
29
|
create_pycafe_url,
|
|
30
|
+
get_chart_prompt,
|
|
31
|
+
get_dashboard_instructions,
|
|
32
|
+
get_dashboard_prompt,
|
|
37
33
|
get_dataframe_info,
|
|
38
34
|
get_python_code_and_preview_link,
|
|
35
|
+
get_starter_dashboard_prompt,
|
|
39
36
|
load_dataframe_by_format,
|
|
40
37
|
path_or_url_check,
|
|
41
38
|
)
|
|
42
39
|
|
|
43
|
-
# PyCafe URL for Vizro snippets
|
|
44
|
-
PYCAFE_URL = "https://py.cafe"
|
|
45
|
-
|
|
46
40
|
|
|
47
41
|
@dataclass
|
|
48
|
-
class
|
|
49
|
-
"""Results of
|
|
42
|
+
class ValidateResults:
|
|
43
|
+
"""Results of validation tools."""
|
|
50
44
|
|
|
51
45
|
valid: bool
|
|
52
46
|
message: str
|
|
@@ -65,96 +59,50 @@ class DataAnalysisResults:
|
|
|
65
59
|
df_metadata: Optional[DFMetaData]
|
|
66
60
|
|
|
67
61
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
@mcp.tool()
|
|
75
|
-
def get_sample_data_info(data_name: Literal["iris", "tips", "stocks", "gapminder"]) -> DFMetaData:
|
|
76
|
-
"""If user provides no data, use this tool to get sample data information.
|
|
62
|
+
@dataclass
|
|
63
|
+
class ModelJsonSchemaResults:
|
|
64
|
+
"""Results of the get_model_json_schema tool."""
|
|
77
65
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
- stocks: stock prices, good for line, scatter, generally things that change over time
|
|
82
|
-
- gapminder: demographic data, good for line, scatter, generally things with maps or many categories
|
|
66
|
+
model_name: str
|
|
67
|
+
json_schema: dict[str, Any]
|
|
68
|
+
additional_info: str
|
|
83
69
|
|
|
84
|
-
Args:
|
|
85
|
-
data_name: Name of the dataset to get sample data for
|
|
86
70
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
""
|
|
90
|
-
|
|
91
|
-
return IRIS
|
|
92
|
-
elif data_name == "tips":
|
|
93
|
-
return TIPS
|
|
94
|
-
elif data_name == "stocks":
|
|
95
|
-
return STOCKS
|
|
96
|
-
elif data_name == "gapminder":
|
|
97
|
-
return GAPMINDER
|
|
71
|
+
# TODO: check on https://github.com/modelcontextprotocol/python-sdk what new things are possible to do here
|
|
72
|
+
mcp = FastMCP(
|
|
73
|
+
"MCP server to help create Vizro dashboards and charts.",
|
|
74
|
+
)
|
|
98
75
|
|
|
99
76
|
|
|
100
77
|
@mcp.tool()
|
|
101
|
-
def
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
) ->
|
|
106
|
-
"""
|
|
78
|
+
def get_vizro_chart_or_dashboard_plan(
|
|
79
|
+
user_plan: Literal["chart", "dashboard"],
|
|
80
|
+
user_host: Literal["generic_host", "ide"],
|
|
81
|
+
advanced_mode: bool = False,
|
|
82
|
+
) -> str:
|
|
83
|
+
"""Get instructions for creating a Vizro chart or dashboard. Call FIRST when asked to create Vizro things.
|
|
107
84
|
|
|
108
|
-
|
|
109
|
-
|
|
85
|
+
Must be ALWAYS called FIRST with advanced_mode=False, then call again with advanced_mode=True
|
|
86
|
+
if the JSON config does not suffice anymore.
|
|
110
87
|
|
|
111
88
|
Args:
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
89
|
+
user_plan: The type of Vizro thing the user wants to create
|
|
90
|
+
user_host: The host the user is using, if "ide" you can use the IDE/editor to run python code
|
|
91
|
+
advanced_mode: Only call if you need to use custom CSS, custom components or custom actions.
|
|
92
|
+
No need to call this with advanced_mode=True if you need advanced charts, use `custom_charts` in
|
|
93
|
+
the `validate_dashboard_config` tool instead.
|
|
115
94
|
|
|
116
95
|
Returns:
|
|
117
|
-
|
|
96
|
+
Instructions for creating a Vizro chart or dashboard
|
|
118
97
|
"""
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
except ValidationError as e:
|
|
124
|
-
return ValidationResults(
|
|
125
|
-
valid=False,
|
|
126
|
-
message=f"Validation Error: {e!s}",
|
|
127
|
-
python_code="",
|
|
128
|
-
pycafe_url=None,
|
|
129
|
-
browser_opened=False,
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
else:
|
|
133
|
-
result = get_python_code_and_preview_link(dashboard, data_infos)
|
|
134
|
-
|
|
135
|
-
pycafe_url = result.pycafe_url if all(info.file_location_type == "remote" for info in data_infos) else None
|
|
136
|
-
browser_opened = False
|
|
137
|
-
|
|
138
|
-
if pycafe_url and auto_open:
|
|
139
|
-
try:
|
|
140
|
-
browser_opened = webbrowser.open(pycafe_url)
|
|
141
|
-
except Exception:
|
|
142
|
-
browser_opened = False
|
|
143
|
-
|
|
144
|
-
return ValidationResults(
|
|
145
|
-
valid=True,
|
|
146
|
-
message="Configuration is valid for Dashboard!",
|
|
147
|
-
python_code=result.python_code,
|
|
148
|
-
pycafe_url=pycafe_url,
|
|
149
|
-
browser_opened=browser_opened,
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
finally:
|
|
153
|
-
Vizro._reset()
|
|
98
|
+
if user_plan == "chart":
|
|
99
|
+
return CHART_INSTRUCTIONS
|
|
100
|
+
elif user_plan == "dashboard":
|
|
101
|
+
return f"{get_dashboard_instructions(advanced_mode, user_host)}"
|
|
154
102
|
|
|
155
103
|
|
|
156
104
|
@mcp.tool()
|
|
157
|
-
def get_model_json_schema(model_name: str) ->
|
|
105
|
+
def get_model_json_schema(model_name: str) -> ModelJsonSchemaResults:
|
|
158
106
|
"""Get the JSON schema for the specified Vizro model.
|
|
159
107
|
|
|
160
108
|
Args:
|
|
@@ -163,88 +111,65 @@ def get_model_json_schema(model_name: str) -> dict[str, Any]:
|
|
|
163
111
|
Returns:
|
|
164
112
|
JSON schema of the requested Vizro model
|
|
165
113
|
"""
|
|
166
|
-
# Dictionary mapping model names to their simplified versions
|
|
167
114
|
modified_models = {
|
|
168
|
-
"Page": PageSimplified,
|
|
169
|
-
"Dashboard": DashboardSimplified,
|
|
170
115
|
"Graph": GraphEnhanced,
|
|
171
116
|
"AgGrid": AgGridEnhanced,
|
|
172
117
|
"Table": AgGridEnhanced,
|
|
173
|
-
"Tabs": TabsSimplified,
|
|
174
|
-
"Container": ContainerSimplified,
|
|
175
|
-
"Filter": FilterSimplified,
|
|
176
|
-
"Parameter": ParameterSimplified,
|
|
177
118
|
}
|
|
178
119
|
|
|
179
|
-
# Check if model_name is in the simplified models dictionary
|
|
180
120
|
if model_name in modified_models:
|
|
181
|
-
return
|
|
121
|
+
return ModelJsonSchemaResults(
|
|
122
|
+
model_name=model_name,
|
|
123
|
+
json_schema=modified_models[model_name].model_json_schema(schema_generator=NoDefsGenerateJsonSchema),
|
|
124
|
+
additional_info="""LLM must remember to replace `$ref` with the actual config. Request the schema of
|
|
125
|
+
that model if necessary. Do NOT forget to call `validate_dashboard_config` after each iteration.""",
|
|
126
|
+
)
|
|
182
127
|
|
|
183
|
-
# Check if model exists in vizro.models
|
|
184
128
|
if not hasattr(vm, model_name):
|
|
185
|
-
return
|
|
129
|
+
return ModelJsonSchemaResults(
|
|
130
|
+
model_name=model_name,
|
|
131
|
+
json_schema={},
|
|
132
|
+
additional_info=f"Model '{model_name}' not found in vizro.models",
|
|
133
|
+
)
|
|
186
134
|
|
|
187
|
-
# Get schema for standard model
|
|
188
135
|
model_class = getattr(vm, model_name)
|
|
189
|
-
return
|
|
136
|
+
return ModelJsonSchemaResults(
|
|
137
|
+
model_name=model_name,
|
|
138
|
+
json_schema=model_class.model_json_schema(schema_generator=NoDefsGenerateJsonSchema),
|
|
139
|
+
additional_info="""LLM must remember to replace `$ref` with the actual config. Request the schema of
|
|
140
|
+
that model if necessary. Do NOT forget to call `validate_dashboard_config` after each iteration.""",
|
|
141
|
+
)
|
|
190
142
|
|
|
191
143
|
|
|
192
144
|
@mcp.tool()
|
|
193
|
-
def
|
|
194
|
-
"""
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
tool to get sample data information
|
|
208
|
-
- create a chart using plotly express and/or plotly graph objects, and call the function `custom_chart`
|
|
209
|
-
- call the validate_chart_code tool to validate the chart code, display the figure code to the user (as artifact)
|
|
210
|
-
- do NOT call any other tool after, especially do NOT create a dashboard
|
|
211
|
-
"""
|
|
212
|
-
elif user_plan == "dashboard":
|
|
213
|
-
return f"""
|
|
214
|
-
IMPORTANT:
|
|
215
|
-
- KEEP IT SIMPLE: rather than iterating yourself, ask the user for more instructions
|
|
216
|
-
- ALWAYS VALIDATE:if you iterate over a valid produced solution, make sure to ALWAYS call the
|
|
217
|
-
validate_model_config tool again to ensure the solution is still valid
|
|
218
|
-
- DO NOT show any code or config to the user until you have validated the solution, do not say you are preparing
|
|
219
|
-
a solution, just do it and validate it
|
|
220
|
-
- IF STUCK: try enquiring the schema of the component in question
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
Instructions for creating a Vizro dashboard:
|
|
224
|
-
- IF the user has no plan (ie no components or pages), use the config at the bottom of this prompt
|
|
225
|
-
and validate that solution without any additions, OTHERWISE:
|
|
226
|
-
- analyze the datasets needed for the dashboard using the load_and_analyze_data tool - the most
|
|
227
|
-
important information here are the column names and column types
|
|
228
|
-
- if the user provides no data, but you need to display a chart or table, use the get_sample_data_info
|
|
229
|
-
tool to get sample data information
|
|
230
|
-
- make a plan of what components you would like to use, then request all necessary schemas
|
|
231
|
-
using the get_model_json_schema tool
|
|
232
|
-
- assemble your components into a page, then add the page or pages to a dashboard, DO NOT show config or code
|
|
233
|
-
to the user until you have validated the solution
|
|
234
|
-
- ALWAYS validate the dashboard configuration using the validate_model_config tool
|
|
235
|
-
- if you display any code artifact, you must use the above created code, do not add new config to it
|
|
236
|
-
|
|
237
|
-
Models you can use:
|
|
238
|
-
{get_overview_vizro_models()}
|
|
239
|
-
|
|
240
|
-
Very simple dashboard config:
|
|
241
|
-
{get_simple_dashboard_config()}
|
|
145
|
+
def get_sample_data_info(data_name: Literal["iris", "tips", "stocks", "gapminder"]) -> DFMetaData:
|
|
146
|
+
"""If user provides no data, use this tool to get sample data information.
|
|
147
|
+
|
|
148
|
+
Use the following data for the below purposes:
|
|
149
|
+
- iris: mostly numerical with one categorical column, good for scatter, histogram, boxplot, etc.
|
|
150
|
+
- tips: contains mix of numerical and categorical columns, good for bar, pie, etc.
|
|
151
|
+
- stocks: stock prices, good for line, scatter, generally things that change over time
|
|
152
|
+
- gapminder: demographic data, good for line, scatter, generally things with maps or many categories
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
data_name: Name of the dataset to get sample data for
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
Data info object containing information about the dataset.
|
|
242
159
|
"""
|
|
160
|
+
if data_name == "iris":
|
|
161
|
+
return IRIS
|
|
162
|
+
elif data_name == "tips":
|
|
163
|
+
return TIPS
|
|
164
|
+
elif data_name == "stocks":
|
|
165
|
+
return STOCKS
|
|
166
|
+
elif data_name == "gapminder":
|
|
167
|
+
return GAPMINDER
|
|
243
168
|
|
|
244
169
|
|
|
245
170
|
@mcp.tool()
|
|
246
171
|
def load_and_analyze_data(path_or_url: str) -> DataAnalysisResults:
|
|
247
|
-
"""
|
|
172
|
+
"""Use to understand local or remote data files. Must be called with absolute paths or URLs.
|
|
248
173
|
|
|
249
174
|
Supported formats:
|
|
250
175
|
- CSV (.csv)
|
|
@@ -255,7 +180,7 @@ def load_and_analyze_data(path_or_url: str) -> DataAnalysisResults:
|
|
|
255
180
|
- Parquet (.parquet)
|
|
256
181
|
|
|
257
182
|
Args:
|
|
258
|
-
path_or_url:
|
|
183
|
+
path_or_url: Absolute (important!) local file path or URL to a data file
|
|
259
184
|
|
|
260
185
|
Returns:
|
|
261
186
|
DataAnalysisResults object containing DataFrame information and metadata
|
|
@@ -276,7 +201,14 @@ def load_and_analyze_data(path_or_url: str) -> DataAnalysisResults:
|
|
|
276
201
|
df, read_fn = load_dataframe_by_format(processed_path_or_url, mime_type)
|
|
277
202
|
|
|
278
203
|
except Exception as e:
|
|
279
|
-
return DataAnalysisResults(
|
|
204
|
+
return DataAnalysisResults(
|
|
205
|
+
valid=False,
|
|
206
|
+
message=f"""Failed to load data: {e!s}. Remember to use the ABSOLUTE path or URL!
|
|
207
|
+
Alternatively, you can use any data analysis means available to you. Most important information are the column names and
|
|
208
|
+
column types for passing along to the `validate_dashboard_config` or `validate_chart_code` tools.""",
|
|
209
|
+
df_info=None,
|
|
210
|
+
df_metadata=None,
|
|
211
|
+
)
|
|
280
212
|
|
|
281
213
|
df_info = get_dataframe_info(df)
|
|
282
214
|
df_metadata = DFMetaData(
|
|
@@ -289,58 +221,97 @@ def load_and_analyze_data(path_or_url: str) -> DataAnalysisResults:
|
|
|
289
221
|
return DataAnalysisResults(valid=True, message="Data loaded successfully", df_info=df_info, df_metadata=df_metadata)
|
|
290
222
|
|
|
291
223
|
|
|
224
|
+
# TODO: Additional things we could validate:
|
|
225
|
+
# - data_infos: check we are referring to the correct dataframe, or at least A DF
|
|
226
|
+
@mcp.tool()
|
|
227
|
+
def validate_dashboard_config(
|
|
228
|
+
dashboard_config: dict[str, Any],
|
|
229
|
+
data_infos: list[DFMetaData],
|
|
230
|
+
custom_charts: list[ChartPlan],
|
|
231
|
+
auto_open: bool = True,
|
|
232
|
+
) -> ValidateResults:
|
|
233
|
+
"""Validate Vizro model configuration. Run ALWAYS when you have a complete dashboard configuration.
|
|
234
|
+
|
|
235
|
+
If successful, the tool will return the python code and, if it is a remote file, the py.cafe link to the chart.
|
|
236
|
+
The PyCafe link will be automatically opened in your default browser if auto_open is True.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
dashboard_config: Either a JSON string or a dictionary representing a Vizro dashboard model configuration
|
|
240
|
+
data_infos: List of DFMetaData objects containing information about the data files
|
|
241
|
+
custom_charts: List of ChartPlan objects containing information about the custom charts in the dashboard
|
|
242
|
+
auto_open: Whether to automatically open the PyCafe link in a browser
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
ValidationResults object with status and dashboard details
|
|
246
|
+
"""
|
|
247
|
+
Vizro._reset()
|
|
248
|
+
|
|
249
|
+
try:
|
|
250
|
+
dashboard = vm.Dashboard.model_validate(
|
|
251
|
+
dashboard_config,
|
|
252
|
+
context={"allow_undefined_captured_callable": [custom_chart.chart_name for custom_chart in custom_charts]},
|
|
253
|
+
)
|
|
254
|
+
except ValidationError as e:
|
|
255
|
+
return ValidateResults(
|
|
256
|
+
valid=False,
|
|
257
|
+
message=f"""Validation Error: {e!s}. Fix the error and call this tool again.
|
|
258
|
+
Calling `get_model_json_schema` may help.""",
|
|
259
|
+
python_code="",
|
|
260
|
+
pycafe_url=None,
|
|
261
|
+
browser_opened=False,
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
else:
|
|
265
|
+
code_link = get_python_code_and_preview_link(dashboard, data_infos, custom_charts)
|
|
266
|
+
|
|
267
|
+
pycafe_url = code_link.pycafe_url if all(info.file_location_type == "remote" for info in data_infos) else None
|
|
268
|
+
browser_opened = False
|
|
269
|
+
|
|
270
|
+
if pycafe_url and auto_open:
|
|
271
|
+
try:
|
|
272
|
+
browser_opened = webbrowser.open(pycafe_url)
|
|
273
|
+
except Exception:
|
|
274
|
+
browser_opened = False
|
|
275
|
+
|
|
276
|
+
return ValidateResults(
|
|
277
|
+
valid=True,
|
|
278
|
+
message="""Configuration is valid for Dashboard! Do not forget to call this tool again after each iteration.
|
|
279
|
+
If you are creating an `app.py` file, you MUST use the code from the validation tool, do not modify it, watch out for
|
|
280
|
+
differences to previous `app.py`""",
|
|
281
|
+
python_code=code_link.python_code,
|
|
282
|
+
pycafe_url=pycafe_url,
|
|
283
|
+
browser_opened=browser_opened,
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
finally:
|
|
287
|
+
Vizro._reset()
|
|
288
|
+
|
|
289
|
+
|
|
292
290
|
@mcp.prompt()
|
|
293
291
|
def create_starter_dashboard():
|
|
294
292
|
"""Prompt template for getting started with Vizro."""
|
|
295
|
-
|
|
296
|
-
Create a super simple Vizro dashboard with one page and one chart and one filter:
|
|
297
|
-
- No need to call any tools except for validate_model_config
|
|
298
|
-
- Call this tool with the precise config as shown below
|
|
299
|
-
- The PyCafe link will be automatically opened in your default browser
|
|
300
|
-
- THEN show the python code after validation, but do not show the PyCafe link
|
|
301
|
-
- Be concise, do not explain anything else, just create the dashboard
|
|
302
|
-
- Finally ask the user what they would like to do next, then you can call other tools to get more information,
|
|
303
|
-
you should then start with the get_chart_or_dashboard_plan tool
|
|
304
|
-
|
|
305
|
-
{SAMPLE_DASHBOARD_CONFIG}
|
|
306
|
-
"""
|
|
307
|
-
return content
|
|
293
|
+
return get_starter_dashboard_prompt()
|
|
308
294
|
|
|
309
295
|
|
|
310
296
|
@mcp.prompt()
|
|
311
|
-
def
|
|
312
|
-
file_path_or_url: str,
|
|
297
|
+
def create_dashboard(
|
|
298
|
+
file_path_or_url: str = Field(description="The absolute path or URL to the data file you want to use."),
|
|
299
|
+
context: Optional[str] = Field(default=None, description="(Optional) Describe the dashboard you want to create."),
|
|
313
300
|
) -> str:
|
|
314
301
|
"""Prompt template for creating an EDA dashboard based on one dataset."""
|
|
315
|
-
|
|
316
|
-
Create an EDA dashboard based on the following dataset:{file_path_or_url}. Proceed as follows:
|
|
317
|
-
1. Analyze the data using the load_and_analyze_data tool first, passing the file path or github url {file_path_or_url}
|
|
318
|
-
to the tool.
|
|
319
|
-
2. Create a dashboard with 4 pages:
|
|
320
|
-
- Page 1: Summary of the dataset using the Card component and the dataset itself using the plain AgGrid component.
|
|
321
|
-
- Page 2: Visualizing the distribution of all numeric columns using the Graph component with a histogram.
|
|
322
|
-
- use a Parameter that targets the Graph component and the x argument, and you can select the column to
|
|
323
|
-
be displayed
|
|
324
|
-
- IMPORTANT:remember that you target the chart like: <graph_id>.x and NOT <graph_id>.figure.x
|
|
325
|
-
- do not use any color schemes etc.
|
|
326
|
-
- add filters for all categorical columns
|
|
327
|
-
- Page 3: Visualizing the correlation between all numeric columns using the Graph component with a scatter plot.
|
|
328
|
-
- Page 4: Two interesting charts side by side, use the Graph component for this. Make sure they look good
|
|
329
|
-
but do not try something beyond the scope of plotly express
|
|
330
|
-
"""
|
|
331
|
-
return content
|
|
302
|
+
return get_dashboard_prompt(file_path_or_url, context)
|
|
332
303
|
|
|
333
304
|
|
|
334
305
|
@mcp.tool()
|
|
335
306
|
def validate_chart_code(
|
|
336
|
-
|
|
307
|
+
chart_config: ChartPlan,
|
|
337
308
|
data_info: DFMetaData,
|
|
338
309
|
auto_open: bool = True,
|
|
339
|
-
) ->
|
|
310
|
+
) -> ValidateResults:
|
|
340
311
|
"""Validate the chart code created by the user and optionally open the PyCafe link in a browser.
|
|
341
312
|
|
|
342
313
|
Args:
|
|
343
|
-
|
|
314
|
+
chart_config: A ChartPlan object with the chart configuration
|
|
344
315
|
data_info: Metadata for the dataset to be used in the chart
|
|
345
316
|
auto_open: Whether to automatically open the PyCafe link in a browser
|
|
346
317
|
|
|
@@ -350,9 +321,9 @@ def validate_chart_code(
|
|
|
350
321
|
Vizro._reset()
|
|
351
322
|
|
|
352
323
|
try:
|
|
353
|
-
chart_plan_obj = ChartPlan.model_validate(
|
|
324
|
+
chart_plan_obj = ChartPlan.model_validate(chart_config)
|
|
354
325
|
except ValidationError as e:
|
|
355
|
-
return
|
|
326
|
+
return ValidateResults(
|
|
356
327
|
valid=False,
|
|
357
328
|
message=f"Validation Error: {e!s}",
|
|
358
329
|
python_code="",
|
|
@@ -372,7 +343,7 @@ def validate_chart_code(
|
|
|
372
343
|
except Exception:
|
|
373
344
|
browser_opened = False
|
|
374
345
|
|
|
375
|
-
return
|
|
346
|
+
return ValidateResults(
|
|
376
347
|
valid=True,
|
|
377
348
|
message="Chart only dashboard created successfully!",
|
|
378
349
|
python_code=chart_plan_obj.get_chart_code(vizro=True),
|
|
@@ -386,15 +357,8 @@ def validate_chart_code(
|
|
|
386
357
|
|
|
387
358
|
@mcp.prompt()
|
|
388
359
|
def create_vizro_chart(
|
|
389
|
-
|
|
390
|
-
|
|
360
|
+
file_path_or_url: str = Field(description="The absolute path or URL to the data file you want to use."),
|
|
361
|
+
context: Optional[str] = Field(default=None, description="(Optional) Describe the chart you want to create."),
|
|
391
362
|
) -> str:
|
|
392
363
|
"""Prompt template for creating a Vizro chart."""
|
|
393
|
-
|
|
394
|
-
- Create a chart using the following chart type: {chart_type}.
|
|
395
|
-
- You MUST name the function containing the fig `custom_chart`
|
|
396
|
-
- Make sure to analyze the data using the load_and_analyze_data tool first, passing the file path or github url
|
|
397
|
-
{file_path_or_url} OR choose the most appropriate sample data using the get_sample_data_info tool.
|
|
398
|
-
Then you MUST use the validate_chart_code tool to validate the chart code.
|
|
399
|
-
"""
|
|
400
|
-
return content
|
|
364
|
+
return get_chart_prompt(file_path_or_url, context)
|