halib 0.2.27__py3-none-any.whl → 0.2.28__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.
halib/system/path.py CHANGED
@@ -21,7 +21,7 @@ def load_pc_meta_info():
21
21
  # 2. Locate the file
22
22
  csv_path = resources.files(package_name).joinpath(file_name)
23
23
  global PC_TO_ABBR, ABBR_DISK_MAP, pc_df
24
- pc_df = pd.read_csv(csv_path, sep=';', encoding='utf-8')
24
+ pc_df = pd.read_csv(csv_path, sep=';', encoding='utf-8') # ty:ignore[no-matching-overload]
25
25
  PC_TO_ABBR = dict(zip(pc_df['pc_name'], pc_df['abbr']))
26
26
  ABBR_DISK_MAP = dict(zip(pc_df['abbr'], pc_df['working_disk']))
27
27
  # pprint("Loaded PC meta info:")
@@ -57,7 +57,7 @@ def get_working_disk(abbr_disk_map=ABBR_DISK_MAP):
57
57
 
58
58
  cDisk = get_working_disk()
59
59
 
60
- # ! This funcction search for full paths in the obj and normalize them according to the current platform and working disk
60
+ # ! This function search for full paths in the obj and normalize them according to the current platform and working disk
61
61
  # ! E.g: "E:/zdataset/DFire", but working_disk: "D:", current_platform: "windows" => "D:/zdataset/DFire"
62
62
  # ! E.g: "E:/zdataset/DFire", but working_disk: "D:", current_platform: "linux" => "/mnt/d/zdataset/DFire"
63
63
  def normalize_paths(obj, working_disk=cDisk, current_platform=cPlatform):
halib/utils/dict.py CHANGED
@@ -1,4 +1,3 @@
1
- from pygments.token import Other
2
1
  from typing import Dict, Any, Callable, Optional
3
2
  from rich.pretty import pprint
4
3
  import json
halib/utils/list.py CHANGED
@@ -1,12 +1,17 @@
1
- def subtract(list_a, list_b):
2
- return [item for item in list_a if item not in list_b]
1
+ class ListUtils:
2
+ """Utility functions for list operations."""
3
3
 
4
+ @staticmethod
5
+ def subtract(list_a, list_b):
6
+ return [item for item in list_a if item not in list_b]
4
7
 
5
- def union(list_a, list_b, no_duplicate=False):
6
- if no_duplicate:
7
- return list(set(list_a) | set(list_b))
8
- else:
9
- return list_a + list_b
8
+ @staticmethod
9
+ def union(list_a, list_b, no_duplicate=False):
10
+ if no_duplicate:
11
+ return list(set(list_a) | set(list_b))
12
+ else:
13
+ return list_a + list_b
10
14
 
