speedy-utils 1.1.42__tar.gz → 1.1.44__tar.gz

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.
Files changed (147) hide show
  1. speedy_utils-1.1.44/.github/prompts/improveParallelErrorHandling.prompt.md +64 -0
  2. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/PKG-INFO +158 -9
  3. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/README.md +155 -7
  4. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/pyproject.toml +3 -2
  5. speedy_utils-1.1.44/scripts/bug.py +34 -0
  6. speedy_utils-1.1.44/scripts/bug_simple.py +11 -0
  7. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/scripts/debug_import_time.py +80 -18
  8. speedy_utils-1.1.44/scripts/test.py +26 -0
  9. speedy_utils-1.1.44/scripts/test_both_backends.py +25 -0
  10. speedy_utils-1.1.44/scripts/test_error_handling.py +37 -0
  11. speedy_utils-1.1.44/scripts/test_locals.py +18 -0
  12. speedy_utils-1.1.44/scripts/test_ray_locals.py +10 -0
  13. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/__init__.py +7 -0
  14. speedy_utils-1.1.44/src/speedy_utils/multi_worker/process.py +1309 -0
  15. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/multi_worker/thread.py +202 -42
  16. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/uv.lock +5247 -2937
  17. speedy_utils-1.1.42/src/speedy_utils/multi_worker/process.py +0 -699
  18. speedy_utils-1.1.42/test2.txt +0 -0
  19. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.githooks/pre-push +0 -0
  20. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/copilot-instructions.md +0 -0
  21. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/skills/caching-utilities/SKILL.md +0 -0
  22. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/skills/caching-utilities/examples/caching_example.py +0 -0
  23. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/skills/io-utilities/SKILL.md +0 -0
  24. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/skills/io-utilities/examples/io_example.py +0 -0
  25. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/skills/llm-integration/SKILL.md +0 -0
  26. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/skills/llm-integration/examples/llm_example.py +0 -0
  27. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/skills/multi-threading-processing/SKILL.md +0 -0
  28. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/skills/ray-distributed-computing/SKILL.md +0 -0
  29. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/skills/skill-creation/SKILL.md +0 -0
  30. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/skills/vision-utilities/SKILL.md +0 -0
  31. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/skills/vision-utilities/examples/vision_example.py +0 -0
  32. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.github/workflows/publish.yml +0 -0
  33. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.gitignore +0 -0
  34. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/.pre-commit-config.yaml +0 -0
  35. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/AGENTS.md +0 -0
  36. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/bumpversion.sh +0 -0
  37. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/debug/debug_generate_response.py +0 -0
  38. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/debug/debug_n_param.py +0 -0
  39. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/debug/debug_n_structure.py +0 -0
  40. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/debug/integration_test.py +0 -0
  41. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/debug/test_decode_api.py +0 -0
  42. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/debug/test_endpoints.py +0 -0
  43. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/debug/test_generate.py +0 -0
  44. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/debug/test_generate_endpoint.py +0 -0
  45. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/docs/GENERATE_QUICKREF.md +0 -0
  46. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/docs/IMPLEMENTATION.md +0 -0
  47. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/docs/QUICKSTART.md +0 -0
  48. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/docs/TOKENIZATION.md +0 -0
  49. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/docs/TOKENIZATION_IMPLEMENTATION.md +0 -0
  50. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/docs/zero_copy_sharing.md +0 -0
  51. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/examples/generate_example.py +0 -0
  52. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/examples/llm_ray_example.py +0 -0
  53. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/examples/pytorch_large_model.py +0 -0
  54. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/examples/shared_kwargs_example.py +0 -0
  55. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/examples/temperature_range_example.py +0 -0
  56. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/examples/test_parallel_gpu.py +0 -0
  57. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/examples/test_share_ray.py +0 -0
  58. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/examples/tokenization_example.py +0 -0
  59. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/examples/vision_utils_example.py +0 -0
  60. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/experiments/exp1/dockerfile +0 -0
  61. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/experiments/exp1/run_in_docker.sh +0 -0
  62. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/experiments/exp1/test.png +0 -0
  63. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/experiments/test_read_image.py +0 -0
  64. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/notebooks/README.ipynb +0 -0
  65. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/notebooks/llm_utils/llm_as_a_judge.ipynb +0 -0
  66. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/notebooks/parallel_gpu_pool.ipynb +0 -0
  67. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/notebooks/ray_tutorial.ipynb +0 -0
  68. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/notebooks/test_multi_thread.ipynb +0 -0
  69. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/ruff.toml +0 -0
  70. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/scripts/deploy.sh +0 -0
  71. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/scripts/imports.sh +0 -0
  72. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/scripts/test_import_time_vision.py +0 -0
  73. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/scripts/test_ray_mp.py +0 -0
  74. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/setup.cfg +0 -0
  75. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/datasets_utils/convert_to_arrow.py +0 -0
  76. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/__init__.py +0 -0
  77. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/chat_format/__init__.py +0 -0
  78. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/chat_format/display.py +0 -0
  79. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/chat_format/transform.py +0 -0
  80. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/chat_format/utils.py +0 -0
  81. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/group_messages.py +0 -0
  82. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/llm_ray.py +0 -0
  83. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/__init__.py +0 -0
  84. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/async_lm/__init__.py +0 -0
  85. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/async_lm/_utils.py +0 -0
  86. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/async_lm/async_llm_task.py +0 -0
  87. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/async_lm/async_lm.py +0 -0
  88. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/async_lm/async_lm_base.py +0 -0
  89. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/async_lm/lm_specific.py +0 -0
  90. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/base_prompt_builder.py +0 -0
  91. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/llm.py +0 -0
  92. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/llm_signature.py +0 -0
  93. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/lm_base.py +0 -0
  94. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/mixins.py +0 -0
  95. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/openai_memoize.py +0 -0
  96. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/signature.py +0 -0
  97. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/lm/utils.py +0 -0
  98. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/scripts/README.md +0 -0
  99. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/scripts/fast_vllm.py +0 -0
  100. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/scripts/vllm_load_balancer.py +0 -0
  101. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/scripts/vllm_serve.py +0 -0
  102. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/vector_cache/__init__.py +0 -0
  103. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/vector_cache/cli.py +0 -0
  104. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/vector_cache/core.py +0 -0
  105. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/vector_cache/types.py +0 -0
  106. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/llm_utils/vector_cache/utils.py +0 -0
  107. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/__imports.py +0 -0
  108. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/common/__init__.py +0 -0
  109. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/common/clock.py +0 -0
  110. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/common/function_decorator.py +0 -0
  111. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/common/logger.py +0 -0
  112. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/common/notebook_utils.py +0 -0
  113. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/common/patcher.py +0 -0
  114. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/common/report_manager.py +0 -0
  115. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/common/utils_cache.py +0 -0
  116. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/common/utils_io.py +0 -0
  117. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/common/utils_misc.py +0 -0
  118. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/common/utils_print.py +0 -0
  119. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/multi_worker/__init__.py +0 -0
  120. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/multi_worker/dataset_ray.py +0 -0
  121. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/multi_worker/parallel_gpu_pool.py +0 -0
  122. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/multi_worker/progress.py +0 -0
  123. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/scripts/__init__.py +0 -0
  124. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/scripts/mpython.py +0 -0
  125. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/speedy_utils/scripts/openapi_client_codegen.py +0 -0
  126. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/vision_utils/README.md +0 -0
  127. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/vision_utils/__init__.py +0 -0
  128. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/vision_utils/io_utils.py +0 -0
  129. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/src/vision_utils/plot.py +0 -0
  130. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/test_s3.py +0 -0
  131. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/import_all.py +0 -0
  132. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/import_time_report.py +0 -0
  133. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/integration_test.py +0 -0
  134. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/llm_utils/test_llm_mixins.py +0 -0
  135. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/sample_objects.py +0 -0
  136. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test.py +0 -0
  137. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test_logger.py +0 -0
  138. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test_logger_format.py +0 -0
  139. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test_memoize_typing.py +0 -0
  140. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test_mpython.py +0 -0
  141. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test_multithread_error_trace.py +0 -0
  142. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test_process.py +0 -0
  143. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test_process_update.py +0 -0
  144. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test_pytorch_sharing.py +0 -0
  145. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test_shared_kwargs.py +0 -0
  146. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test_thread.py +0 -0
  147. {speedy_utils-1.1.42 → speedy_utils-1.1.44}/tests/test_tokenization.py +0 -0
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: improveParallelErrorHandling
3
+ description: Enhance error tracebacks in parallel execution with rich formatting and context
4
+ argument-hint: the parallel execution function and backend type
5
+ ---
6
+
7
+ Improve error handling for the specified parallel execution function to provide clean, user-focused tracebacks similar to direct function calls.
8
+
9
+ ## Requirements
10
+
11
+ 1. **Filter Internal Frames**: Remove framework/library internal frames from tracebacks, showing only user code
12
+ 2. **Add Context Lines**: Display 3 lines before and after each error location with line numbers
13
+ 3. **Include Caller Frame**: Show where the parallel execution function was called, not just where the error occurred
14
+ 4. **Rich Formatting**: Use rich library's Panel/formatting for clean, readable output
15
+ 5. **Suppress Noise**: Set environment variables or flags to suppress verbose framework error logs
16
+
17
+ ## Implementation Steps
18
+
19
+ 1. **Capture Caller Context**: Use `inspect.currentframe().f_back` to capture where the parallel function was called (filename, line number, function name)
20
+
21
+ 2. **Wrap Error Handling**: Catch framework-specific exceptions (e.g., `RayTaskError`, thread exceptions) in the execution loop
22
+
23
+ 3. **Parse/Extract Original Exception**: Get the underlying user exception from the framework wrapper
24
+ - Extract exception type, message, and traceback information
25
+ - Parse from string representation if traceback objects aren't preserved
26
+
27
+ 4. **Filter Frames**: Skip frames matching internal paths:
28
+ - Framework internals (e.g., `ray/_private`, `concurrent/futures`)
29
+ - Library worker implementations (e.g., `speedy_utils/multi_worker`)
30
+ - Site-packages for the framework
31
+
32
+ 5. **Format with Context**:
33
+ - For each user frame, show: `filepath:lineno in function_name`
34
+ - Use `linecache.getline()` to retrieve surrounding lines
35
+ - Highlight the error line with `❱` marker
36
+ - Number all lines (e.g., ` 4 │ code here` or ` 5 ❱ error here`)
37
+
38
+ 6. **Display Caller Frame First**: Show where the parallel function was invoked before showing the actual error location
39
+
40
+ 7. **Clean Exit**: Flush output streams before exiting to ensure traceback displays
41
+
42
+ ## Example Output Format
43
+
44
+ ```
45
+ ╭─────────────── Traceback (most recent call last) ───────────────╮
46
+ │ /path/to/user/script.py:42 in main │
47
+ │ │
48
+ │ 40 │ data = load_data() │
49
+ │ 41 │ # Process in parallel │
50
+ │ 42 ❱ results = multi_process(process_item, data, workers=8) │
51
+ │ 43 │ │
52
+ │ │
53
+ │ /path/to/user/module.py:15 in process_item │
54
+ │ │
55
+ │ 12 │ def process_item(item): │
56
+ │ 13 │ value = item['key'] │
57
+ │ 14 │ denominator = value - 100 │
58
+ │ 15 ❱ return 1 / denominator │
59
+ │ 16 │ │
60
+ ╰──────────────────────────────────────────────────────────────────╯
61
+ ZeroDivisionError: division by zero
62
+ ```
63
+
64
+ Apply these improvements to the specified parallel execution function, ensuring error messages are as clear as direct function calls while maintaining all performance benefits of parallel execution.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: speedy-utils
3
- Version: 1.1.42
3
+ Version: 1.1.44
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
@@ -17,7 +17,7 @@ Classifier: Programming Language :: Python :: 3.11
17
17
  Classifier: Programming Language :: Python :: 3.12
