speedy-utils 1.1.44__py3-none-any.whl → 1.1.46__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.
llm_utils/lm/llm.py CHANGED
@@ -16,6 +16,7 @@ from openai.types.chat import ChatCompletionMessageParam
16
16
  from pydantic import BaseModel
17
17
 
18
18
  from speedy_utils.common.utils_io import jdumps
19
+ from speedy_utils import clean_traceback
19
20
 
20
21
  from .base_prompt_builder import BasePromptBuilder
21
22
  from .mixins import (
@@ -159,6 +160,7 @@ class LLM(
159
160
  messages.append({'role': 'user', 'content': user_content})
160
161
  return cast(Messages, messages)
161
162
 
163
+ @clean_traceback
162
164
  def text_completion(
163
165
  self, input_data: str | BaseModel | list[dict], **runtime_kwargs
164
166
  ) -> list[dict[str, Any]]:
@@ -214,6 +216,7 @@ class LLM(
214
216
  results.append(result_dict)
215
217
  return results
216
218
 
219
+ @clean_traceback
217
220
  def pydantic_parse(
218
221
  self,
219
222
  input_data: str | BaseModel | list[dict],
speedy_utils/__init__.py CHANGED
@@ -58,6 +58,9 @@ from .common.utils_print import (
58
58
  fprint,
59
59
  )
60
60
 
61
+ # Error handling utilities
62
+ from .common.utils_error import clean_traceback, handle_exceptions_with_clean_traceback
63
+
61
64
  # Multi-worker processing
62
65
  from .multi_worker.process import multi_process
63
66
  from .multi_worker.thread import kill_all_thread, multi_thread
@@ -156,6 +159,9 @@ __all__ = [
156
159
  'print_table',
157
160
  'setup_logger',
158
161
  'log',
162
+ # Error handling utilities
163
+ 'clean_traceback',
164
+ 'handle_exceptions_with_clean_traceback',
159
165
  # Multi-worker processing
160
166
  'multi_process',
161
167
  'multi_thread',
@@ -0,0 +1,261 @@
1
+ """
2
+ Error handling utilities for clean, user-focused tracebacks.
3
+ """
4
+
5
+ import inspect
6
+ import linecache
7
+ import sys
8
+ import traceback
9
+ from typing import Any, Callable, TypeVar
10
+
11
+ try:
12
+ from rich.console import Console
13
+ from rich.panel import Panel
14
+ from rich.text import Text
15
+ except ImportError:
16
+ Console = None
17
+ Panel = None
18
+ Text = None
19
+
20
+ F = TypeVar('F', bound=Callable[..., Any])
21
+
22
+
23
+ class CleanTracebackError(Exception):
24
+ """Exception wrapper that provides clean, user-focused tracebacks."""
25
+
26
+ def __init__(
27
+ self,
28
+ original_exception: Exception,
29
+ user_traceback: list[traceback.FrameSummary],
30
+ caller_frame: traceback.FrameSummary | None = None,
31
+ func_name: str | None = None,
32
+ ) -> None:
33
+ self.original_exception = original_exception
34
+ self.user_traceback = user_traceback
35
+ self.caller_frame = caller_frame
36
+ self.func_name = func_name
37
+
38
+ # Create a focused error message
39
+ tb_str = ''.join(traceback.format_list(user_traceback))
40
+ func_part = f' in {func_name}' if func_name else ''
41
+ msg = (
42
+ f'Error{func_part}:\n'
43
+ f'\nUser code traceback:\n{tb_str}'
44
+ f'{type(original_exception).__name__}: {original_exception}'
45
+ )
46
+ super().__init__(msg)
47
+
48
+ def __str__(self) -> str:
49
+ return super().__str__()
50
+
51
+ def format_rich(self) -> None:
52
+ """Format and print error with rich panels and code context."""
53
+ if Console is None or Panel is None or Text is None:
54
+ print(str(self), file=sys.stderr)
55
+ return
56
+
57
+ console = Console(stderr=True, force_terminal=True)
58
+
59
+ # Build traceback display with code context
60
+ tb_parts: list[str] = []
61
+
62
+ # Show caller frame first if available
63
+ if self.caller_frame and self.caller_frame.lineno is not None:
64
+ tb_parts.append(
65
+ f'[cyan]{self.caller_frame.filename}[/cyan]:[yellow]{self.caller_frame.lineno}[/yellow] '
66
+ f'in [green]{self.caller_frame.name}[/green]'
67
+ )
68
+ tb_parts.append('')
69
+ context = _get_code_context_rich(self.caller_frame.filename, self.caller_frame.lineno, 3)
70
+ tb_parts.extend(context)
71
+ tb_parts.append('')
72
+
73
+ # Show user code frames with context
74
+ for frame in self.user_traceback:
75
+ if frame.lineno is not None:
76
+ func_name = f' {self.func_name}' if self.func_name else ''
77
+ tb_parts.append(
78
+ f'[cyan]{frame.filename}[/cyan]:[yellow]{frame.lineno}[/yellow] '
79
+ f'in [green]{frame.name}{func_name}[/green]'
80
+ )
81
+ tb_parts.append('')
82
+ context = _get_code_context_rich(frame.filename, frame.lineno, 3)
83
+ tb_parts.extend(context)
84
+ tb_parts.append('')
85
+
86
+ # Print with rich Panel
87
+ console.print()
88
+ console.print(
89
+ Panel(
90
+ '\n'.join(tb_parts),
91
+ title='[bold red]Traceback (most recent call last)[/bold red]',
92
+ border_style='red',
93
+ expand=False,
94
+ )
95
+ )
96
+ console.print(
97
+ f'[bold red]{type(self.original_exception).__name__}[/bold red]: '
98
+ f'{self.original_exception}'
99
+ )
100
+ console.print()
101
+
102
+
103
+ def _get_code_context(filename: str, lineno: int, context_lines: int = 3) -> list[str]:
104
+ """Get code context around a line with line numbers and highlighting."""
105
+ lines: list[str] = []
106
+ start = max(1, lineno - context_lines)
107
+ end = lineno + context_lines
108
+
109
+ for i in range(start, end + 1):
110
+ line = linecache.getline(filename, i)
111
+ if not line:
112
+ continue
113
+ line = line.rstrip()
114
+ marker = '❱' if i == lineno else ' '
115
+ lines.append(f' {i:4d} {marker} {line}')
116
+
117
+ return lines
118
+
119
+
120
+ def _get_code_context_rich(filename: str, lineno: int, context_lines: int = 3) -> list[str]:
121
+ """Get code context with rich formatting (colors)."""
122
+ lines: list[str] = []
123
+ start = max(1, lineno - context_lines)
124
+ end = lineno + context_lines
125
+
126
+ for i in range(start, end + 1):
127
+ line = linecache.getline(filename, i)
128
+ if not line:
129
+ continue
130
+ line = line.rstrip()
131
+ num_str = f'{i:4d}'
132
+
133
+ if i == lineno:
134
+ # Highlight error line
135
+ lines.append(f'[dim]{num_str}[/dim] [red]❱[/red] {line}')
136
+ else:
137
+ # Normal context line
138
+ lines.append(f'[dim]{num_str} │[/dim] {line}')
139
+
140
+ return lines
141
+
142
+
143
+ def _filter_traceback_frames(tb_list: list[traceback.FrameSummary]) -> list[traceback.FrameSummary]:
144
+ """Filter traceback frames to show only user code."""
145
+ user_frames = []
146
+ skip_patterns = [
147
+ 'site-packages/',
148
+ 'dist-packages/',
149
+ 'python3.',
150
+ 'lib/python',
151
+ 'concurrent/futures/',
152
+ 'threading.py',
153
+ 'multiprocessing/',
154
+ 'urllib/',
155
+ 'httpx/',
156
+ 'httpcore/',
157
+ 'openai/',
158
+ 'requests/',
159
+ 'aiohttp/',
160
+ 'urllib3/',
161
+ 'speedy_utils/common/',
162
+ 'speedy_utils/multi_worker/',
163
+ 'llm_utils/lm/',
164
+ 'llm_utils/chat_format/',
165
+ 'llm_utils/vector_cache/',
166
+ ]
167
+
168
+ skip_functions = [
169
+ 'wrapper', # Our decorator wrapper
170
+ '__call__', # Internal calls
171
+ '__inner_call__', # Internal calls
172
+ '_worker', # Multi-thread worker
173
+ '_run_batch', # Batch runner
174
+ ]
175
+
176
+ for frame in tb_list:
177
+ # Skip frames matching skip patterns
178
+ if any(pattern in frame.filename for pattern in skip_patterns):
179
+ continue
180
+ # Skip specific function names
181
+ if frame.name in skip_functions:
182
+ continue
183
+ # Skip frames that are too deep in the call stack (internal implementation)
184
+ if 'speedy_utils' in frame.filename and any(
185
+ name in frame.name for name in ['__inner_call__', '_worker', '_run_batch']
186
+ ):
187
+ continue
188
+ user_frames.append(frame)
189
+
190
+ # If no user frames found, keep frames that are likely user code (not deep library internals)
191
+ if not user_frames:
192
+ for frame in reversed(tb_list):
193
+ # Keep if it's not in site-packages and not in standard library
194
+ if ('site-packages/' not in frame.filename and
195
+ 'dist-packages/' not in frame.filename and
196
+ not frame.filename.startswith('/usr/') and
197
+ not frame.filename.startswith('/opt/') and
198
+ 'python3.' not in frame.filename and
199
+ frame.name not in skip_functions):
200
+ user_frames.append(frame)
201
+ if len(user_frames) >= 5: # Keep up to 5 frames
202
+ break
203
+ user_frames.reverse()
204
+
205
+ return user_frames
206
+
207
+
208
+ def clean_traceback(func: F) -> F:
209
+ """Decorator to wrap function calls with clean traceback handling."""
210
+ def wrapper(*args, **kwargs):
211
+ try:
212
+ return func(*args, **kwargs)
213
+ except Exception as exc:
214
+ # Get the current traceback
215
+ exc_tb = sys.exc_info()[2]
216
+
217
+ if exc_tb is not None:
218
+ tb_list = traceback.extract_tb(exc_tb)
219
+
220
+ # Filter to keep only user code frames
221
+ user_frames = _filter_traceback_frames(tb_list)
222
+
223
+ # Get caller frame - walk up the stack to find the original caller
224
+ caller_context = None
225
+ frame = inspect.currentframe()
226
+ while frame:
227
+ frame = frame.f_back
228
+ if frame and frame.f_code.co_name not in ['wrapper', '__call__', '__inner_call__']:
229
+ caller_info = inspect.getframeinfo(frame)
230
+ if not any(skip in caller_info.filename for skip in [
231
+ 'speedy_utils/common/', 'speedy_utils/multi_worker/',
232
+ 'llm_utils/lm/', 'site-packages/', 'dist-packages/'
233
+ ]):
234
+ caller_context = traceback.FrameSummary(
235
+ caller_info.filename,
236
+ caller_info.lineno,
237
+ caller_info.function,
238
+ )
239
+ break
240
+
241
+ # If we have user frames, create and format our custom exception
242
+ if user_frames:
243
+ func_name = getattr(func, '__name__', repr(func))
244
+ clean_error = CleanTracebackError(
245
+ exc,
246
+ user_frames,
247
+ caller_context,
248
+ func_name,
249
+ )
250
+ clean_error.format_rich()
251
+ sys.exit(1) # Exit after formatting
252
+
253
+ # Fallback: re-raise original if we couldn't extract frames
254
+ raise
255
+
256
+ return wrapper # type: ignore
257
+
258
+
259
+ def handle_exceptions_with_clean_traceback(func: F) -> F:
260
+ """Alias for clean_traceback decorator."""
261
+ return clean_traceback(func)
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env python3
2
+ """Script to kill all tmux sessions matching 'mpython*' pattern."""
3
+
4
+ import subprocess
5
+ import sys
6
+
7
+
8
+ def main():
9
+ """Kill all tmux sessions with names starting with 'mpython'."""
10
+ try:
11
+ # Get list of tmux sessions matching the pattern
12
+ result = subprocess.run(
13
+ ["tmux", "ls"],
14
+ capture_output=True,
15
+ text=True
16
+ )
17
+ if result.returncode != 0:
18
+ if "no server running" in result.stderr.lower():
19
+ print("No tmux server running.")
20
+ return
21
+ print(f"Error listing tmux sessions: {result.stderr}")
22
+ sys.exit(result.returncode)
23
+
24
+ sessions = []
25
+ for line in result.stdout.strip().split('\n'):
26
+ if line.strip():
27
+ session_name = line.split(':')[0]
28
+ if session_name.startswith('mpython'):
29
+ sessions.append(session_name)
30
+
31
+ if not sessions:
32
+ print("No tmux sessions found matching 'mpython*'")
33
+ return
34
+
35
+ print(f"Found {len(sessions)} tmux session(s) to kill: {', '.join(sessions)}")
36
+
37
+ # Kill each session
38
+ for session in sessions:
39
+ kill_result = subprocess.run(
40
+ ["tmux", "kill-session", "-t", session],
41
+ capture_output=True,
42
+ text=True
43
+ )
44
+ if kill_result.returncode == 0:
45
+ print(f"Successfully killed tmux session '{session}'")
46
+ else:
47
+ print(f"Error killing tmux session '{session}': {kill_result.stderr}")
48
+
49
+ except FileNotFoundError:
50
+ print("Error: tmux command not found. Please ensure tmux is installed.")
51
+ sys.exit(1)
52
+ except Exception as e:
53
+ print(f"Unexpected error: {e}")
54
+ sys.exit(1)
55
+
56
+
57
+ if __name__ == "__main__":
58
+ main()
@@ -7,6 +7,19 @@ import re
7
7
  import shlex # To properly escape command line arguments
8
8
  import shutil
9
9
  import subprocess
10
+ import sys
11
+
12
+ try:
13
+ from rich.console import Console, Group
14
+ from rich.panel import Panel
15
+ from rich.text import Text
16
+ from rich.syntax import Syntax
17
+ except ImportError:
18
+ Console = None
19
+ Group = None
20
+ Panel = None
21
+ Text = None
22
+ Syntax = None
10
23
 
11
24
 
12
25
  taskset_path = shutil.which('taskset')
@@ -60,18 +73,34 @@ def assert_script(python_path):
60
73
  with open(python_path) as f:
61
74
  code_str = f.read()
62
75
  if 'MP_ID' not in code_str or 'MP_TOTAL' not in code_str:
63
- example_code = (
64
- 'import os; MP_TOTAL = int(os.environ.get("MP_TOTAL"));MP_ID = int(os.environ.get("MP_ID"))\n'
76
+ helper_code = (
77
+ 'import os\n'
78
+ 'MP_ID = int(os.getenv("MP_ID", "0"))\n'
79
+ 'MP_TOTAL = int(os.getenv("MP_TOTAL", "1"))\n'
65
80
  'inputs = list(inputs[MP_ID::MP_TOTAL])'
66
81
  )
67
- # ANSI escape codes for coloring
68
- YELLOW = '\033[93m'
69
- RESET = '\033[0m'
70
- raise_msg = (
71
- f'MP_ID and MP_TOTAL not found in {python_path}, please add them.\n\n'
72
- f'Example:\n{YELLOW}{example_code}{RESET}'
73
- )
74
- raise Exception(raise_msg)
82
+ if Console and Panel and Text and Syntax and Group:
83
+ console = Console(stderr=True, force_terminal=True)
84
+ syntax = Syntax(helper_code, "python", theme="monokai", line_numbers=False)
85
+ console.print()
86
+ console.print(
87
+ Panel(
88
+ f'Your script {python_path} is missing MP_ID and/or MP_TOTAL variables.\n\n'
89
+ f'Add the following code to enable multi-process sharding:',
90
+ title='[bold yellow]Warning: Missing Multi-Process Variables[/bold yellow]',
91
+ border_style='yellow',
92
+ expand=False,
93
+ )
94
+ )
95
+ console.print()
96
+ console.print("```python")
97
+ console.print(syntax)
98
+ console.print("```")
99
+ console.print("-"*80)
100
+ else:
101
+ # Fallback to plain text
102
+ print(f'Warning: MP_ID and MP_TOTAL not found in {python_path}, please add them.', file=sys.stderr)
103
+ print(f'Example:\n{helper_code}', file=sys.stderr)
75
104
 
76
105
 
77
106
  def run_in_tmux(commands_to_run, tmux_name, num_windows):
@@ -96,7 +125,18 @@ def run_in_tmux(commands_to_run, tmux_name, num_windows):
96
125
  def main():
97
126
  # Assert that MP_ID and MP_TOTAL are not already set
98
127
 
99
- parser = argparse.ArgumentParser(description='Process fold arguments')
128
+ helper_code = (
129
+ 'import os\n'
130
+ 'MP_ID = int(os.getenv("MP_ID", "0"))\n'
131
+ 'MP_TOTAL = int(os.getenv("MP_TOTAL", "1"))\n'
132
+ 'inputs = list(inputs[MP_ID::MP_TOTAL])'
133
+ )
134
+
135
+ parser = argparse.ArgumentParser(
136
+ description='Process fold arguments',
137
+ epilog=f'Helper code for multi-process sharding:\n{helper_code}',
138
+ formatter_class=argparse.RawDescriptionHelpFormatter
139
+ )
100
140
  parser.add_argument(
101
141
  '--total_fold', '-t', default=16, type=int, help='total number of folds'
102
142
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: speedy-utils
3
- Version: 1.1.44
3
+ Version: 1.1.46
4
4
  Summary: Fast and easy-to-use package for data science
5
5
  Project-URL: Homepage, https://github.com/anhvth/speedy
6
6
  Project-URL: Repository, https://github.com/anhvth/speedy
@@ -61,6 +61,7 @@ Description-Content-Type: text/markdown
61
61
  ## 🚀 Recent Updates (January 27, 2026)
62
62
 
63
63
  **Enhanced Error Handling in Parallel Processing:**
64
+
64
65
  - Rich-formatted error tracebacks with code context and syntax highlighting
65
66
  - Three error handling modes: 'raise', 'ignore', and 'log'
66
67
  - Filtered tracebacks focusing on user code (hiding infrastructure)
@@ -261,6 +262,7 @@ print(results) # [0, 1, 4, 9, 16, None, 36, 49, 64, 81, None, 121]
261
262
  #### Rich Error Tracebacks
262
263
 
263
264
  When errors occur, you'll see beautifully formatted tracebacks with:
265
+
264
266
  - **Code context**: Lines of code around the error location
265
267
  - **Caller information**: Shows where the parallel function was invoked
266
268
  - **Filtered frames**: Focuses on user code, hiding infrastructure details
@@ -282,7 +284,7 @@ When using `error_handler='log'`, errors are automatically saved to timestamped
282
284
 
283
285
  Progress bars now show real-time error and success counts:
284
286
 
285
- ```
287
+ ```bash
286
288
  Multi-thread [8/10] [00:02<00:00, 3.45it/s, success=8, errors=2, pending=0]
287
289
  ```
288
290
 
@@ -7,7 +7,7 @@ llm_utils/chat_format/transform.py,sha256=PJ2g9KT1GSbWuAs7giEbTpTAffpU9QsIXyRlbf
7
7
  llm_utils/chat_format/utils.py,sha256=M2EctZ6NeHXqFYufh26Y3CpSphN0bdZm5xoNaEJj5vg,1251
8
8
  llm_utils/lm/__init__.py,sha256=4jYMy3wPH3tg-tHFyWEWOqrnmX4Tu32VZCdzRGMGQsI,778
9
9
  llm_utils/lm/base_prompt_builder.py,sha256=_TzYMsWr-SsbA_JNXptUVN56lV5RfgWWTrFi-E8LMy4,12337
10
- llm_utils/lm/llm.py,sha256=4nTBNvIZfsKUZo5SdllLQOp3w-HohR3B1hcfUnYDl7A,20014
10
+ llm_utils/lm/llm.py,sha256=i6L5aKF6NhzmaFPBA2pCm8TkQmS1nCgORMqP5QyfJ28,20097
11
11
  llm_utils/lm/llm_signature.py,sha256=vV8uZgLLd6ZKqWbq0OPywWvXAfl7hrJQnbtBF-VnZRU,1244
12
12
  llm_utils/lm/lm_base.py,sha256=Bk3q34KrcCK_bC4Ryxbc3KqkiPL39zuVZaBQ1i6wJqs,9437
13
13
  llm_utils/lm/mixins.py,sha256=Nz7CwJFBOvbZNbODUlJC04Pcbac3zWnT8vy7sZG_MVI,24906
@@ -30,7 +30,7 @@ llm_utils/vector_cache/core.py,sha256=VXuYJy1AX22NHKvIXRriETip5RrmQcNp73-g-ZT774
30
30
  llm_utils/vector_cache/types.py,sha256=CpMZanJSTeBVxQSqjBq6pBVWp7u2-JRcgY9t5jhykdQ,438
31
31
  llm_utils/vector_cache/utils.py,sha256=OsiRFydv8i8HiJtPL9hh40aUv8I5pYfg2zvmtDi4DME,1446
32
32
  speedy_utils/__imports.py,sha256=V0YzkDK4-QkK_IDXY1be6C6_STuNhXAKIp4_dM0coQs,7800
33
- speedy_utils/__init__.py,sha256=1ubAYR6P0cEZJLDt7KQLLxl6ylh-T7WE7HPP94-rVLI,3045
33
+ speedy_utils/__init__.py,sha256=_kSjS816Kv5UZPd4EM_juB68tXM_sHUYt6OFB-RhE6U,3261
34
34
  speedy_utils/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  speedy_utils/common/clock.py,sha256=raLtMGIgzrRej5kUt7hOUm2ZZw2THVPo-q8dMvdZOxw,7354
36
36
  speedy_utils/common/function_decorator.py,sha256=GKXqRs_hHFFmhyhql0Br0o52WzekUnpNlm99NfaVwgY,2025
@@ -39,6 +39,7 @@ speedy_utils/common/notebook_utils.py,sha256=6mxXZcTHwYob3nobAzbSZnDyXRahFaaSko1
39
39
  speedy_utils/common/patcher.py,sha256=Rku-N4DJNue8BCLUx7y3ad_3t_WU2HleHKlbR0vhaRc,2319
40
40
  speedy_utils/common/report_manager.py,sha256=78KQ0gUzvbzT6EjHYZ5zgtV41cPRvdX8hnF2oSWA4qA,3849
41
41
  speedy_utils/common/utils_cache.py,sha256=1UAqOSb4nFVlhuQRfTEXCN-8Wf6yntXyMA6yp61-98I,26277
42
+ speedy_utils/common/utils_error.py,sha256=KQx2JTZsvsX2DsKRIoVR-4rc-6-l3OzEz9UtnHt8HJg,9108
42
43
  speedy_utils/common/utils_io.py,sha256=94m_EZ2eIs3w2m0rx-QQWsREPpVJctpweYHco3byczQ,15876
43
44
  speedy_utils/common/utils_misc.py,sha256=ZRJCS7OJxybpVm1sasoeCYRW2TaaGCXj4DySYlQeVR8,2227
44
45
  speedy_utils/common/utils_print.py,sha256=AGDB7mgJnO00QkJBH6kJb46738q3GzMUZPwtQ248vQw,4763
@@ -49,13 +50,14 @@ speedy_utils/multi_worker/process.py,sha256=U-pjHoWZ3xOeplMl2nSxVeiJE0F9V-eswpSd
49
50
  speedy_utils/multi_worker/progress.py,sha256=Ozeca-t-j1224n_dWwZkWzva9DC16SCLgScKeGtXLaQ,4717
50
51
  speedy_utils/multi_worker/thread.py,sha256=E7o_iUCIKmgk1tFt7mZAFT7c5q229wVzWj-trmVsxVA,27254
51
52
  speedy_utils/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
- speedy_utils/scripts/mpython.py,sha256=uJ-QPG43cyHUptMP4MnyH7IdSTh4mzVQAejy9o1cQoE,5068
53
+ speedy_utils/scripts/kill_mpython.py,sha256=xYdJIs1KQ4zlyj-E4XN6j1T7dOhzVo65uKzjXmIvUDU,1847
54
+ speedy_utils/scripts/mpython.py,sha256=bf_pdCm5_NaDUV0J652Cg_YFIwva_5AhoVKTGOowENo,6485
53
55
  speedy_utils/scripts/openapi_client_codegen.py,sha256=GModmmhkvGnxljK4KczyixKDrk-VEcLaW5I0XT6tzWo,9657
54
56
  vision_utils/README.md,sha256=AIDZZj8jo_QNrEjFyHwd00iOO431s-js-M2dLtVTn3I,5740
55
57
  vision_utils/__init__.py,sha256=hF54sT6FAxby8kDVhOvruy4yot8O-Ateey5n96O1pQM,284
56
58
  vision_utils/io_utils.py,sha256=pI0Va6miesBysJcllK6NXCay8HpGZsaMWwlsKB2DMgA,26510
57
59
  vision_utils/plot.py,sha256=HkNj3osA3moPuupP1VguXfPPOW614dZO5tvC-EFKpKM,12028
58
- speedy_utils-1.1.44.dist-info/METADATA,sha256=Y5wQ_VbeiPTcqUkOCEbEvOKZ-wnwKCF2nvGhSnU3AJs,13067
59
- speedy_utils-1.1.44.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
60
- speedy_utils-1.1.44.dist-info/entry_points.txt,sha256=rwn89AYfBUh9SRJtFbpp-u2JIKiqmZ2sczvqyO6s9cI,289
61
- speedy_utils-1.1.44.dist-info/RECORD,,
60
+ speedy_utils-1.1.46.dist-info/METADATA,sha256=nIgSDMrAbHssvJznZtozJZbZVdH4K8dALKRdExipi1g,13073
61
+ speedy_utils-1.1.46.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
62
+ speedy_utils-1.1.46.dist-info/entry_points.txt,sha256=QY_2Vn6IcPCaqlY74pDRyZ6UTvPilaNPT7Gxijj7XI8,343
63
+ speedy_utils-1.1.46.dist-info/RECORD,,
@@ -1,5 +1,6 @@
1
1
  [console_scripts]
2
2
  fast-vllm = llm_utils.scripts.fast_vllm:main
3
+ kill-mpython = speedy_utils.scripts.kill_mpython:main
3
4
  mpython = speedy_utils.scripts.mpython:main
4
5
  openapi_client_codegen = speedy_utils.scripts.openapi_client_codegen:main
5
6
  svllm = llm_utils.scripts.vllm_serve:main