11
- def intersection(list_a, list_b):
12
- return list(set(list_a) & set(list_b))
15
+ @staticmethod
16
+ def intersection(list_a, list_b):
17
+ return list(set(list_a) & set(list_b))
halib/utils/slack.py ADDED
@@ -0,0 +1,84 @@
1
+ import time
2
+ from slack_sdk import WebClient
3
+ from slack_sdk.errors import SlackApiError
4
+ from rich.pretty import pprint
5
+
6
+
7
+ class SlackUtils:
8
+ _instance = None
9
+
10
+ def __new__(cls, token=None):
11
+ """
12
+ Singleton __new__ method.
13
+ Ensures only one instance of SlackUtils exists.
14
+ """
15
+ if cls._instance is None:
16
+ if token is None:
17
+ raise ValueError(
18
+ "A Slack Token is required for the first initialization."
19
+ )
20
+
21
+ # Create the instance
22
+ cls._instance = super(SlackUtils, cls).__new__(cls)
23
+
24
+ # Initialize the WebClient only once
25
+ cls._instance.client = WebClient(token=token)
26
+ cls._instance.token = token
27
+
28
+ return cls._instance
29
+
30
+ def clear_channel(self, channel_id, sleep_interval=1.0):
31
+ """
32
+ Fetches and deletes all messages in a specified channel.
33
+ """
34
+ cursor = None
35
+ deleted_count = 0
36
+
37
+ pprint(f"--- Starting cleanup for Channel ID: {channel_id} ---")
38
+
39
+ while True:
40
+ try:
41
+ # Fetch history in batches of 100
42
+ response = self.client.conversations_history( # ty:ignore[unresolved-attribute]
43
+ channel=channel_id, cursor=cursor, limit=100
44
+ )
45
+
46
+ messages = response.get("messages", [])
47
+
48
+ if not messages:
49
+ pprint("No more messages found to delete.")
50
+ break
51
+
52
+ for msg in messages:
53
+ ts = msg.get("ts")
54
+
55
+ try:
56
+ # Attempt delete
57
+ self.client.chat_delete( # ty:ignore[unresolved-attribute]
58
+ channel=channel_id, ts=ts
59
+ )
60
+ pprint(f"Deleted: {ts}")
61
+ deleted_count += 1
62
+
63
+ # Rate limit protection (Tier 3 limit)
64
+ time.sleep(sleep_interval)
65
+
66
+ except SlackApiError as e:
67
+ error_code = e.response["error"]
68
+ if error_code == "cant_delete_message":
69
+ pprint(f"Skipped (Permission denied): {ts}")
70
+ elif error_code == "message_not_found":
71
+ pprint(f"Skipped (Already deleted): {ts}")
72
+ else:
73
+ pprint(f"Error deleting {ts}: {error_code}")
74
+ # Check for pagination
75
+ if response["has_more"]:
76
+ cursor = response["response_metadata"]["next_cursor"]
77
+ else:
78
+ break
79
+
80
+ except SlackApiError as e:
81
+ print(f"Critical API Error fetching history: {e.response['error']}")
82
+ break
83
+
84
+ print(f"--- Completed. Total messages deleted: {deleted_count} ---")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: halib
3
- Version: 0.2.27
3
+ Version: 0.2.28
4
4
  Summary: Small library for common tasks
5
5
  Author: Hoang Van Ha
6
6
  Author-email: hoangvanhauit@gmail.com
@@ -42,6 +42,7 @@ Requires-Dist: tube_dl
42
42
  Requires-Dist: wandb
43
43
  Requires-Dist: ipynbname
44
44
  Requires-Dist: typed-argument-parser
45
+ Requires-Dist: slack_sdk
45
46
  Dynamic: author
46
47
  Dynamic: author-email
47
48
  Dynamic: classifier
@@ -56,25 +57,32 @@ Dynamic: summary
56
57
 
57
58
  ## v0.2.x (Experiment & Core Updates)
58
59
 
59
- ### **v0.2.27**
60
+ ### **v0.2.28**
61
+
62
+ - ✨ **New Feature:** Implement `utils.slack.SlackUtils` class for managing Slack channel message deletion
63
+
60
64
  - ✨ **New Feature:** Added `utils.dict.DictUtils` for advanced dictionary manipulations (merging, filtering, transforming).
61
65
 
62
66
  - ✨ **New Feature:** Added `common.common.pprint_stack_trace` to print stack traces with optional custom messages and force stop capability.
63
67
 
64
- - 🚀 **Improvement:** `exp.perf.profiler` - allow to export *report dict* as csv files for further analysis
68
+ - 🚀 **Improvement:** `exp.perf.profiler` - allow to export _report dict_ as csv files for further analysis
65
69
 
66
70
  ### **v0.2.19**
71
+
67
72
  - ✨ **New Feature:** Added `exp.core.param_gen` to facilitate fast generation of parameter combination sweeps (grid search) using YAML configurations.
68
73
 
69
74
  ### **v0.2.17**
75
+
70
76
  - 🚀 **Improvement:** Updated `exp.perf.profiler` with an `enabled` flag for dynamic toggling.
71
77
  - 🚀 **Improvement:** Added a `measure` context manager to simplify performance measuring of code blocks.
72
78
 
73
79
  ### **v0.2.13**