18
18
  Classifier: Programming Language :: Python :: 3.13
19
19
  Classifier: Programming Language :: Python :: 3.14
20
- Requires-Python: >=3.8
20
+ Requires-Python: >=3.9
21
21
  Requires-Dist: aiohttp
22
22
  Requires-Dist: bump2version
23
23
  Requires-Dist: cachetools
@@ -39,6 +39,7 @@ Requires-Dist: pydantic
39
39
  Requires-Dist: pytest
40
40
  Requires-Dist: ray
41
41
  Requires-Dist: requests
42
+ Requires-Dist: rich>=14.3.1
42
43
  Requires-Dist: ruff
43
44
  Requires-Dist: scikit-learn
44
45
  Requires-Dist: tabulate
@@ -57,13 +58,48 @@ Description-Content-Type: text/markdown
57
58
 
58
59
  **Speedy Utils** is a Python utility library designed to streamline common programming tasks such as caching, parallel processing, file I/O, and data manipulation. It provides a collection of decorators, functions, and classes to enhance productivity and performance in your Python projects.
59
60
 
61
+ ## 🚀 Recent Updates (January 27, 2026)
62
+
63
+ **Enhanced Error Handling in Parallel Processing:**
64
+ - Rich-formatted error tracebacks with code context and syntax highlighting
65
+ - Three error handling modes: 'raise', 'ignore', and 'log'
66
+ - Filtered tracebacks focusing on user code (hiding infrastructure)
67
+ - Real-time progress reporting with error/success statistics
68
+ - Automatic error logging to timestamped files
69
+ - Caller frame information showing where parallel functions were invoked
70
+
71
+ ## Quick Start
72
+
73
+ ### Parallel Processing with Error Handling
74
+
75
+ ```python
76
+ from speedy_utils import multi_thread, multi_process
77
+
78
+ # Simple parallel processing
79
+ results = multi_thread(lambda x: x * 2, [1, 2, 3, 4, 5])
80
+ # Results: [2, 4, 6, 8, 10]
81
+
82
+ # Robust processing with error handling
83
+ def process_item(item):
84
+ if item == 3:
85
+ raise ValueError(f"Cannot process item {item}")
86
+ return item * 2
87
+
88
+ # Continue processing despite errors
89
+ results = multi_thread(process_item, [1, 2, 3, 4, 5], error_handler='log')
90
+ # Results: [2, 4, None, 8, 10] - errors logged automatically
91
+ ```
92
+
60
93
  ## Table of Contents
