pycoze 0.1.445__py3-none-any.whl → 0.1.447__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.
@@ -2,4 +2,4 @@ from .bot import ref_bot
2
2
  from .tool import ref_tools
3
3
  from .workflow import ref_workflow
4
4
  from .lib import call_func
5
- from .fn import single_process, multi_process, generator_function, compatibility, global_thread
5
+ from .fn import single_process, multi_process, generator_function, compatibility, global_process
pycoze/reference/fn.py CHANGED
@@ -34,7 +34,7 @@ def compatibility(func=None):
34
34
  return decorator
35
35
 
36
36
 
37
- def global_thread(func=None):
37
+ def global_process(func=None):
38
38
  def decorator(f):
39
39
  return f
40
40
 
pycoze/reference/lib.py CHANGED
@@ -9,6 +9,10 @@ import nest_asyncio
9
9
  nest_asyncio.apply()
10
10
 
11
11
  def call_func(func, args=None, kwargs=None):
12
+ """
13
+ args:是一个元组
14
+ kwargs:是一个字典
15
+ """
12
16
  if args is None:
13
17
  args = ()
14
18
  if kwargs is None:
@@ -0,0 +1,133 @@
1
+ import asyncio
2
+ import os
3
+ import sys
4
+ import atexit
5
+ import time
6
+ import chardet
7
+
8
+
9
+ def better_kill(process, raiseError: bool):
10
+ """优雅地终止进程,如果超时则强制终止"""
11
+ try:
12
+ process.terminate() # 先尝试优雅终止
13
+ time.sleep(5) # 等待5秒
14
+ except asyncio.TimeoutError:
15
+ try:
16
+ process.kill() # 如果超时,强制终止
17
+ except:
18
+ if raiseError:
19
+ raise
20
+ else:
21
+ pass
22
+ except Exception as e:
23
+ # print(f"Error while terminating process: {e}")
24
+ if raiseError:
25
+ raise
26
+ else:
27
+ pass
28
+
29
+
30
+
31
+ async def read_stream(stream, log, separator=b'\n'):
32
+ def log_func(data):
33
+ try:
34
+ data = data.decode().strip()
35
+ log(data)
36
+ except:
37
+ try:
38
+ encoding = chardet.detect(data)['encoding']
39
+ data = data.decode(encoding).strip()
40
+ finally:
41
+ log(data)
42
+
43
+ while True:
44
+ try:
45
+ line = await stream.readuntil(separator)
46
+ log_func(line)
47
+ except asyncio.IncompleteReadError as e:
48
+ # If the stream ends without a separator, output the remaining content
49
+ if e.partial:
50
+ log_func(e.partial)
51
+ break
52
+ except asyncio.LimitOverrunError as e:
53
+ # If the separator is found but not within the limit, read the chunk
54
+ chunk = await stream.read(e.consumed)
55
+ log_func(chunk)
56
+
57
+
58
+
59
+
60
+ async def execute_script(script_path, *args, cwd=None, env=None):
61
+ cwd = cwd or os.path.dirname(script_path)
62
+ process = await asyncio.create_subprocess_exec(
63
+ sys.executable,
64
+ "-u",
65
+ script_path,
66
+ *args,
67
+ cwd=cwd,
68
+ env=env,
69
+ stdout=asyncio.subprocess.PIPE,
70
+ stderr=asyncio.subprocess.PIPE,
71
+ )
72
+ return process
73
+
74
+
75
+ async def execute_script_and_block(script_path, log, *args, cwd=None, env=None):
76
+ try:
77
+ # 执行脚本
78
+ process = await execute_script(script_path, *args, cwd=cwd, env=env)
79
+ except Exception as e:
80
+ better_kill(process, False)
81
+ raise Exception(f"Failed to execute script: {e}")
82
+
83
+ try:
84
+ # 开始并行读取 stdout 和 stderr
85
+ stdout_task = asyncio.create_task(read_stream(process.stdout, log))
86
+ stderr_task = asyncio.create_task(read_stream(process.stderr, log))
87
+
88
+ # 注册atexit处理程序
89
+ async def cleanup():
90
+ better_kill(process, False)
91
+ stdout_task.cancel()
92
+ stderr_task.cancel()
93
+ atexit.register(cleanup)
94
+
95
+ # 等待进程完成
96
+ return_code = await process.wait()
97
+
98
+ # 等待读取任务完成
99
+ await stdout_task
100
+ await stderr_task
101
+
102
+ except Exception as e:
103
+ better_kill(process, False)
104
+ stdout_task.cancel()
105
+ stderr_task.cancel()
106
+ raise Exception(f"Error during script execution or stream reading: {e}")
107
+
108
+ # 检查返回码
109
+ if return_code != 0:
110
+ better_kill(process, False)
111
+ raise Exception("Error executing script, return code: {}".format(return_code))
112
+
113
+ # 如果一切正常,返回成功
114
+ return "success"
115
+
116
+
117
+
118
+ async def execute_script_no_block(script_path, log, *args, cwd=None, env=None):
119
+ process = await execute_script(script_path, *args, cwd=cwd, env=env)
120
+
121
+ # Start reading stdout and stderr in parallel
122
+ stdout_task = asyncio.create_task(read_stream(process.stdout, log))
123
+ stderr_task = asyncio.create_task(read_stream(process.stderr, log))
124
+
125
+ # Register atexit handler to ensure process cleanup
126
+ def cleanup():
127
+ better_kill(process, False)
128
+ stdout_task.cancel()
129
+ stderr_task.cancel()
130
+
131
+ atexit.register(cleanup)
132
+
133
+ return process, stdout_task, stderr_task
pycoze/utils/socket.py CHANGED
@@ -12,7 +12,8 @@ class TcpSocket:
12
12
  self.is_connected = True
