funcguard 0.1.1__tar.gz → 0.1.4__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.

Potentially problematic release.


This version of funcguard might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: funcguard
3
- Version: 0.1.1
3
+ Version: 0.1.4
4
4
  Summary: A funcguard for Python.
5
5
  Home-page: https://github.com/tinycen/funcguard
6
6
  Author: tinycen
@@ -21,13 +21,11 @@ FuncGuard是一个Python库,提供了函数执行超时控制和重试机制
21
21
  - 函数执行超时控制
22
22
  - 函数执行失败自动重试
23
23
  - HTTP请求封装(支持自动重试)
24
+ - 格式化打印工具(分隔线和块打印)
25
+ - 时间日志记录和耗时统计
24
26
 
25
27
  ## 安装/升级
26
28
 
27
- ```bash
28
- pip install funcguard
29
- ```
30
-
31
29
  ```bash
32
30
  pip install --upgrade funcguard
33
31
  ```
@@ -40,7 +38,7 @@ pip install --upgrade funcguard
40
38
  使用`timeout_handler`函数可以控制函数的执行时间,防止函数运行时间过长:
41
39
 
42
40
  ```python
43
- from funcguard.core import timeout_handler
41
+ from funcguard import timeout_handler
44
42
 
45
43
  def long_running_function():
46
44
  # 模拟一个耗时操作
@@ -61,7 +59,7 @@ except TimeoutError as e:
61
59
  使用`retry_function`函数可以在函数执行失败时自动重试:
62
60
 
63
61
  ```python
64
- from funcguard.core import retry_function
62
+ from funcguard import retry_function
65
63
 
66
64
  def unstable_function():
67
65
  # 模拟一个可能失败的操作
@@ -83,7 +81,7 @@ except Exception as e:
83
81
  使用`send_request`函数发送HTTP请求,支持自动重试:
84
82
 
85
83
  ```python
86
- from funcguard.tools import send_request
84
+ from funcguard import send_request
87
85
 
88
86
  # 不使用重试
89
87
  response = send_request(
@@ -110,6 +108,63 @@ response = send_request(
110
108
  print(response)
111
109
  ```
112
110
 
111
+ ### 格式化打印
112
+
113
+ 使用`print_line`和`print_block`函数进行格式化打印,便于查看和调试:
114
+
115
+ ```python
116
+ from funcguard import print_line, print_block
117
+
118
+ # 打印分隔线
119
+ print_line() # 默认使用40个'-'字符
120
+ print_line("*", 30) # 使用30个'*'字符
121
+
122
+ # 打印块内容
123
+ print_block("用户信息", {"name": "张三", "age": 25})
124
+
125
+ # 自定义分隔符
126
+ print_block("配置信息", {"debug": True, "port": 8080}, "=", 50)
127
+
128
+ # 打印复杂内容
129
+ result = {
130
+ "status": "success",
131
+ "data": [1, 2, 3, 4, 5],
132
+ "message": "操作完成"
133
+ }
134
+ print_block("API响应", result)
135
+ ```
136
+
137
+ ### 时间日志记录
138
+
139
+ 使用`time_log`和`time_diff`函数记录任务执行时间和统计信息:
140
+
141
+ ```python
142
+ from funcguard import time_log, time_diff
143
+
144
+ # 获取开始时间
145
+ start_time = time_diff()
146
+
147
+ # 记录任务开始
148
+ time_log("开始处理数据", 0, 100, start_time)
149
+
150
+ # 模拟处理过程
151
+ import time
152
+ for i in range(1, 101):
153
+ time.sleep(0.1) # 模拟处理时间
154
+ if i % 20 == 0:
155
+ time_log(f"处理进度", i, 100, start_time) # 显示进度和预计完成时间
156
+
157
+ # 记录任务完成并打印统计信息
158
+ time_log("数据处理完成", 100, 100, start_time)
159
+ time_diff(start_time, 100, "cn") # 中文显示统计信息
160
+ ```
161
+
162
+ 时间日志功能特点:
163
+ - 自动显示北京时间(UTC+8)
164
+ - 支持进度显示和预计完成时间计算
165
+ - 提供中英文双语统计信息
166
+ - 可显示总耗时、平均耗时等详细统计
167
+
113
168
  ## API文档
