ygo 1.0.9__tar.gz → 1.0.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.

Potentially problematic release.


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

Files changed (33) hide show
  1. {ygo-1.0.9/ygo.egg-info → ygo-1.0.11}/PKG-INFO +7 -2
  2. {ygo-1.0.9 → ygo-1.0.11}/pyproject.toml +8 -3
  3. {ygo-1.0.9 → ygo-1.0.11}/ycat/__init__.py +7 -8
  4. ygo-1.0.11/ycat/client.py +172 -0
  5. {ygo-1.0.9 → ygo-1.0.11}/ycat/parse.py +0 -2
  6. ygo-1.0.11/ycat/provider.py +101 -0
  7. {ygo-1.0.9 → ygo-1.0.11/ycat}/qdf/__init__.py +1 -0
  8. ygo-1.0.11/ygo/__init__.py +34 -0
  9. {ygo-1.0.9 → ygo-1.0.11}/ygo/exceptions.py +17 -1
  10. {ygo-1.0.9 → ygo-1.0.11}/ygo/ygo.py +3 -15
  11. {ygo-1.0.9 → ygo-1.0.11/ygo.egg-info}/PKG-INFO +7 -2
  12. {ygo-1.0.9 → ygo-1.0.11}/ygo.egg-info/SOURCES.txt +11 -12
  13. {ygo-1.0.9 → ygo-1.0.11}/ygo.egg-info/requires.txt +5 -0
  14. {ygo-1.0.9 → ygo-1.0.11}/ygo.egg-info/top_level.txt +0 -1
  15. {ygo-1.0.9 → ygo-1.0.11}/ylog/__init__.py +3 -2
  16. {ygo-1.0.9 → ygo-1.0.11}/ylog/core.py +61 -28
  17. ygo-1.0.9/ycat/client.py +0 -145
  18. ygo-1.0.9/ycat/dtype.py +0 -389
  19. ygo-1.0.9/ycat/yck.py +0 -87
  20. ygo-1.0.9/ygo/__init__.py +0 -10
  21. {ygo-1.0.9 → ygo-1.0.11}/LICENSE +0 -0
  22. {ygo-1.0.9 → ygo-1.0.11}/README.md +0 -0
  23. {ygo-1.0.9 → ygo-1.0.11}/setup.cfg +0 -0
  24. {ygo-1.0.9 → ygo-1.0.11/ycat}/qdf/errors.py +0 -0
  25. {ygo-1.0.9 → ygo-1.0.11/ycat}/qdf/expr.py +0 -0
  26. {ygo-1.0.9 → ygo-1.0.11/ycat}/qdf/qdf.py +0 -0
  27. {ygo-1.0.9 → ygo-1.0.11/ycat}/qdf/udf/__init__.py +0 -0
  28. {ygo-1.0.9 → ygo-1.0.11/ycat}/qdf/udf/base_udf.py +0 -0
  29. {ygo-1.0.9 → ygo-1.0.11/ycat}/qdf/udf/cs_udf.py +0 -0
  30. {ygo-1.0.9 → ygo-1.0.11/ycat}/qdf/udf/d_udf.py +0 -0
  31. {ygo-1.0.9 → ygo-1.0.11/ycat}/qdf/udf/ind_udf.py +0 -0
  32. {ygo-1.0.9 → ygo-1.0.11/ycat}/qdf/udf/ts_udf.py +0 -0
  33. {ygo-1.0.9 → ygo-1.0.11}/ygo.egg-info/dependency_links.txt +0 -0
@@ -1,17 +1,21 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ygo
3
- Version: 1.0.9
3
+ Version: 1.0.11
4
4
  Project-URL: homepage, https://github.com/link-yundi/ygo
5
5
  Project-URL: repository, https://github.com/link-yundi/ygo
6
- Requires-Python: >=3.8
6
+ Requires-Python: >=3.9
7
7
  Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
+ Requires-Dist: clickhouse-df>=0.1.5
9
10
  Requires-Dist: clickhouse-driver>=0.2.9
11
+ Requires-Dist: connectorx>=0.3.3
10
12
  Requires-Dist: dynaconf>=3.2.11
11
13
  Requires-Dist: exchange-calendars>=4.2.8
12
14
  Requires-Dist: joblib>=1.4.2
13
15
  Requires-Dist: lark>=1.2.2
16
+ Requires-Dist: lightgbm>=4.6.0
14
17
  Requires-Dist: loguru>=0.7.3
