datacom-device-api 0.1.9__tar.gz → 0.1.11__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 (25) hide show
  1. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/PKG-INFO +1 -1
  2. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/pyproject.toml +1 -1
  3. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/process/terminal_process.py +44 -8
  4. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api.egg-info/PKG-INFO +1 -1
  5. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/README.md +0 -0
  6. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/setup.cfg +0 -0
  7. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/__init__.py +0 -0
  8. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/data/__init__.py +0 -0
  9. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/data/table.py +0 -0
  10. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/event/event.py +0 -0
  11. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/ext/ext_meta.py +0 -0
  12. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/ext/ext_meta_display.py +0 -0
  13. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/operation/__init__.py +0 -0
  14. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/operation/table_operation.py +0 -0
  15. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/operation/table_read_from_xlsx.py +0 -0
  16. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/operation/table_save_to_db.py +0 -0
  17. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/process/__init__.py +0 -0
  18. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/utils/__init__.py +0 -0
  19. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/utils/directory_util.py +0 -0
  20. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api/utils/logger.py +0 -0
  21. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api.egg-info/SOURCES.txt +0 -0
  22. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api.egg-info/dependency_links.txt +0 -0
  23. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api.egg-info/requires.txt +0 -0
  24. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/src/datacom_device_api.egg-info/top_level.txt +0 -0
  25. {datacom_device_api-0.1.9 → datacom_device_api-0.1.11}/test/test_table_matching.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datacom-device-api
3
- Version: 0.1.9
3
+ Version: 0.1.11
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.14
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "datacom-device-api"
3
- version = "0.1.9"
3
+ version = "0.1.11"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.14"
@@ -7,6 +7,8 @@
7
7
  from concurrent.futures import Future, ProcessPoolExecutor
8
8
  from dataclasses import dataclass
9
9
  from functools import partial
10
+ import logging
11
+ from logging.handlers import QueueHandler, QueueListener
10
12
  from multiprocessing import Manager
11
13
  import os
12
14
  import queue
@@ -49,6 +51,22 @@ class ProgressMessage:
49
51
  __PROGRESS_UPDATE_FN_TYPE = Callable[[ProgressMessage], None]
50
52
 
51
53
 
54
+ class _ConsoleLogHandler(logging.Handler):
55
+ """将日志输出到 Rich Console,确保日志显示在进度条上方。"""
56
+
57
+ def __init__(self, console: Console):
58
+ super().__init__()
59
+ self.__console = console
60
+ self.setFormatter(logging.Formatter('[%(asctime)s-%(levelname)s](%(name)s): %(message)s'))
61
+
62
+ def emit(self, record: logging.LogRecord) -> None:
63
+ try:
64
+ msg = self.format(record)
65
+ self.__console.print(msg)
66
+ except Exception:
67
+ self.handleError(record)
68
+
69
+
52
70
  class TerminalProcess:
53
71
  """多进程任务执行器,支持进度展示与监听器机制。
54
72
 
@@ -71,6 +89,7 @@ class TerminalProcess:
71
89
  self.__pool = ProcessPoolExecutor(max_workers=max_workers or os.cpu_count())
72
90
  self.__manager = Manager()
73
91
  self.__progress_queue: queue.Queue[ProgressMessage] = self.__manager.Queue()
92
+ self.__log_queue: queue.Queue[str] = self.__manager.Queue()
74
93
 
75
94
  self.__task_future_count = 0
76
95
  self.__tasks: dict[UUID, Future[Any]] = {}
@@ -87,6 +106,10 @@ class TerminalProcess:
87
106
  'main', total=self.__task_future_count
88
107
  )
89
108
 
109
+ # 日志队列监听器:从 log_queue 消费 LogRecord 并输出到 Console
110
+ self.__log_handler = _ConsoleLogHandler(self.__console)
111
+ self.__log_listener = QueueListener(self.__log_queue, self.__log_handler)
112
+
90
113
  def trigger_progress(self, task_id: UUID, message: ProgressMessage) -> None:
91
114
  """触发指定任务的所有进度监听器。
92
115
 
