kaq-quant-common 0.2.12__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.
Files changed (67) hide show
  1. kaq_quant_common/__init__.py +0 -0
  2. kaq_quant_common/api/__init__.py +0 -0
  3. kaq_quant_common/api/common/__init__.py +1 -0
  4. kaq_quant_common/api/common/api_interface.py +38 -0
  5. kaq_quant_common/api/common/auth.py +118 -0
  6. kaq_quant_common/api/rest/__init__.py +0 -0
  7. kaq_quant_common/api/rest/api_client_base.py +42 -0
  8. kaq_quant_common/api/rest/api_server_base.py +135 -0
  9. kaq_quant_common/api/rest/instruction/helper/order_helper.py +342 -0
  10. kaq_quant_common/api/rest/instruction/instruction_client.py +86 -0
  11. kaq_quant_common/api/rest/instruction/instruction_server_base.py +154 -0
  12. kaq_quant_common/api/rest/instruction/models/__init__.py +17 -0
  13. kaq_quant_common/api/rest/instruction/models/account.py +49 -0
  14. kaq_quant_common/api/rest/instruction/models/order.py +248 -0
  15. kaq_quant_common/api/rest/instruction/models/position.py +70 -0
  16. kaq_quant_common/api/rest/instruction/models/transfer.py +32 -0
  17. kaq_quant_common/api/ws/__init__.py +0 -0
  18. kaq_quant_common/api/ws/exchange/models.py +23 -0
  19. kaq_quant_common/api/ws/exchange/ws_exchange_client.py +31 -0
  20. kaq_quant_common/api/ws/exchange/ws_exchange_server.py +440 -0
  21. kaq_quant_common/api/ws/instruction/__init__.py +0 -0
  22. kaq_quant_common/api/ws/instruction/ws_instruction_client.py +82 -0
  23. kaq_quant_common/api/ws/instruction/ws_instruction_server_base.py +139 -0
  24. kaq_quant_common/api/ws/models.py +46 -0
  25. kaq_quant_common/api/ws/ws_client_base.py +235 -0
  26. kaq_quant_common/api/ws/ws_server_base.py +288 -0
  27. kaq_quant_common/common/__init__.py +0 -0
  28. kaq_quant_common/common/ddb_table_monitor.py +106 -0
  29. kaq_quant_common/common/http_monitor.py +69 -0
  30. kaq_quant_common/common/modules/funding_rate_helper.py +137 -0
  31. kaq_quant_common/common/modules/limit_order_helper.py +158 -0
  32. kaq_quant_common/common/modules/limit_order_symbol_monitor.py +76 -0
  33. kaq_quant_common/common/modules/limit_order_symbol_monitor_group.py +69 -0
  34. kaq_quant_common/common/monitor_base.py +84 -0
  35. kaq_quant_common/common/monitor_group.py +97 -0
  36. kaq_quant_common/common/redis_table_monitor.py +123 -0
  37. kaq_quant_common/common/statistics/funding_rate_history_statistics.py +208 -0
  38. kaq_quant_common/common/statistics/kline_history_statistics.py +211 -0
  39. kaq_quant_common/common/ws_wrapper.py +21 -0
  40. kaq_quant_common/config/config.yaml +5 -0
  41. kaq_quant_common/resources/__init__.py +0 -0
  42. kaq_quant_common/resources/kaq_ddb_pool_stream_read_resources.py +56 -0
  43. kaq_quant_common/resources/kaq_ddb_stream_init_resources.py +88 -0
  44. kaq_quant_common/resources/kaq_ddb_stream_read_resources.py +81 -0
  45. kaq_quant_common/resources/kaq_ddb_stream_write_resources.py +359 -0
  46. kaq_quant_common/resources/kaq_mysql_init_resources.py +23 -0
  47. kaq_quant_common/resources/kaq_mysql_resources.py +341 -0
  48. kaq_quant_common/resources/kaq_postgresql_resources.py +58 -0
  49. kaq_quant_common/resources/kaq_quant_hive_resources.py +107 -0
  50. kaq_quant_common/resources/kaq_redis_resources.py +117 -0
  51. kaq_quant_common/utils/__init__.py +0 -0
  52. kaq_quant_common/utils/dagster_job_check_utils.py +29 -0
  53. kaq_quant_common/utils/dagster_utils.py +19 -0
  54. kaq_quant_common/utils/date_util.py +204 -0
  55. kaq_quant_common/utils/enums_utils.py +79 -0
  56. kaq_quant_common/utils/error_utils.py +22 -0
  57. kaq_quant_common/utils/hash_utils.py +48 -0
  58. kaq_quant_common/utils/log_time_utils.py +32 -0
  59. kaq_quant_common/utils/logger_utils.py +97 -0
  60. kaq_quant_common/utils/mytt_utils.py +372 -0
  61. kaq_quant_common/utils/signal_utils.py +23 -0
  62. kaq_quant_common/utils/sqlite_utils.py +169 -0
  63. kaq_quant_common/utils/uuid_utils.py +5 -0
  64. kaq_quant_common/utils/yml_utils.py +148 -0
  65. kaq_quant_common-0.2.12.dist-info/METADATA +66 -0
  66. kaq_quant_common-0.2.12.dist-info/RECORD +67 -0
  67. kaq_quant_common-0.2.12.dist-info/WHEEL +4 -0
