plotext-plus 1.0.8__py3-none-any.whl → 1.0.9__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.
@@ -71,11 +71,15 @@ async def scatter_plot(x: List[Union[int, float]], y: List[Union[int, float]],
71
71
  Returns:
72
72
  The rendered plot as text
73
73
  """
74
+ # Convert string inputs to float
75
+ x_numeric = [float(val) if isinstance(val, str) else val for val in x]
76
+ y_numeric = [float(val) if isinstance(val, str) else val for val in y]
77
+
74
78
  plotting.clear_figure()
75
79
  if title:
76
80
  plotting.title(title)
77
81
 
78
- _, output = _capture_plot_output(plotting.scatter, x, y, marker=marker, color=color)
82
+ _, output = _capture_plot_output(plotting.scatter, x_numeric, y_numeric, marker=marker, color=color)
79
83
  _, show_output = _capture_plot_output(plotting.show)
80
84
 
81
85
  return output + show_output
@@ -95,14 +99,41 @@ async def line_plot(x: List[Union[int, float]], y: List[Union[int, float]],
95
99
  Returns:
96
100
  The rendered plot as text
97
101
  """
98
- plotting.clear_figure()
99
- if title:
100
- plotting.title(title)
102
+ import sys
103
+ print(f"DEBUG: line_plot called with x={x}, y={y}, title={title}", file=sys.stderr)
101
104
 
102
- _, output = _capture_plot_output(plotting.plot, x, y, color=color)
103
- _, show_output = _capture_plot_output(plotting.show)
105
+ # Convert string inputs to float
106
+ try:
107
+ x_numeric = [float(val) if isinstance(val, str) else val for val in x]
108
+ y_numeric = [float(val) if isinstance(val, str) else val for val in y]
109
+ print(f"DEBUG: Converted to x_numeric={x_numeric}, y_numeric={y_numeric}", file=sys.stderr)
110
+ except Exception as e:
111
+ print(f"DEBUG: Error converting inputs: {e}", file=sys.stderr)
112
+ raise
104
113
 
105
- return output + show_output
114
+ try:
115
+ plotting.clear_figure()
116
+ print("DEBUG: Cleared figure", file=sys.stderr)
117
+
118
+ if title:
119
+ plotting.title(title)
120
+ print(f"DEBUG: Set title: {title}", file=sys.stderr)
121
+
122
+ _, output = _capture_plot_output(plotting.plot, x_numeric, y_numeric, color=color)
123
+ print(f"DEBUG: Generated plot output, length: {len(output)}", file=sys.stderr)
124
+
125
+ _, show_output = _capture_plot_output(plotting.show)
126
+ print(f"DEBUG: Generated show output, length: {len(show_output)}", file=sys.stderr)
127
+
128
+ result = output + show_output
129
+ print(f"DEBUG: Returning result, total length: {len(result)}", file=sys.stderr)
130
+ return result
131
+
132
+ except Exception as e:
133
+ print(f"DEBUG: Error during plotting: {e}", file=sys.stderr)
134
+ import traceback
135
+ traceback.print_exc(file=sys.stderr)
136
+ raise
106
137
 
107
138
 
108
139
  @tool
@@ -119,11 +150,14 @@ async def bar_chart(labels: List[str], values: List[Union[int, float]],
119
150
  Returns:
120
151
  The rendered plot as text
121
152
  """
153
+ # Convert string inputs to float
154
+ values_numeric = [float(val) if isinstance(val, str) else val for val in values]
155
+
122
156
  plotting.clear_figure()
123
157
  if title:
124
158
  plotting.title(title)
125
159
 
126
- _, output = _capture_plot_output(plotting.bar, labels, values, color=color)
160
+ _, output = _capture_plot_output(plotting.bar, labels, values_numeric, color=color)
127
161
  _, show_output = _capture_plot_output(plotting.show)
128
162
 
129
163
  return output + show_output
@@ -212,7 +246,11 @@ async def quick_scatter(x: List[Union[int, float]], y: List[Union[int, float]],
212
246
  Returns:
213
247
  The rendered chart as text
214
248
  """
215
- _, output = _capture_plot_output(charts.quick_scatter, x, y, title=title, theme=theme_name)
249
+ # Convert string inputs to float
250
+ x_numeric = [float(val) if isinstance(val, str) else val for val in x]
251
+ y_numeric = [float(val) if isinstance(val, str) else val for val in y]
252
+
253
+ _, output = _capture_plot_output(charts.quick_scatter, x_numeric, y_numeric, title=title, theme=theme_name)
216
254
  return output
217
255
 
218
256
 
@@ -230,7 +268,11 @@ async def quick_line(x: List[Union[int, float]], y: List[Union[int, float]],
230
268
  Returns:
231
269
  The rendered chart as text
232
270
  """
233
- _, output = _capture_plot_output(charts.quick_line, x, y, title=title, theme=theme_name)
271
+ # Convert string inputs to float
272
+ x_numeric = [float(val) if isinstance(val, str) else val for val in x]
273
+ y_numeric = [float(val) if isinstance(val, str) else val for val in y]
274
+
275
+ _, output = _capture_plot_output(charts.quick_line, x_numeric, y_numeric, title=title, theme=theme_name)
234
276
  return output
235
277
 
236
278
 
@@ -248,7 +290,10 @@ async def quick_bar(labels: List[str], values: List[Union[int, float]],
248
290
  Returns:
249
291
  The rendered chart as text
250
292
  """
251
- _, output = _capture_plot_output(charts.quick_bar, labels, values, title=title, theme=theme_name)
293
+ # Convert string inputs to float
294
+ values_numeric = [float(val) if isinstance(val, str) else val for val in values]
295
+
296
+ _, output = _capture_plot_output(charts.quick_bar, labels, values_numeric, title=title, theme=theme_name)
252
297
  return output
253
298
 
254
299
 
@@ -274,7 +319,10 @@ async def quick_pie(labels: List[str], values: List[Union[int, float]],
274
319
  Returns:
275
320
  The rendered pie chart as text
276
321
  """
277
- _, output = _capture_plot_output(charts.quick_pie, labels, values, colors=colors,
322
+ # Convert string inputs to float
323
+ values_numeric = [float(val) if isinstance(val, str) else val for val in values]
324
+
325
+ _, output = _capture_plot_output(charts.quick_pie, labels, values_numeric, colors=colors,
278
326
  title=title, show_values=show_values,
279
327
  show_percentages=show_percentages,
280
328
  show_values_on_slices=show_values_on_slices,
@@ -303,7 +351,10 @@ async def quick_donut(labels: List[str], values: List[Union[int, float]],
303
351
  Returns:
304
352
  The rendered doughnut chart as text
305
353
  """
306
- _, output = _capture_plot_output(charts.quick_donut, labels, values, colors=colors,
354
+ # Convert string inputs to float
355
+ values_numeric = [float(val) if isinstance(val, str) else val for val in values]
356
+
357
+ _, output = _capture_plot_output(charts.quick_donut, labels, values_numeric, colors=colors,
307
358
  title=title, show_values=show_values,
308
359
  show_percentages=show_percentages,
309
360
  show_values_on_slices=show_values_on_slices,
@@ -803,8 +854,152 @@ async def quick_donut_convenience_prompt() -> str:
803
854
  # Main server entry point
804
855
  def start_server():
805
856
  """Start the MCP server."""
806
- print("Starting Plotext Plus MCP Server...")
807
- run()
857
+ import sys
858
+ import os
859
+
860
+ # Check if we're being run in STDIO mode (by MCP CLI)
861
+ # Force HTTP mode if MCP_HTTP_MODE is set, otherwise detect based on stdin
862
+ force_http = os.getenv('MCP_HTTP_MODE', '').lower() == 'true'
863
+ force_stdio = os.getenv('MCP_STDIO_MODE', '').lower() == 'true'
864
+
865
+ if force_http:
866
+ is_stdio_mode = False
867
+ elif force_stdio:
868
+ is_stdio_mode = True
869
+ else:
870
+ # Auto-detect: STDIO mode when stdin is not a terminal (pipes/redirects)
871
+ is_stdio_mode = not sys.stdin.isatty()
872
+
873
+ if is_stdio_mode:
874
+ # STDIO mode for MCP CLI - simple JSON-RPC implementation
875
+ import json
876
+ import asyncio
877
+
878
+ async def handle_stdio():
879
+ try:
880
+ for line in sys.stdin:
881
+ if not line.strip():
882
+ continue
883
+
884
+ try:
885
+ request = json.loads(line)
886
+ method = request.get('method')
887
+ request_id = request.get('id')
888
+
889
+ if method == 'initialize':
890
+ response = {
891
+ "jsonrpc": "2.0",
892
+ "id": request_id,
893
+ "result": {
894
+ "protocolVersion": "2024-11-05",
895
+ "capabilities": {
896
+ "tools": {},
897
+ "prompts": {},
898
+ "resources": {}
899
+ },
900
+ "serverInfo": {
901
+ "name": "Plotext Plus MCP Server",
902
+ "version": "1.0.0"
903
+ }
904
+ }
905
+ }
906
+ elif method == 'tools/list':
907
+ response = {
908
+ "jsonrpc": "2.0",
909
+ "id": request_id,
910
+ "result": {
911
+ "tools": [
912
+ {
913
+ "name": "line_plot",
914
+ "description": "Create a line plot with given x and y data points",
915
+ "inputSchema": {
916
+ "type": "object",
917
+ "properties": {
918
+ "x": {"type": "array", "items": {"type": "number"}},
919
+ "y": {"type": "array", "items": {"type": "number"}},
920
+ "title": {"type": "string"}
921
+ },
922
+ "required": ["x", "y"]
923
+ }
924
+ }
925
+ ]
926
+ }
927
+ }
928
+ elif method == 'tools/call':
929
+ tool_name = request['params']['name']
930
+ arguments = request['params']['arguments']
931
+
932
+ if tool_name == 'line_plot':
933
+ try:
934
+ result = await line_plot(**arguments)
935
+ response = {
936
+ "jsonrpc": "2.0",
937
+ "id": request_id,
938
+ "result": {
939
+ "content": [
940
+ {
941
+ "type": "text",
942
+ "text": result
943
+ }
944
+ ]
945
+ }
946
+ }
947
+ except Exception as e:
948
+ response = {
949
+ "jsonrpc": "2.0",
950
+ "id": request_id,
951
+ "error": {
952
+ "code": -32000,
953
+ "message": str(e)
954
+ }
955
+ }
956
+ else:
957
+ response = {
958
+ "jsonrpc": "2.0",
959
+ "id": request_id,
960
+ "error": {
961
+ "code": -32601,
962
+ "message": f"Unknown tool: {tool_name}"
963
+ }
964
+ }
965
+ else:
966
+ response = {
967
+ "jsonrpc": "2.0",
968
+ "id": request_id,
969
+ "error": {
970
+ "code": -32601,
971
+ "message": f"Unknown method: {method}"
972
+ }
973
+ }
974
+
975
+ print(json.dumps(response), flush=True)
976
+
977
+ except Exception as e:
978
+ error_response = {
979
+ "jsonrpc": "2.0",
980
+ "id": request.get('id') if 'request' in locals() else None,
981
+ "error": {
982
+ "code": -32700,
983
+ "message": f"Parse error: {str(e)}"
984
+ }
985
+ }
986
+ print(json.dumps(error_response), flush=True)
987
+
988
+ except Exception as e:
989
+ print(f"STDIO handler error: {e}", file=sys.stderr)
990
+
991
+ asyncio.run(handle_stdio())
992
+ else:
993
+ # HTTP server mode (default)
994
+ print("Starting Plotext Plus MCP Server...")
995
+ from chuk_mcp_server import ChukMCPServer
996
+ server = ChukMCPServer(
997
+ name="Plotext Plus MCP Server",
998
+ version="1.0.0",
999
+ prompts=True, # Enable prompts capability
1000
+ logging=True # Enable logging capability for MCP clients
1001
+ )
1002
+ server.run()
808
1003
 
809
1004
 
810
1005
  if __name__ == "__main__":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotext_plus
3
- Version: 1.0.8
3
+ Version: 1.0.9
4
4
  Summary: Modern terminal plotting library with enhanced visual features, themes, and AI integration
5
5
  Project-URL: Homepage, https://github.com/ccmitchellusa/plotext_plus
6
6
  Project-URL: Repository, https://github.com/ccmitchellusa/plotext_plus.git
@@ -20,14 +20,14 @@ plotext_plus/api.py,sha256=56xYn9uzkMe88iELbanRQ-12bC8Rvv2Jk0BX45Fk8zY,28424
20
20
  plotext_plus/charts.py,sha256=VfL0keEo02TPwjUZ6eNFx2q2qOTpiVoq_igL5rGE-gY,1315
21
21
  plotext_plus/core.py,sha256=k6g2dYuHFcNevLJM0elkYupz7fC8Qqk_vLEyrXu2V3I,20668
22
22
  plotext_plus/mcp_cli.py,sha256=otZaP1tolvAL2vx84TVNiTlFdJyDx1cMIMcbhqsSna8,2651
23
- plotext_plus/mcp_server.py,sha256=96NOcmhi68QRnCa5Mcxrt27nM7aX9nnZYeY8xQwKeE0,28041
23
+ plotext_plus/mcp_server.py,sha256=cL-6CL3nQ53LbC3ZReC77_zxFrRVA8UgqQEqNRakaXI,37130
24
24
  plotext_plus/plotext_cli.py,sha256=o3JmSNc7Ify4C6Wkva8x8QRh-pLeiD3VArc3E78xlVU,17677
25
25
  plotext_plus/plotting.py,sha256=7YUISs2Aolqo-lMEX8amGfMNOSFV9zcSqlrEMwVK2RM,2063
26
26
  plotext_plus/themes.py,sha256=xX6XqL2U-7MQmv-k1HU-UTSZRbTfv9op5_4ZRXm435g,725
27
27
  plotext_plus/utilities.py,sha256=scdPDGf6po2rvEL5DX7y1pY41uxlCXTVVIo0w5qA8JE,1170
28
28
  plotext_plus/utils.py,sha256=NFEupN17WY2Xk4EgDY-On_1J3MOvwNBYubnt6Rg8QW4,15387
29
- plotext_plus-1.0.8.dist-info/METADATA,sha256=ef4BaFUFBVldc-p72EQyNiZGkwwoj39lUqijj00RVZc,11355
30
- plotext_plus-1.0.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
31
- plotext_plus-1.0.8.dist-info/entry_points.txt,sha256=XocAh2z8hTGtuQL1zEcGTulrgfZ2g5UMyHSV-JOSNN8,103
32
- plotext_plus-1.0.8.dist-info/licenses/LICENSE,sha256=MkgUiRFwIvXwUVDEPy11uIULq7pGDHpIulD4KulsjnM,1150
33
- plotext_plus-1.0.8.dist-info/RECORD,,
29
+ plotext_plus-1.0.9.dist-info/METADATA,sha256=mMcu8ukY6WNT9L86-ROTSG9-PVhxTi2ENtP2owMLtmE,11355
30
+ plotext_plus-1.0.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
31
+ plotext_plus-1.0.9.dist-info/entry_points.txt,sha256=XocAh2z8hTGtuQL1zEcGTulrgfZ2g5UMyHSV-JOSNN8,103
32
+ plotext_plus-1.0.9.dist-info/licenses/LICENSE,sha256=MkgUiRFwIvXwUVDEPy11uIULq7pGDHpIulD4KulsjnM,1150
33
+ plotext_plus-1.0.9.dist-info/RECORD,,