metaflow 2.18.9__py2.py3-none-any.whl → 2.18.10__py2.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.
@@ -0,0 +1,232 @@
1
+ """
2
+ JSONViewer component for displaying JSON data with syntax highlighting and collapsible sections.
3
+ """
4
+
5
+ from typing import Any, Optional, Union
6
+ from .card import MetaflowCardComponent, with_default_component_id
7
+ from .renderer_tools import render_safely
8
+ import json
9
+ from metaflow._vendor import yaml
10
+
11
+
12
+ class JSONViewer(MetaflowCardComponent):
13
+ """
14
+ A component for displaying JSON data with syntax highlighting and collapsible sections.
15
+
16
+ This component provides a rich view of JSON data with proper formatting, syntax highlighting,
17
+ and the ability to collapse/expand sections for better readability.
18
+
19
+ Example:
20
+ ```python
21
+ from metaflow.cards import JSONViewer
22
+ from metaflow import current
23
+
24
+ data = {
25
+ "user": {"name": "Alice", "age": 30},
26
+ "items": [{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}],
27
+ "metadata": {"created": "2024-01-01", "version": "1.0"}
28
+ }
29
+
30
+ json_viewer = JSONViewer(data, collapsible=True, max_height="400px")
31
+ current.card.append(json_viewer)
32
+ ```
33
+
34
+ Parameters
35
+ ----------
36
+ data : Any
37
+ The data to display as JSON. Will be serialized using json.dumps().
38
+ collapsible : bool, default True
39
+ Whether to make the JSON viewer collapsible.
40
+ max_height : str, optional
41
+ Maximum height for the viewer (CSS value like "300px" or "20rem").
42
+ show_copy_button : bool, default True
43
+ Whether to show a copy-to-clipboard button.
44
+ """
45
+
46
+ type = "jsonViewer"
47
+
48
+ REALTIME_UPDATABLE = True
49
+
50
+ def __init__(
51
+ self,
52
+ data: Any,
53
+ collapsible: bool = True,
54
+ max_height: Optional[str] = None,
55
+ show_copy_button: bool = True,
56
+ title: Optional[str] = None,
57
+ ):
58
+ self._data = data
59
+ self._collapsible = collapsible
60
+ self._max_height = max_height
61
+ self._show_copy_button = show_copy_button
62
+ self._title = title
63
+
64
+ def update(self, data: Any):
65
+ """
66
+ Update the JSON data.
67
+
68
+ Parameters
69
+ ----------
70
+ data : Any
71
+ New data to display as JSON.
72
+ """
73
+ self._data = data
74
+
75
+ @with_default_component_id
76
+ @render_safely
77
+ def render(self):
78
+ # Serialize data to JSON string
79
+ try:
80
+ if isinstance(self._data, str):
81
+ # If already a string, try to parse and re-serialize for formatting
82
+ try:
83
+ parsed = json.loads(self._data)
84
+ json_string = json.dumps(parsed, indent=2, ensure_ascii=False)
85
+ except json.JSONDecodeError:
86
+ # If not valid JSON, treat as plain string
87
+ json_string = json.dumps(self._data, indent=2, ensure_ascii=False)
88
+ else:
89
+ json_string = json.dumps(
90
+ self._data, indent=2, ensure_ascii=False, default=str
91
+ )
92
+ except Exception as e:
93
+ # Fallback for non-serializable objects
94
+ json_string = json.dumps(
95
+ {"error": f"Could not serialize data: {str(e)}"}, indent=2
96
+ )
97
+
98
+ data = {
99
+ "type": self.type,
100
+ "id": self.component_id,
101
+ "json_string": json_string,
102
+ "collapsible": self._collapsible,
103
+ "show_copy_button": self._show_copy_button,
104
+ "title": self._title or "JSON",
105
+ }
106
+
107
+ if self._max_height:
108
+ data["max_height"] = self._max_height
109
+
110
+ return data
111
+
112
+
113
+ class YAMLViewer(MetaflowCardComponent):
114
+ """
115
+ A component for displaying YAML data with syntax highlighting and collapsible sections.
116
+
117
+ This component provides a rich view of YAML data with proper formatting and syntax highlighting.
118
+
119
+ Example:
120
+ ```python
121
+ from metaflow.cards import YAMLViewer
122
+ from metaflow import current
123
+
124
+ data = {
125
+ "database": {
126
+ "host": "localhost",
127
+ "port": 5432,
128
+ "credentials": {"username": "admin", "password": "secret"}
129
+ },
130
+ "features": ["auth", "logging", "monitoring"]
131
+ }
132
+
133
+ yaml_viewer = YAMLViewer(data, collapsible=True)
134
+ current.card.append(yaml_viewer)
135
+ ```
136
+
137
+ Parameters
138
+ ----------
139
+ data : Any
140
+ The data to display as YAML. Will be serialized to YAML format.
141
+ collapsible : bool, default True
142
+ Whether to make the YAML viewer collapsible.
143
+ max_height : str, optional
144
+ Maximum height for the viewer (CSS value like "300px" or "20rem").
145
+ show_copy_button : bool, default True
146
+ Whether to show a copy-to-clipboard button.
147
+ """
148
+
149
+ type = "yamlViewer"
150
+
151
+ REALTIME_UPDATABLE = True
152
+
153
+ def __init__(
154
+ self,
155
+ data: Any,
156
+ collapsible: bool = True,
157
+ max_height: Optional[str] = None,
158
+ show_copy_button: bool = True,
159
+ title: Optional[str] = None,
160
+ ):
161
+ self._data = data
162
+ self._collapsible = collapsible
163
+ self._max_height = max_height
164
+ self._show_copy_button = show_copy_button
165
+ self._title = title
166
+
167
+ def update(self, data: Any):
168
+ """
169
+ Update the YAML data.
170
+
171
+ Parameters
172
+ ----------
173
+ data : Any
174
+ New data to display as YAML.
175
+ """
176
+ self._data = data
177
+
178
+ def _to_yaml_string(self, data: Any) -> str:
179
+ """
180
+ Convert data to YAML string format using vendored YAML module.
181
+ """
182
+ try:
183
+ if isinstance(data, str):
184
+ # Try to parse as JSON first, then convert to YAML
185
+ try:
186
+ import json
187
+
188
+ parsed = json.loads(data)
189
+ yaml_result = yaml.dump(
190
+ parsed, default_flow_style=False, indent=2, sort_keys=False
191
+ )
192
+ return (
193
+ str(yaml_result)
194
+ if yaml_result is not None
195
+ else "# Empty YAML result"
196
+ )
197
+ except json.JSONDecodeError:
198
+ # If not JSON, return as-is
199
+ return data
200
+ else:
201
+ yaml_result = yaml.dump(
202
+ data, default_flow_style=False, indent=2, sort_keys=False
203
+ )
204
+ return (
205
+ str(yaml_result)
206
+ if yaml_result is not None
207
+ else "# Empty YAML result"
208
+ )
209
+ except Exception as e:
210
+ # Fallback to JSON on any error
211
+ import json
212
+
213
+ return f"# Error converting to YAML: {str(e)}\n{json.dumps(data, indent=2, default=str)}"
214
+
215
+ @with_default_component_id
216
+ @render_safely
217
+ def render(self):
218
+ yaml_string = self._to_yaml_string(self._data)
219
+
220
+ data = {
221
+ "type": self.type,
222
+ "id": self.component_id,
223
+ "yaml_string": yaml_string,
224
+ "collapsible": self._collapsible,
225
+ "show_copy_button": self._show_copy_button,
226
+ "title": self._title or "YAML",
227
+ }
228
+
229
+ if self._max_height:
230
+ data["max_height"] = self._max_height
231
+
232
+ return data