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 CHANGED
@@ -3,7 +3,7 @@ import sys
3
3
 
4
4
  from .server import mcp
5
5
 
6
- __version__ = "0.1.3"
6
+ __version__ = "0.1.4"
7
7
 
8
8
 
9
9
  def main():
@@ -1,6 +1,6 @@
1
1
  """Schema defining pydantic models for usage in the MCP server."""
2
2
 
3
- from typing import Annotated, Any, Optional
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: Optional[str] = None, vizro: bool = False):
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}")
@@ -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",
@@ -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, Optional
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: Optional[dict[str, str]] = None
13
+ column_names_types: dict[str, str] | None = None
14
14
 
15
15
 
16
16
  @dataclass
@@ -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, Optional, Protocol
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 use `Flex` (layout setting is NOT optional, contrary to what schema says); use `Grid` only if asked for precise placement or no scroll
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__: Optional[str]
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.export_data,
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.__dict__[func] for func in vf.__all__],
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: Optional[str] = None) -> str:
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: Optional[str] = None) -> str:
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, Optional, Union
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: Union[str, Path], mime_type: Optional[str] = None
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, Optional
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: Optional[str]
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: Optional[DFInfo]
62
- df_metadata: Optional[DFMetaData]
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=LAYOUT_INSTRUCTIONS,
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: Optional[str] = Field(default=None, description="(Optional) Describe the dashboard you want to create."),
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: Optional[str] = Field(default=None, description="(Optional) Describe the chart you want to create."),
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
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,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -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,,