@@ -0,0 +1,204 @@
1
+ import time as new_time
2
+ from datetime import datetime, time, timedelta, timezone
3
+ from loguru import logger
4
+
5
+ yymmdd = '%Y-%m-%d'
6
+ yymmdd_hhmm = '%Y-%m-%d %H:%M'
7
+ yymmdd_hhmmss = '%Y-%m-%d %H:%M:%S'
8
+ yymmdd_hhmmss_long = '%Y%m%d%H%M%S'
9
+ yymm = '%Y%m'
10
+ yy = '%Y'
11
+ yyweek = '%Y%W'
12
+
13
+ morning_start = time(9, 30, 0)
14
+ morning_end = time(11, 30, 0)
15
+ afternoon_start = time(13, 0, 0)
16
+ afternoon_end = time(15, 0, 0)
17
+
18
+ def get_day_year(_datetime : datetime=None):
19
+ '''
20
+ @param: datetime类型
21
+ 获取日期是一年中的第几天
22
+ '''
23
+ try:
24
+ # 获取当前日期
25
+ today = datetime.today()
26
+ if _datetime is not None:
27
+ today = _datetime
28
+ # 获取当前日期是一年中的第几天
29
+ year = today.timetuple().tm_year
30
+ mon = today.timetuple().tm_mon
31
+ day_of_year = today.timetuple().tm_yday
32
+ return year, mon, day_of_year
33
+ except Exception as e:
34
+ logger.error(f'【date_util.get_day_year】异常, - {str(e)}')
35
+
36
+ def get_week_year(_datetime : datetime=None):
37
+ '''
38
+ @param: datetime类型
39
+ 获取日期是一年中的第几周
40
+ '''
41
+ try:
42
+ # 获取当前日期
43
+ today = datetime.today()
44
+ if _datetime is not None:
45
+ today = _datetime
46
+ # 获取当前日期是一年中的第几周
47
+ # today = datetime.date.today()
48
+ # 使用isocalendar()方法获取年、周数和周内日期
49
+ isocalendar = today.isocalendar()
50
+ # year_week 是一个包含三个元素的元组:年、周数、周内日期
51
+ return isocalendar.year, isocalendar.week
52
+ except Exception as e:
53
+ logger.error(f'【date_util.get_week_year】异常, - {str(e)}')
54
+
55
+ def get_week_year_by_timestamp(timestamp: int=datetime.now().timestamp()):
56
+ if len(str(timestamp)) == 13:
57
+ timestamp = timestamp / 1000
58
+ _date = datetime.fromtimestamp(timestamp)
59
+ return get_week_year(_date)
60
+
61
+ def get_mon_year(_datetime : datetime=None):
62
+ '''
63
+ @param: datetime类型
64
+ 获取日期是一年中的第几月
65
+ '''
66
+ try:
67
+ # 获取当前日期
68
+ today = datetime.today()
69
+ if _datetime is not None:
70
+ today = _datetime
71
+ return today.year, today.month
72
+ except Exception as e:
73
+ logger.error(f'【date_util.get_week_year】异常, - {str(e)}')
74
+
75
+ def get_mon_year_by_timestamp(timestamp : int=datetime.now().timestamp()):
76
+ '''
77
+ @param: datetime类型
78
+ 获取日期是一年中的第几月
79
+ '''
80
+ if len(str(timestamp)) == 13:
81
+ timestamp = timestamp / 1000
82
+ _date = datetime.fromtimestamp(timestamp)
83
+ return get_mon_year(_date)
84
+
85
+ def get_timezone_utc_timestamp_ms():
86
+ '''
87
+ 获取utc时区时间戳数据
88
+ '''
89
+ utc_now = datetime.now(timezone.utc)
90
+ utc_now = datetime(utc_now.year, utc_now.month, utc_now.day, utc_now.hour, utc_now.minute, utc_now.second, utc_now.microsecond)
91
+ return int(utc_now.timestamp()) * 1000
92
+
93
+ def get_time_zone_diff():
94
+ '''
95
+ 获取与utc的时区差值
96
+ '''
97
+ utc_now = datetime.now(timezone.utc)
98
+ now = datetime.now()
99
+ utc_now = datetime(utc_now.year, utc_now.month, utc_now.day, utc_now.hour, utc_now.minute, utc_now.second, utc_now.microsecond)
100
+ now = datetime(now.year, now.month, now.day, now.hour, now.minute, now.second, now.microsecond)
101
+ diff = int(now.timestamp() - utc_now.timestamp())
102
+ return diff
103
+
104
+ def get_time_zone_diff_ms():
105
+
106
+ return get_time_zone_diff() * 1000
107
+
108
+ def day2str(day, format_str='%Y-%m-%d'):
109
+ return datetime.strftime(day, format_str)
110
+
111
+
112
+ def str2day(day_str, format_str='%Y-%m-%d'):
113
+ return datetime.strptime(day_str, format_str)
114
+
115
+
116
+ def str2timestampe(day_str, format_str='%Y-%m-%d %H:%M:%S'):
117
+ dateTime = new_time.strptime(day_str, format_str)
118
+ timestampe = new_time.mktime(dateTime)
119
+ return int(timestampe)
120
+
121
+
122
+ def time2date(time_float):
123
+ time_float = int(time_float)
124
+ return str2day(str(time_float), yymmdd_hhmmss)
125
+
126
+
127
+ def date2time(date):
128
+ return float(day2str(date, yymmdd_hhmmss_long) + '000')
129
+
130
+
131
+ def get_detail_time(_datetime=datetime.today(), hour=0, minute=0, second=0):
132
+ # 获取任意时刻的时间戳
133
+ today_0 = _datetime - timedelta(hours=_datetime.hour, minutes=_datetime.minute, seconds=_datetime.second)
134
+ today_anytime = today_0 + timedelta(hours=hour, minutes=minute, seconds=second)
135
+ # tsp = today_anytime.timestamp()
136
+ # print('{} 的时间戳是 {}'.format(today_anytime, tsp))
137
+ return today_anytime
138
+
139
+
140
+ def get_datestr_start(date):
141
+ timestampe = str2timestampe(date, yymmdd)
142
+ start_date = datetime.fromtimestamp(timestampe)
143
+ ago = get_detail_time(start_date, 0, 0)
144
+ return int(ago.timestamp())
145
+
146
+
147
+ def get_before_now(now, days=0, seconds=0, minutes=0, hours=0, format=yymmdd_hhmmss):
148
+ # 当前时间往前推30天
149
+ ago = now - timedelta(days=days, seconds=seconds, minutes=minutes, hours=hours)
150
+ return ago.strftime(format)
151
+
152
+
153
+ def get_aftertime(n:int=0): # 精确到分钟
154
+ """
155
+ 获取当前时间往后的时间
156
+ :param n: 当前时间后的n分钟
157
+ :return: 返回当前时间后的时间,精确当分钟
158
+ """
159
+ nowtime = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 获取当前时间
160
+ # 将当前时间转换为时间数组
161
+ timeArray1= new_time.strptime(nowtime, "%Y-%m-%d %H:%M:%S")
162
+ print(timeArray1)
163
+ # 将时间转换为时间戳:
164
+ timeStamp = int(new_time.mktime(timeArray1))
165
+ print(timeStamp)
166
+ # 在原来时间戳的基础上加n*60
167
+ timeStamp += (n * 60)
168
+ print(timeStamp)
169
+ # 把timestamp处理之后转换为时间数组,格式化为需要的格式
170
+ timeArray2 = new_time.localtime(timeStamp)
171
+ print(timeArray2)
172
+ aftertime = new_time.strftime("%Y-%m-%d %H:%M", timeArray2)
173
+ print(aftertime)
174
+ new_date = (datetime(timeArray2.tm_year, timeArray2.tm_mon, timeArray2.tm_mday, timeArray2.tm_hour, timeArray2.tm_min))
175
+ return new_date, aftertime
176
+
177
+ def get_current_hour_minutes_time(current_time, hour, minutes):
178
+ '''
179
+ 获取之前的时间
180
+ '''
181
+ creation = datetime(current_time.year, current_time.month, current_time.day, hour, minutes) # 2023年3月15日 12:00
182
+ return creation
183
+
184
+ def get_before_date(days=0, seconds=0, minutes=0, hours=0, format=yymmdd_hhmmss):
185
+ now = datetime.fromtimestamp(datetime.now(timezone.utc).timestamp())
186
+ # 当前时间往前推30天
187
+ ago = now - timedelta(days=days, seconds=seconds, minutes=minutes, hours=hours)
188
+ return ago.strftime(format)
189
+
190
+ def get_before_date_start(days :int=0, format=yymmdd_hhmmss):
191
+ '''
192
+ 获取当天开始时间,也就是凌晨时间0点
193
+ '''
194
+ machine_now = datetime.now(timezone.utc).timestamp()
195
+ now = datetime.fromtimestamp(machine_now)
196
+
197
+ ago = now - timedelta(days=days)
198
+ ago = get_detail_time(ago, 0, 0)
199
+ return ago.strftime(format)
200
+
201
+ if __name__ == '__main__':
202
+ get_week_year_by_timestamp(datetime.now().timestamp())
203
+ get_detail_time()
204
+ get_week_year()
@@ -0,0 +1,79 @@
1
+ from enum import Enum
2
+
3
+
4
+ class KaqExchangeEnum(Enum):
5
+ binance = 1
6
+ bitget = 2
7
+ bybit = 3
8
+ gate = 4
9
+ htx = 5
10
+ okx = 6
11
+ mexc = 7
12
+
13
+ class KaqCommsionRateRedisPrefixEnum(Enum):
14
+ binance_future = 'kaq_binance_futures_commission_rate'
15
+ bybit_future = 'kaq_bybit_futures_commission_rate'
16
+ okx_future = 'kaq_okx_futures_commission_rate'
17
+ mexc_future = 'kaq_mexc_futures_commission_rate'
18
+ bitget_future = 'kaq_bitget_futures_commission_rate'
19
+ gate_future = 'kaq_gate_futures_commission_rate'
20
+ htx_future = 'kaq_gate_futures_commission_rate'
21
+
22
+ binance_spot = 'kaq_binance_spot_commsion_rate'
23
+ bybit_spot = 'kaq_bybit_spot_commsion_rate'
24
+ okx_spot = 'kaq_okx_spot_commsion_rate'
25
+ bitget_spot = 'kaq_bitget_spot_commsion_rate'
26
+ gate_spot = 'kaq_gate_spot_commsion_rate'
27
+ mexc_future_spot = 'kaq_mexc_spot_commsion_rate'
28
+ htx_spot = 'kaq_htx_spot_commsion_rate'
29
+
30
+ class KaqSpotInterestRateRedisPrefixEnum(Enum):
31
+
32
+ binance_spot = 'kaq_binance_spot_interest_rate'
33
+ bybit_spot = 'kaq_bybit_spot_interest_rate'
34
+ okx_spot = 'kaq_okx_spot_interest_rate'
35
+ bitget_spot = 'kaq_bitget_spot_interest_rate'
36
+ gate_spot = 'kaq_gate_spot_interest_rate'
37
+ htx_spot = 'kaq_htx_spot_interest_rate'
38
+ mexc_spot = 'kaq_mexc_spot_interest_rate'
39
+
40
+ class KaqCoinDataEnum(Enum):
41
+ '''
42
+ 枚举检测
43
+ '''
44
+ klines = 'klines' # klines
45
+ global_long_short_account_ratio = 'global_long_short_account_ratio' # 多空持仓人数比
46
+ open_interest_hist = 'open_interest_hist' # 合约持仓量历史
47
+ taker_long_short_ratio = 'taker_long_short_ratio' # 合约主动买卖量
48
+ top_long_short_account_ratio = 'top_long_short_account_ratio' # 大户账户数多空比
49
+ top_long_short_position_ratio = 'top_long_short_position_ratio' # 大户持仓量多空比
50
+
51
+
52
+ class KaqHighCirculationSymbolsEnum(Enum):
53
+ '''
54
+ 高流通量的交易对列表: 由大到小排列
55
+ '''
56
+ symbols = 'Kaq_high_circulation_symbols'
57
+
58
+
59
+ class KaqPriceAndVolumeSymbolsEnum(Enum):
60
+ '''
61
+ 量价更新订阅
62
+ '''
63
+ symbols = 'kaq_all_futures_limit_order_symbols_config'
64
+
65
+
66
+ class AccountIncomeType(Enum):
67
+ FUNDING_FEE = 1 # 资金费用
68
+ COMMISSION = 2 # 手续费
69
+
70
+ class KaqOrderMonitorSymbolEnum(Enum):
71
+ '''
72
+ 有限档深度
73
+ '''
74
+ limit_order = 'kaq_all_futures_limit_order_symbols_config'
75
+
76
+ '''
77
+ 最优挂单
78
+ '''
79
+ best_order = 'kaq_all_futures_best_order_symbols_config'
@@ -0,0 +1,22 @@
1
+ import os
2
+
3
+ _path = os.getcwd()
4
+
5
+ '''
6
+ 根据异常错误判断是否重试
7
+ '''
8
+
9
+
10
+ def retry_if_io_error(exception):
11
+ print("【zhima_util】异常错误为", exception)
12
+ return isinstance(exception, IOError) or isinstance(exception, OSError)
13
+
14
+ '''
15
+ 这里只是为了提供一个重试的方式,不一定要执行代理方式
16
+ '''
17
+
18
+
19
+ def retry_if_env_error(exception):
20
+ return isinstance(exception, EnvironmentError)
21
+
22
+
@@ -0,0 +1,48 @@
1
+ import time
2
+ import hashlib
3
+
4
+
5
+ def generate_hash_id(_series, time_salt=False):
6
+ now = time.localtime()
7
+ salt = str(now.tm_year) + ' ' + str(now.tm_mon) + ' ' + str(now.tm_mday) + ' ' + str(now.tm_hour)
8
+ sss = [str(_series.iloc[i]) for i in range(len(_series))]
9
+ if time_salt:
10
+ str_values = " ".join(sss) + ' ' + salt
11
+ else:
12
+ str_values = " ".join(sss)
13
+
14
+ return hashlib.sha3_256(str_values.encode('utf-8')).hexdigest()
15
+
16
+ def row_hash_id(_series, time_salt=False):
17
+ now = time.localtime()
18
+ salt = str(now.tm_year) + ' ' + str(now.tm_mon) + ' ' + str(now.tm_mday) + ' ' + str(now.tm_hour)
19
+ sss = [str(_series.iloc[i]) for i in range(len(_series))]
20
+ if time_salt:
21
+ str_values = " ".join(sss) + ' ' + salt
22
+ else:
23
+ str_values = " ".join(sss)
24
+
25
+ return hashlib.sha3_256(str_values.encode('utf-8')).hexdigest()
26
+
27
+ def dict_hash_id(_dict:dict, time_salt=False):
28
+ now = time.localtime()
29
+ salt = str(now.tm_year) + ' ' + str(now.tm_mon) + ' ' + str(now.tm_mday) + ' ' + str(now.tm_hour)
30
+ sss = [f'{key}: {value}' for key, value in _dict.items()]
31
+ if time_salt:
32
+ str_values = " ".join(sss) + ' ' + salt
33
+ else:
34
+ str_values = " ".join(sss)
35
+
36
+ return hashlib.sha3_256(str_values.encode('utf-8')).hexdigest()
37
+
38
+ def array_hash_id(_array, time_salt=False):
39
+ now = time.localtime()
40
+ salt = str(now.tm_year) + ' ' + str(now.tm_mon) + ' ' + str(now.tm_mday) + ' ' + str(now.tm_hour)
41
+ sss = [str(i) for i in _array]
42
+ if time_salt:
43
+ str_values = " ".join(sss) + ' ' + salt
44
+ else:
45
+ str_values = " ".join(sss)
46
+
47
+ return hashlib.sha3_256(str_values.encode('utf-8')).hexdigest()
48
+
@@ -0,0 +1,32 @@
1
+ import time
2
+
3
+ from kaq_quant_common.utils import logger_utils
4
+
5
+
6
+ def log_time(start_msg:str = ""):
7
+ """
8
+ 使用示例:
9
+ timer = log_time("开始了吗???")()
10
+ time.sleep(2) # 模拟一些操作
11
+ timer("测试操作完成1") # 记录结束并输出
12
+ time.sleep(2) # 模拟一些操作
13
+ timer("测试操作完成2") # 记录结束并输出
14
+
15
+ timer2 = log_time("开始了吗???")()
16
+ time.sleep(3)
17
+ timer2("测试操作完成3")
18
+ """
19
+ logger = logger_utils.get_logger()
20
+ start = [None]
21
+
22
+ def begin():
23
+ start[0] = time.time()
24
+ logger.info(f"{start_msg}[start]")
25
+ return end
26
+
27
+ def end(msg=""):
28
+ duration = time.time() - start[0]
29
+ logger.info(f"{start_msg}{msg}:[end] Duration {duration:.6f} 秒")
30
+ return duration
31
+
32
+ return begin
@@ -0,0 +1,97 @@
1
+ import logging
2
+ import os
3
+ import sys
4
+ from typing import Union
5
+
6
+ from dagster import get_dagster_logger
7
+ from loguru import logger
8
+
9
+ # 清除所有已添加的处理器(包括默认控制台输出)
10
+ logger.remove()
11
+ # 自定义日志输出
12
+ logger.add(
13
+ # 输出到标准输出(控制台)
14
+ sink=sys.stdout,
15
+ # TODO 配置
16
+ level="INFO",
17
+ #
18
+ # format="{time} {level} [{extra[module]}] {message}", # 显示绑定的module
19
+ format=(
20
+ "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
21
+ "<level>{level}</level> | "
22
+ "<cyan>[{extra[module]}]</cyan>"
23
+ "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - "
24
+ "<level>{message}</level>"
25
+ ),
26
+ # 启用颜色(默认已启用,显式指定更清晰)
27
+ colorize=True,
28
+ )
29
+
30
+
31
+ def _is_dagster_env():
32
+ # 方法1: 检查Dagster特有的环境变量(推荐)
33
+ # Dagster运行时会设置多个以DAGSTER_开头的环境变量
34
+ is_dagster_env = any(key.startswith("DAGSTER_") for key in os.environ)
35
+ return is_dagster_env
36
+
37
+
38
+ def get_logger(obj: Union[str, object] = None):
39
+ '''
40
+ 获取logger
41
+ '''
42
+
43
+ is_dagster_env = _is_dagster_env()
44
+
45
+ name = obj or ""
46
+ if isinstance(obj, str):
47
+ # do nothing
48
+ name = obj
49
+ elif hasattr(obj, '__class__'):
50
+ name = obj.__class__.__name__
51
+ elif hasattr(obj, '__name__'):
52
+ name = obj.__name__
53
+ else:
54
+ name = ""
55
+
56
+ l = None
57
+ if is_dagster_env:
58
+ # TODO
59
+ l = get_dagster_logger()
60
+ else:
61
+ # 使用loguru, 绑定module
62
+ l = logger.bind(module=name)
63
+ return l
64
+
65
+
66
+ ########################
67
+ # 创建一个适配器,将logging日志转发到Loguru
68
+ class LoguruHandler(logging.Handler):
69
+
70
+ def emit(self, record):
71
+ # 获取Loguru对应的日志级别
72
+ try:
73
+ level = logger.level(record.levelname).name
74
+ except ValueError:
75
+ level = record.levelno
76
+
77
+ # 获取日志消息
78
+ frame, depth = logging.currentframe(), 2
79
+ while frame.f_code.co_filename == logging.__file__:
80
+ frame = frame.f_back
81
+ depth += 1
82
+
83
+ # 转发到Loguru
84
+ logger.opt(depth=depth, exception=record.exc_info).bind(module=record.module).log(level, record.getMessage())
85
+
86
+
87
+ # loguru接管logging
88
+ def takeover_logging():
89
+ is_dagster_env = _is_dagster_env()
90
+ if is_dagster_env:
91
+ # 不用处理
92
+ return
93
+ #
94
+ logging.basicConfig(handlers=[LoguruHandler()], level=logging.DEBUG)
95
+
96
+
97
+ takeover_logging()