kumoai 2.14.0.dev202512211732__cp313-cp313-macosx_11_0_arm64.whl → 2.15.0.dev202601181732__cp313-cp313-macosx_11_0_arm64.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 (42) hide show
  1. kumoai/__init__.py +38 -30
  2. kumoai/_version.py +1 -1
  3. kumoai/client/client.py +6 -0
  4. kumoai/client/jobs.py +26 -0
  5. kumoai/connector/utils.py +21 -7
  6. kumoai/experimental/rfm/__init__.py +24 -22
  7. kumoai/experimental/rfm/backend/local/graph_store.py +12 -21
  8. kumoai/experimental/rfm/backend/local/sampler.py +0 -3
  9. kumoai/experimental/rfm/backend/local/table.py +24 -25
  10. kumoai/experimental/rfm/backend/snow/sampler.py +235 -80
  11. kumoai/experimental/rfm/backend/snow/table.py +146 -70
  12. kumoai/experimental/rfm/backend/sqlite/sampler.py +196 -89
  13. kumoai/experimental/rfm/backend/sqlite/table.py +85 -55
  14. kumoai/experimental/rfm/base/__init__.py +6 -9
  15. kumoai/experimental/rfm/base/column.py +95 -11
  16. kumoai/experimental/rfm/base/expression.py +44 -0
  17. kumoai/experimental/rfm/base/mapper.py +69 -0
  18. kumoai/experimental/rfm/base/sampler.py +28 -18
  19. kumoai/experimental/rfm/base/source.py +1 -1
  20. kumoai/experimental/rfm/base/sql_sampler.py +320 -19
  21. kumoai/experimental/rfm/base/table.py +256 -109
  22. kumoai/experimental/rfm/base/utils.py +36 -0
  23. kumoai/experimental/rfm/graph.py +134 -114
  24. kumoai/experimental/rfm/infer/dtype.py +7 -2
  25. kumoai/experimental/rfm/infer/multicategorical.py +1 -1
  26. kumoai/experimental/rfm/infer/time_col.py +4 -2
  27. kumoai/experimental/rfm/relbench.py +76 -0
  28. kumoai/experimental/rfm/rfm.py +541 -307
  29. kumoai/experimental/rfm/task_table.py +292 -0
  30. kumoai/pquery/training_table.py +16 -2
  31. kumoai/testing/snow.py +3 -3
  32. kumoai/trainer/distilled_trainer.py +175 -0
  33. kumoai/utils/display.py +95 -0
  34. kumoai/utils/progress_logger.py +205 -117
  35. kumoai/utils/sql.py +2 -2
  36. {kumoai-2.14.0.dev202512211732.dist-info → kumoai-2.15.0.dev202601181732.dist-info}/METADATA +2 -2
  37. {kumoai-2.14.0.dev202512211732.dist-info → kumoai-2.15.0.dev202601181732.dist-info}/RECORD +40 -35
  38. kumoai/experimental/rfm/base/column_expression.py +0 -50
  39. kumoai/experimental/rfm/base/sql_table.py +0 -229
  40. {kumoai-2.14.0.dev202512211732.dist-info → kumoai-2.15.0.dev202601181732.dist-info}/WHEEL +0 -0
  41. {kumoai-2.14.0.dev202512211732.dist-info → kumoai-2.15.0.dev202601181732.dist-info}/licenses/LICENSE +0 -0
  42. {kumoai-2.14.0.dev202512211732.dist-info → kumoai-2.15.0.dev202601181732.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,7 @@
1
1
  import re
2
2
  import sys
3
3
  import time
4
+ from abc import ABC, abstractmethod
4
5
  from typing import Any
5
6
 
6
7
  from rich.console import Console, ConsoleOptions, RenderResult
@@ -20,49 +21,179 @@ from rich.text import Text
20
21
  from typing_extensions import Self
21
22
 
22
23
 
23
- class ProgressLogger:
24
+ class ProgressLogger(ABC):
25
+ r"""An abstract base class for logging progress updates."""
24
26
  def __init__(self, msg: str, verbose: bool = True) -> None:
25
- self.msg = msg
26
- self.verbose = verbose
27
+ self.msg: str = msg
28
+ self.verbose: bool = verbose
27
29
 
28
30
  self.logs: list[str] = []
29
31
 
30
32
  self.start_time: float | None = None
31
33
  self.end_time: float | None = None
32
34
 
35
+ # Handle nested loggers gracefully:
36
+ self._depth: int = 0
37
+
38
+ # Internal progress bar cache:
39
+ self._progress_bar_msg: str | None = None
40
+ self._total: int = 0
41
+ self._current: int = 0
42
+
43
+ def __repr__(self) -> str:
44
+ return f'{self.__class__.__name__}()'
45
+
33
46
  @classmethod
34
47
  def default(cls, msg: str, verbose: bool = True) -> 'ProgressLogger':
35
- from kumoai import in_snowflake_notebook
48
+ r"""The default progress logger for the current environment."""
49
+ from kumoai import in_streamlit_notebook, in_vnext_notebook
36
50
 
37
- if in_snowflake_notebook():
51
+ if in_streamlit_notebook():
38
52
  return StreamlitProgressLogger(msg, verbose)
53
+ if in_vnext_notebook():
54
+ return PlainProgressLogger(msg, verbose)
39
55
  return RichProgressLogger(msg, verbose)
40
56
 
41
57
  @property
42
58
  def duration(self) -> float:
59
+ r"""The current/final duration."""
43
60
  assert self.start_time is not None
44
61
  if self.end_time is not None:
45
62
  return self.end_time - self.start_time
46
63
  return time.perf_counter() - self.start_time
47
64
 
65
+ def __enter__(self) -> Self:
66
+ from kumoai import in_notebook
67
+
68
+ self._depth += 1
69
+ if self._depth == 1:
70
+ self.start_time = time.perf_counter()
71
+ if self._depth == 1 and not in_notebook(): # Show progress bar in TUI.
72
+ sys.stdout.write("\x1b]9;4;3\x07")
73
+ sys.stdout.flush()
74
+ if self._depth == 1 and self.verbose:
75
+ self.on_enter()
76
+ return self
77
+
78
+ def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
79
+ from kumoai import in_notebook
80
+
81
+ self._depth -= 1
82
+ if self._depth == 0:
83
+ self.end_time = time.perf_counter()
84
+ if self._depth == 0 and self.verbose:
85
+ self.on_exit(error=exc_val is not None)
86
+ if self._depth == 0 and not in_notebook(): # Stop progress bar in TUI.
87
+ sys.stdout.write("\x1b]9;4;0\x07")
88
+ sys.stdout.flush()
89
+
48
90
  def log(self, msg: str) -> None:
91
+ r"""Logs a new message."""
49
92
  self.logs.append(msg)
93
+ if self.verbose:
94
+ self.on_log(msg)
50
95
 
51
- def init_progress(self, total: int, description: str) -> None:
52
- pass
96
+ def init_progress(self, msg: str, total: int) -> None:
97
+ r"""Initializes a progress bar."""
98
+ if self._progress_bar_msg is not None:
99
+ raise RuntimeError("Current progress not yet finished")
100
+ self._progress_bar_msg = msg
101
+ self._current = 0
102
+ self._total = total
103
+ if self.verbose:
104
+ self.on_init_progress(msg, total)
53
105
 
54
106
  def step(self) -> None:
107
+ r"""Increments an active progress bar."""
108
+ assert self._progress_bar_msg is not None
109
+ self._current += 1
110
+ if self.verbose:
111
+ self.on_step(self._progress_bar_msg, self._current, self._total)
112
+ if self._current >= self._total:
113
+ self._progress_bar_msg = None
114
+ self._current = self._total = 0
115
+
116
+ @abstractmethod
117
+ def on_enter(self) -> None:
55
118
  pass
56
119
 
57
- def __enter__(self) -> Self:
58
- self.start_time = time.perf_counter()
59
- return self
120
+ @abstractmethod
121
+ def on_exit(self, error: bool) -> None:
122
+ pass
60
123
 
61
- def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
62
- self.end_time = time.perf_counter()
124
+ @abstractmethod
125
+ def on_log(self, msg: str) -> None:
126
+ pass
63
127
 
64
- def __repr__(self) -> str:
65
- return f'{self.__class__.__name__}({self.msg})'
128
+ @abstractmethod
129
+ def on_init_progress(self, msg: str, total: int) -> None:
130
+ pass
131
+
132
+ @abstractmethod
133
+ def on_step(self, msg: str, current: int, total: int) -> None:
134
+ pass
135
+
136
+
137
+ class PlainProgressLogger(ProgressLogger):
138
+ RESET: str = '\x1b[0m'
139
+ BOLD: str = '\x1b[1m'
140
+ DIM: str = '\x1b[2m'
141
+ RED: str = '\x1b[31m'
142
+ GREEN: str = '\x1b[32m'
143
+ CYAN: str = '\x1b[36m'
144
+
145
+ def on_enter(self) -> None:
146
+ from kumoai import in_vnext_notebook
147
+
148
+ msg = self.msg.replace('[bold]', self.BOLD)
149
+ msg = msg.replace('[/bold]', self.RESET + self.CYAN)
150
+ msg = self.CYAN + msg + self.RESET
151
+ print(msg, end='\n' if in_vnext_notebook() else '', flush=True)
152
+
153
+ def on_exit(self, error: bool) -> None:
154
+ from kumoai import in_vnext_notebook
155
+
156
+ if error:
157
+ msg = f"❌ {self.RED}({self.duration:.2f}s){self.RESET}"
158
+ else:
159
+ msg = f"✅ {self.GREEN}({self.duration:.2f}s){self.RESET}"
160
+
161
+ if in_vnext_notebook():
162
+ print(f"{self.DIM}↳{self.RESET} {msg}", flush=True)
163
+ else:
164
+ print(f" {msg}", flush=True)
165
+
166
+ def on_log(self, msg: str) -> None:
167
+ from kumoai import in_vnext_notebook
168
+
169
+ msg = f"{self.DIM}↳ {msg}{self.RESET}"
170
+
171
+ if in_vnext_notebook():
172
+ print(msg, flush=True)
173
+ else:
174
+ print(f"\n{msg}", end='', flush=True)
175
+
176
+ def on_init_progress(self, msg: str, total: int) -> None:
177
+ from kumoai import in_vnext_notebook
178
+
179
+ msg = f"{self.DIM}↳ {msg}{self.RESET}"
180
+
181
+ if in_vnext_notebook():
182
+ print(msg, flush=True)
183
+ else:
184
+ print(f"\n{msg} {self.DIM}[{self.RESET}", end='', flush=True)
185
+
186
+ def on_step(self, msg: str, current: int, total: int) -> None:
187
+ from kumoai import in_vnext_notebook
188
+
189
+ if in_vnext_notebook():
190
+ return
191
+
192
+ msg = f"{self.DIM}#{self.RESET}"
193
+ if current == total:
194
+ msg += f"{self.DIM}]{self.RESET}"
195
+
196
+ print(msg, end='', flush=True)
66
197
 
67
198
 
68
199
  class ColoredMofNCompleteColumn(MofNCompleteColumn):
@@ -100,65 +231,51 @@ class RichProgressLogger(ProgressLogger):
100
231
  self._live: Live | None = None
101
232
  self._exception: bool = False
102
233
 
103
- def init_progress(self, total: int, description: str) -> None:
104
- assert self._progress is None
105
- if self.verbose:
106
- self._progress = Progress(
107
- TextColumn(f' ↳ {description}', style='dim'),
108
- BarColumn(bar_width=None),
109
- ColoredMofNCompleteColumn(style='dim'),
110
- TextColumn('•', style='dim'),
111
- ColoredTimeRemainingColumn(style='dim'),
112
- )
113
- self._task = self._progress.add_task("Progress", total=total)
114
-
115
- def step(self) -> None:
116
- if self.verbose:
117
- assert self._progress is not None
118
- assert self._task is not None
119
- self._progress.update(self._task, advance=1) # type: ignore
120
-
121
- def __enter__(self) -> Self:
122
- from kumoai import in_notebook
234
+ def on_enter(self) -> None:
235
+ self._live = Live(
236
+ self,
237
+ refresh_per_second=self.refresh_per_second,
238
+ vertical_overflow='visible',
239
+ )
240
+ self._live.start()
123
241
 
124
- super().__enter__()
242
+ def on_exit(self, error: bool) -> None:
243
+ self._exception = error
125
244
 
126
- if not in_notebook(): # Render progress bar in TUI.
127
- sys.stdout.write("\x1b]9;4;3\x07")
128
- sys.stdout.flush()
245
+ if self._progress is not None:
246
+ self._progress.stop()
129
247
 
130
- if self.verbose:
131
- self._live = Live(
132
- self,
133
- refresh_per_second=self.refresh_per_second,
134
- vertical_overflow='visible',
135
- )
136
- self._live.start()
248
+ if self._live is not None:
249
+ self._live.update(self, refresh=True)
250
+ self._live.stop()
137
251
 
138
- return self
252
+ self._progress = None
253
+ self._task = None
254
+ self._live = None
139
255
 
140
- def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
141
- from kumoai import in_notebook
256
+ def on_log(self, msg: str) -> None:
257
+ pass
142
258
 
143
- super().__exit__(exc_type, exc_val, exc_tb)
259
+ def on_init_progress(self, msg: str, total: int) -> None:
260
+ self._progress = Progress(
261
+ TextColumn(f' ↳ {msg}', style='dim'),
262
+ BarColumn(bar_width=None),
263
+ ColoredMofNCompleteColumn(style='dim'),
264
+ TextColumn('•', style='dim'),
265
+ ColoredTimeRemainingColumn(style='dim'),
266
+ )
267
+ self._task = self._progress.add_task("Progress", total=total)
144
268
 
145
- if exc_type is not None:
146
- self._exception = True
269
+ def on_step(self, msg: str, current: int, total: int) -> None:
270
+ assert self._progress is not None
271
+ assert self._task is not None
272
+ self._progress.update(self._task, advance=1) # type: ignore
147
273
 
148
- if self._progress is not None:
274
+ if current == total:
149
275
  self._progress.stop()
150
276
  self._progress = None
151
277
  self._task = None
152
278
 
153
- if self._live is not None:
154
- self._live.update(self, refresh=True)
155
- self._live.stop()
156
- self._live = None
157
-
158
- if not in_notebook():
159
- sys.stdout.write("\x1b]9;4;0\x07")
160
- sys.stdout.flush()
161
-
162
279
  def __rich_console__(
163
280
  self,
164
281
  console: Console,
@@ -189,7 +306,7 @@ class RichProgressLogger(ProgressLogger):
189
306
 
190
307
  yield table
191
308
 
192
- if self.verbose and self._progress is not None:
309
+ if self._progress is not None:
193
310
  yield self._progress.get_renderable()
194
311
 
195
312
 
@@ -202,78 +319,49 @@ class StreamlitProgressLogger(ProgressLogger):
202
319
  super().__init__(msg=msg, verbose=verbose)
203
320
 
204
321
  self._status: Any = None
205
-
206
- self._total = 0
207
- self._current = 0
208
- self._description: str = ''
209
322
  self._progress: Any = None
210
323
 
211
- def __enter__(self) -> Self:
212
- super().__enter__()
324
+ @staticmethod
325
+ def _sanitize_text(msg: str) -> str:
326
+ return re.sub(r'\[/?bold\]', '**', msg)
213
327
 
328
+ def on_enter(self) -> None:
214
329
  import streamlit as st
215
330
 
216
331
  # Adjust layout for prettier output:
217
332
  st.markdown(STREAMLIT_CSS, unsafe_allow_html=True)
218
333
 
219
- if self.verbose:
220
- self._status = st.status(
221
- f':blue[{self._sanitize_text(self.msg)}]',
334
+ self._status = st.status(
335
+ f':blue[{self._sanitize_text(self.msg)}]',
336
+ expanded=True,
337
+ )
338
+
339
+ def on_exit(self, error: bool) -> None:
340
+ if self._status is not None:
341
+ label = f'{self._sanitize_text(self.msg)} ({self.duration:.2f}s)'
342
+ self._status.update(
343
+ label=f':red[{label}]' if error else f':green[{label}]',
344
+ state='error' if error else 'complete',
222
345
  expanded=True,
223
346
  )
224
347
 
225
- return self
348
+ def on_log(self, msg: str) -> None:
349
+ if self._status is not None:
350
+ self._status.write(msg)
226
351
 
227
- def log(self, msg: str) -> None:
228
- super().log(msg)
229
- if self.verbose and self._status is not None:
230
- self._status.write(self._sanitize_text(msg))
231
-
232
- def init_progress(self, total: int, description: str) -> None:
233
- if self.verbose and self._status is not None:
234
- self._total = total
235
- self._current = 0
236
- self._description = self._sanitize_text(description)
237
- percent = min(self._current / self._total, 1.0)
352
+ def on_init_progress(self, msg: str, total: int) -> None:
353
+ if self._status is not None:
238
354
  self._progress = self._status.progress(
239
- value=percent,
240
- text=f'{self._description} [{self._current}/{self._total}]',
355
+ value=0.0,
356
+ text=f'{msg} [{0}/{total}]',
241
357
  )
242
358
 
243
- def step(self) -> None:
244
- self._current += 1
245
-
246
- if self.verbose and self._progress is not None:
247
- percent = min(self._current / self._total, 1.0)
359
+ def on_step(self, msg: str, current: int, total: int) -> None:
360
+ if self._progress is not None:
248
361
  self._progress.progress(
249
- value=percent,
250
- text=f'{self._description} [{self._current}/{self._total}]',
251
- )
252
-
253
- def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
254
- super().__exit__(exc_type, exc_val, exc_tb)
255
-
256
- if not self.verbose or self._status is None:
257
- return
258
-
259
- label = f'{self._sanitize_text(self.msg)} ({self.duration:.2f}s)'
260
-
261
- if exc_type is not None:
262
- self._status.update(
263
- label=f':red[{label}]',
264
- state='error',
265
- expanded=True,
362
+ value=min(current / total, 1.0),
363
+ text=f'{msg} [{current}/{total}]',
266
364
  )
267
- else:
268
- self._status.update(
269
- label=f':green[{label}]',
270
- state='complete',
271
- expanded=True,
272
- )
273
-
274
- @staticmethod
275
- def _sanitize_text(msg: str) -> str:
276
- return re.sub(r'\[/?bold\]', '**', msg)
277
365
 
278
366
 
279
367
  STREAMLIT_CSS = """
kumoai/utils/sql.py CHANGED
@@ -1,3 +1,3 @@
1
- def quote_ident(name: str) -> str:
1
+ def quote_ident(ident: str, char: str = '"') -> str:
2
2
  r"""Quotes a SQL identifier."""
3
- return '"' + name.replace('"', '""') + '"'
3
+ return char + ident.replace(char, char + char) + char
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kumoai
3
- Version: 2.14.0.dev202512211732
3
+ Version: 2.15.0.dev202601181732
4
4
  Summary: AI on the Modern Data Stack
5
5
  Author-email: "Kumo.AI" <hello@kumo.ai>
6
6
  License-Expression: MIT
@@ -23,7 +23,7 @@ Requires-Dist: requests>=2.28.2
23
23
  Requires-Dist: urllib3
24
24
  Requires-Dist: plotly
25
25
  Requires-Dist: typing_extensions>=4.5.0
26
- Requires-Dist: kumo-api==0.49.0
26
+ Requires-Dist: kumo-api<1.0.0,>=0.53.0
27
27
  Requires-Dist: tqdm>=4.66.0
28
28
  Requires-Dist: aiohttp>=3.10.0
29
29
  Requires-Dist: pydantic>=1.10.21
@@ -1,8 +1,8 @@
1
1
  kumoai/kumolib.cpython-313-darwin.so,sha256=waBv-DiZ3WcasxiCQ-OM9EbSTgTtCfBTZIibXAK-JiQ,232816
2
2
  kumoai/_logging.py,sha256=U2_5ROdyk92P4xO4H2WJV8EC7dr6YxmmnM-b7QX9M7I,886
3
3
  kumoai/mixin.py,sha256=MP413xzuCqWhxAPUHmloLA3j4ZyF1tEtfi516b_hOXQ,812
4
- kumoai/_version.py,sha256=r_ZJN4_1Q2z42px3GUoxeFu6s1G0ZVF0s5q_k2WJWS8,39
5
- kumoai/__init__.py,sha256=Nn9YH_x9kAeEFn8RWbP95slZow0qFnakPZZ1WADe1hY,10843
4
+ kumoai/_version.py,sha256=2ksd2GuX-AZRJGtcuDxCIRV0etIpcKZFRxJlf6Of638,39
5
+ kumoai/__init__.py,sha256=n2Mi2n5S_WKpxpCInQKfGEmsIWVwrX86nGnYn5HwtIE,11171
6
6
  kumoai/formatting.py,sha256=jA_rLDCGKZI8WWCha-vtuLenVKTZvli99Tqpurz1H84,953
7
7
  kumoai/futures.py,sha256=oJFIfdCM_3nWIqQteBKYMY4fPhoYlYWE_JA2o6tx-ng,3737
8
8
  kumoai/jobs.py,sha256=NrdLEFNo7oeCYSy-kj2nAvCFrz9BZ_xrhkqHFHk5ksY,2496
@@ -11,42 +11,45 @@ kumoai/databricks.py,sha256=e6E4lOFvZHXFwh4CO1kXU1zzDU3AapLQYMxjiHPC-HQ,476
11
11
  kumoai/spcs.py,sha256=N31d7rLa-bgYh8e2J4YzX1ScxGLqiVXrqJnCl1y4Mts,4139
12
12
  kumoai/_singleton.py,sha256=UTwrbDkoZSGB8ZelorvprPDDv9uZkUi1q_SrmsyngpQ,836
13
13
  kumoai/experimental/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- kumoai/experimental/rfm/graph.py,sha256=63Sovf7Da4q3FLRKTMcImB4v_VkjC87AdCBQm385w6w,46270
15
- kumoai/experimental/rfm/__init__.py,sha256=9aelcHodt2Oriw76vdEmtWrmAQ0CXTdFPrKgwVB9eKc,7124
14
+ kumoai/experimental/rfm/relbench.py,sha256=cVsxxV3TIL3PLEoYb-8tAVW3GSef6NQAd3rxdHJL63I,2276
15
+ kumoai/experimental/rfm/graph.py,sha256=4Jo17oYSoZouzvNQT2-Ai9GOX-bIdefPcxj_gcoM3dI,46873
16
+ kumoai/experimental/rfm/__init__.py,sha256=bW2XyYtkbdiu_iICYFF2Fu1Fx5fyGbqne6m_6c1P-fY,7016
16
17
  kumoai/experimental/rfm/sagemaker.py,sha256=6fyXO1Jd_scq-DH7kcv6JcV8QPyTbh4ceqwQDPADlZ0,4963
17
- kumoai/experimental/rfm/rfm.py,sha256=Yssmo-PaCfjT9hll0BKl8fahsuKpG-gViwFdKH1F3os,50247
18
+ kumoai/experimental/rfm/rfm.py,sha256=XsxwiDIvlZ_js7rvvffrOiXFsLX15-C7N0T9M-aptCw,60017
18
19
  kumoai/experimental/rfm/authenticate.py,sha256=G2RkRWznMVQUzvhvbKhn0bMCY7VmoNYxluz3THRqSdE,18851
20
+ kumoai/experimental/rfm/task_table.py,sha256=n_gZNQlCqHOiAkbeaa18nnQ-amt1oWKA9riO2rkrZuw,9847
19
21
  kumoai/experimental/rfm/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
22
  kumoai/experimental/rfm/backend/sqlite/__init__.py,sha256=jl-DBbhsqQ-dUXyWhyQTM1AU2qNAtXCmi1mokdhtBTg,902
21
- kumoai/experimental/rfm/backend/sqlite/table.py,sha256=JpHtA6Sdz96VpqC73h_1YnuW8mQ9cMInG6y4KmjZYHE,5983
22
- kumoai/experimental/rfm/backend/sqlite/sampler.py,sha256=pBCj0bXnh1PMg9cYJw-K983FzJX1_SLOe3QuOxkmvBQ,14242
23
+ kumoai/experimental/rfm/backend/sqlite/table.py,sha256=WqYtd_rwlawItRMXZUfv14qdyU6huQmODuFjDo483dI,6683
24
+ kumoai/experimental/rfm/backend/sqlite/sampler.py,sha256=I-zaSMd5XLg0qaJOoCR8arFBauUfhW_ZMl7gI97ress,18699
23
25
  kumoai/experimental/rfm/backend/local/__init__.py,sha256=2s9sSA-E-8pfkkzCH4XPuaSxSznEURMfMgwEIfYYPsg,1014
24
- kumoai/experimental/rfm/backend/local/table.py,sha256=VP3s-MgWKXPjezgRfc2bxr-9Fp2X5i9V2Do0IiNAmVM,3819
25
- kumoai/experimental/rfm/backend/local/graph_store.py,sha256=cY9KeLir9Xsp4MJl_K0VZckNa_LMKiiWCZG14uu21JI,11854
26
- kumoai/experimental/rfm/backend/local/sampler.py,sha256=85HoHCDiFOiuD_vFPZRx9JCyQUlLsqgsuB3NAw50wNw,10836
26
+ kumoai/experimental/rfm/backend/local/table.py,sha256=GKeYGcu52ztCU8EBMqp5UVj85E145Ug41xiCPiTCXq4,3489
27
+ kumoai/experimental/rfm/backend/local/graph_store.py,sha256=RHhkI13KpdPxqb4vXkwEwuFiX5DkrEsfZsOLywNnrvU,11294
28
+ kumoai/experimental/rfm/backend/local/sampler.py,sha256=UKxTjsYs00sYuV_LAlDuZOvQq0BZzPCzZK1Fki2Fd70,10726
27
29
  kumoai/experimental/rfm/backend/snow/__init__.py,sha256=BYfsiuJ4Ee30GjG9EuUtitMHXnRfvVKi85zNlIwldV4,993
28
- kumoai/experimental/rfm/backend/snow/table.py,sha256=0W4jtb3MdYpsGzjU7UBS8xt8yfvYIou3nX4woVd-vZQ,6282
29
- kumoai/experimental/rfm/backend/snow/sampler.py,sha256=oNiBTo-Dr6LNCFJ9uHzLfKFYtx0rZq-Do2UOluwWWt0,10010
30
+ kumoai/experimental/rfm/backend/snow/table.py,sha256=1RXpPiTxawTTOFprXvu7jDLG0ZGio_vE9lSfB6wqbWM,9078
31
+ kumoai/experimental/rfm/backend/snow/sampler.py,sha256=tDOEiPTFFG6pWDcuuTvaOBAsMJLsxu4PzqryIgH1Kb4,16322
30
32
  kumoai/experimental/rfm/pquery/__init__.py,sha256=X0O3EIq5SMfBEE-ii5Cq6iDhR3s3XMXB52Cx5htoePw,152
31
33
  kumoai/experimental/rfm/pquery/pandas_executor.py,sha256=MwSvFRwLq-z19LEdF0G0AT7Gj9tCqu-XLEA7mNbqXwc,18454
32
34
  kumoai/experimental/rfm/pquery/executor.py,sha256=gs5AVNaA50ci8zXOBD3qt5szdTReSwTs4BGuEyx4BEE,2728
33
- kumoai/experimental/rfm/infer/multicategorical.py,sha256=0-cLpDnGryhr76QhZNO-klKokJ6MUSfxXcGdQ61oykY,1102
35
+ kumoai/experimental/rfm/infer/multicategorical.py,sha256=lNO_8aJw1whO6QVEMB3PRWMNlEEiX44g3v4tP88TSQY,1119
34
36
  kumoai/experimental/rfm/infer/categorical.py,sha256=VwNaKwKbRYkTxEJ1R6gziffC8dGsEThcDEfbi-KqW5c,853
35
- kumoai/experimental/rfm/infer/time_col.py,sha256=oNenUK6P7ql8uwShodtQ73uG1x3fbFWT78jRcF9DLTI,1789
37
+ kumoai/experimental/rfm/infer/time_col.py,sha256=iw_aUcHD2bHr7uRa3E7uDC30kU37aLIRTVAFdQEpt68,1818
36
38
  kumoai/experimental/rfm/infer/pkey.py,sha256=IaJI5GHK8ds_a3AOr3YYVgUlSmYYEgr4Nu92s2RyBV4,4412
37
39
  kumoai/experimental/rfm/infer/id.py,sha256=ZIO0DWIoiEoS_8MVc5lkqBfkTWWQ0yGCgjkwLdaYa_Q,908
38
- kumoai/experimental/rfm/infer/dtype.py,sha256=rzZRafxjr_mhvC7jeAZHVBvlbHJwmHvMlQqDuuePX8k,2635
40
+ kumoai/experimental/rfm/infer/dtype.py,sha256=fbRRyyKSzO4riqX3RlhvBK7DhnjhwTgZVUjQ9inVPYI,2811
39
41
  kumoai/experimental/rfm/infer/__init__.py,sha256=8GDxQKd0pxZULdk7mpwl3CsOpL4v2HPuPEsbi2t_vzc,519
40
42
  kumoai/experimental/rfm/infer/timestamp.py,sha256=vM9--7eStzaGG13Y-oLYlpNJyhL6f9dp17HDXwtl_DM,1094
41
43
  kumoai/experimental/rfm/infer/stype.py,sha256=fu4zsOB-C7jNeMnq6dsK4bOZSewe7PtZe_AkohSRLoM,894
42
- kumoai/experimental/rfm/base/sql_sampler.py,sha256=-2dyftqvfbzMceIhE6i4wYFt7-p7FDeqlfH4P--qjWw,2598
43
- kumoai/experimental/rfm/base/__init__.py,sha256=E8Zrh52vczubhepBbS5AIe5wiBFeXbQCzfQ1-jLg_rU,885
44
- kumoai/experimental/rfm/base/sql_table.py,sha256=JP-fX8SLHGKeltMxkc2gdQ4RwW0DU3QHg5sjixMXRLs,8251
45
- kumoai/experimental/rfm/base/table.py,sha256=bRn3lP0Vc5uxCgsH8YD3aeMY6MnVTxi7eCMj92MhcfM,20446
46
- kumoai/experimental/rfm/base/column_expression.py,sha256=OoZXSaQRB7cBLVDEg1gcp65jHpUUO7e-vW-_asiAUPo,1261
47
- kumoai/experimental/rfm/base/sampler.py,sha256=aCD98t0CUhAvGXEFv24Vq2g4otuclpKkkyL1rMR_mFg,31449
48
- kumoai/experimental/rfm/base/source.py,sha256=RqlI_kBoRV0ADb8KdEKn15RNHMdFUzEVzb57lIoyBM4,294
49
- kumoai/experimental/rfm/base/column.py,sha256=wmKlqixNCmrmrAhSHfymJp76izpaykF9bdxNqgKbJzw,2288
44
+ kumoai/experimental/rfm/base/sql_sampler.py,sha256=_go8TnH7AHki-0gg_pB7xd228VYhogQh10OkxT7PEnI,15682
45
+ kumoai/experimental/rfm/base/mapper.py,sha256=WbWXSF8Vkdeud7UeQ2JgSX7z4d27b_b6o7nR4zET1aw,2420
46
+ kumoai/experimental/rfm/base/__init__.py,sha256=rjmMux5lG8srw1bjQGcFQFv6zET9e5riP81nPkw28Jg,724
47
+ kumoai/experimental/rfm/base/utils.py,sha256=Easg1bvjPLR8oZIoxIQCtCyl92pp2dUskdnSv1eayxQ,1133
48
+ kumoai/experimental/rfm/base/table.py,sha256=eJuOUM64VWDkHaslNgeR5A_FZjlPF_4czC8OfFGR62E,26015
49
+ kumoai/experimental/rfm/base/sampler.py,sha256=2G6VmgAGV1mSQWHK4wUgf5Ngr8nnH8Hg6_D3sPZZx1A,31951
50
+ kumoai/experimental/rfm/base/expression.py,sha256=Y7NtLTnKlx6euG_N3fLTcrFKheB6P5KS_jhCfoXV9DE,1252
51
+ kumoai/experimental/rfm/base/source.py,sha256=bwu3GU2TvIXR2fwKAmJ1-5BDoNXMnI1SU3Fgdk8lWnc,301
52
+ kumoai/experimental/rfm/base/column.py,sha256=GXzLC-VpShr6PecUzaj1MJKc_PHzfW5Jn9bOYPA8fFA,4965
50
53
  kumoai/encoder/__init__.py,sha256=VPGs4miBC_WfwWeOXeHhFomOUocERFavhKf5fqITcds,182
51
54
  kumoai/graph/graph.py,sha256=iyp4klPIMn2ttuEqMJvsrxKb_tmz_DTnvziIhCegduM,38291
52
55
  kumoai/graph/__init__.py,sha256=n8X4X8luox4hPBHTRC9R-3JzvYYMoR8n7lF1H4w4Hzc,228
@@ -57,8 +60,9 @@ kumoai/artifact_export/job.py,sha256=GEisSwvcjK_35RgOfsLXGgxMTXIWm765B_BW_Kgs-V0
57
60
  kumoai/artifact_export/__init__.py,sha256=BsfDrc3mCHpO9-BqvqKm8qrXDIwfdaoH5UIoG4eQkc4,238
58
61
  kumoai/utils/datasets.py,sha256=ptKIUoBONVD55pTVNdRCkQT3NWdN_r9UAUu4xewPa3U,2928
59
62
  kumoai/utils/__init__.py,sha256=6S-UtwjeLpnCYRCCIEWhkitPYGaqOGXC1ChE13DzXiU,256
60
- kumoai/utils/progress_logger.py,sha256=3aYOoVSbQv5i9m2T8IqMydofKf6iNB1jxsl1uGjHZz8,9265
61
- kumoai/utils/sql.py,sha256=f6lR6rBEW7Dtk0NdM26dOZXUHDizEHb1WPlBCJrwoq0,118
63
+ kumoai/utils/display.py,sha256=QmgeQQT7SzoC1CK2A0ftWbfkEuVN4KQfrKoPCrCDaGc,2626
64
+ kumoai/utils/progress_logger.py,sha256=1PtXxfMteg2nyQAfTGx6qnljiZMZvhwDTndQ9_4_nCE,12161
65
+ kumoai/utils/sql.py,sha256=CNKa-M56QiWoCSe9WLuumahsu3_ugQGr2YoTbveFHq0,147
62
66
  kumoai/utils/forecasting.py,sha256=-nDS6ucKNfQhTQOfebjefj0wwWH3-KYNslIomxwwMBM,7415
63
67
  kumoai/codegen/generate.py,sha256=SvfWWa71xSAOjH9645yQvgoEM-o4BYjupM_EpUxqB_E,7331
64
68
  kumoai/codegen/naming.py,sha256=_XVQGxHfuub4bhvyuBKjltD5Lm_oPpibvP_LZteCGk0,3021
@@ -76,7 +80,7 @@ kumoai/codegen/handlers/__init__.py,sha256=k8TB_Kn-1BycBBi51kqFS2fZHCpCPgR9-3J9g
76
80
  kumoai/codegen/handlers/utils.py,sha256=58b2GCgaTBUp2aId7BLMXMV0ENrusbNbfw7mlyXAXPE,1447
77
81
  kumoai/codegen/handlers/connector.py,sha256=afGf_GreyQ9y6qF3QTgSiM416qtUcP298SatNqUFhvQ,3828
78
82
  kumoai/codegen/handlers/table.py,sha256=POHpA-GFYFGTSuerGmtigYablk-Wq1L3EBvsOI-iFMQ,3956
79
- kumoai/testing/snow.py,sha256=ubx3yJP0UHxsNiar1-jNdv8ZfszKc8Js3_Gg70uf008,1487
83
+ kumoai/testing/snow.py,sha256=S2ayiJ0WCZQdPKYiAKqT8OkQEw0xjYjOgDtGcjs3o7Q,1526
80
84
  kumoai/testing/__init__.py,sha256=goHIIo3JE7uHV7njo4_aTd89mVVR74BEAZ2uyBaOR0w,170
81
85
  kumoai/testing/decorators.py,sha256=83tMifuPTpUqX7zHxMttkj1TDdB62EBtAP-Fjj72Zdo,1607
82
86
  kumoai/connector/glue_connector.py,sha256=HivT0QYQ8-XeB4QLgWvghiqXuq7jyBK9G2R1py_NnE4,4697
@@ -86,20 +90,20 @@ kumoai/connector/bigquery_connector.py,sha256=IkyRqvF8Cg96kApUuuz86eYnl-BqBmDX1f
86
90
  kumoai/connector/source_table.py,sha256=QLT8bEYaxeMwy-b168url0VfnkTrs5K6VKLbxTI4hEY,17539
87
91
  kumoai/connector/__init__.py,sha256=9g6oNJ0qHWFlL5enTSoK4_SSH_5hP74xUDZx-9SggC4,842
88
92
  kumoai/connector/file_upload_connector.py,sha256=swp03HgChOvmNPJetuujBSAqADe7NRmS_T0F3o9it4w,7008
89
- kumoai/connector/utils.py,sha256=wlqQxMmPvnFNoCcczGkKYjSu05h8OhWh4fhTzQm_2bQ,64694
93
+ kumoai/connector/utils.py,sha256=sD3_Dmf42FobMfVayzMVkDHIfXzPN-htD3RHd6Kw8hQ,65055
90
94
  kumoai/connector/s3_connector.py,sha256=3kbv-h7DwD8O260Q0h1GPm5wwQpLt-Tb3d_CBSaie44,10155
91
95
  kumoai/connector/base.py,sha256=cujXSZF3zAfuxNuEw54DSL1T7XCuR4t0shSMDuPUagQ,5291
92
96
  kumoai/pquery/__init__.py,sha256=uTXr7t1eXcVfM-ETaM_1ImfEqhrmaj8BjiIvy1YZTL8,533
93
97
  kumoai/pquery/predictive_query.py,sha256=UXn1s8ztubYZMNGl4ijaeidMiGlFveb1TGw9qI5-TAo,24901
94
98
  kumoai/pquery/prediction_table.py,sha256=QPDH22X1UB0NIufY7qGuV2XW7brG3Pv--FbjNezzM2g,10776
95
- kumoai/pquery/training_table.py,sha256=elmPDZx11kPiC_dkOhJcBUGtHKgL32GCBvZ9k6U0pMg,15809
99
+ kumoai/pquery/training_table.py,sha256=QsZbqA1o-hFSi8GygtDQgYKFi8-3Ur2PftnpgAMqAec,16566
96
100
  kumoai/client/pquery.py,sha256=IQ8As-OOJOkuMoMosphOsA5hxQYLCbzOQJO7RezK8uY,7091
97
- kumoai/client/client.py,sha256=Jda8V9yiu3LbhxlcgRWPeYi7eF6jzCKcq8-B_vEd1ik,8514
101
+ kumoai/client/client.py,sha256=npTLooBtmZ9xOo7AbEiYQTh9wFktsGSEpSEfdB7vdB4,8715
98
102
  kumoai/client/graph.py,sha256=zvLEDExLT_RVbUMHqVl0m6tO6s2gXmYSoWmPF6YMlnA,3831
99
103
  kumoai/client/online.py,sha256=pkBBh_DEC3GAnPcNw6bopNRlGe7EUbIFe7_seQqZRaw,2720
100
104
  kumoai/client/source_table.py,sha256=VCsCcM7KYcnjGP7HLTb-AOSEGEVsJTWjk8bMg1JdgPU,2101
101
105
  kumoai/client/__init__.py,sha256=MkyOuMaHQ2c8GPxjBDQSVFhfRE2d2_6CXQ6rxj4ps4w,64
102
- kumoai/client/jobs.py,sha256=iu_Wrta6BQMlV6ZtzSnmhjwNPKDMQDXOsqVVIyWodqw,17074
106
+ kumoai/client/jobs.py,sha256=Aq-JO5yfU5BvD5_8ZXJ8NYxsE4yFXj_NdG9-ilymsr4,18164
103
107
  kumoai/client/utils.py,sha256=lz1NubwMDHCwzQRowRXm7mjAoYRd5UjRQIwXdtWAl90,3849
104
108
  kumoai/client/connector.py,sha256=x3i2aBTJTEMZvYRcWkY-UfWVOANZjqAso4GBbcshFjw,3920
105
109
  kumoai/client/table.py,sha256=cQG-RPm-e91idEgse1IPJDvBmzddIDGDkuyrR1rq4wU,3235
@@ -111,9 +115,10 @@ kumoai/trainer/job.py,sha256=Wk69nzFhbvuA3nEvtCstI04z5CxkgvQ6tHnGchE0Lkg,44938
111
115
  kumoai/trainer/baseline_trainer.py,sha256=LlfViNOmswNv4c6zJJLsyv0pC2mM2WKMGYx06ogtEVc,4024
112
116
  kumoai/trainer/__init__.py,sha256=zUdFl-f-sBWmm2x8R-rdVzPBeU2FaMzUY5mkcgoTa1k,939
113
117
  kumoai/trainer/online_serving.py,sha256=9cddb5paeZaCgbUeceQdAOxysCtV5XP-KcsgFz_XR5w,9566
118
+ kumoai/trainer/distilled_trainer.py,sha256=2pPs5clakNxkLfaak7uqPJOrpTWe1RVVM7ztDSqQZvU,6484
114
119
  kumoai/trainer/trainer.py,sha256=hBXO7gwpo3t59zKFTeIkK65B8QRmWCwO33sbDuEAPlY,20133
115
- kumoai-2.14.0.dev202512211732.dist-info/RECORD,,
116
- kumoai-2.14.0.dev202512211732.dist-info/WHEEL,sha256=oqGJCpG61FZJmvyZ3C_0aCv-2mdfcY9e3fXvyUNmWfM,136
117
- kumoai-2.14.0.dev202512211732.dist-info/top_level.txt,sha256=YjU6UcmomoDx30vEXLsOU784ED7VztQOsFApk1SFwvs,7
118
- kumoai-2.14.0.dev202512211732.dist-info/METADATA,sha256=Vz_IsRTT5aua1Y4hwKx5cfyOucfGCb2VsE1ThYwSqI4,2557
119
- kumoai-2.14.0.dev202512211732.dist-info/licenses/LICENSE,sha256=TbWlyqRmhq9PEzCaTI0H0nWLQCCOywQM8wYH8MbjfLo,1102
120
+ kumoai-2.15.0.dev202601181732.dist-info/RECORD,,
121
+ kumoai-2.15.0.dev202601181732.dist-info/WHEEL,sha256=oqGJCpG61FZJmvyZ3C_0aCv-2mdfcY9e3fXvyUNmWfM,136
122
+ kumoai-2.15.0.dev202601181732.dist-info/top_level.txt,sha256=YjU6UcmomoDx30vEXLsOU784ED7VztQOsFApk1SFwvs,7
123
+ kumoai-2.15.0.dev202601181732.dist-info/METADATA,sha256=ETr8-9Zfq1pM_Smk8KOWZZm14cRdtNl9vcd_hqSQBKg,2564
124
+ kumoai-2.15.0.dev202601181732.dist-info/licenses/LICENSE,sha256=TbWlyqRmhq9PEzCaTI0H0nWLQCCOywQM8wYH8MbjfLo,1102
@@ -1,50 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import Any, TypeAlias
3
-
4
- from kumoapi.typing import Dtype, Stype
5
-
6
- from kumoai.experimental.rfm.base import Column
7
- from kumoai.mixin import CastMixin
8
-
9
-
10
- @dataclass(frozen=True)
11
- class ColumnExpressionSpec(CastMixin):
12
- name: str
13
- expr: str
14
- dtype: Dtype | None = None
15
-
16
-
17
- ColumnExpressionType: TypeAlias = ColumnExpressionSpec | dict[str, Any]
18
-
19
-
20
- @dataclass(init=False, repr=False, eq=False)
21
- class ColumnExpression(Column):
22
- def __init__(
23
- self,
24
- name: str,
25
- expr: str,
26
- stype: Stype,
27
- dtype: Dtype,
28
- ) -> None:
29
- super().__init__(name=name, stype=stype, dtype=dtype)
30
- self._expr = expr
31
-
32
- @property
33
- def expr(self) -> str:
34
- return self._expr
35
-
36
- @property
37
- def is_physical(self) -> bool:
38
- return False
39
-
40
- def __hash__(self) -> int:
41
- return hash((self.name, self.expr, self.stype, self.dtype))
42
-
43
- def __eq__(self, other: Any) -> bool:
44
- if not isinstance(other, ColumnExpression):
45
- return False
46
- return hash(self) == hash(other)
47
-
48
- def __repr__(self) -> str:
49
- return (f'{self.__class__.__name__}(name={self.name}, '
50
- f'expr={self.expr}, stype={self.stype}, dtype={self.dtype})')