18
+ Requires-Dist: mlflow>=2.17.2
15
19
  Requires-Dist: pandas>=2.0.3
16
20
  Requires-Dist: polars>=1.8.2
17
21
  Requires-Dist: pyarrow>=17.0.0
@@ -19,6 +23,7 @@ Requires-Dist: pymysql>=1.1.1
19
23
  Requires-Dist: sqlalchemy>=2.0.40
20
24
  Requires-Dist: sqlparse>=0.5.3
21
25
  Requires-Dist: toolz>=1.0.0
26
+ Requires-Dist: torch>=2.5.1
22
27
  Requires-Dist: tqdm>=4.67.1
23
28
  Dynamic: license-file
24
29
 
@@ -4,17 +4,21 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ygo"
7
- version = "1.0.9"
7
+ version = "1.0.11"
8
8
  description = ""
9
9
  readme = "README.md"
10
- requires-python = ">=3.8"
10
+ requires-python = ">=3.9"
11
11
  dependencies = [
12
+ "clickhouse-df>=0.1.5",
12
13
  "clickhouse-driver>=0.2.9",
14
+ "connectorx>=0.3.3",
13
15
  "dynaconf>=3.2.11",
14
16
  "exchange-calendars>=4.2.8",
15
17
  "joblib>=1.4.2",
16
18
  "lark>=1.2.2",
19
+ "lightgbm>=4.6.0",
17
20
  "loguru>=0.7.3",
21
+ "mlflow>=2.17.2",
18
22
  "pandas>=2.0.3",
19
23
  "polars>=1.8.2",
20
24
  "pyarrow>=17.0.0",
@@ -22,12 +26,13 @@ dependencies = [
22
26
  "sqlalchemy>=2.0.40",
23
27
  "sqlparse>=0.5.3",
24
28
  "toolz>=1.0.0",
29
+ "torch>=2.5.1",
25
30
  "tqdm>=4.67.1",
26
31
  ]
27
32
 
28
33
  [tool.setuptools.packages.find]
29
34
  where = ["."]
30
- include = ["ygo", "ygo.*", "ylog", "ylog.*", "ycat", "ycat.*", "qdf", "qdf.*"]
35
+ include = ["ygo", "ygo.*", "ylog", "ylog.*", "ycat", "ycat.*",]
31
36
 
32
37
  [project.urls]
33
38
  homepage = "https://github.com/link-yundi/ygo"
@@ -13,12 +13,12 @@ from .client import (
13
13
  get_settings,
14
14
  sql,
15
15
  put,
16
- create_engine_ck,
17
- create_engine_mysql,
18
- read_mysql,
19
- read_ck,
20
16
  tb_path,
17
+ read_ck,
18
+ read_mysql,
21
19
  )
20
+ from .qdf import from_polars
21
+ from .provider import Provider
22
22
 
23
23
  __all__ = [
24
24
  "HOME",
@@ -26,9 +26,8 @@ __all__ = [
26
26
  "get_settings",
27
27
  "sql",
28
28
  "put",
29
- "create_engine_ck",
30
- "create_engine_mysql",
31
- "read_mysql",
32
- "read_ck",
33
29
  "tb_path",
30
+ "read_ck",
31
+ "read_mysql",
32
+ "Provider",
34
33
  ]
@@ -0,0 +1,172 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ ---------------------------------------------
4
+ Created on 2024/7/1 09:44
5
+ @author: ZhangYundi
6
+ @email: yundi.xxii@outlook.com
7
+ ---------------------------------------------
8
+ """
9
+ import os
10
+ import re
11
+ import urllib
12
+ from pathlib import Path
13
+
14
+ import clickhouse_df
15
+ import polars as pl
16
+ from dynaconf import Dynaconf
17
+
18
+ import ylog
19
+ from .parse import extract_table_names_from_sql
20
+
21
+ # 配置文件在 “~/.catdb/setting.toml”
22
+ USERHOME = os.path.expanduser('~') # 用户家目录
23
+ NAME = "catdb"
24
+ CONFIG_PATH = os.path.join(USERHOME, f".{NAME}", "settings.toml")
25
+ if not os.path.exists(CONFIG_PATH):
26
+ try:
27
+ os.makedirs(os.path.dirname(CONFIG_PATH))
28
+ except FileExistsError as e:
29
+ ...
30
+ except Exception as e:
31
+ ylog.error(f"配置文件生成失败: {e}")
32
+ catdb_path = os.path.join(USERHOME, NAME)
33
+ template_content = f"""[paths]
34
+ {NAME}="{catdb_path}" # 本地数据库,默认家目录
35
+
36
+ ## 数据库配置:
37
+ [database]
38
+ [database.ck]
39
+ # urls=["<host1>:<port1>", "<host2>:<port2>",]
40
+ # user="xxx"
41
+ # password="xxxxxx"
42
+ [database.jy]
43
+ # url="<host>:<port>"
44
+ # user="xxxx"
45
+ # password="xxxxxx"
46
+
47
+ ## 视情况自由增加其他配置
48
+ """
49
+ with open(CONFIG_PATH, "w") as f:
50
+ f.write(template_content)
51
+ ylog.info(f"生成配置文件: {CONFIG_PATH}")
52
+
53
+
54
+ def get_settings():
55
+ try:
56
+ return Dynaconf(settings_files=[CONFIG_PATH])
57
+ except Exception as e:
58
+ ylog.error(f"读取配置文件失败: {e}")
59
+ return {}
60
+
61
+
62
+ HOME = USERHOME
63
+ CATDB = os.path.join(HOME, NAME)
64
+ # 读取配置文件覆盖
65
+ SETTINGS = get_settings()
66
+ if SETTINGS is not None:
67
+ CATDB = SETTINGS["PATHS"][NAME]
68
+ if not CATDB.endswith(NAME):
69
+ CATDB = os.path.join(CATDB, NAME)
70
+
71
+
72
+ # ======================== 本地数据库 catdb ========================
73
+ def tb_path(tb_name: str) -> Path:
74
+ """
75
+ 返回指定表名 完整的本地路径
76
+ Parameters
77
+ ----------
78
+ tb_name: str
79
+ 表名,路径写法: a/b/c
80
+ Returns
81
+ -------
82
+ full_abs_path: pathlib.Path
83
+ 完整的本地绝对路径 $HOME/catdb/a/b/c
84
+ """
85
+ return Path(CATDB, tb_name)
86
+
87
+
88
+ def put(df: pl.DataFrame, tb_name: str, partitions: list[str] | None = None, abs_path: bool = False):
89
+ if not abs_path:
90
+ tbpath = tb_path(tb_name)
91
+ else:
92
+ tbpath = tb_name
93
+ if not tbpath.exists():
94
+ os.makedirs(tbpath, exist_ok=True)
95
+ if partitions is not None:
96
+ df.write_parquet(tbpath, partition_by=partitions)
97
+ else:
98
+ df.write_parquet(tbpath / "data.parquet")
99
+
100
+
101
+ def sql(query: str, abs_path: bool = False, lazy: bool = True):
102
+ tbs = extract_table_names_from_sql(query)
103
+ convertor = dict()
104
+ for tb in tbs:
105
+ if not abs_path:
106
+ db_path = tb_path(tb)
107
+ else:
108
+ db_path = tb
109
+ format_tb = f"read_parquet('{db_path}/**/*.parquet')"
110
+ convertor[tb] = format_tb
111
+ pattern = re.compile("|".join(re.escape(k) for k in convertor.keys()))
112
+ new_query = pattern.sub(lambda m: convertor[m.group(0)], query)
113
+ if not lazy:
114
+ return pl.sql(new_query).collect()
115
+ return pl.sql(new_query)
116
+
117
+
118
+ def read_mysql(query: str, db_conf: str = "database.mysql") -> pl.DataFrame:
119
+ """
120
+ 读取 mysql 返回 polars.DataFrame
121
+ :param query:
122
+ :param db_conf: .catdb/settings.toml 中的 database 配置
123
+ :return: polars.DataFrame
124
+ """
125
+ try:
126
+ db_setting = get_settings().get(db_conf, {})
127
+ if not isinstance(db_setting, dict):
128
+ raise ValueError(f"Database configuration '{db_conf}' is not a dictionary.")
129
+
130
+ required_keys = ['user', 'password', 'url']
131
+ missing_keys = [key for key in required_keys if key not in db_setting]
132
+ if missing_keys:
133
+ raise KeyError(f"Missing required keys in database config: {missing_keys}")
134
+
135
+ user = urllib.parse.quote_plus(db_setting['user'])
136
+ password = urllib.parse.quote_plus(db_setting['password'])
137
+ uri = f"mysql://{user}:{password}@{db_setting['url']}"
138
+ return pl.read_database_uri(query, uri)
139
+
140
+ except KeyError as e:
141
+ raise RuntimeError("Database configuration error: missing required fields.") from e
142
+ except Exception as e:
143
+ raise RuntimeError(f"Failed to execute MySQL query: {e}") from e
144
+
145
+
146
+ def read_ck(query: str, db_conf: str = "database.ck") -> pl.DataFrame:
147
+ """
148
+ 读取 clickhouse 集群 返回 polars.DataFrame
149
+ :param query:
150
+ :param db_conf: .catdb/settings.toml 中的 database 配置
151
+ :return: polars.DataFrame
152
+ """
153
+ try:
154
+ db_setting = get_settings().get(db_conf, {})
155
+ if not isinstance(db_setting, dict):
156
+ raise ValueError(f"Database configuration '{db_conf}' is not a dictionary.")
157
+
158
+ required_keys = ['user', 'password', 'urls']
159
+ missing_keys = [key for key in required_keys if key not in db_setting]
160
+ if missing_keys:
161
+ raise KeyError(f"Missing required keys in database config: {missing_keys}")
162
+
163
+ user = urllib.parse.quote_plus(db_setting['user'])
164
+ password = urllib.parse.quote_plus(db_setting['password'])
165
+
166
+ with clickhouse_df.connect(db_setting['urls'], user=user, password=password):
167
+ return clickhouse_df.to_polars(query)
168
+
169
+ except KeyError as e:
170
+ raise RuntimeError("Database configuration error: missing required fields.") from e
171
+ except Exception as e:
172
+ raise RuntimeError(f"Failed to execute ClickHouse query: {e}") from e
@@ -61,6 +61,4 @@ def extract_table_names_from_sql(sql_query):
61
61
  return table_names
62
62
 
63
63
 
64
- if __name__ == '__main__':
65
- print(extract_table_names_from_sql("select * from c.a/b/c/d"))
66
64
 
@@ -0,0 +1,101 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ ---------------------------------------------
4
+ Created on 2025/5/23 01:34
5
+ @author: ZhangYundi
6
+ @email: yundi.xxii@outlook.com
7
+ ---------------------------------------------
8
+ """
9
+ import os
10
+ from datetime import datetime, timedelta
11
+ from pathlib import Path
12
+
13
+ import ygo
14
+ import ylog
15
+ from .client import CATDB
16
+
17
+ DATE_FORMAT = "%Y-%m-%d"
18
+
19
+
20
+ class Provider:
21
+ """
22
+ 数据更新器
23
+ 路径:{ycat.CATDB}/provider/{name}
24
+ """
25
+
26
+ def __init__(self, name: str, update_time="16:30"):
27
+ """
28
+ 数据更新器
29
+ :param name: 数据更新器名称
30
+ :param update_time: 数据更新时间,默认16:30
31
+ """
32
+ self.name = name
33
+ self._tb_path = Path(CATDB) / name
34
+ os.makedirs(self._tb_path, exist_ok=True)
35
+ self._update_time = update_time
36
+ self.present = datetime.now().today()
37
+
38
+ if self.present.strftime("%H:%M") >= self._update_time:
39
+ self.last_date = self.present.strftime(DATE_FORMAT)
40
+ else:
41
+ self.last_date = (self.present - timedelta(days=1)).strftime(DATE_FORMAT)
42
+
43
+ self._tasks = list()
44
+ self._last_run_file = self._tb_path / f".last_run"
45
+ self.logger = ylog.get_logger("provider")
46
+
47
+ @property
48
+ def last_update_date(self):
49
+ return self._read_last_run_date()
50
+
51
+ def _read_last_run_date(self):
52
+ if self._last_run_file.exists():
53
+ with open(self._last_run_file, "r") as f:
54
+ return f.read().strip()
55
+ return
56
+
57
+ def _write_last_run_date(self, date_str: str):
58
+ with open(self._last_run_file, "w") as f:
59
+ f.write(date_str)
60
+
61
+ def wrap_fn(self, task_name: str, update_fn: callable):
62
+ """包装函数,添加异常处理"""
63
+ try:
64
+ update_fn()
65
+ return 0
66
+ except Exception as e:
67
+ self.logger.error(ygo.FailTaskError(task_name=task_name, error=e))
68
+ return 1
69
+
70
+ def add_task(self, task_name: str, update_fn: callable):
71
+ """添加任务"""
72
+ self._tasks.append((task_name, ygo.delay(self.wrap_fn)(task_name=task_name, update_fn=update_fn)))
73
+
74
+ def do(self,
75
+ overwrite: bool = False,
76
+ n_jobs: int = 10,
77
+ backend: str = "threading"):
78
+ """
79
+ 执行任务
80
+ :param overwrite: 是否覆盖现有数据
81
+ :param n_jobs: 并发数
82
+ :param backend: loky/threading/multiprocessing
83
+ :return:
84
+ """
85
+ if not overwrite:
86
+ local_last_date = self._read_last_run_date()
87
+ if local_last_date is not None:
88
+ if local_last_date >= self.last_date:
89
+ self.logger.info(f"[{self.name}] 已是最新数据,跳过更新")
90
+ return
91
+ self.logger.info(f"[{self.name}] 更新数据")
92
+ failed_num = 0
93
+ with ygo.pool(n_jobs=n_jobs, backend=backend) as go:
94
+ for task_name, task in self._tasks:
95
+ go.submit(task, job_name=task_name)()
96
+ for status in go.do():
97
+ failed_num += status
98
+ if failed_num < 1:
99
+ self._write_last_run_date(self.last_date)
100
+ self.logger.info(f"[{self.name}] 更新成功,最新数据日期:{self.last_date}")
101
+ self.logger.info(f"[{self.name}] 更新完成,失败任务数:{str(failed_num).zfill(2)}/{str(len(self._tasks)).zfill(2)}")
@@ -29,6 +29,7 @@ def signature(function):
29
29
 
30
30
 
31
31
  def from_polars(df: pl.DataFrame, index: tuple[str] = ("date", "time", "asset"), align: bool = True, ) -> QDF:
32
+ """polars dataframe 转为 表达式数据库"""
32
33
  return QDF(df, index, align,)
33
34
 
34
35
 
@@ -0,0 +1,34 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ ---------------------------------------------
4
+ Created on 2025/4/28 15:25
5
+ @author: ZhangYundi
6
+ @email: yundi.xxii@outlook.com
7
+ ---------------------------------------------
8
+ """
9
+
10
+ from .exceptions import FailTaskError
11
+ from .ygo import (
12
+ delay,
13
+ fn_params,
14
+ fn_signature_params,
15
+ fn_path,
16
+ fn_code,
17
+ fn_info,
18
+ module_from_str,
19
+ fn_from_str,
20
+ pool,
21
+ )
22
+
23
+ __all__ = [
24
+ "FailTaskError",
25
+ "delay",
26
+ "fn_params",
27
+ "fn_signature_params",
28
+ "fn_path",
29
+ "fn_code",
30
+ "fn_info",
31
+ "fn_from_str",
32
+ "module_from_str",
33
+ "pool"
34
+ ]
@@ -7,7 +7,23 @@ Created on 2024/12/18 下午7:01
7
7
  ---------------------------------------------
8
8
  """
9
9
 
10
+ from dataclasses import dataclass
11
+
10
12
  class WarnException(Exception):
11
13
  """自定义异常类,仅用于警告"""
12
14
  def __init__(self, message):
13
- super().__init__(message) # 调用父类的构造函数
15
+ super().__init__(message) # 调用父类的构造函数
16
+
17
+ @dataclass
18
+ class FailTaskError:
19
+ task_name: str
20
+ error: Exception
21
+
22
+ def __str__(self):
23
+ return f"""
24
+ [失败任务]: {self.task_name}
25
+ [错误信息]: \n{self.error}
26
+ """
27
+
28
+ def __repr__(self):
29
+ return self.__str__()
@@ -18,7 +18,7 @@ from pathlib import Path
18
18
  from joblib import Parallel, delayed
19
19
 
20
20
  import ylog
21
- from .exceptions import WarnException
21
+ from .exceptions import WarnException, FailTaskError
22
22
 
23
23
  with warnings.catch_warnings():
24
24
  warnings.simplefilter("ignore")
@@ -228,22 +228,10 @@ def run_job(job, task_id, queue):
228
228
  try:
229
229
  result = job()
230
230
  except WarnException as e:
231
- warn_msg = f"""
232
- =============================================================
233
- {job.task_name}: {job.task_id}
234
- {e}
235
- =============================================================
236
- """
237
- ylog.warning(warn_msg)
231
+ ylog.warning(FailTaskError(task_name=job.task_name, error=e))
238
232
  result = None
239
233
  except Exception as e:
240
- error_msg = f"""
241
- =============================================================
242
- {job.task_name}: {job.task_id}
243
- {e}
244
- =============================================================
245
- """
246
- ylog.error(error_msg)
234
+ ylog.error(FailTaskError(task_name=job.task_name, error=e))
247
235
  result = None
248
236
  queue.put((task_id, 1))
249
237
  return result
@@ -1,17 +1,21 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ygo
3
- Version: 1.0.9
3
+ Version: 1.0.11
4
4
  Project-URL: homepage, https://github.com/link-yundi/ygo
5
5
  Project-URL: repository, https://github.com/link-yundi/ygo
6
- Requires-Python: >=3.8
6
+ Requires-Python: >=3.9
7
7
  Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
+ Requires-Dist: clickhouse-df>=0.1.5
9
10
  Requires-Dist: clickhouse-driver>=0.2.9
11
+ Requires-Dist: connectorx>=0.3.3
10
12
  Requires-Dist: dynaconf>=3.2.11
11
13
  Requires-Dist: exchange-calendars>=4.2.8
12
14
  Requires-Dist: joblib>=1.4.2
13
15
  Requires-Dist: lark>=1.2.2
16
+ Requires-Dist: lightgbm>=4.6.0
14
17
  Requires-Dist: loguru>=0.7.3
18
+ Requires-Dist: mlflow>=2.17.2
15
19
  Requires-Dist: pandas>=2.0.3
16
20
  Requires-Dist: polars>=1.8.2
17
21
  Requires-Dist: pyarrow>=17.0.0
@@ -19,6 +23,7 @@ Requires-Dist: pymysql>=1.1.1
19
23
  Requires-Dist: sqlalchemy>=2.0.40
20
24
  Requires-Dist: sqlparse>=0.5.3
21
25
  Requires-Dist: toolz>=1.0.0
26
+ Requires-Dist: torch>=2.5.1
22
27
  Requires-Dist: tqdm>=4.67.1
23
28
  Dynamic: license-file
24
29
 
@@ -1,21 +1,20 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
- qdf/__init__.py
5
- qdf/errors.py
6
- qdf/expr.py
7
- qdf/qdf.py
8
- qdf/udf/__init__.py
9
- qdf/udf/base_udf.py
10
- qdf/udf/cs_udf.py
11
- qdf/udf/d_udf.py
12
- qdf/udf/ind_udf.py
13
- qdf/udf/ts_udf.py
14
4
  ycat/__init__.py
15
5
  ycat/client.py
16
- ycat/dtype.py
17
6
  ycat/parse.py
18
- ycat/yck.py
7
+ ycat/provider.py
8
+ ycat/qdf/__init__.py
9
+ ycat/qdf/errors.py
10
+ ycat/qdf/expr.py
11
+ ycat/qdf/qdf.py
12
+ ycat/qdf/udf/__init__.py
13
+ ycat/qdf/udf/base_udf.py
14
+ ycat/qdf/udf/cs_udf.py
15
+ ycat/qdf/udf/d_udf.py
16
+ ycat/qdf/udf/ind_udf.py
17
+ ycat/qdf/udf/ts_udf.py
19
18
  ygo/__init__.py
20
19
  ygo/exceptions.py
21
20
  ygo/ygo.py
@@ -1,9 +1,13 @@
1
+ clickhouse-df>=0.1.5
1
2
  clickhouse-driver>=0.2.9
3
+ connectorx>=0.3.3
2
4
  dynaconf>=3.2.11
3
5
  exchange-calendars>=4.2.8
4
6
  joblib>=1.4.2
5
7
  lark>=1.2.2
8
+ lightgbm>=4.6.0
6
9
  loguru>=0.7.3
10
+ mlflow>=2.17.2
7
11
  pandas>=2.0.3
8
12
  polars>=1.8.2
9
13
  pyarrow>=17.0.0
@@ -11,4 +15,5 @@ pymysql>=1.1.1
11
15
  sqlalchemy>=2.0.40
12
16
  sqlparse>=0.5.3
13
17
  toolz>=1.0.0
18
+ torch>=2.5.1
14
19
  tqdm>=4.67.1
@@ -1,4 +1,3 @@
1
- qdf
2
1
  ycat
3
2
  ygo
4
3
  ylog
@@ -7,7 +7,7 @@ Created on 2025/5/14 15:37
7
7
  ---------------------------------------------
8
8
  """
9
9
 
10
- from .core import trace, debug, info, warning, error, critical, update_config
10
+ from .core import trace, debug, info, warning, error, critical, update_config, get_logger
11
11
 
12
12
  __all__ = [
13
13
  "trace",
@@ -16,5 +16,6 @@ __all__ = [
16
16
  "warning",
17
17
  "error",
18
18
  "critical",
19
- "update_config"
19
+ "update_config",
20
+ "get_logger",
20
21
  ]