kumoai 2.13.0.dev202511131731__cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.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.
Potentially problematic release.
This version of kumoai might be problematic. Click here for more details.
- kumoai/__init__.py +294 -0
- kumoai/_logging.py +29 -0
- kumoai/_singleton.py +25 -0
- kumoai/_version.py +1 -0
- kumoai/artifact_export/__init__.py +9 -0
- kumoai/artifact_export/config.py +209 -0
- kumoai/artifact_export/job.py +108 -0
- kumoai/client/__init__.py +5 -0
- kumoai/client/client.py +221 -0
- kumoai/client/connector.py +110 -0
- kumoai/client/endpoints.py +150 -0
- kumoai/client/graph.py +120 -0
- kumoai/client/jobs.py +447 -0
- kumoai/client/online.py +78 -0
- kumoai/client/pquery.py +203 -0
- kumoai/client/rfm.py +112 -0
- kumoai/client/source_table.py +53 -0
- kumoai/client/table.py +101 -0
- kumoai/client/utils.py +130 -0
- kumoai/codegen/__init__.py +19 -0
- kumoai/codegen/cli.py +100 -0
- kumoai/codegen/context.py +16 -0
- kumoai/codegen/edits.py +473 -0
- kumoai/codegen/exceptions.py +10 -0
- kumoai/codegen/generate.py +222 -0
- kumoai/codegen/handlers/__init__.py +4 -0
- kumoai/codegen/handlers/connector.py +118 -0
- kumoai/codegen/handlers/graph.py +71 -0
- kumoai/codegen/handlers/pquery.py +62 -0
- kumoai/codegen/handlers/table.py +109 -0
- kumoai/codegen/handlers/utils.py +42 -0
- kumoai/codegen/identity.py +114 -0
- kumoai/codegen/loader.py +93 -0
- kumoai/codegen/naming.py +94 -0
- kumoai/codegen/registry.py +121 -0
- kumoai/connector/__init__.py +31 -0
- kumoai/connector/base.py +153 -0
- kumoai/connector/bigquery_connector.py +200 -0
- kumoai/connector/databricks_connector.py +213 -0
- kumoai/connector/file_upload_connector.py +189 -0
- kumoai/connector/glue_connector.py +150 -0
- kumoai/connector/s3_connector.py +278 -0
- kumoai/connector/snowflake_connector.py +252 -0
- kumoai/connector/source_table.py +471 -0
- kumoai/connector/utils.py +1775 -0
- kumoai/databricks.py +14 -0
- kumoai/encoder/__init__.py +4 -0
- kumoai/exceptions.py +26 -0
- kumoai/experimental/__init__.py +0 -0
- kumoai/experimental/rfm/__init__.py +67 -0
- kumoai/experimental/rfm/authenticate.py +433 -0
- kumoai/experimental/rfm/infer/__init__.py +11 -0
- kumoai/experimental/rfm/infer/categorical.py +40 -0
- kumoai/experimental/rfm/infer/id.py +46 -0
- kumoai/experimental/rfm/infer/multicategorical.py +48 -0
- kumoai/experimental/rfm/infer/timestamp.py +41 -0
- kumoai/experimental/rfm/local_graph.py +810 -0
- kumoai/experimental/rfm/local_graph_sampler.py +184 -0
- kumoai/experimental/rfm/local_graph_store.py +359 -0
- kumoai/experimental/rfm/local_pquery_driver.py +689 -0
- kumoai/experimental/rfm/local_table.py +545 -0
- kumoai/experimental/rfm/pquery/__init__.py +7 -0
- kumoai/experimental/rfm/pquery/executor.py +102 -0
- kumoai/experimental/rfm/pquery/pandas_executor.py +532 -0
- kumoai/experimental/rfm/rfm.py +1130 -0
- kumoai/experimental/rfm/utils.py +344 -0
- kumoai/formatting.py +30 -0
- kumoai/futures.py +99 -0
- kumoai/graph/__init__.py +12 -0
- kumoai/graph/column.py +106 -0
- kumoai/graph/graph.py +948 -0
- kumoai/graph/table.py +838 -0
- kumoai/jobs.py +80 -0
- kumoai/kumolib.cpython-313-x86_64-linux-gnu.so +0 -0
- kumoai/mixin.py +28 -0
- kumoai/pquery/__init__.py +25 -0
- kumoai/pquery/prediction_table.py +287 -0
- kumoai/pquery/predictive_query.py +637 -0
- kumoai/pquery/training_table.py +424 -0
- kumoai/spcs.py +123 -0
- kumoai/testing/__init__.py +8 -0
- kumoai/testing/decorators.py +57 -0
- kumoai/trainer/__init__.py +42 -0
- kumoai/trainer/baseline_trainer.py +93 -0
- kumoai/trainer/config.py +2 -0
- kumoai/trainer/job.py +1192 -0
- kumoai/trainer/online_serving.py +258 -0
- kumoai/trainer/trainer.py +475 -0
- kumoai/trainer/util.py +103 -0
- kumoai/utils/__init__.py +10 -0
- kumoai/utils/datasets.py +83 -0
- kumoai/utils/forecasting.py +209 -0
- kumoai/utils/progress_logger.py +177 -0
- kumoai-2.13.0.dev202511131731.dist-info/METADATA +60 -0
- kumoai-2.13.0.dev202511131731.dist-info/RECORD +98 -0
- kumoai-2.13.0.dev202511131731.dist-info/WHEEL +6 -0
- kumoai-2.13.0.dev202511131731.dist-info/licenses/LICENSE +9 -0
- kumoai-2.13.0.dev202511131731.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
from typing import Dict, List
|
|
2
|
+
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import plotly.graph_objects as go
|
|
5
|
+
from plotly.subplots import make_subplots
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ForecastVisualizer:
|
|
9
|
+
r"""A tool for quickly visualizing forecast results from the holdout
|
|
10
|
+
dataframe of a forecasting job.
|
|
11
|
+
|
|
12
|
+
.. code-block:: python
|
|
13
|
+
|
|
14
|
+
import kumoai
|
|
15
|
+
|
|
16
|
+
# Retrieve job results from a training training job. Note
|
|
17
|
+
# that the job ID passed here must be in a completed state:
|
|
18
|
+
job_result = kumoai.TrainingJob("trainingjob-...").result()
|
|
19
|
+
|
|
20
|
+
# Read the holdout table as a Pandas DataFrame:
|
|
21
|
+
holdout_df = job_result.holdout_df()
|
|
22
|
+
|
|
23
|
+
# Pass holdout table to ForecastVisualizer and visualize results
|
|
24
|
+
holdout_forecast = kumoai.utils.ForecastVisualizer(holdout_df)
|
|
25
|
+
holdout_forecast.visualize()
|
|
26
|
+
"""
|
|
27
|
+
def __init__(self, holdout_df: pd.DataFrame) -> None:
|
|
28
|
+
# Sort the holdout dataframe and extract unique entities:
|
|
29
|
+
self.forecast = holdout_df.sort_values(['ENTITY', 'TIMESTAMP'])
|
|
30
|
+
self.entities = holdout_df['ENTITY'].unique().tolist()
|
|
31
|
+
|
|
32
|
+
self.fig = self._initialize_subplot()
|
|
33
|
+
self.buttons: List[Dict] = []
|
|
34
|
+
self.plot_config = {
|
|
35
|
+
'target': {
|
|
36
|
+
'color': 'blue',
|
|
37
|
+
'name': 'TARGET'
|
|
38
|
+
},
|
|
39
|
+
'prediction': {
|
|
40
|
+
'color': 'red',
|
|
41
|
+
'name': 'TARGET_PRED'
|
|
42
|
+
},
|
|
43
|
+
'residuals': {
|
|
44
|
+
'color': 'green',
|
|
45
|
+
'name': 'Residuals'
|
|
46
|
+
},
|
|
47
|
+
'residuals_time': {
|
|
48
|
+
'color': 'orange',
|
|
49
|
+
'name': 'Residuals Over Time'
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@staticmethod
|
|
54
|
+
def _initialize_subplot() -> go.Figure:
|
|
55
|
+
r"""Initializes the subplot structure with three rows:
|
|
56
|
+
Row 1: Line plot of actual forecast vs predicted
|
|
57
|
+
Row 2: Line plot of residuals overtime
|
|
58
|
+
Row 3: Histogram distribution of residuals
|
|
59
|
+
"""
|
|
60
|
+
return make_subplots(
|
|
61
|
+
rows=3,
|
|
62
|
+
cols=1,
|
|
63
|
+
specs=[[{
|
|
64
|
+
"type": "scatter"
|
|
65
|
+
}], [{
|
|
66
|
+
"type": "scatter"
|
|
67
|
+
}], [{
|
|
68
|
+
"type": "xy"
|
|
69
|
+
}]],
|
|
70
|
+
row_heights=[0.5, 0.25, 0.25],
|
|
71
|
+
subplot_titles=('Forecast vs Actual', 'Residuals Over Time',
|
|
72
|
+
'Residuals Distribution'),
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
def _create_time_series_trace(
|
|
76
|
+
self,
|
|
77
|
+
data: pd.Series,
|
|
78
|
+
entity: str,
|
|
79
|
+
trace_type: str,
|
|
80
|
+
visibility: bool,
|
|
81
|
+
) -> go.Scatter:
|
|
82
|
+
r"""Create a time series trace for either target or prediction"""
|
|
83
|
+
config = self.plot_config[trace_type]
|
|
84
|
+
return go.Scatter(
|
|
85
|
+
x=data["TIMESTAMP"],
|
|
86
|
+
y=data[config['name']],
|
|
87
|
+
name=f"{entity} - {config['name']}",
|
|
88
|
+
mode="lines",
|
|
89
|
+
line=dict(color=config['color']),
|
|
90
|
+
visible=visibility,
|
|
91
|
+
opacity=0.75,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
def _create_residuals_time_trace(
|
|
95
|
+
self,
|
|
96
|
+
data: pd.Series,
|
|
97
|
+
entity: str,
|
|
98
|
+
visibility: bool,
|
|
99
|
+
) -> go.Scatter:
|
|
100
|
+
r"""Create a time series trace for residuals over time"""
|
|
101
|
+
residuals = data["TARGET"] - data["TARGET_PRED"]
|
|
102
|
+
return go.Scatter(
|
|
103
|
+
x=data["TIMESTAMP"],
|
|
104
|
+
y=residuals,
|
|
105
|
+
name=f"{entity} - Residuals Over Time",
|
|
106
|
+
mode="lines+markers",
|
|
107
|
+
line=dict(color=self.plot_config['residuals_time']['color']),
|
|
108
|
+
visible=visibility,
|
|
109
|
+
opacity=0.75,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
def _create_residuals_hist_trace(
|
|
113
|
+
self,
|
|
114
|
+
data: pd.Series,
|
|
115
|
+
entity: str,
|
|
116
|
+
visibility: bool,
|
|
117
|
+
) -> go.Histogram:
|
|
118
|
+
r"""Create a histogram trace for residuals distribution."""
|
|
119
|
+
residuals = data["TARGET"] - data["TARGET_PRED"]
|
|
120
|
+
return go.Histogram(
|
|
121
|
+
x=residuals,
|
|
122
|
+
name=f"{entity} - Residuals Distribution",
|
|
123
|
+
marker=dict(color=self.plot_config['residuals']['color']),
|
|
124
|
+
visible=visibility,
|
|
125
|
+
opacity=0.75,
|
|
126
|
+
nbinsx=30,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
def _create_button(self, index: int, entity: str) -> None:
|
|
130
|
+
r"""Create visibility toggle button for an entity."""
|
|
131
|
+
# target, prediction, residuals time, and residuals hist:
|
|
132
|
+
num_traces_per_entity = 4
|
|
133
|
+
total_traces = len(self.entities) * num_traces_per_entity
|
|
134
|
+
|
|
135
|
+
button = dict(label=entity, method="update", args=[{
|
|
136
|
+
"visible": [False] * total_traces
|
|
137
|
+
}])
|
|
138
|
+
|
|
139
|
+
# Set visibility for the entity's traces:
|
|
140
|
+
base_index = index * num_traces_per_entity
|
|
141
|
+
for i in range(num_traces_per_entity):
|
|
142
|
+
button["args"][0]["visible"][base_index + i] = True # type: ignore
|
|
143
|
+
|
|
144
|
+
self.buttons.append(button)
|
|
145
|
+
|
|
146
|
+
def _create_traces(self) -> None:
|
|
147
|
+
"""Create all traces for the visualization."""
|
|
148
|
+
for i, entity in enumerate(self.entities):
|
|
149
|
+
entity_data = self.forecast.loc[self.forecast.ENTITY == entity]
|
|
150
|
+
|
|
151
|
+
# First entity's traces are visible by default:
|
|
152
|
+
visibility = (i == 0)
|
|
153
|
+
|
|
154
|
+
# Create traces
|
|
155
|
+
trace_target = self._create_time_series_trace(
|
|
156
|
+
entity_data, entity, 'target', visibility)
|
|
157
|
+
trace_pred = self._create_time_series_trace(
|
|
158
|
+
entity_data, entity, 'prediction', visibility)
|
|
159
|
+
trace_residuals_time = self._create_residuals_time_trace(
|
|
160
|
+
entity_data, entity, visibility)
|
|
161
|
+
trace_residuals_hist = self._create_residuals_hist_trace(
|
|
162
|
+
entity_data, entity, visibility)
|
|
163
|
+
|
|
164
|
+
# Add traces to appropriate subplots
|
|
165
|
+
self.fig.add_trace(trace_target, row=1, col=1)
|
|
166
|
+
self.fig.add_trace(trace_pred, row=1, col=1)
|
|
167
|
+
self.fig.add_trace(trace_residuals_time, row=2, col=1)
|
|
168
|
+
self.fig.add_trace(trace_residuals_hist, row=3, col=1)
|
|
169
|
+
|
|
170
|
+
self._create_button(i, entity)
|
|
171
|
+
|
|
172
|
+
def _update_layout(self) -> None:
|
|
173
|
+
r"""Update the figure layout with all necessary configurations."""
|
|
174
|
+
self.fig.update_layout(
|
|
175
|
+
updatemenus=[
|
|
176
|
+
dict(active=0, buttons=self.buttons, direction="down", pad={
|
|
177
|
+
"r": 10,
|
|
178
|
+
"t": 10
|
|
179
|
+
}, showactive=True, x=1, xanchor="left", y=1.07, yanchor="top")
|
|
180
|
+
],
|
|
181
|
+
title="Forecast Results by Department",
|
|
182
|
+
height=1000, # Increased height to accommodate third plot
|
|
183
|
+
width=1300,
|
|
184
|
+
showlegend=True,
|
|
185
|
+
hovermode='x unified')
|
|
186
|
+
|
|
187
|
+
# Update axis labels and add zero reference line for residuals
|
|
188
|
+
self.fig.update_xaxes(title_text="Timestamp", row=1, col=1)
|
|
189
|
+
self.fig.update_xaxes(title_text="Timestamp", row=2, col=1)
|
|
190
|
+
self.fig.update_xaxes(title_text="Residual Value", row=3, col=1)
|
|
191
|
+
|
|
192
|
+
self.fig.update_yaxes(title_text="Patient Volume", row=1, col=1)
|
|
193
|
+
self.fig.update_yaxes(title_text="Residual Value", row=2, col=1)
|
|
194
|
+
self.fig.update_yaxes(title_text="Frequency", row=3, col=1)
|
|
195
|
+
|
|
196
|
+
# Add zero reference line for residuals time series
|
|
197
|
+
self.fig.add_hline(
|
|
198
|
+
y=0,
|
|
199
|
+
line_dash="dash",
|
|
200
|
+
line_color="gray",
|
|
201
|
+
row=2,
|
|
202
|
+
col=1,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
def visualize(self) -> None:
|
|
206
|
+
r"""Generate and display the complete visualization."""
|
|
207
|
+
self._create_traces()
|
|
208
|
+
self._update_layout()
|
|
209
|
+
self.fig.show()
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import time
|
|
3
|
+
from typing import Any, List, Optional, Union
|
|
4
|
+
|
|
5
|
+
from rich.console import Console, ConsoleOptions, RenderResult
|
|
6
|
+
from rich.live import Live
|
|
7
|
+
from rich.padding import Padding
|
|
8
|
+
from rich.progress import (
|
|
9
|
+
BarColumn,
|
|
10
|
+
MofNCompleteColumn,
|
|
11
|
+
Progress,
|
|
12
|
+
Task,
|
|
13
|
+
TextColumn,
|
|
14
|
+
TimeRemainingColumn,
|
|
15
|
+
)
|
|
16
|
+
from rich.spinner import Spinner
|
|
17
|
+
from rich.table import Table
|
|
18
|
+
from rich.text import Text
|
|
19
|
+
from typing_extensions import Self
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ProgressLogger:
|
|
23
|
+
def __init__(self, msg: str) -> None:
|
|
24
|
+
self.msg = msg
|
|
25
|
+
self.logs: List[str] = []
|
|
26
|
+
|
|
27
|
+
self.start_time: Optional[float] = None
|
|
28
|
+
self.end_time: Optional[float] = None
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def duration(self) -> float:
|
|
32
|
+
assert self.start_time is not None
|
|
33
|
+
if self.end_time is not None:
|
|
34
|
+
return self.end_time - self.start_time
|
|
35
|
+
return time.perf_counter() - self.start_time
|
|
36
|
+
|
|
37
|
+
def log(self, msg: str) -> None:
|
|
38
|
+
self.logs.append(msg)
|
|
39
|
+
|
|
40
|
+
def __enter__(self) -> Self:
|
|
41
|
+
self.start_time = time.perf_counter()
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
45
|
+
self.end_time = time.perf_counter()
|
|
46
|
+
|
|
47
|
+
def __repr__(self) -> str:
|
|
48
|
+
return f'{self.__class__.__name__}({self.msg})'
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ColoredMofNCompleteColumn(MofNCompleteColumn):
|
|
52
|
+
def __init__(self, style: str = 'green') -> None:
|
|
53
|
+
super().__init__()
|
|
54
|
+
self.style = style
|
|
55
|
+
|
|
56
|
+
def render(self, task: Task) -> Text:
|
|
57
|
+
return Text(str(super().render(task)), style=self.style)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class ColoredTimeRemainingColumn(TimeRemainingColumn):
|
|
61
|
+
def __init__(self, style: str = 'cyan') -> None:
|
|
62
|
+
super().__init__()
|
|
63
|
+
self.style = style
|
|
64
|
+
|
|
65
|
+
def render(self, task: Task) -> Text:
|
|
66
|
+
return Text(str(super().render(task)), style=self.style)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class InteractiveProgressLogger(ProgressLogger):
|
|
70
|
+
def __init__(
|
|
71
|
+
self,
|
|
72
|
+
msg: str,
|
|
73
|
+
verbose: bool = True,
|
|
74
|
+
refresh_per_second: int = 10,
|
|
75
|
+
) -> None:
|
|
76
|
+
super().__init__(msg=msg)
|
|
77
|
+
|
|
78
|
+
self.verbose = verbose
|
|
79
|
+
self.refresh_per_second = refresh_per_second
|
|
80
|
+
|
|
81
|
+
self._progress: Optional[Progress] = None
|
|
82
|
+
self._task: Optional[int] = None
|
|
83
|
+
|
|
84
|
+
self._live: Optional[Live] = None
|
|
85
|
+
self._exception: bool = False
|
|
86
|
+
|
|
87
|
+
def init_progress(self, total: int, description: str) -> None:
|
|
88
|
+
assert self._progress is None
|
|
89
|
+
if self.verbose:
|
|
90
|
+
self._progress = Progress(
|
|
91
|
+
TextColumn(f' ↳ {description}', style='dim'),
|
|
92
|
+
BarColumn(bar_width=None),
|
|
93
|
+
ColoredMofNCompleteColumn(style='dim'),
|
|
94
|
+
TextColumn('•', style='dim'),
|
|
95
|
+
ColoredTimeRemainingColumn(style='dim'),
|
|
96
|
+
)
|
|
97
|
+
self._task = self._progress.add_task("Progress", total=total)
|
|
98
|
+
|
|
99
|
+
def step(self) -> None:
|
|
100
|
+
if self.verbose:
|
|
101
|
+
assert self._progress is not None
|
|
102
|
+
assert self._task is not None
|
|
103
|
+
self._progress.update(self._task, advance=1) # type: ignore
|
|
104
|
+
|
|
105
|
+
def __enter__(self) -> Self:
|
|
106
|
+
from kumoai import in_notebook
|
|
107
|
+
|
|
108
|
+
super().__enter__()
|
|
109
|
+
|
|
110
|
+
if not in_notebook(): # Render progress bar in TUI.
|
|
111
|
+
sys.stdout.write("\x1b]9;4;3\x07")
|
|
112
|
+
sys.stdout.flush()
|
|
113
|
+
|
|
114
|
+
if self.verbose:
|
|
115
|
+
self._live = Live(
|
|
116
|
+
self,
|
|
117
|
+
refresh_per_second=self.refresh_per_second,
|
|
118
|
+
vertical_overflow='visible',
|
|
119
|
+
)
|
|
120
|
+
self._live.start()
|
|
121
|
+
|
|
122
|
+
return self
|
|
123
|
+
|
|
124
|
+
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
125
|
+
from kumoai import in_notebook
|
|
126
|
+
|
|
127
|
+
super().__exit__(exc_type, exc_val, exc_tb)
|
|
128
|
+
|
|
129
|
+
if exc_type is not None:
|
|
130
|
+
self._exception = True
|
|
131
|
+
|
|
132
|
+
if self._progress is not None:
|
|
133
|
+
self._progress.stop()
|
|
134
|
+
self._progress = None
|
|
135
|
+
self._task = None
|
|
136
|
+
|
|
137
|
+
if self._live is not None:
|
|
138
|
+
self._live.update(self, refresh=True)
|
|
139
|
+
self._live.stop()
|
|
140
|
+
self._live = None
|
|
141
|
+
|
|
142
|
+
if not in_notebook():
|
|
143
|
+
sys.stdout.write("\x1b]9;4;0\x07")
|
|
144
|
+
sys.stdout.flush()
|
|
145
|
+
|
|
146
|
+
def __rich_console__(
|
|
147
|
+
self,
|
|
148
|
+
console: Console,
|
|
149
|
+
options: ConsoleOptions,
|
|
150
|
+
) -> RenderResult:
|
|
151
|
+
|
|
152
|
+
table = Table.grid(padding=(0, 1))
|
|
153
|
+
|
|
154
|
+
icon: Union[Text, Padding]
|
|
155
|
+
if self._exception:
|
|
156
|
+
style = 'red'
|
|
157
|
+
icon = Text('❌', style=style)
|
|
158
|
+
elif self.end_time is not None:
|
|
159
|
+
style = 'green'
|
|
160
|
+
icon = Text('✅', style=style)
|
|
161
|
+
else:
|
|
162
|
+
style = 'cyan'
|
|
163
|
+
icon = Padding(Spinner('dots', style=style), (0, 1, 0, 0))
|
|
164
|
+
|
|
165
|
+
title = Text.from_markup(
|
|
166
|
+
f'{self.msg} ({self.duration:.2f}s)',
|
|
167
|
+
style=style,
|
|
168
|
+
)
|
|
169
|
+
table.add_row(icon, title)
|
|
170
|
+
|
|
171
|
+
for log in self.logs:
|
|
172
|
+
table.add_row('', Text(f'↳ {log}', style='dim'))
|
|
173
|
+
|
|
174
|
+
yield table
|
|
175
|
+
|
|
176
|
+
if self.verbose and self._progress is not None:
|
|
177
|
+
yield self._progress.get_renderable()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kumoai
|
|
3
|
+
Version: 2.13.0.dev202511131731
|
|
4
|
+
Summary: AI on the Modern Data Stack
|
|
5
|
+
Author-email: "Kumo.AI" <hello@kumo.ai>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: homepage, https://kumo.ai
|
|
8
|
+
Project-URL: documentation, https://kumo.ai/docs
|
|
9
|
+
Keywords: deep-learning,graph-neural-networks,cloud-data-warehouse
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Programming Language :: Python
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: pandas
|
|
21
|
+
Requires-Dist: pyarrow<19.0.0,>=8.0.0
|
|
22
|
+
Requires-Dist: requests>=2.28.2
|
|
23
|
+
Requires-Dist: urllib3
|
|
24
|
+
Requires-Dist: plotly
|
|
25
|
+
Requires-Dist: typing_extensions>=4.5.0
|
|
26
|
+
Requires-Dist: kumo-api==0.45.0
|
|
27
|
+
Requires-Dist: tqdm>=4.66.0
|
|
28
|
+
Requires-Dist: aiohttp>=3.10.0
|
|
29
|
+
Requires-Dist: pydantic>=1.10.21
|
|
30
|
+
Requires-Dist: rich>=9.0.0
|
|
31
|
+
Provides-Extra: doc
|
|
32
|
+
Requires-Dist: sphinx; extra == "doc"
|
|
33
|
+
Requires-Dist: sphinx-book-theme; extra == "doc"
|
|
34
|
+
Requires-Dist: sphinx-copybutton; extra == "doc"
|
|
35
|
+
Requires-Dist: sphinx-autodoc-typehints; extra == "doc"
|
|
36
|
+
Requires-Dist: graphviz; extra == "doc"
|
|
37
|
+
Provides-Extra: test
|
|
38
|
+
Requires-Dist: pytest; extra == "test"
|
|
39
|
+
Requires-Dist: pytest-mock; extra == "test"
|
|
40
|
+
Requires-Dist: requests-mock; extra == "test"
|
|
41
|
+
Dynamic: license-file
|
|
42
|
+
Dynamic: requires-dist
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<img height="180" src="https://s3.us-west-1.amazonaws.com/data.kumo.ai/img/kumo_pink_md.svg" />
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
______________________________________________________________________
|
|
49
|
+
|
|
50
|
+
The Kumo SDK implements a pythonic interface for users to programmatically
|
|
51
|
+
interact with the Kumo machine learning platform
|
|
52
|
+
([documentation](https://kumo-ai.github.io/kumo-sdk/docs/#)).
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
The Kumo SDK is available for Python 3.10 to Python 3.13. To install, simply run
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
pip install kumoai
|
|
60
|
+
```
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
kumoai/__init__.py,sha256=LU1zmKYc0KV5hy2VGKUuXgSvbJwj2rSRQ_R_bpHyl1o,10708
|
|
2
|
+
kumoai/_logging.py,sha256=U2_5ROdyk92P4xO4H2WJV8EC7dr6YxmmnM-b7QX9M7I,886
|
|
3
|
+
kumoai/_singleton.py,sha256=UTwrbDkoZSGB8ZelorvprPDDv9uZkUi1q_SrmsyngpQ,836
|
|
4
|
+
kumoai/_version.py,sha256=wvQ56Gsck9T4OuBZmYnas0mpqXe3G7yxp7naBy-NTH4,39
|
|
5
|
+
kumoai/databricks.py,sha256=e6E4lOFvZHXFwh4CO1kXU1zzDU3AapLQYMxjiHPC-HQ,476
|
|
6
|
+
kumoai/exceptions.py,sha256=b-_sdbAKOg50uaJZ65GmBLdTo4HANdjl8_R0sJpwaN0,833
|
|
7
|
+
kumoai/formatting.py,sha256=jA_rLDCGKZI8WWCha-vtuLenVKTZvli99Tqpurz1H84,953
|
|
8
|
+
kumoai/futures.py,sha256=oJFIfdCM_3nWIqQteBKYMY4fPhoYlYWE_JA2o6tx-ng,3737
|
|
9
|
+
kumoai/jobs.py,sha256=NrdLEFNo7oeCYSy-kj2nAvCFrz9BZ_xrhkqHFHk5ksY,2496
|
|
10
|
+
kumoai/kumolib.cpython-313-x86_64-linux-gnu.so,sha256=SDReSaBnZSOzE8FHJuAzJr3Zj6zqXhWr68v5RUflqyk,229072
|
|
11
|
+
kumoai/mixin.py,sha256=MP413xzuCqWhxAPUHmloLA3j4ZyF1tEtfi516b_hOXQ,812
|
|
12
|
+
kumoai/spcs.py,sha256=N4ddeoHAc4I3bKrDitsb91lUx5VKvCyPyMT3zWiuCcY,4275
|
|
13
|
+
kumoai/artifact_export/__init__.py,sha256=BsfDrc3mCHpO9-BqvqKm8qrXDIwfdaoH5UIoG4eQkc4,238
|
|
14
|
+
kumoai/artifact_export/config.py,sha256=jOPDduduxv0uuB-7xVlDiZglfpmFF5lzQhhH1SMkGvw,8024
|
|
15
|
+
kumoai/artifact_export/job.py,sha256=GEisSwvcjK_35RgOfsLXGgxMTXIWm765B_BW_Kgs-V0,3275
|
|
16
|
+
kumoai/client/__init__.py,sha256=MkyOuMaHQ2c8GPxjBDQSVFhfRE2d2_6CXQ6rxj4ps4w,64
|
|
17
|
+
kumoai/client/client.py,sha256=S1OfGDwTzoyf40fhg111xGQGNfEP-OnoXqFV6X9iMEc,8580
|
|
18
|
+
kumoai/client/connector.py,sha256=x3i2aBTJTEMZvYRcWkY-UfWVOANZjqAso4GBbcshFjw,3920
|
|
19
|
+
kumoai/client/endpoints.py,sha256=iF2ZD25AJCIVbmBJ8tTZ8y1Ch0m6nTp18ydN7h4WiTk,5382
|
|
20
|
+
kumoai/client/graph.py,sha256=zvLEDExLT_RVbUMHqVl0m6tO6s2gXmYSoWmPF6YMlnA,3831
|
|
21
|
+
kumoai/client/jobs.py,sha256=iu_Wrta6BQMlV6ZtzSnmhjwNPKDMQDXOsqVVIyWodqw,17074
|
|
22
|
+
kumoai/client/online.py,sha256=pkBBh_DEC3GAnPcNw6bopNRlGe7EUbIFe7_seQqZRaw,2720
|
|
23
|
+
kumoai/client/pquery.py,sha256=R2hc-M8vPoyIDH0ywLwFVxCznVAqpZz3w2HszjdNW-o,6891
|
|
24
|
+
kumoai/client/rfm.py,sha256=NxKk8mH2A-B58rSXhDWaph4KeiSyJYDq-RO-vAHh7es,3726
|
|
25
|
+
kumoai/client/source_table.py,sha256=VCsCcM7KYcnjGP7HLTb-AOSEGEVsJTWjk8bMg1JdgPU,2101
|
|
26
|
+
kumoai/client/table.py,sha256=cQG-RPm-e91idEgse1IPJDvBmzddIDGDkuyrR1rq4wU,3235
|
|
27
|
+
kumoai/client/utils.py,sha256=lz1NubwMDHCwzQRowRXm7mjAoYRd5UjRQIwXdtWAl90,3849
|
|
28
|
+
kumoai/codegen/__init__.py,sha256=-a1QPslwq1g0j9Hsg4Ky-m1FzQesRRQ3u22-pYUlYDs,399
|
|
29
|
+
kumoai/codegen/cli.py,sha256=WTH81l3yplX01bvA6KjUyTKPoHcs51FD20A3dhRxuEQ,2848
|
|
30
|
+
kumoai/codegen/context.py,sha256=mW1-jdy_cZqZsnYNTtMb-90KthlkJaJ9iU60ON9TXBU,519
|
|
31
|
+
kumoai/codegen/edits.py,sha256=E3xT9k3wROeCZ6FZqZelch-S6ylRdJegPS-Ke7pCSgE,16436
|
|
32
|
+
kumoai/codegen/exceptions.py,sha256=_wEalz96R8R60-a7klo_u-11q8mFFiOZM15lIuJU554,149
|
|
33
|
+
kumoai/codegen/generate.py,sha256=SvfWWa71xSAOjH9645yQvgoEM-o4BYjupM_EpUxqB_E,7331
|
|
34
|
+
kumoai/codegen/identity.py,sha256=P_QVdE1h22L3SqWIPcycZ3XYvIRRKQ50OQ8BOH7RzSs,3985
|
|
35
|
+
kumoai/codegen/loader.py,sha256=X9zYfrFHM0kz9xAq4MSFNxsDw7nF-X2_kd24fg757xE,3564
|
|
36
|
+
kumoai/codegen/naming.py,sha256=_XVQGxHfuub4bhvyuBKjltD5Lm_oPpibvP_LZteCGk0,3021
|
|
37
|
+
kumoai/codegen/registry.py,sha256=JtvQT3UpWgFO3fhVQyZW-iisVegFzie01cJKDVn1HjA,4170
|
|
38
|
+
kumoai/codegen/handlers/__init__.py,sha256=k8TB_Kn-1BycBBi51kqFS2fZHCpCPgR9-3J9g9tvLQU,117
|
|
39
|
+
kumoai/codegen/handlers/connector.py,sha256=afGf_GreyQ9y6qF3QTgSiM416qtUcP298SatNqUFhvQ,3828
|
|
40
|
+
kumoai/codegen/handlers/graph.py,sha256=dGbPP99Lt3YrZdc_61IacrxG4seNdKqt9pbXc1z-qHE,2520
|
|
41
|
+
kumoai/codegen/handlers/pquery.py,sha256=m8rOLp8YcVB-hTpMH1OZui5tQ5QJkIrwt2OpSsCkO3g,1977
|
|
42
|
+
kumoai/codegen/handlers/table.py,sha256=POHpA-GFYFGTSuerGmtigYablk-Wq1L3EBvsOI-iFMQ,3956
|
|
43
|
+
kumoai/codegen/handlers/utils.py,sha256=58b2GCgaTBUp2aId7BLMXMV0ENrusbNbfw7mlyXAXPE,1447
|
|
44
|
+
kumoai/connector/__init__.py,sha256=9g6oNJ0qHWFlL5enTSoK4_SSH_5hP74xUDZx-9SggC4,842
|
|
45
|
+
kumoai/connector/base.py,sha256=cujXSZF3zAfuxNuEw54DSL1T7XCuR4t0shSMDuPUagQ,5291
|
|
46
|
+
kumoai/connector/bigquery_connector.py,sha256=IkyRqvF8Cg96kApUuuz86eYnl-BqBmDX1f_jIKL0pxc,7082
|
|
47
|
+
kumoai/connector/databricks_connector.py,sha256=YQy203XHZGzNJ8bPUjUOnrVt2KlpgMdVuTHpc6sVCcs,7574
|
|
48
|
+
kumoai/connector/file_upload_connector.py,sha256=swp03HgChOvmNPJetuujBSAqADe7NRmS_T0F3o9it4w,7008
|
|
49
|
+
kumoai/connector/glue_connector.py,sha256=HivT0QYQ8-XeB4QLgWvghiqXuq7jyBK9G2R1py_NnE4,4697
|
|
50
|
+
kumoai/connector/s3_connector.py,sha256=3kbv-h7DwD8O260Q0h1GPm5wwQpLt-Tb3d_CBSaie44,10155
|
|
51
|
+
kumoai/connector/snowflake_connector.py,sha256=K0s-H9tW3rve8g2x1PbyxvzSpkROfGQZz-Qa4PoT4UE,9022
|
|
52
|
+
kumoai/connector/source_table.py,sha256=QLT8bEYaxeMwy-b168url0VfnkTrs5K6VKLbxTI4hEY,17539
|
|
53
|
+
kumoai/connector/utils.py,sha256=PUjunLpfqMZsrPDo2EmnyJRBl_mt-E6ugv2kNkf5Rn8,64011
|
|
54
|
+
kumoai/encoder/__init__.py,sha256=VPGs4miBC_WfwWeOXeHhFomOUocERFavhKf5fqITcds,182
|
|
55
|
+
kumoai/experimental/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
|
+
kumoai/experimental/rfm/__init__.py,sha256=ornmi2x947jkQLptMn7ZLvTf2Sw-RMcVW73AnjVsWAo,1709
|
|
57
|
+
kumoai/experimental/rfm/authenticate.py,sha256=FiuHMvP7V3zBZUlHMDMbNLhc-UgDZgz4hjVSTuQ7DRw,18888
|
|
58
|
+
kumoai/experimental/rfm/local_graph.py,sha256=2iJDlsGVzqCe1bD_puXWlhwGkn7YnQyJ4p4C-fwCZNE,30076
|
|
59
|
+
kumoai/experimental/rfm/local_graph_sampler.py,sha256=o60_sdMa_fr60DrdmCIaE6lKQAD2msp1t-GGubFNt-o,6738
|
|
60
|
+
kumoai/experimental/rfm/local_graph_store.py,sha256=8BqonuaMftAAsjgZpB369i5AeNd1PkisMbbEqc0cKBo,13847
|
|
61
|
+
kumoai/experimental/rfm/local_pquery_driver.py,sha256=aO7Jfwx9gxGKYvpqxZx1LLWdI1MhuZQOPtAITxoOQO0,26162
|
|
62
|
+
kumoai/experimental/rfm/local_table.py,sha256=r8xZ33Mjs6JD8ud6h23tZ99Dag2DvZ4h6tWjmGrKQg4,19605
|
|
63
|
+
kumoai/experimental/rfm/rfm.py,sha256=OHE6xpVREfm5GtZ4LXPY71FKzjNc94LWiBTPrmE6Xzc,48097
|
|
64
|
+
kumoai/experimental/rfm/utils.py,sha256=3IiBvT_aLBkkcJh3H11_50yt_XlEzHR0cm9Kprrtl8k,11123
|
|
65
|
+
kumoai/experimental/rfm/infer/__init__.py,sha256=xQ8_SuejIzXyn2J7bIKX3pXumFtRuEfBtE5oEDUDJjI,293
|
|
66
|
+
kumoai/experimental/rfm/infer/categorical.py,sha256=VwNaKwKbRYkTxEJ1R6gziffC8dGsEThcDEfbi-KqW5c,853
|
|
67
|
+
kumoai/experimental/rfm/infer/id.py,sha256=ZIO0DWIoiEoS_8MVc5lkqBfkTWWQ0yGCgjkwLdaYa_Q,908
|
|
68
|
+
kumoai/experimental/rfm/infer/multicategorical.py,sha256=0-cLpDnGryhr76QhZNO-klKokJ6MUSfxXcGdQ61oykY,1102
|
|
69
|
+
kumoai/experimental/rfm/infer/timestamp.py,sha256=vM9--7eStzaGG13Y-oLYlpNJyhL6f9dp17HDXwtl_DM,1094
|
|
70
|
+
kumoai/experimental/rfm/pquery/__init__.py,sha256=X0O3EIq5SMfBEE-ii5Cq6iDhR3s3XMXB52Cx5htoePw,152
|
|
71
|
+
kumoai/experimental/rfm/pquery/executor.py,sha256=f7-pJhL0BgFU9E4o4gQpQyArOvyrZtwxFmks34-QOAE,2741
|
|
72
|
+
kumoai/experimental/rfm/pquery/pandas_executor.py,sha256=kiBJq7uVGbasG7TiqsubEl6ey3UYzZiM4bwxILqp_54,18487
|
|
73
|
+
kumoai/graph/__init__.py,sha256=n8X4X8luox4hPBHTRC9R-3JzvYYMoR8n7lF1H4w4Hzc,228
|
|
74
|
+
kumoai/graph/column.py,sha256=t7wBmcx0VYKXjIoESU9Nq-AisiJOdlqd80t8zby1R8Y,4189
|
|
75
|
+
kumoai/graph/graph.py,sha256=iyp4klPIMn2ttuEqMJvsrxKb_tmz_DTnvziIhCegduM,38291
|
|
76
|
+
kumoai/graph/table.py,sha256=nZqYX8xlyAz6kVtlE2vf9BAIOCoWeFNIfbGbReDCb7k,33888
|
|
77
|
+
kumoai/pquery/__init__.py,sha256=uTXr7t1eXcVfM-ETaM_1ImfEqhrmaj8BjiIvy1YZTL8,533
|
|
78
|
+
kumoai/pquery/prediction_table.py,sha256=QPDH22X1UB0NIufY7qGuV2XW7brG3Pv--FbjNezzM2g,10776
|
|
79
|
+
kumoai/pquery/predictive_query.py,sha256=oUqwdOWLLkPM-G4PhpUk_6mwSJGBtaD3t37Wp5Oow8M,24971
|
|
80
|
+
kumoai/pquery/training_table.py,sha256=elmPDZx11kPiC_dkOhJcBUGtHKgL32GCBvZ9k6U0pMg,15809
|
|
81
|
+
kumoai/testing/__init__.py,sha256=goHIIo3JE7uHV7njo4_aTd89mVVR74BEAZ2uyBaOR0w,170
|
|
82
|
+
kumoai/testing/decorators.py,sha256=RiFrJcP-ym-mB1BYSGC26bBiryxoR9-GwL1G4EHc2sc,1591
|
|
83
|
+
kumoai/trainer/__init__.py,sha256=zUdFl-f-sBWmm2x8R-rdVzPBeU2FaMzUY5mkcgoTa1k,939
|
|
84
|
+
kumoai/trainer/baseline_trainer.py,sha256=LlfViNOmswNv4c6zJJLsyv0pC2mM2WKMGYx06ogtEVc,4024
|
|
85
|
+
kumoai/trainer/config.py,sha256=-2RfK10AsVVThSyfWtlyfH4Fc4EwTdu0V3yrDRtIOjk,98
|
|
86
|
+
kumoai/trainer/job.py,sha256=Wk69nzFhbvuA3nEvtCstI04z5CxkgvQ6tHnGchE0Lkg,44938
|
|
87
|
+
kumoai/trainer/online_serving.py,sha256=9cddb5paeZaCgbUeceQdAOxysCtV5XP-KcsgFz_XR5w,9566
|
|
88
|
+
kumoai/trainer/trainer.py,sha256=hBXO7gwpo3t59zKFTeIkK65B8QRmWCwO33sbDuEAPlY,20133
|
|
89
|
+
kumoai/trainer/util.py,sha256=bDPGkMF9KOy4HgtA-OwhXP17z9cbrfMnZGtyGuUq_Eo,4062
|
|
90
|
+
kumoai/utils/__init__.py,sha256=wGDC_31XJ-7ipm6eawjLAJaP4EfmtNOH8BHzaetQ9Ko,268
|
|
91
|
+
kumoai/utils/datasets.py,sha256=ptKIUoBONVD55pTVNdRCkQT3NWdN_r9UAUu4xewPa3U,2928
|
|
92
|
+
kumoai/utils/forecasting.py,sha256=-nDS6ucKNfQhTQOfebjefj0wwWH3-KYNslIomxwwMBM,7415
|
|
93
|
+
kumoai/utils/progress_logger.py,sha256=pngEGzMHkiOUKOa6fbzxCEc2xlA4SJKV4TDTVVoqObM,5062
|
|
94
|
+
kumoai-2.13.0.dev202511131731.dist-info/METADATA,sha256=jnAtMb9qlOGKD4KIpUq9Tt65dnfVaeCNZUtJ3d6-Ihw,2052
|
|
95
|
+
kumoai-2.13.0.dev202511131731.dist-info/WHEEL,sha256=FGhoiLBD6z3eO88tnYRS0TgLaWveAr5uyXIqBlx6mno,152
|
|
96
|
+
kumoai-2.13.0.dev202511131731.dist-info/top_level.txt,sha256=YjU6UcmomoDx30vEXLsOU784ED7VztQOsFApk1SFwvs,7
|
|
97
|
+
kumoai-2.13.0.dev202511131731.dist-info/RECORD,,
|
|
98
|
+
kumoai-2.13.0.dev202511131731.dist-info/licenses/LICENSE,sha256=TbWlyqRmhq9PEzCaTI0H0nWLQCCOywQM8wYH8MbjfLo,1102
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Kumo.ai, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the " Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
kumoai
|