13
13
  self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
14
14
  if params is not None:
15
- self.socket.connect(("localhost", int(params["tcpPort"])))
15
+ if "tcpPort" in params:
16
+ self.socket.connect(("localhost", int(params["tcpPort"])))
16
17
 
17
18
  def post(self, subject, message):
18
19
  subject = "python-event:" + subject
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pycoze
3
- Version: 0.1.445
3
+ Version: 0.1.447
4
4
  Summary: Package for pycoze only!
5
5
  Author: Yuan Jie Xiong
6
6
  Author-email: aiqqqqqqq@qq.com
@@ -16,10 +16,10 @@ pycoze/bot/lib.py,sha256=RivPA2f5fqzqbW6jL0sx9X9pwgFPxwkk8lt62CWvaZo,7255
16
16
  pycoze/bot/message.py,sha256=udnIi-h4QgGzkbr_5VcAsVGjoLp9wXJSfBCeuOz7_Bk,802
17
17
  pycoze/bot/prompt.md,sha256=UtwZ31wFvNtvM9ZTA4BU2yT1Rb-qnUdU3Ny1O37Tt3Q,14077
18
18
  pycoze/bot/tools.py,sha256=BWMdwvqLzvcyaW38lzxUWtc0K1V-C_qPSEZ3OKlAQvU,11108
19
- pycoze/reference/__init__.py,sha256=wEhM5lIZ58UQV5YSYOPrtuTlpibPvcLgiZnVlG3RIf8,210
19
+ pycoze/reference/__init__.py,sha256=u25FWJnOBWsDRoL8_O4jzW4tkJrHT3Sqp9EGCxUhS3E,211
20
20
  pycoze/reference/bot.py,sha256=UZK24Qm8kpqpwXJy_zNZeTEEDee05luXdSBeUm0NCt0,2029
21
- pycoze/reference/fn.py,sha256=UIXwNNCXTbumCWKVeInbe96vAf9926LlT7bU3aEmZzA,749
22
- pycoze/reference/lib.py,sha256=T-oBOKxkus5dTouc0oDgfRzUyi6aTyY-FF4yX7SzF5M,3755
21
+ pycoze/reference/fn.py,sha256=ZXnG2ctbHMgr3quQp-4bpnErIkuT-t2_ToSET5LTLbc,750
22
+ pycoze/reference/lib.py,sha256=R-0T2QjxCUSF7K7XQtKaGm2n7uVptW4BnGu8s1QjMe0,3835
23
23
  pycoze/reference/tool.py,sha256=kv5Ww8fZVECNJfE7Ku5M88jqHgSO0yTF0S6eijQu9KE,1104
24
24
  pycoze/reference/workflow.py,sha256=59teXvIM_kOa-rJMLudJaJb9FBumYEmOzMT5jifKqDY,1337
25
25
  pycoze/ui/__init__.py,sha256=uaXet23wUk64TcZjpBX8qOx4aUhwA_ucrmcxy7Q4Qr4,929
@@ -30,10 +30,11 @@ pycoze/ui/ui_def.py,sha256=lGWZGpzRoegP34D562PvK0EJHrmVZrlHW1JjsIG9A9Q,4521
30
30
  pycoze/utils/__init__.py,sha256=H-2KRUsUG47owL0sbD1KwDOuRm-j_0K4RkeNhzr7ISo,319
31
31
  pycoze/utils/arg.py,sha256=jop1tBfe5hYkHW1NSpCeaZBEznkgguBscj_7M2dWfrs,503
32
32
  pycoze/utils/env.py,sha256=5pWlXfM1F5ZU9hhv1rHlDEanjEW5wf0nbyez9bNRqqA,559
33
- pycoze/utils/socket.py,sha256=bZbFFRH4mfThzRqt55BAAGQ6eICx_ja4x8UGGrUdAm8,2428
33
+ pycoze/utils/process.py,sha256=U2MURGmxfyWBqdbKfy5UvyV17M40B6HHlNELgWfgrTE,3824
34
+ pycoze/utils/socket.py,sha256=4Wm4LlwdWXC_kAV0NnZbUc0Y3Kc6KRMyFRqSw79u-9w,2468
34
35
  pycoze/utils/text_or_file.py,sha256=gpxZVWt2DW6YiEg_MnMuwg36VNf3TX383QD_1oZNB0Y,551
35
- pycoze-0.1.445.dist-info/LICENSE,sha256=QStd_Qsd0-kAam_-sOesCIp_uKrGWeoKwt9M49NVkNU,1090
36
- pycoze-0.1.445.dist-info/METADATA,sha256=4WuLUFZ7FoXtSNoCS5OlK7f-kryaCn3i2OXzSAQaDw0,854
37
- pycoze-0.1.445.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
38
- pycoze-0.1.445.dist-info/top_level.txt,sha256=76dPeDhKvOCleL3ZC5gl1-y4vdS1tT_U1hxWVAn7sFo,7
39
- pycoze-0.1.445.dist-info/RECORD,,
36
+ pycoze-0.1.447.dist-info/LICENSE,sha256=QStd_Qsd0-kAam_-sOesCIp_uKrGWeoKwt9M49NVkNU,1090
37
+ pycoze-0.1.447.dist-info/METADATA,sha256=EBKllPIWr_-30XTHbUZMMDDRJcNKvXDU_G4RUjvs-2c,854
38
+ pycoze-0.1.447.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
39
+ pycoze-0.1.447.dist-info/top_level.txt,sha256=76dPeDhKvOCleL3ZC5gl1-y4vdS1tT_U1hxWVAn7sFo,7
40
+ pycoze-0.1.447.dist-info/RECORD,,