@@ -135,6 +158,7 @@ class TerminalProcess:
135
158
  def _warrper_fn(
136
159
  fn: EXECUTE_FUNC_TYPE,
137
160
  progress_queue: queue.Queue[ProgressMessage],
161
+ log_queue: queue.Queue[str],
138
162
  task_id: UUID,
139
163
  *args,
140
164
  **kwargs,
@@ -143,7 +167,13 @@ class TerminalProcess:
143
167
 
144
168
  封装进度上报、完成标记和异常处理,通过队列将进度消息
145
169
  发送回主进程。任务正常结束或异常均会发送对应类型的消息。
170
+ 同时配置根 logger 使用 QueueHandler 将子进程日志转发到主进程。
146
171
  """
172
+ root_logger = logging.getLogger()
173
+ queue_handler = QueueHandler(log_queue)
174
+ root_logger.addHandler(queue_handler)
175
+ root_logger.setLevel(logging.INFO)
176
+
147
177
  done_send = False
148
178
 
149
179
  def report(progress: float, total: float, message: str, msg_type: str = 'progress'):
@@ -185,6 +215,7 @@ class TerminalProcess:
185
215
 
186
216
  持续从队列中取出进度消息,依次更新内置进度条并触发监听器。
187
217
  使用带超时的轮询避免阻塞,确保停止事件触发后能及时退出。
218
+ 日志消息由 QueueListener 在后台线程中消费并输出到终端。
188
219
  """
189
220
  while not self.__progress_thread_stop_event.is_set() or not self.__progress_queue.empty():
190
221
  try:
@@ -192,11 +223,14 @@ class TerminalProcess:
192
223
  self.update_progress(message)
193
224
  self.trigger_progress(message.task_id, message)
194
225
  except queue.Empty:
195
- if (
196
- self.__progress_thread_stop_event.is_set()
197
- and all(futrue.done() for futrue in self.__tasks.values())
198
- ):
199
- break
226
+ pass
227
+
228
+ if (
229
+ self.__progress_thread_stop_event.is_set()
230
+ and all(futrue.done() for futrue in self.__tasks.values())
231
+ and self.__progress_queue.empty()
232
+ ):
233
+ break
200
234
 
201
235
  def submit(
202
236
  self,
@@ -217,7 +251,7 @@ class TerminalProcess:
217
251
  任务的 Future 对象,可用于获取结果或异常
218
252
  """
219
253
  task_id = uuid.uuid4()
220
- task_fn = partial(TerminalProcess._warrper_fn, fn, self.__progress_queue, task_id)
254
+ task_fn = partial(TerminalProcess._warrper_fn, fn, self.__progress_queue, self.__log_queue, task_id)
221
255
  future = self.__pool.submit(task_fn, *args, **kwargs)
222
256
  self.__tasks[task_id] = future
223
257
  self.__task_update_lisening_fn_dict[task_id] = []
@@ -233,6 +267,7 @@ class TerminalProcess:
233
267
  def start(self) -> None:
234
268
  """启动进度条显示与消息消费线程。"""
235
269
  self.__progress.start()
270
+ self.__log_listener.start()
236
271
  self.__progress_thread_stop_event.clear()
237
272
  self.__progress_thread = threading.Thread(target=self.run_display_progress)
238
273
  self.__progress_thread.start()
@@ -240,8 +275,8 @@ class TerminalProcess:
240
275
  def shutdown(self) -> None:
241
276
  """停止任务执行并释放资源。
242
277
 
243
- 按顺序执行:等待所有任务完成 → 消费完剩余进度消息
244
- 关闭进程池 → 停止进度条。确保不会因消息未消费完而丢失进度。
278
+ 按顺序执行:等待所有任务完成 → 设置停止事件 消费线程退出并消费剩余消息 →
279
+ 关闭进程池 → 停止进度条。确保不会因消息未消费完而丢失进度或日志。
245
280
  """
246
281
  for future in self.__tasks.values():
247
282
  try:
@@ -254,6 +289,7 @@ class TerminalProcess:
254
289
  self.__progress_thread.join()
255
290
  self.__progress_thread = None
256
291
 
292
+ self.__log_listener.stop()
257
293
  self.__pool.shutdown(wait=True)
258
294
  self.__progress.stop()
259
295
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datacom-device-api
3
- Version: 0.1.9
3
+ Version: 0.1.11
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.14
6
6
  Description-Content-Type: text/markdown