114
169
 
115
170
  ### funcguard.core
@@ -151,6 +206,45 @@ print(response)
151
206
  - **返回值**: 根据return_type参数返回不同格式的响应数据
152
207
  - **异常**: 当请求失败且重试次数用尽后,抛出相应的异常
153
208
 
209
+ #### time_log(message, i=0, max_num=0, s_time=None)
210
+
211
+ - **参数**:
212
+ - `message`: 日志消息
213
+ - `i`: 当前进度(从0开始),默认为0
214
+ - `max_num`: 总进度数量,默认为0
215
+ - `s_time`: 开始时间,用于计算预计完成时间,默认为None
216
+ - **返回值**: 无
217
+ - **功能**: 打印带时间戳的日志信息,支持进度显示和预计完成时间计算
218
+
219
+ #### time_diff(s_time=None, max_num=0, language="cn")
220
+
221
+ - **参数**:
222
+ - `s_time`: 开始时间,默认为None
223
+ - `max_num`: 任务数量,默认为0
224
+ - `language`: 语言选择("cn"中文,其他为英文),默认为"cn"
225
+ - **返回值**: 如果s_time为None则返回当前时间,否则返回None
226
+ - **功能**: 计算并打印任务执行时间统计信息,支持中英文双语输出
227
+
228
+ ### funcguard.printer
229
+
230
+ #### print_line(separator_char: str = "-", separator_length: int = 40) -> None
231
+
232
+ - **参数**:
233
+ - `separator_char`: 分隔符字符,默认为'-'
234
+ - `separator_length`: 分隔符长度,默认为40
235
+ - **返回值**: 无
236
+ - **功能**: 打印分隔线,用于分隔不同的打印块
237
+
238
+ #### print_block(title: str, content: Any, separator_char: str = "-", separator_length: int = 40) -> None
239
+
240
+ - **参数**:
241
+ - `title`: 标题
242
+ - `content`: 打印的内容
243
+ - `separator_char`: 分隔符字符,默认为'-'
244
+ - `separator_length`: 分隔符长度,默认为40
245
+ - **返回值**: 无
246
+ - **功能**: 使用分隔符打印标题和内容,便于查看
247
+
154
248
  ## 许可证
155
249
 
156
250
  MIT License
@@ -7,13 +7,11 @@ FuncGuard是一个Python库,提供了函数执行超时控制和重试机制
7
7
  - 函数执行超时控制
8
8
  - 函数执行失败自动重试
9
9
  - HTTP请求封装(支持自动重试)
10
+ - 格式化打印工具(分隔线和块打印)
11
+ - 时间日志记录和耗时统计
10
12
 
11
13
  ## 安装/升级
12
14
 
13
- ```bash
14
- pip install funcguard
15
- ```
16
-
17
15
  ```bash
18
16
  pip install --upgrade funcguard
19
17
  ```
@@ -26,7 +24,7 @@ pip install --upgrade funcguard
26
24
  使用`timeout_handler`函数可以控制函数的执行时间,防止函数运行时间过长:
27
25
 
28
26
  ```python
29
- from funcguard.core import timeout_handler
27
+ from funcguard import timeout_handler
30
28
 
31
29
  def long_running_function():
32
30
  # 模拟一个耗时操作
@@ -47,7 +45,7 @@ except TimeoutError as e:
47
45
  使用`retry_function`函数可以在函数执行失败时自动重试:
48
46
 
49
47
  ```python
50
- from funcguard.core import retry_function
48
+ from funcguard import retry_function
51
49
 
52
50
  def unstable_function():
53
51
  # 模拟一个可能失败的操作
@@ -69,7 +67,7 @@ except Exception as e:
69
67
  使用`send_request`函数发送HTTP请求,支持自动重试:
70
68
 
71
69
  ```python
72
- from funcguard.tools import send_request
70
+ from funcguard import send_request
73
71
 
74
72
  # 不使用重试
75
73
  response = send_request(
@@ -96,6 +94,63 @@ response = send_request(
96
94
  print(response)
97
95
  ```