80
+
74
81
  - ♻️ **Refactor:** Major reorganization of packages. Renamed `research` package to `exp` (Experiment Management).
75
82
  - 🚀 **Improvement:** Updated `exp/perfcalc.py` to allow saving computed performance metrics to CSV without explicitly calling `calc_perfs`.
76
83
 
77
84
  ### **v0.2.1**
85
+
78
86
  - ✨ **New Feature:** Added `eval_exp` method to `exp/base_exp` for running evaluations (e.g., model testing) after experiments conclude.
79
87
 
80
88
  ---
@@ -82,15 +90,19 @@ Dynamic: summary
82
90
  ## v0.1.9x (Visualization & Generators)
83
91
 
84
92
  ### **v0.1.99**
93
+
85
94
  - ✨ **New Feature:** Added `gen_ipynb_name` to `filetype/ipynb`. Generates filenames based on the current notebook name with optional timestamps.
86
95
 
87
96
  ### **v0.1.96**
97
+
88
98
  - ✨ **New Feature:** Added `PlotHelper` class in `research/plot` for plotting training history and image grids (dataset samples or model outputs).
89
99
 
90
100
  ### **v0.1.91**
101
+
91
102
  - ✨ **New Feature:** Added `ParamGen` class to `research/param_gen` for parsing YAML files into parameter lists for hyperparameter searches.
92
103
 
93
104
  ### **v0.1.90**
105
+
94
106
  - ✨ **New Feature:** Added `zProfiler` class to `research/profiler` for measuring context/step execution time, supporting dynamic color scales in plots.
95
107
 
96
108
  ---
@@ -98,26 +110,33 @@ Dynamic: summary
98
110
  ## v0.1.5x - v0.1.7x (Infrastructure & Utilities)
99
111
 
100
112
  ### **v0.1.77**
113
+
101
114
  - ✨ **New Feature:** Added `BaseExp` class in `research/base_exp` to handle common experiment tasks (performance calculation, result saving).
102
115
 
103
116
  ### **v0.1.67**
117
+
104
118
  - 🔧 **Maintenance:** Switched to **uv** for virtual environment management.
105
119
  - 🚀 **Improvement:** Updated `research/perfcalc` to support both `torchmetrics` and custom metrics.
106
120
 
107
121
  ### **v0.1.61**
122
+
108
123
  - ✨ **New Feature:** Added `VideoUtils` (`util/video`) for common video handling tasks.
109
124
  - ✨ **New Feature:** Added `GPUMonitor` (`util/gpu_mon`) for tracking GPU usage and performance.
110
125
 
111
126
  ### **v0.1.59**
127
+
112
128
  - 🔨 **Architecture:** Added `util/perfcalc` abstract base class. This requires implementation of specific performance calculation logic.
113
129
 
114
130
  ### **v0.1.55**
131
+
115
132
  - ✨ **New Feature:** Added `util/dataclass_util` for dynamic creation of `dataclass` objects from dictionaries or YAML (supports nested structures).
116
133
 
117
134
  ### **v0.1.52**
135
+
118
136
  - ✨ **New Feature:** Added `research/perftb` module for managing experiment performance tables (filtering by dataset, metric, etc.).
119
137
 
120
138
  ### **v0.1.50**
139
+
121
140
  - ✨ **New Feature:** Added `pprint_local_path` to print clickable file URIs for local paths.
122
141
  - ✨ **New Feature:** Added `research` package containing `benchquery` for dataframe benchmarking.
123
142
  - ✨ **New Feature:** Added `wandb` module for offline syncing and batch clearing of Weights & Biases runs.
@@ -127,19 +146,24 @@ Dynamic: summary
127
146
  ## v0.1.4x (Display & formatting)
128
147
 
129
148
  ### **v0.1.47**
149
+
130
150
  - ✨ **New Feature:** Added `pprint_box` to print objects or strings inside a decorative box frame.
131
151
 
132
152
  ### **v0.1.46**