61
94
 
95
+ - [🚀 Recent Updates](#-recent-updates-january-27-2026)
96
+ - [Quick Start](#quick-start)
62
97
  - [Features](#features)
63
98
  - [Installation](#installation)
64
99
  - [Usage](#usage)
65
- - [Caching](#caching)
66
100
  - [Parallel Processing](#parallel-processing)
101
+ - [Enhanced Error Handling](#enhanced-error-handling)
102
+ - [Caching](#caching)
67
103
  - [File I/O](#file-io)
68
104
  - [Data Manipulation](#data-manipulation)
69
105
  - [Utility Functions](#utility-functions)
@@ -72,11 +108,12 @@ Description-Content-Type: text/markdown
72
108
  ## Features
73
109
 
74
110
  - **Caching Mechanisms**: Disk-based and in-memory caching to optimize function calls.
75
- - **Parallel Processing**: Multi-threading, multi-processing, and asynchronous multi-threading utilities.
111
+ - **Parallel Processing**: Multi-threading, multi-processing, and asynchronous multi-threading utilities with enhanced error handling.
76
112
  - **File I/O**: Simplified JSON, JSONL, and pickle file handling with support for various file extensions.
77
113
  - **Data Manipulation**: Utilities for flattening lists and dictionaries, converting data types, and more.
78
114
  - **Timing Utilities**: Tools to measure and log execution time of functions and processes.
79
115
  - **Pretty Printing**: Enhanced printing functions for structured data, including HTML tables for Jupyter notebooks.
116
+ - **Enhanced Error Handling**: Rich error tracebacks with code context, configurable error handling modes ('raise', 'ignore', 'log'), and detailed progress reporting.
80
117
 
81
118
  ## Installation
82
119
 
@@ -161,20 +198,132 @@ result = compute_sum(5, 7) # Retrieved from in-memory cache
161
198
 
162
199
  ### Parallel Processing
163
200
 
164
- #### Multi-threading
201
+ #### Multi-threading with Enhanced Error Handling
165
202
 
166
- Execute functions concurrently using multiple threads. This approach is straightforward and automatically handles both notebook and Python script executions. In a notebook environment, it delegates the running thread to a separate process. If interrupted, it immediately stops this process, avoiding thread dependency issues where threads continue running until all tasks are completed.
203
+ Execute functions concurrently using multiple threads with comprehensive error handling. The enhanced error handling provides three modes: 'raise' (default), 'ignore', and 'log'. When errors occur, you'll see rich-formatted tracebacks with code context and caller information.
167
204
 
168
205
  ```python
169
206
  from speedy_utils import multi_thread
170
207
 
171
208
  def process_item(item):
172
- # Your processing logic
209
+ # Simulate processing that might fail
210
+ if item == 3:
211
+ raise ValueError(f"Invalid item: {item}")
173
212
  return item * 2
174
213
 
175
214
  items = [1, 2, 3, 4, 5]
176
- results = multi_thread(process_item, items, workers=3)
177
- print(results) # [2, 4, 6, 8, 10]
215
+
216
+ # Default behavior: raise on first error with rich traceback
217
+ try:
218
+ results = multi_thread(process_item, items, workers=3)
219
+ except SystemExit:
220
+ print("Error occurred and was displayed with rich formatting")
221
+
222
+ # Continue processing on errors, return None for failed items
223
+ results = multi_thread(process_item, items, workers=3, error_handler='ignore')
224
+ print(results) # [2, 4, None, 8, 10]
225
+
226
+ # Log errors to files and continue processing
227
+ results = multi_thread(process_item, items, workers=3, error_handler='log', max_error_files=10)
228
+ print(results) # [2, 4, None, 8, 10] - errors logged to .cache/speedy_utils/error_logs/
229
+ ```
230
+
231
+ #### Multi-processing with Error Handling
232
+
233
+ Process items across multiple processes with the same enhanced error handling capabilities.
234
+
235
+ ```python
236
+ from speedy_utils import multi_process
237
+
238
+ def risky_computation(x):
239
+ """Computation that might fail for certain inputs."""
240
+ if x % 5 == 0:
241
+ raise RuntimeError(f"Cannot process multiples of 5: {x}")
242
+ return x ** 2
243
+
244
+ data = list(range(12))
245
+
246
+ # Process with error logging (continues on errors)
247
+ results = multi_process(
248
+ risky_computation,
249
+ data,
250
+ backend='mp',
251
+ error_handler='log',
252
+ max_error_files=5
253
+ )
254
+ print(results) # [0, 1, 4, 9, 16, None, 36, 49, 64, 81, None, 121]
255
+ ```
256
+
257
+ ### Enhanced Error Handling
258
+
259
+ **Speedy Utils** now provides comprehensive error handling for parallel processing with rich formatting and detailed diagnostics.
260
+
261
+ #### Rich Error Tracebacks
262
+
263
+ When errors occur, you'll see beautifully formatted tracebacks with:
264
+ - **Code context**: Lines of code around the error location
265
+ - **Caller information**: Shows where the parallel function was invoked
266
+ - **Filtered frames**: Focuses on user code, hiding infrastructure details
267
+ - **Color coding**: Easy-to-read formatting with syntax highlighting
268
+
269
+ #### Error Handling Modes
270
+
271
+ Choose how to handle errors in parallel processing:
272
+
273
+ - **`'raise'` (default)**: Stop on first error with detailed traceback
274
+ - **`'ignore'`**: Continue processing, return `None` for failed items
275
+ - **`'log'`**: Log errors to files and continue processing
276
+
277
+ #### Error Logging
278
+
279
+ When using `error_handler='log'`, errors are automatically saved to timestamped files in `.cache/speedy_utils/error_logs/` with full context and stack traces.
280
+
281
+ #### Progress Reporting with Error Statistics
282
+
283
+ Progress bars now show real-time error and success counts:
284
+
285
+ ```
286
+ Multi-thread [8/10] [00:02<00:00, 3.45it/s, success=8, errors=2, pending=0]
287
+ ```
288
+
289
+ This makes it easy to monitor processing health at a glance.
290
+
291
+ #### Example: Robust Data Processing
292
+
293
+ ```python
294
+ from speedy_utils import multi_thread
295
+
296
+ def process_data_record(record):
297
+ """Process a data record that might have issues."""
298
+ try:
299
+ # Your processing logic here
300
+ value = record['value'] / record['divisor']
301
+ return {'result': value, 'status': 'success'}
302
+ except KeyError as e:
303
+ raise ValueError(f"Missing required field in record: {e}")
304
+ except ZeroDivisionError:
305
+ raise ValueError("Division by zero in record")
306
+
307
+ # Sample data with some problematic records
308
+ data = [
309
+ {'value': 10, 'divisor': 2}, # OK
310
+ {'value': 15, 'divisor': 0}, # Will error
311
+ {'value': 20, 'divisor': 4}, # OK
312
+ {'value': 25}, # Missing divisor - will error
313
+ ]
314
+
315
+ # Process with error logging - continues despite errors
316
+ results = multi_thread(
317
+ process_data_record,
318
+ data,
319
+ workers=4,
320
+ error_handler='log',
321
+ max_error_files=10
322
+ )
323
+
324
+ print("Results:", results)
325
+ # Output: Results: [{'result': 5.0, 'status': 'success'}, None, {'result': 5.0, 'status': 'success'}, None]
326
+ # Errors are logged to files for later analysis
178
327
  ```
179
328
 
180
329
  ### File I/O
@@ -6,13 +6,48 @@
6
6
 
7
7
  **Speedy Utils** is a Python utility library designed to streamline common programming tasks such as caching, parallel processing, file I/O, and data manipulation. It provides a collection of decorators, functions, and classes to enhance productivity and performance in your Python projects.
8
8
 
9
+ ## 🚀 Recent Updates (January 27, 2026)
10
+
11
+ **Enhanced Error Handling in Parallel Processing:**
12
+ - Rich-formatted error tracebacks with code context and syntax highlighting
13
+ - Three error handling modes: 'raise', 'ignore', and 'log'
14
+ - Filtered tracebacks focusing on user code (hiding infrastructure)
15
+ - Real-time progress reporting with error/success statistics
16
+ - Automatic error logging to timestamped files
17
+ - Caller frame information showing where parallel functions were invoked
18
+
19
+ ## Quick Start
20
+
21
+ ### Parallel Processing with Error Handling
22
+
23
+ ```python
24
+ from speedy_utils import multi_thread, multi_process
25
+
26
+ # Simple parallel processing
27
+ results = multi_thread(lambda x: x * 2, [1, 2, 3, 4, 5])
28
+ # Results: [2, 4, 6, 8, 10]
29
+
30
+ # Robust processing with error handling
31
+ def process_item(item):
32
+ if item == 3:
33
+ raise ValueError(f"Cannot process item {item}")
34
+ return item * 2
35
+
36
+ # Continue processing despite errors
37
+ results = multi_thread(process_item, [1, 2, 3, 4, 5], error_handler='log')
38
+ # Results: [2, 4, None, 8, 10] - errors logged automatically
39
+ ```
40
+
9
41
  ## Table of Contents
10
42
 
43
+ - [🚀 Recent Updates](#-recent-updates-january-27-2026)
44
+ - [Quick Start](#quick-start)
11
45
  - [Features](#features)
12
46
  - [Installation](#installation)
13
47
  - [Usage](#usage)
14
- - [Caching](#caching)
15
48
  - [Parallel Processing](#parallel-processing)
49
+ - [Enhanced Error Handling](#enhanced-error-handling)
50
+ - [Caching](#caching)
16
51
  - [File I/O](#file-io)
17
52
  - [Data Manipulation](#data-manipulation)
18
53
  - [Utility Functions](#utility-functions)
@@ -21,11 +56,12 @@
21
56
  ## Features
22
57
 
23
58
  - **Caching Mechanisms**: Disk-based and in-memory caching to optimize function calls.
24
- - **Parallel Processing**: Multi-threading, multi-processing, and asynchronous multi-threading utilities.
59
+ - **Parallel Processing**: Multi-threading, multi-processing, and asynchronous multi-threading utilities with enhanced error handling.
25
60
  - **File I/O**: Simplified JSON, JSONL, and pickle file handling with support for various file extensions.
26
61
  - **Data Manipulation**: Utilities for flattening lists and dictionaries, converting data types, and more.
27
62
  - **Timing Utilities**: Tools to measure and log execution time of functions and processes.
28
63
  - **Pretty Printing**: Enhanced printing functions for structured data, including HTML tables for Jupyter notebooks.
64
+ - **Enhanced Error Handling**: Rich error tracebacks with code context, configurable error handling modes ('raise', 'ignore', 'log'), and detailed progress reporting.
29
65
 
30
66
  ## Installation
31
67
 
@@ -110,20 +146,132 @@ result = compute_sum(5, 7) # Retrieved from in-memory cache
110
146
 
111
147
  ### Parallel Processing
112
148
 
113
- #### Multi-threading
149
+ #### Multi-threading with Enhanced Error Handling
114
150
 
115
- Execute functions concurrently using multiple threads. This approach is straightforward and automatically handles both notebook and Python script executions. In a notebook environment, it delegates the running thread to a separate process. If interrupted, it immediately stops this process, avoiding thread dependency issues where threads continue running until all tasks are completed.
151
+ Execute functions concurrently using multiple threads with comprehensive error handling. The enhanced error handling provides three modes: 'raise' (default), 'ignore', and 'log'. When errors occur, you'll see rich-formatted tracebacks with code context and caller information.
116
152
 
117
153
  ```python
118
154
  from speedy_utils import multi_thread
119
155
 
120
156
  def process_item(item):
121
- # Your processing logic
157
+ # Simulate processing that might fail
158
+ if item == 3:
159
+ raise ValueError(f"Invalid item: {item}")
122
160
  return item * 2
123
161
 
124
162
  items = [1, 2, 3, 4, 5]
125
- results = multi_thread(process_item, items, workers=3)
126
- print(results) # [2, 4, 6, 8, 10]
163
+
164
+ # Default behavior: raise on first error with rich traceback
165
+ try:
166
+ results = multi_thread(process_item, items, workers=3)
167
+ except SystemExit:
168
+ print("Error occurred and was displayed with rich formatting")
169
+
170
+ # Continue processing on errors, return None for failed items
171
+ results = multi_thread(process_item, items, workers=3, error_handler='ignore')
172
+ print(results) # [2, 4, None, 8, 10]
173
+
174
+ # Log errors to files and continue processing
175
+ results = multi_thread(process_item, items, workers=3, error_handler='log', max_error_files=10)
176
+ print(results) # [2, 4, None, 8, 10] - errors logged to .cache/speedy_utils/error_logs/
177
+ ```
178
+
179
+ #### Multi-processing with Error Handling
180
+
181
+ Process items across multiple processes with the same enhanced error handling capabilities.
182
+
183
+ ```python
184
+ from speedy_utils import multi_process
185
+
186
+ def risky_computation(x):
187
+ """Computation that might fail for certain inputs."""
188
+ if x % 5 == 0:
189
+ raise RuntimeError(f"Cannot process multiples of 5: {x}")
190
+ return x ** 2
191
+
192
+ data = list(range(12))
193
+
194
+ # Process with error logging (continues on errors)
195
+ results = multi_process(
196
+ risky_computation,
197
+ data,
198
+ backend='mp',
199
+ error_handler='log',
200
+ max_error_files=5
201
+ )
202
+ print(results) # [0, 1, 4, 9, 16, None, 36, 49, 64, 81, None, 121]
203
+ ```
204
+
205
+ ### Enhanced Error Handling
206
+
207
+ **Speedy Utils** now provides comprehensive error handling for parallel processing with rich formatting and detailed diagnostics.
208
+
209
+ #### Rich Error Tracebacks
210
+
211
+ When errors occur, you'll see beautifully formatted tracebacks with:
212
+ - **Code context**: Lines of code around the error location
213
+ - **Caller information**: Shows where the parallel function was invoked
214
+ - **Filtered frames**: Focuses on user code, hiding infrastructure details
215
+ - **Color coding**: Easy-to-read formatting with syntax highlighting
216
+
217
+ #### Error Handling Modes
218
+
219
+ Choose how to handle errors in parallel processing:
220
+
221
+ - **`'raise'` (default)**: Stop on first error with detailed traceback
222
+ - **`'ignore'`**: Continue processing, return `None` for failed items
223
+ - **`'log'`**: Log errors to files and continue processing
224
+
225
+ #### Error Logging
226
+
227
+ When using `error_handler='log'`, errors are automatically saved to timestamped files in `.cache/speedy_utils/error_logs/` with full context and stack traces.
228
+
229
+ #### Progress Reporting with Error Statistics
230
+
231
+ Progress bars now show real-time error and success counts:
232
+
233
+ ```
234
+ Multi-thread [8/10] [00:02<00:00, 3.45it/s, success=8, errors=2, pending=0]
235
+ ```
236
+
237
+ This makes it easy to monitor processing health at a glance.
238
+
239
+ #### Example: Robust Data Processing
240
+
241
+ ```python
242
+ from speedy_utils import multi_thread
243
+
244
+ def process_data_record(record):
245
+ """Process a data record that might have issues."""
246
+ try:
247
+ # Your processing logic here
248
+ value = record['value'] / record['divisor']
249
+ return {'result': value, 'status': 'success'}
250
+ except KeyError as e:
251
+ raise ValueError(f"Missing required field in record: {e}")
252
+ except ZeroDivisionError:
253
+ raise ValueError("Division by zero in record")
254
+
255
+ # Sample data with some problematic records
256
+ data = [
257
+ {'value': 10, 'divisor': 2}, # OK
258
+ {'value': 15, 'divisor': 0}, # Will error
259
+ {'value': 20, 'divisor': 4}, # OK
260
+ {'value': 25}, # Missing divisor - will error
261
+ ]
262
+
263
+ # Process with error logging - continues despite errors
264
+ results = multi_thread(
265
+ process_data_record,
266
+ data,
267
+ workers=4,
268
+ error_handler='log',
269
+ max_error_files=10
270
+ )
271
+
272
+ print("Results:", results)
273
+ # Output: Results: [{'result': 5.0, 'status': 'success'}, None, {'result': 5.0, 'status': 'success'}, None]
274
+ # Errors are logged to files for later analysis
127
275
  ```
128
276
 
129
277
  ### File I/O
@@ -1,11 +1,11 @@
1
1
  [project]
2
2
  name = "speedy-utils"
3
- version = "1.1.42"
3
+ version = "1.1.44"
4
4
  description = "Fast and easy-to-use package for data science"
5
5
  authors = [{ name = "AnhVTH", email = "anhvth.226@gmail.com" }]
6
6
  readme = "README.md"
7
7
  license = { text = "MIT" }
8
- requires-python = ">=3.8"
8
+ requires-python = ">=3.9"
9
9
  dependencies = [
10
10
  "numpy",
11
11
  "requests",
@@ -33,6 +33,7 @@ dependencies = [
33
33
  "ray",
34
34
  "aiohttp",
35
35
  "pytest",
36
+ "rich>=14.3.1",
36
37
  ]
37
38
  classifiers = [
38
39
  "Development Status :: 4 - Beta",
@@ -0,0 +1,34 @@
1
+ # type: ignore
2
+ from speedy_utils import multi_process, multi_thread
3
+
4
+
5
+ def do_something(x):
6
+ if x % 3 == 0:
7
+ raise ValueError(f'Error at index {x}')
8
+ return x * 2
9
+
10
+
11
+ inputs = range(10)
12
+
13
+
14
+ if __name__ == '__main__':
15
+ print('Testing error_handler="log" with mp backend:')
16
+ results = multi_process(
17
+ do_something,
18
+ inputs,
19
+ backend='mp',
20
+ error_handler='log',
21
+ max_error_files=5,
22
+ )
23
+ print(f'Results: {results}')
24
+ print()
25
+
26
+ # print('Testing error_handler="log" with multi_thread:')
27
+ # results = multi_thread(
28
+ # do_something,
29
+ # inputs,
30
+ # error_handler='log',
31
+ # max_error_files=5,
32
+ # )
33
+ # print(f'Results: {results}')
34
+
@@ -0,0 +1,11 @@
1
+ from speedy_utils import *
2
+
3
+
4
+ def do_something(x):
5
+ x = 10
6
+ y = 0
7
+ x/y
8
+
9
+
10
+ do_something(1)
11
+