98
96
 
97
+ ### 格式化打印
98
+
99
+ 使用`print_line`和`print_block`函数进行格式化打印,便于查看和调试:
100
+
101
+ ```python
102
+ from funcguard import print_line, print_block
103
+
104
+ # 打印分隔线
105
+ print_line() # 默认使用40个'-'字符
106
+ print_line("*", 30) # 使用30个'*'字符
107
+
108
+ # 打印块内容
109
+ print_block("用户信息", {"name": "张三", "age": 25})
110
+
111
+ # 自定义分隔符
112
+ print_block("配置信息", {"debug": True, "port": 8080}, "=", 50)
113
+
114
+ # 打印复杂内容
115
+ result = {
116
+ "status": "success",
117
+ "data": [1, 2, 3, 4, 5],
118
+ "message": "操作完成"
119
+ }
120
+ print_block("API响应", result)
121
+ ```
122
+
123
+ ### 时间日志记录
124
+
125
+ 使用`time_log`和`time_diff`函数记录任务执行时间和统计信息:
126
+
127
+ ```python
128
+ from funcguard import time_log, time_diff
129
+
130
+ # 获取开始时间
131
+ start_time = time_diff()
132
+
133
+ # 记录任务开始
134
+ time_log("开始处理数据", 0, 100, start_time)
135
+
136
+ # 模拟处理过程
137
+ import time
138
+ for i in range(1, 101):
139
+ time.sleep(0.1) # 模拟处理时间
140
+ if i % 20 == 0:
141
+ time_log(f"处理进度", i, 100, start_time) # 显示进度和预计完成时间
142
+
143
+ # 记录任务完成并打印统计信息
144
+ time_log("数据处理完成", 100, 100, start_time)
145
+ time_diff(start_time, 100, "cn") # 中文显示统计信息
146
+ ```
147
+
148
+ 时间日志功能特点:
149
+ - 自动显示北京时间(UTC+8)
150
+ - 支持进度显示和预计完成时间计算
151
+ - 提供中英文双语统计信息
152
+ - 可显示总耗时、平均耗时等详细统计
153
+
99
154
  ## API文档
100
155
 
101
156
  ### funcguard.core
@@ -137,6 +192,45 @@ print(response)
137
192
  - **返回值**: 根据return_type参数返回不同格式的响应数据
138
193
  - **异常**: 当请求失败且重试次数用尽后,抛出相应的异常
139
194
 
195
+ #### time_log(message, i=0, max_num=0, s_time=None)
196
+
197
+ - **参数**:
198
+ - `message`: 日志消息
199
+ - `i`: 当前进度(从0开始),默认为0
200
+ - `max_num`: 总进度数量,默认为0
201
+ - `s_time`: 开始时间,用于计算预计完成时间,默认为None
202
+ - **返回值**: 无
203
+ - **功能**: 打印带时间戳的日志信息,支持进度显示和预计完成时间计算
204
+
205
+ #### time_diff(s_time=None, max_num=0, language="cn")
206
+
207
+ - **参数**:
208
+ - `s_time`: 开始时间,默认为None
209
+ - `max_num`: 任务数量,默认为0
210
+ - `language`: 语言选择("cn"中文,其他为英文),默认为"cn"
211
+ - **返回值**: 如果s_time为None则返回当前时间,否则返回None
212
+ - **功能**: 计算并打印任务执行时间统计信息,支持中英文双语输出
213
+
214
+ ### funcguard.printer
215
+
216
+ #### print_line(separator_char: str = "-", separator_length: int = 40) -> None
217
+
218
+ - **参数**:
219
+ - `separator_char`: 分隔符字符,默认为'-'
220
+ - `separator_length`: 分隔符长度,默认为40
221
+ - **返回值**: 无
222
+ - **功能**: 打印分隔线,用于分隔不同的打印块
223
+
224
+ #### print_block(title: str, content: Any, separator_char: str = "-", separator_length: int = 40) -> None
225
+
226
+ - **参数**:
227
+ - `title`: 标题
228
+ - `content`: 打印的内容
229
+ - `separator_char`: 分隔符字符,默认为'-'
230
+ - `separator_length`: 分隔符长度,默认为40
231
+ - **返回值**: 无
232
+ - **功能**: 使用分隔符打印标题和内容,便于查看
233
+
140
234
  ## 许可证