153
+
133
154
  - 🐛 **Fix:** Filtered `UserWarning: Unable to import Axes3D`.
134
155
  - 🚀 **Improvement:** Added `auto_wrap_text` to `fn_display_df` to prevent long text overflow in tables.
135
156
 
136
157
  ### **v0.1.42**
158
+
137
159
  - ✨ **New Feature:** Added `rich_color.py` wrapper for basic color lists.
138
160
 
139
161
  ### **v0.1.41**
162
+
140
163
  - ✨ **New Feature:** Added `rich_color.py` to support rich color information (palettes, strings) using the `rich` library.
141
164
 
142
165
  ### **v0.1.40**
166
+
143
167
  - 🚀 **Improvement:** Updated `csvfile.py` to use `itables` and `pygwalker` for interactive dataframe display in Jupyter notebooks.
144
168
 
145
169
  ---
@@ -147,12 +171,15 @@ Dynamic: summary
147
171
  ## v0.1.3x (Data & Loading)
148
172
 
149
173
  ### **v0.1.38**
174
+
150
175
  - ✨ **New Feature:** Added `torchloader.py` to search for optimal `DataLoader` configurations (num_workers, batch_size, pin_memory).
151
176
 
152
177
  ### **v0.1.37**
178
+
153
179
  - ✨ **New Feature:** Added `dataset.py` for splitting classification datasets into train/val/test sets.
154
180
 
155
181
  ### **v0.1.33**
182
+
156
183
  - ✨ **New Feature:** Added `plot.py` for plotting Deep Learning training history (accuracy/loss) using `seaborn` and `matplotlib`.
157
184
 
158
185
  ---
@@ -160,35 +187,45 @@ Dynamic: summary
160
187
  ## v0.1.0 - v0.1.2x (Early Utilities)
161
188
 
162
189
  ### **v0.1.29**
190
+
163
191
  - 🐛 **Fix:** Pinned `kaleido==0.1.*` for `tele_noti` as version `0.2.*` caused image generation hangs.
164
192
 
165
193
  ### **v0.1.24**
194
+
166
195
  - ♻️ **Refactor:** Renamed `sys` module to `system` to avoid conflicts with Python's built-in `sys`.
167
196
  - ✨ **New Feature:** Added `tele_noti` module for Telegram notifications regarding training progress.
168
197
 
169
198
  ### **v0.1.22**
199
+
170
200
  - ✨ **New Feature:** Added `cuda.py` to check CUDA availability for both PyTorch and TensorFlow.
171
201
 
172
202
  ### **v0.1.21**
203
+
173
204
  - ✨ **New Feature:** Added YAML inheritance and overriding support using `networkx` and `omegaconf`.
174
205
 
175
206
  ### **v0.1.15**
207
+
176
208
  - ✨ **New Feature:** Added common logging library and `@console_log` decorator for function tracing.
177
209
 
178
210
  ### **v0.1.10**
211
+
179
212
  - 🐛 **Fix:** Fixed typo `is_exit` -> `is_exist` in `filesys`.
180
213
  - 🚀 **Improvement:** Updated `gdrive` to support uploading to specific folders and returning direct shareable links.
181
214
 
182
215
  ### **v0.1.9**
216
+
183
217
  - 🔧 **Maintenance:** Added `requirements.txt`.
184
218
 
185
219
  ### **v0.1.6 - v0.1.8**
220
+
186
221
  - 🚀 **Performance:** Optimized table insertion by using an in-memory `row_pool_dict` before committing to the DataFrame.
187
222
  - ✨ **New Feature:** Added `DFCreator` for manipulating DataFrames (create, insert, display, save).
188
223
 
189
224
  ### **v0.1.4 - v0.1.5**
225
+
190
226
  - ✨ **New Feature:** Added `cmd` module.
191
227
  - ✨ **New Feature:** Support for creating Bitbucket Projects from templates.
192
228
 
193
229
  ### **v0.1.2**
230
+
194
231
  - ✨ **New Feature:** Added support for uploading local files to Google Drive.
