Soumik555 commited on
Commit
4355ae7
·
1 Parent(s): 8733796

added csv-agent-default in next.js

Browse files
charts/chart_67061795-658f-4411-a078-74ebe53ca1da.html ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <head><meta charset="utf-8" /></head>
3
+ <body>
4
+ <div> <script type="text/javascript">window.PlotlyConfig = {MathJaxConfig: 'local'};</script>
5
+ <script charset="utf-8" src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script> <div id="f21b13f1-7d59-4175-b117-76e29607bd2c" class="plotly-graph-div" style="height:100%; width:100%;"></div> <script type="text/javascript"> window.PLOTLYENV=window.PLOTLYENV || {}; if (document.getElementById("f21b13f1-7d59-4175-b117-76e29607bd2c")) { Plotly.newPlot( "f21b13f1-7d59-4175-b117-76e29607bd2c", [{"alignmentgroup":"True","hovertemplate":"x=%{x}\u003cbr\u003ey=%{y}\u003cextra\u003e\u003c\u002fextra\u003e","legendgroup":"","marker":{"color":"#636efa","pattern":{"shape":""}},"name":"","offsetgroup":"","orientation":"v","showlegend":false,"textposition":"auto","x":["A","B","C"],"xaxis":"x","y":[1,3,2],"yaxis":"y","type":"bar"}], {"template":{"data":{"histogram2dcontour":[{"type":"histogram2dcontour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"choropleth":[{"type":"choropleth","colorbar":{"outlinewidth":0,"ticks":""}}],"histogram2d":[{"type":"histogram2d","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmap":[{"type":"heatmap","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmapgl":[{"type":"heatmapgl","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"contourcarpet":[{"type":"contourcarpet","colorbar":{"outlinewidth":0,"ticks":""}}],"contour":[{"type":"contour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"surface":[{"type":"surface","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"mesh3d":[{"type":"mesh3d","colorbar":{"outlinewidth":0,"ticks":""}}],"scatter":[{"fillpattern":{"fillmode":"overlay","size":10,"solidity":0.2},"type":"scatter"}],"parcoords":[{"type":"parcoords","line":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolargl":[{"type":"scatterpolargl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"scattergeo":[{"type":"scattergeo","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolar":[{"type":"scatterpolar","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"scattergl":[{"type":"scattergl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatter3d":[{"type":"scatter3d","line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermapbox":[{"type":"scattermapbox","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterternary":[{"type":"scatterternary","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattercarpet":[{"type":"scattercarpet","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"pie":[{"automargin":true,"type":"pie"}]},"layout":{"autotypenumbers":"strict","colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"hovermode":"closest","hoverlabel":{"align":"left"},"paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"bgcolor":"#E5ECF6","angularaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"ternary":{"bgcolor":"#E5ECF6","aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"sequential":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"sequentialminus":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]]},"xaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"yaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"geo":{"bgcolor":"white","landcolor":"#E5ECF6","subunitcolor":"white","showland":true,"showlakes":true,"lakecolor":"white"},"title":{"x":0.05},"mapbox":{"style":"light"}}},"xaxis":{"anchor":"y","domain":[0.0,1.0],"title":{"text":"x"}},"yaxis":{"anchor":"x","domain":[0.0,1.0],"title":{"text":"y"}},"legend":{"tracegroupgap":0},"title":{"text":"Plotly Test Plot"},"barmode":"relative"}, {"responsive": true} ) }; </script> </div>
6
+ </body>
7
+ </html>
data/test_output.csv ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Name,Age,Score
2
+ Alice,25,85
3
+ Bob,30,92
4
+ Charlie,35,88
data/test_output.xlsx ADDED
Binary file (5.01 kB). View file
 
main.py CHANGED
@@ -20,6 +20,7 @@ from fastapi.concurrency import run_in_threadpool
20
  from fastapi import Depends, HTTPException, status
21
  from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
22
  import logging
 
23
 
24
  load_dotenv()
25
 
@@ -81,19 +82,21 @@ async def verify_token(credentials: HTTPAuthorizationCredentials = Depends(secur
81
  )
82
  return True
83
 
 
84
  @app.post("/python/execute")
85
  async def execute_code(
86
  code_request: dict,
87
  token_valid: bool = Depends(verify_token)
88
  ) -> Dict[str, Any]:
89
  """
90
- Execute Python code and return the results
91
 
92
  Args:
93
  code_request: Dictionary containing 'code' key with the Python code to execute
94
 
95
  Returns:
96
- dict: Dictionary containing execution results with all plots, output, variables, and any errors
 
97
  """
98
  if not token_valid:
99
  raise HTTPException(status_code=401, detail="Not authenticated")
@@ -118,13 +121,14 @@ async def execute_code(
118
  response_content = {
119
  "success": result['error'] is None,
120
  "output": result['output'],
121
- # "variables": result['variables'],
122
  "plots": [],
123
- "html_charts": result.get('html_charts', [])
 
124
  }
125
 
126
  # Add all plots if they exist
127
- if result['plots']:
128
  response_content["plots"] = [
129
  {
130
  "image": plot_data,
@@ -134,13 +138,27 @@ async def execute_code(
134
  for index, plot_data in enumerate(result['plots'])
135
  ]
136
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  # Add error information if exists
138
- if result['error']:
139
  response_content["error"] = result['error']
140
 
141
  return response_content
142
 
143
  except Exception as e:
 
 
144
  raise HTTPException(
145
  status_code=500,
146
  detail={
@@ -148,7 +166,6 @@ async def execute_code(
148
  "traceback": traceback.format_exc()
149
  }
150
  )
151
-
152
 
153
 
154
 
 
20
  from fastapi import Depends, HTTPException, status
21
  from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
22
  import logging
23
+ import base64
24
 
25
  load_dotenv()
26
 
 
82
  )
83
  return True
84
 
85
+
86
  @app.post("/python/execute")
87
  async def execute_code(
88
  code_request: dict,
89
  token_valid: bool = Depends(verify_token)
90
  ) -> Dict[str, Any]:
91
  """
92
+ Execute Python code and return the results including generated files
93
 
94
  Args:
95
  code_request: Dictionary containing 'code' key with the Python code to execute
96
 
97
  Returns:
98
+ dict: Dictionary containing execution results with all plots, output, variables,
99
+ generated files, and any errors
100
  """
101
  if not token_valid:
102
  raise HTTPException(status_code=401, detail="Not authenticated")
 
121
  response_content = {
122
  "success": result['error'] is None,
123
  "output": result['output'],
124
+ # "variables": result.get('variables', {}),
125
  "plots": [],
126
+ "html_charts": result.get('html_charts', []),
127
+ "generated_files": []
128
  }
129
 
130
  # Add all plots if they exist
131
+ if result.get('plots'):
132
  response_content["plots"] = [
133
  {
134
  "image": plot_data,
 
138
  for index, plot_data in enumerate(result['plots'])
139
  ]
140
 
141
+ # Add generated files if they exist
142
+ if result.get('generated_files'):
143
+ response_content["generated_files"] = [
144
+ {
145
+ "filename": file['filename'],
146
+ "filetype": file['filetype'],
147
+ "content": file['content'],
148
+ "size": len(base64.b64decode(file['content']))
149
+ }
150
+ for file in result['generated_files']
151
+ ]
152
+
153
  # Add error information if exists
154
+ if result.get('error'):
155
  response_content["error"] = result['error']
156
 
157
  return response_content
158
 
159
  except Exception as e:
160
+ logger.error(f"Error executing code: {str(e)}")
161
+ logger.error(traceback.format_exc())
162
  raise HTTPException(
163
  status_code=500,
164
  detail={
 
166
  "traceback": traceback.format_exc()
167
  }
168
  )
 
169
 
170
 
171
 
python_code_interpreter_service.py CHANGED
@@ -19,7 +19,7 @@ import sklearn
19
  import pytz
20
  from dateutil import parser
21
  import json
22
- from typing import Any, Dict
23
  import traceback
24
  import warnings
25
  import plotly.express as px
@@ -36,7 +36,7 @@ def execute_python_code(code: str, df: pd.DataFrame = None) -> Dict[str, Any]:
36
  df (pd.DataFrame): Optional DataFrame to make available in the execution context
37
 
38
  Returns:
39
- dict: Dictionary containing execution results, variables, and any generated plots
40
  """
41
  # Create directories if they don't exist
42
  charts_dir = Path("charts")
@@ -51,6 +51,7 @@ def execute_python_code(code: str, df: pd.DataFrame = None) -> Dict[str, Any]:
51
  plot_base64 = []
52
  variables = {}
53
  html_charts = []
 
54
 
55
  # Monkey patch plt.show() to save figures
56
  original_show = plt.show
@@ -113,6 +114,7 @@ def execute_python_code(code: str, df: pd.DataFrame = None) -> Dict[str, Any]:
113
  'sys': sys,
114
  'warnings': warnings,
115
  'json': json,
 
116
 
117
  # File paths
118
  'DATA_DIR': data_dir,
@@ -154,15 +156,26 @@ def execute_python_code(code: str, df: pd.DataFrame = None) -> Dict[str, Any]:
154
  # First execute to get variables
155
  exec(code, exec_globals)
156
 
 
 
 
 
 
 
 
 
 
 
 
157
  # Capture all variables that were created
158
  for name, value in exec_globals.items():
159
  if not name.startswith('_') and name not in [
160
  'np', 'pd', 'plt', 'sns', 'sm', 'stats', 'sklearn',
161
  'px', 'go', 'datetime', 'parser', 'pytz', 'holidays',
162
  'os', 'sys', 'warnings', 'json', 'DATA_DIR', 'CHARTS_DIR',
163
- 'datasets', 'preprocessing', 'model_selection', 'linear_model',
164
- 'ensemble', 'metrics', 'svm', 'decomposition', 'cluster',
165
- 'feature_selection', 'df' # Exclude our parameter from variables
166
  ]:
167
  variables[name] = value
168
 
@@ -221,5 +234,102 @@ def execute_python_code(code: str, df: pd.DataFrame = None) -> Dict[str, Any]:
221
  'output': output,
222
  'error': error,
223
  'plots': plot_base64,
224
- 'html_charts': html_charts
225
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  import pytz
20
  from dateutil import parser
21
  import json
22
+ from typing import Any, Dict, List
23
  import traceback
24
  import warnings
25
  import plotly.express as px
 
36
  df (pd.DataFrame): Optional DataFrame to make available in the execution context
37
 
38
  Returns:
39
+ dict: Dictionary containing execution results, variables, and any generated files
40
  """
41
  # Create directories if they don't exist
42
  charts_dir = Path("charts")
 
51
  plot_base64 = []
52
  variables = {}
53
  html_charts = []
54
+ generated_files = []
55
 
56
  # Monkey patch plt.show() to save figures
57
  original_show = plt.show
 
114
  'sys': sys,
115
  'warnings': warnings,
116
  'json': json,
117
+ 'Path': Path,
118
 
119
  # File paths
120
  'DATA_DIR': data_dir,
 
156
  # First execute to get variables
157
  exec(code, exec_globals)
158
 
159
+ # Check for newly created files in the data directory
160
+ for file in data_dir.glob('*'):
161
+ if file.suffix.lower() in ['.xlsx', '.csv']:
162
+ with open(file, 'rb') as f:
163
+ file_content = f.read()
164
+ generated_files.append({
165
+ 'filename': file.name,
166
+ 'content': base64.b64encode(file_content).decode('utf-8'),
167
+ 'filetype': file.suffix.lower()[1:] # 'xlsx' or 'csv'
168
+ })
169
+
170
  # Capture all variables that were created
171
  for name, value in exec_globals.items():
172
  if not name.startswith('_') and name not in [
173
  'np', 'pd', 'plt', 'sns', 'sm', 'stats', 'sklearn',
174
  'px', 'go', 'datetime', 'parser', 'pytz', 'holidays',
175
  'os', 'sys', 'warnings', 'json', 'DATA_DIR', 'CHARTS_DIR',
176
+ 'Path', 'datasets', 'preprocessing', 'model_selection',
177
+ 'linear_model', 'ensemble', 'metrics', 'svm', 'decomposition',
178
+ 'cluster', 'feature_selection', 'df' # Exclude our parameter from variables
179
  ]:
180
  variables[name] = value
181
 
 
234
  'output': output,
235
  'error': error,
236
  'plots': plot_base64,
237
+ 'html_charts': html_charts,
238
+ 'generated_files': generated_files,
239
+ 'variables': processed_vars
240
+ }
241
+
242
+
243
+
244
+
245
+
246
+ # EXAMPLE CODE:
247
+
248
+ # test_code = """
249
+ # # Test case that generates all types of outputs
250
+ # import pandas as pd
251
+ # import numpy as np
252
+ # import matplotlib.pyplot as plt
253
+ # import plotly.express as px
254
+ # from pathlib import Path
255
+
256
+ # # 1. Test basic output
257
+ # print("Starting test execution...")
258
+ # print("This is standard output")
259
+
260
+ # # 2. Test variable creation
261
+ # test_var = "Hello, World!"
262
+ # numeric_var = 42
263
+ # array_var = np.array([1, 2, 3])
264
+ # df_var = pd.DataFrame({'A': [1, 2], 'B': ['x', 'y']})
265
+
266
+ # # 3. Test matplotlib plot generation
267
+ # plt.figure()
268
+ # plt.plot([1, 2, 3], [4, 5, 6], label='Test Line')
269
+ # plt.title('Matplotlib Test Plot')
270
+ # plt.legend()
271
+ # plt.show()
272
+
273
+ # # 4. Test plotly plot generation
274
+ # fig = px.bar(x=['A', 'B', 'C'], y=[1, 3, 2], title='Plotly Test Plot')
275
+ # fig.show()
276
+
277
+ # # 5. Test Excel file generation
278
+ # excel_path = Path('data') / 'test_output.xlsx'
279
+ # df_excel = pd.DataFrame({
280
+ # 'Product': ['A', 'B', 'C'],
281
+ # 'Sales': [100, 200, 150],
282
+ # 'Profit': [30, 50, 40]
283
+ # })
284
+ # df_excel.to_excel(excel_path, index=False)
285
+ # print(f"Generated Excel file at {excel_path}")
286
+
287
+ # # 6. Test CSV file generation
288
+ # csv_path = Path('data') / 'test_output.csv'
289
+ # df_csv = pd.DataFrame({
290
+ # 'Name': ['Alice', 'Bob', 'Charlie'],
291
+ # 'Age': [25, 30, 35],
292
+ # 'Score': [85, 92, 88]
293
+ # })
294
+ # df_csv.to_csv(csv_path, index=False)
295
+ # print(f"Generated CSV file at {csv_path}")
296
+
297
+ # # 7. Test error case (commented out by default)
298
+ # # Uncomment to test error handling
299
+ # # 1 / 0
300
+
301
+ # # 8. Test empty case (commented out)
302
+ # # Uncomment to test empty response
303
+ # # print("No plots or files generated")
304
+
305
+ # print("Test execution completed successfully")
306
+ # """
307
+
308
+ # # Execute the test code
309
+ # result = execute_python_code(test_code)
310
+
311
+ # # Print the results in a structured way
312
+ # print("\n=== Execution Results ===")
313
+ # print(f"Output:\n{result['output']}\n")
314
+
315
+ # if result['error']:
316
+ # print("=== Error ===")
317
+ # print(f"Message: {result['error']['message']}")
318
+ # print(f"Traceback:\n{result['error']['traceback']}\n")
319
+
320
+ # print("=== Variables ===")
321
+ # for var_name, var_value in result['variables'].items():
322
+ # print(f"{var_name}: {str(var_value)[:100]}... (type: {type(var_value)})")
323
+
324
+ # print("\n=== Generated Files ===")
325
+ # for file in result['generated_files']:
326
+ # print(f"{file['filename']} ({file['filetype']}), size: {len(base64.b64decode(file['content']))} bytes")
327
+
328
+ # print("\n=== Plots ===")
329
+ # print(f"Matplotlib plots generated: {len(result['plots'])}")
330
+ # print(f"Plotly HTML charts generated: {len(result['html_charts'])}")
331
+
332
+ # # To actually view the plots (in a notebook environment):
333
+ # if result['plots']:
334
+ # from IPython.display import display, Image
335
+ # display(Image(base64.b64decode(result['plots'][0])))