141
235
 
142
236
  MIT License
@@ -0,0 +1,16 @@
1
+ from .core import timeout_handler, retry_function
2
+ from .tools import send_request, time_log, time_diff
3
+ from .printer import print_block, print_line
4
+
5
+ __author__ = "ruocen"
6
+
7
+ # 暴露主要接口
8
+ __all__ = [
9
+ "timeout_handler",
10
+ "retry_function",
11
+ "send_request",
12
+ "time_log",
13
+ "time_diff",
14
+ "print_block",
15
+ "print_line",
16
+ ]
@@ -1,4 +1,11 @@
1
1
  class FuncguardTimeoutError(Exception):
2
+ """
3
+ funcguard库专用的超时异常类。
4
+
5
+ 为了避免与concurrent.futures.TimeoutError和Python内置TimeoutError的命名冲突,
6
+ 特定义此异常类来明确表示这是funcguard库抛出的函数执行超时异常。
7
+ 这样用户可以清晰地区分异常来源,并进行针对性的异常处理。
8
+ """
2
9
  pass
3
10
 
4
11
  import time
@@ -55,7 +62,7 @@ def retry_function( func , max_retries = 5 , execute_timeout = 90 , task_name =
55
62
  result = timeout_handler( func , args = args , kwargs = kwargs , execution_timeout = current_timeout )
56
63
  return result # 如果调用成功,则返回结果
57
64
 
58
- except BaseException as e :
65
+ except Exception as e :
59
66
  last_exception = e
60
67
  retry_count += 1
61
68
  print( e )
@@ -0,0 +1,32 @@
1
+ from typing import Any
2
+
3
+ # 打印分隔线
4
+ def print_line(separator_char: str = "-", separator_length: int = 40) -> None:
5
+ """
6
+ 打印分隔线,用于分隔不同的打印块
7
+
8
+ :param separator_char: 分隔符字符,默认为'-'
9
+ :param separator_length: 分隔符长度,默认为40
10
+ """
11
+ separator = separator_char * separator_length
12
+ print(separator)
13
+
14
+
15
+ # 块打印
16
+ def print_block(title: str, content: Any, separator_char: str = "-", separator_length: int = 40) -> None:
17
+ """
18
+ 使用分隔符打印标题和内容,便于查看
19
+
20
+ :param title: 标题
21
+ :param content: 打印的内容
22
+ :param separator_char: 分隔符字符,默认为'-'
23
+ :param separator_length: 分隔符长度,默认为40
24
+ """
25
+ print_line(separator_char, separator_length)
26
+
27
+ if title:
28
+ print(f"{title} :")
29
+ print(content)
30
+
31
+ print_line(separator_char, separator_length)
32
+ # print() # 添加一个空行便于阅读
@@ -0,0 +1,147 @@
1
+ import json
2
+ import requests
3
+ from datetime import datetime, timezone, timedelta
4
+ from typing import Optional, Dict, Any, Union
5
+ from .core import retry_function
6
+
7
+
8
+ # 发起请求
9
+ def send_request(
10
+ method: str,
11
+ url: str,
12
+ headers: Dict[str, str],
13
+ data: Optional[Any] = None,
14
+ return_type: str = "json",
15
+ timeout: int = 60,
16
+ auto_retry: Optional[Dict[str, Any]] = None,
17
+ ) -> Union[Dict, str, requests.Response]:
18
+ """
19
+ 发送HTTP请求的通用函数
20
+
21
+ :param method: HTTP方法(GET, POST等)
22
+ :param url: 请求URL
23
+ :param headers: 请求头
24
+ :param data: 请求数据
25
+ :param return_type: 返回类型(json, text, response)
26
+ :param timeout: 请求超时时间
27
+ :param auto_retry: 自动重试配置,格式为:
28
+ {"task_name": "任务名称", "max_retries": 最大重试次数, "execute_timeout": 执行超时时间}
29
+ :return: 请求结果
30
+ """
31
+ if data is None:
32
+ payload = {}
33
+ else:
34
+ if (isinstance(data, dict) or isinstance(data, list)) and data != {}:
35
+ payload = json.dumps(data, ensure_ascii=False)
36
+ else:
37
+ payload = data
38
+ if auto_retry is None:
39
+ response = requests.request(
40
+ method, url, headers=headers, data=payload, timeout=timeout
41
+ )
42
+ else:
43
+ max_retries = auto_retry.get("max_retries", 5)
44
+ execute_timeout = auto_retry.get("execute_timeout", 90)
45
+ task_name = auto_retry.get("task_name", "")
46
+ response = retry_function(
47
+ requests.request,
48
+ max_retries,
49
+ execute_timeout,
50
+ task_name,
51
+ method,
52
+ url,
53
+ headers=headers,
54
+ data=payload,
55
+ timeout=timeout,
56
+ )
57
+
58
+ if response is None:
59
+ raise ValueError("请求返回的响应为None")
60
+
61
+ if return_type == "json":
62
+ result = response.json()
63
+ elif return_type == "response":
64
+ return response
65
+ else:
66
+ result = response.text
67
+ return result
68
+
69
+
70
+ # 打印时间
71
+ def time_log(message, i = 0, max_num = 0, s_time = None) :
72
+ """
73
+ 打印带时间戳的日志信息,支持进度显示和预计完成时间
74
+
75
+ :param message: 日志消息
76
+ :param i: 当前进度(从0开始)
77
+ :param max_num: 总进度数量
78
+ :param s_time: 开始时间,用于计算预计完成时间
79
+ :return: None
80
+ """
81
+ now = datetime.now( timezone( timedelta( hours = 8 ) ) )
82
+ time_log = "{:02d}:{:02d}:{:02d}".format( now.hour, now.minute, now.second )
83
+ if i < 2 :
84
+ print( time_log + " " + message )
85
+ else :
86
+ if max_num == 0 :
87
+ text = "{}".format( i )
88
+ else :
89
+ text = "{}/{}".format( i, max_num )
90
+ # 检查是否应该显示预计完成时间和剩余时间
91
+ if i % 10 == 0 and s_time is not None and i < max_num :
92
+ duration = now - s_time
93
+ ev_duration = duration / i # 每项平均耗时
94
+ remaining_items = max_num - i
95
+ time_left = ev_duration * remaining_items
96
+ end_time = now + time_left
97
+ end_time_str = end_time.strftime( "%Y-%m-%d %H:%M" )
98
+ remaining_time_str = str( timedelta( seconds = int( time_left.total_seconds() ) ) )
99
+ text = text + "({})etr {}".format( end_time_str, remaining_time_str )
100
+ print( time_log + " " + message + " " + text )
101
+ return
102
+
103
+
104
+ # 计算持续时间
105
+ def time_diff(s_time = None, max_num = 0, language = "cn") :
106
+ """
107
+ 计算并打印任务执行时间统计信息
108
+
109
+ :param s_time: 开始时间
110
+ :param max_num: 任务数量
111
+ :param language: 语言选择("cn"中文,其他为英文)
112
+ :return: 如果s_time为None则返回当前时间,否则返回None
113
+ """
114
+ # 获取当前时间并转换为北京时间
115
+ now = datetime.now( timezone( timedelta( hours = 8 ) ) )
116
+
117
+ if s_time is None :
118
+ return now
119
+
120
+ e_time = now
121
+ duration = e_time - s_time
122
+ hours = duration.seconds // 3600
123
+ duration_minutes = (duration.seconds % 3600) // 60
124
+ seconds = duration.seconds % 60
125
+ result = f"{hours:02d}:{duration_minutes:02d}:{seconds:02d}"
126
+
127
+ # 将时间差转化为分钟
128
+ minutes = round( duration.total_seconds() / 60 )
129
+ if max_num == 0 :
130
+ if language == "cn" :
131
+ print( "总耗时:{}".format( result ) )
132
+ else :
133
+ print( "Total time: {}".format( result ) )
134
+ else :
135
+ eve_minutes = round( minutes / max_num, 3 )
136
+ if language == "cn" :
137
+ print( "开始时间:{},结束时间:{}".format( s_time.strftime( "%Y-%m-%d %H:%M" ),
138
+ e_time.strftime( "%Y-%m-%d %H:%M" ) ) )
139
+ print( "总耗时:{},累计:{}分钟,数量;{},平均耗时:{}分钟".format( result, minutes, max_num, eve_minutes ) )
140
+ else :
141
+ print( "Start time:{},End time:{}".format( s_time.strftime( "%Y-%m-%d %H:%M" ),
142
+ e_time.strftime( "%Y-%m-%d %H:%M" ) ) )
143
+ print( "Total time: {},Total minutes: {},Number: {},Average time: {} minutes".format( result, minutes,
144
+ max_num,
145
+ eve_minutes ) )
146
+
147
+ return
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: funcguard
3
- Version: 0.1.1
3
+ Version: 0.1.4
4
4
  Summary: A funcguard for Python.
5
5
  Home-page: https://github.com/tinycen/funcguard
6
6
  Author: tinycen
@@ -21,13 +21,11 @@ FuncGuard是一个Python库,提供了函数执行超时控制和重试机制
21
21
  - 函数执行超时控制
22
22
  - 函数执行失败自动重试
23
23
  - HTTP请求封装(支持自动重试)
24
+ - 格式化打印工具(分隔线和块打印)
25
+ - 时间日志记录和耗时统计
24
26
 
25
27
  ## 安装/升级
26
28
 
27
- ```bash
28
- pip install funcguard
29
- ```
30
-
31
29
  ```bash
32
30
  pip install --upgrade funcguard
33
31
  ```
@@ -40,7 +38,7 @@ pip install --upgrade funcguard
40
38
  使用`timeout_handler`函数可以控制函数的执行时间,防止函数运行时间过长:
41
39
 
42
40
  ```python
43
- from funcguard.core import timeout_handler
41
+ from funcguard import timeout_handler
44
42
 
45
43
  def long_running_function():
46
44
  # 模拟一个耗时操作
@@ -61,7 +59,7 @@ except TimeoutError as e:
61
59
  使用`retry_function`函数可以在函数执行失败时自动重试:
62
60
 
63
61
  ```python
64
- from funcguard.core import retry_function
62
+ from funcguard import retry_function
65
63
 
66
64
  def unstable_function():
67
65
  # 模拟一个可能失败的操作
@@ -83,7 +81,7 @@ except Exception as e:
83
81
  使用`send_request`函数发送HTTP请求,支持自动重试:
84
82
 
85
83
  ```python
86
- from funcguard.tools import send_request
84
+ from funcguard import send_request
87
85
 
88
86
  # 不使用重试
89
87
  response = send_request(
@@ -110,6 +108,63 @@ response = send_request(
110
108
  print(response)
111
109
  ```
112
110
 
111
+ ### 格式化打印
112
+
113
+ 使用`print_line`和`print_block`函数进行格式化打印,便于查看和调试:
114
+
115
+ ```python
116
+ from funcguard import print_line, print_block
117
+
118
+ # 打印分隔线
119
+ print_line() # 默认使用40个'-'字符
120
+ print_line("*", 30) # 使用30个'*'字符
121
+
122
+ # 打印块内容
123
+ print_block("用户信息", {"name": "张三", "age": 25})
124
+
125
+ # 自定义分隔符
126
+ print_block("配置信息", {"debug": True, "port": 8080}, "=", 50)
127
+
128
+ # 打印复杂内容
129
+ result = {
130
+ "status": "success",
131
+ "data": [1, 2, 3, 4, 5],
132
+ "message": "操作完成"
133
+ }
134
+ print_block("API响应", result)
135
+ ```
136
+
137
+ ### 时间日志记录
138
+
139
+ 使用`time_log`和`time_diff`函数记录任务执行时间和统计信息:
140
+
141
+ ```python
142
+ from funcguard import time_log, time_diff
143
+
144
+ # 获取开始时间
145
+ start_time = time_diff()
146
+
147
+ # 记录任务开始
148
+ time_log("开始处理数据", 0, 100, start_time)
149
+
150
+ # 模拟处理过程
151
+ import time
152
+ for i in range(1, 101):
153
+ time.sleep(0.1) # 模拟处理时间
154
+ if i % 20 == 0:
155
+ time_log(f"处理进度", i, 100, start_time) # 显示进度和预计完成时间
156
+
157
+ # 记录任务完成并打印统计信息
158
+ time_log("数据处理完成", 100, 100, start_time)
159
+ time_diff(start_time, 100, "cn") # 中文显示统计信息
160
+ ```
161
+
162
+ 时间日志功能特点:
163
+ - 自动显示北京时间(UTC+8)
164
+ - 支持进度显示和预计完成时间计算
165
+ - 提供中英文双语统计信息
166
+ - 可显示总耗时、平均耗时等详细统计
167
+
113
168
  ## API文档
114
169
 
115
170
  ### funcguard.core
@@ -151,6 +206,45 @@ print(response)
151
206
  - **返回值**: 根据return_type参数返回不同格式的响应数据
152
207
  - **异常**: 当请求失败且重试次数用尽后,抛出相应的异常
153
208
 
209
+ #### time_log(message, i=0, max_num=0, s_time=None)
210
+
211
+ - **参数**:
212
+ - `message`: 日志消息
213
+ - `i`: 当前进度(从0开始),默认为0
214
+ - `max_num`: 总进度数量,默认为0
215
+ - `s_time`: 开始时间,用于计算预计完成时间,默认为None
216
+ - **返回值**: 无
217
+ - **功能**: 打印带时间戳的日志信息,支持进度显示和预计完成时间计算
218
+
219
+ #### time_diff(s_time=None, max_num=0, language="cn")
220
+
221
+ - **参数**:
222
+ - `s_time`: 开始时间,默认为None
223
+ - `max_num`: 任务数量,默认为0
224
+ - `language`: 语言选择("cn"中文,其他为英文),默认为"cn"
225
+ - **返回值**: 如果s_time为None则返回当前时间,否则返回None
226
+ - **功能**: 计算并打印任务执行时间统计信息,支持中英文双语输出
227
+
228
+ ### funcguard.printer
229
+
230
+ #### print_line(separator_char: str = "-", separator_length: int = 40) -> None
231
+
232
+ - **参数**:
233
+ - `separator_char`: 分隔符字符,默认为'-'
234
+ - `separator_length`: 分隔符长度,默认为40
235
+ - **返回值**: 无
236
+ - **功能**: 打印分隔线,用于分隔不同的打印块
237
+
238
+ #### print_block(title: str, content: Any, separator_char: str = "-", separator_length: int = 40) -> None
239
+
240
+ - **参数**:
241
+ - `title`: 标题
242
+ - `content`: 打印的内容
243
+ - `separator_char`: 分隔符字符,默认为'-'
244
+ - `separator_length`: 分隔符长度,默认为40
245
+ - **返回值**: 无
246
+ - **功能**: 使用分隔符打印标题和内容,便于查看
247
+
154
248
  ## 许可证
155
249
 
156
250
  MIT License
@@ -3,6 +3,7 @@ README.md
3
3
  setup.py
4
4
  funcguard/__init__.py
5
5
  funcguard/core.py
6
+ funcguard/printer.py
6
7
  funcguard/tools.py
7
8
  funcguard.egg-info/PKG-INFO
8
9
  funcguard.egg-info/SOURCES.txt
@@ -9,7 +9,7 @@ except FileNotFoundError:
9
9
 
10
10
  setup(
11
11
  name='funcguard',
12
- version='0.1.1',
12
+ version='0.1.4',
13
13
  packages=find_packages(),
14
14
  install_requires=[
15
15
  'requests',
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  import unittest
3
3
  from unittest.mock import patch, MagicMock
4
+ from typing import Any, Optional, Dict
4
5
  import requests
5
6
 
6
7
  from funcguard.tools import send_request
@@ -9,12 +10,16 @@ from funcguard.tools import send_request
9
10
  class MockResponse:
10
11
  """模拟requests响应"""
11
12
 
12
- def __init__(self, json_data=None, text="", status_code=200):
13
+ json_data: Dict[str, Any]
14
+ text: str
15
+ status_code: int
16
+
17
+ def __init__(self, json_data: Optional[Dict[str, Any]] = None, text: str = "", status_code: int = 200):
13
18
  self.json_data = json_data or {}
14
19
  self.text = text
15
20
  self.status_code = status_code
16
21
 
17
- def json(self):
22
+ def json(self) -> Dict[str, Any]:
18
23
  return self.json_data
19
24
 
20
25
 
@@ -97,7 +102,7 @@ class TestSendRequest(unittest.TestCase):
97
102
 
98
103
  mock_request.assert_called_once()
99
104
 
100
- @patch('funcguard.core.retry_function')
105
+ @patch('funcguard.tools.retry_function')
101
106
  @patch('requests.request')
102
107
  def test_auto_retry_enabled(self, mock_request, mock_retry):
103
108
  """测试启用自动重试"""
@@ -117,12 +122,16 @@ class TestSendRequest(unittest.TestCase):
117
122
  }
118
123
  )
119
124
 
120
- # 验证结果
121
- if hasattr(result, 'json_data'):
122
- # 如果result是MockResponse对象,直接比较其json_data
123
- self.assertEqual(result.json_data, {"success": True})
125
+ # 验证结果 - 使用更安全的方式处理可能的类型差异
126
+ if isinstance(result, dict):
127
+ # 如果result是字典(JSON解析结果)
128
+ self.assertEqual(result, {"success": True})
129
+ elif hasattr(result, 'json_data'):
130
+ # 如果result是MockResponse对象,使用getattr避免类型检查错误
131
+ json_data = getattr(result, 'json_data')
132
+ self.assertEqual(json_data, {"success": True})
124
133
  else:
125
- # 否则直接比较result
134
+ # 其他情况,直接比较
126
135
  self.assertEqual(result, {"success": True})
127
136
  mock_retry.assert_called_once()
128
137
 
@@ -1,7 +0,0 @@
1
- from .core import timeout_handler, retry_function
2
- from .tools import send_request
3
-
4
- __author__ = "ruocen"
5
-
6
- # 暴露主要接口
7
- __all__ = ["timeout_handler", "retry_function","send_request"]
@@ -1,46 +0,0 @@
1
- import json
2
- import requests
3
- from . import core
4
- # 使用 from .core import retry_function 会导致测试失败
5
-
6
- # 发起请求
7
- def send_request( method , url , headers , data = None , return_type = "json" , timeout = 60 , auto_retry = None ) :
8
- '''
9
- 发送HTTP请求的通用函数
10
-
11
- :param method: HTTP方法(GET, POST等)
12
- :param url: 请求URL
13
- :param headers: 请求头
14
- :param data: 请求数据
15
- :param return_type: 返回类型(json, text, response)
16
- :param timeout: 请求超时时间
17
- :param auto_retry: 自动重试配置,格式为:
18
- {"task_name": "任务名称", "max_retries": 最大重试次数, "execute_timeout": 执行超时时间}
19
- :return: 请求结果
20
- '''
21
- if data is None :
22
- payload = { }
23
- else :
24
- if (isinstance( data , dict ) or isinstance( data , list )) and data != { } :
25
- payload = json.dumps( data , ensure_ascii = False )
26
- else :
27
- payload = data
28
- if auto_retry is None :
29
- response = requests.request( method , url , headers = headers , data = payload , timeout = timeout )
30
- else :
31
- max_retries = auto_retry.get( "max_retries" , 5 )
32
- execute_timeout = auto_retry.get( "execute_timeout" , 90 )
33
- task_name = auto_retry.get( "task_name" , "" )
34
- response = core.retry_function( requests.request , max_retries , execute_timeout , task_name , method , url ,
35
- headers = headers , data = payload , timeout = timeout )
36
-
37
- if response is None:
38
- raise ValueError("请求返回的响应为None")
39
-
40
- if return_type == "json" :
41
- result = response.json()
42
- elif return_type == "response" :
43
- return response
44
- else :
45
- result = response.text
46
- return result
File without changes
File without changes
File without changes
File without changes
File without changes