@@ -92,18 +92,19 @@ halib/system/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
92
  halib/system/_list_pc.csv,sha256=r8RwxDWYEeNkPCQBs8dOC8cWgBpa3OULZobwb1feuWg,172
93
93
  halib/system/cmd.py,sha256=b2x7JPcNnFjLGheIESVYvqAb-w2UwBM1PAwYxMZ5YjA,228
94
94
  halib/system/filesys.py,sha256=102J2fkQhmH1_-HQVy2FQ4NOU8LTjMWV3hToT_APtq8,4401
95
- halib/system/path.py,sha256=k_pveq41uXEzKPU2KTIdqjUSb4MVM-hCFXHGeO-6x6Q,3694
95
+ halib/system/path.py,sha256=ewiHI76SLFBG5NnlihLpxBbOEDfHibRwKTcLMjEz6Hw,3728
96
96
  halib/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
97
  halib/utils/dataclass_util.py,sha256=rj2IMLlUzbm2OlF5_B2dRTk9njZOaF7tTjYkOsq8uLY,1416
98
- halib/utils/dict.py,sha256=tUmwKNbTLOyGLl5nKYdT8QIoS4pBFfdsZHCJ6NQCgp4,6922
98
+ halib/utils/dict.py,sha256=cqyo37IitDgTUgoooO8PTKvPYBuHeCyxTz1QKbYKtLI,6888
99
99
  halib/utils/dict_op.py,sha256=wYE6Iw-_CnCWdMg9tpJ2Y2-e2ESkW9FxmdBkZkbUh80,299
100
100
  halib/utils/gpu_mon.py,sha256=vD41_ZnmPLKguuq9X44SB_vwd9JrblO4BDzHLXZhhFY,2233
101
- halib/utils/list.py,sha256=BM-8sRhYyqF7bh4p7TQtV7P_gnFruUCA6DTUOombaZg,337
101
+ halib/utils/list.py,sha256=bbey9_0IaMXnHx1pudv3C3_WU9uFQEQ5qHPklSN-7o0,498
102
102
  halib/utils/listop.py,sha256=Vpa8_2fI0wySpB2-8sfTBkyi_A4FhoFVVvFiuvW8N64,339
103
+ halib/utils/slack.py,sha256=NyiBoH-o653i0tb3KmpbSOmLj0_RACyPgYQWuh4utjs,3007
103
104
  halib/utils/tele_noti.py,sha256=-4WXZelCA4W9BroapkRyIdUu9cUVrcJJhegnMs_WpGU,5928
104
105
  halib/utils/video.py,sha256=zLoj5EHk4SmP9OnoHjO8mLbzPdtq6gQPzTQisOEDdO8,3261
105
- halib-0.2.27.dist-info/licenses/LICENSE.txt,sha256=qZssdna4aETiR8znYsShUjidu-U4jUT9Q-EWNlZ9yBQ,1100
106
- halib-0.2.27.dist-info/METADATA,sha256=Or9W2uqrbMh_PQd3KCda2KZRuuH4Wi7I4aicUPq2Ks0,7719
107
- halib-0.2.27.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
108
- halib-0.2.27.dist-info/top_level.txt,sha256=7AD6PLaQTreE0Fn44mdZsoHBe_Zdd7GUmjsWPyQ7I-k,6
109
- halib-0.2.27.dist-info/RECORD,,
106
+ halib-0.2.28.dist-info/licenses/LICENSE.txt,sha256=qZssdna4aETiR8znYsShUjidu-U4jUT9Q-EWNlZ9yBQ,1100
107
+ halib-0.2.28.dist-info/METADATA,sha256=OLZvOvDQWqp8m_5or_KoqDevjSdjN2mN767yDlYeKLc,7923
108
+ halib-0.2.28.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
109
+ halib-0.2.28.dist-info/top_level.txt,sha256=7AD6PLaQTreE0Fn44mdZsoHBe_Zdd7GUmjsWPyQ7I-k,6
110
+ halib-0.2.28.dist-info/RECORD,,
File without changes