qombra 0.2.0__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.
- qombra-0.2.0/.gitignore +30 -0
- qombra-0.2.0/CHANGELOG.md +28 -0
- qombra-0.2.0/LICENSE +6 -0
- qombra-0.2.0/PKG-INFO +174 -0
- qombra-0.2.0/README.md +133 -0
- qombra-0.2.0/pyproject.toml +71 -0
- qombra-0.2.0/src/qombra/__init__.py +159 -0
- qombra-0.2.0/src/qombra/_auth.py +299 -0
- qombra-0.2.0/src/qombra/_client.py +492 -0
- qombra-0.2.0/src/qombra/_errors.py +83 -0
- qombra-0.2.0/src/qombra/_http.py +272 -0
- qombra-0.2.0/src/qombra/_jobs.py +52 -0
- qombra-0.2.0/src/qombra/_render.py +130 -0
- qombra-0.2.0/src/qombra/_results.py +387 -0
- qombra-0.2.0/src/qombra/_sample.py +20 -0
- qombra-0.2.0/src/qombra/py.typed +0 -0
qombra-0.2.0/.gitignore
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Environment / secrets
|
|
2
|
+
.env
|
|
3
|
+
.env.*
|
|
4
|
+
|
|
5
|
+
# Virtualenvs
|
|
6
|
+
.venv/
|
|
7
|
+
venv/
|
|
8
|
+
|
|
9
|
+
# Python
|
|
10
|
+
__pycache__/
|
|
11
|
+
*.py[cod]
|
|
12
|
+
*.egg-info/
|
|
13
|
+
.eggs/
|
|
14
|
+
|
|
15
|
+
# Build / publish
|
|
16
|
+
dist/
|
|
17
|
+
build/
|
|
18
|
+
|
|
19
|
+
# Tooling caches
|
|
20
|
+
.pytest_cache/
|
|
21
|
+
.mypy_cache/
|
|
22
|
+
.ruff_cache/
|
|
23
|
+
|
|
24
|
+
# OS / editors
|
|
25
|
+
.DS_Store
|
|
26
|
+
.idea/
|
|
27
|
+
.vscode/
|
|
28
|
+
|
|
29
|
+
# Examples
|
|
30
|
+
examples/
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
- `fit()` accepts `metric=` and `effort=`. `metric` chooses the evaluation
|
|
6
|
+
metric the engine tunes, selects and reports on (classification: `accuracy`,
|
|
7
|
+
`roc_auc`, `f1_micro`, `log_loss`, `qwk`; regression: `mape`, `rmse`,
|
|
8
|
+
`rmsle`, `mae`, `median_ae`, `smape`); unset keeps the task default and its
|
|
9
|
+
automatic class-imbalance safeguard. `effort` sets the compute budget
|
|
10
|
+
(`low` / `medium` / `high` / `auto`); unset keeps the server default.
|
|
11
|
+
Unknown values raise `ValidationError` at the call, before any training runs.
|
|
12
|
+
|
|
13
|
+
## 0.1.0
|
|
14
|
+
|
|
15
|
+
Initial release.
|
|
16
|
+
|
|
17
|
+
- Browser login (PKCE loopback flow) with OS-keyring token storage, 12-hour
|
|
18
|
+
sessions, explicit `logout()` / context-manager revocation.
|
|
19
|
+
- `analyze()` — dataset statistics on a least-NaN ≤1000-row sample.
|
|
20
|
+
- `preprocessing()` — server-side, instruction-guided preprocessing returning
|
|
21
|
+
a `PreprocessingResult` (dataframe + summary + warnings).
|
|
22
|
+
- `fit()` — AutoML training returning a server-side `Model` addressable by id
|
|
23
|
+
(`Model.from_id()` reconstructs it in later sessions).
|
|
24
|
+
- `predict()` — inference on new samples, aligned to the caller's index.
|
|
25
|
+
- `explain()` — SHAP values with a formatted console bar chart.
|
|
26
|
+
- `auto_run()` — the full autonomous agent pipeline in one call.
|
|
27
|
+
- `list_models()` / `delete_model()` and
|
|
28
|
+
`list_preprocessing_results()` / `delete_preprocessing_result()`.
|
qombra-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Copyright (c) 2026 Qombra. All rights reserved.
|
|
2
|
+
|
|
3
|
+
This software is proprietary. Use of this client library is permitted only in
|
|
4
|
+
connection with a Qombra account and subject to the Qombra terms of service
|
|
5
|
+
(https://www.qombra.com). Redistribution or modification without written
|
|
6
|
+
permission is prohibited.
|
qombra-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: qombra
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Python client for the Qombra data-analysis and AutoML platform.
|
|
5
|
+
Project-URL: Homepage, https://www.qombra.com
|
|
6
|
+
Project-URL: Documentation, https://www.qombra.com/api/docs
|
|
7
|
+
Author: Qombra Team
|
|
8
|
+
License: Copyright (c) 2026 Qombra. All rights reserved.
|
|
9
|
+
|
|
10
|
+
This software is proprietary. Use of this client library is permitted only in
|
|
11
|
+
connection with a Qombra account and subject to the Qombra terms of service
|
|
12
|
+
(https://www.qombra.com). Redistribution or modification without written
|
|
13
|
+
permission is prohibited.
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Keywords: automl,data-analysis,machine-learning,shap,tabular
|
|
16
|
+
Classifier: Development Status :: 4 - Beta
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Intended Audience :: Science/Research
|
|
19
|
+
Classifier: License :: Other/Proprietary License
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Requires-Dist: httpx>=0.27
|
|
29
|
+
Requires-Dist: keyring>=24
|
|
30
|
+
Requires-Dist: pandas>=2.0
|
|
31
|
+
Requires-Dist: pyarrow>=14
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: build; extra == 'dev'
|
|
34
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
36
|
+
Requires-Dist: python-dotenv>=1.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: respx>=0.21; extra == 'dev'
|
|
38
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
39
|
+
Requires-Dist: twine; extra == 'dev'
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
# qombra
|
|
43
|
+
|
|
44
|
+
Python client for [Qombra](https://www.qombra.com) — data analysis, AI-guided
|
|
45
|
+
preprocessing, AutoML training, inference, and SHAP explainability, all running
|
|
46
|
+
on the Qombra platform through your account.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install qombra
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Quickstart
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
import pandas as pd
|
|
56
|
+
import qombra
|
|
57
|
+
|
|
58
|
+
qombra.login() # opens the browser; approve the SDK session (valid 12 hours)
|
|
59
|
+
|
|
60
|
+
df = pd.read_csv("customers.csv")
|
|
61
|
+
|
|
62
|
+
# 1. Dataset statistics (analyzes a ≤1000-row sample with the fewest NaNs)
|
|
63
|
+
report = qombra.analyze(df)
|
|
64
|
+
print(report.summary, report.warnings)
|
|
65
|
+
|
|
66
|
+
# 2. Preprocessing with a natural-language instruction
|
|
67
|
+
result = qombra.preprocessing(df, "drop duplicate rows and outliers in price")
|
|
68
|
+
print(result) # summary, actions, warnings
|
|
69
|
+
clean_df = result.df
|
|
70
|
+
|
|
71
|
+
# 3. Training — the model stays on the server, addressed by id
|
|
72
|
+
model = qombra.fit(clean_df, target="churn_30d")
|
|
73
|
+
print(model.id, model.metrics)
|
|
74
|
+
# Optional: pick the evaluation metric and the compute budget yourself
|
|
75
|
+
model = qombra.fit(clean_df, target="churn_30d", metric="roc_auc", effort="high")
|
|
76
|
+
|
|
77
|
+
# 4. Inference
|
|
78
|
+
predictions = model.predict(clean_df.head(100))
|
|
79
|
+
|
|
80
|
+
# 5. Explainability (SHAP)
|
|
81
|
+
print(model.explain())
|
|
82
|
+
|
|
83
|
+
qombra.logout() # revoke the session token
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Later, in another session — no retraining
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
import qombra
|
|
90
|
+
|
|
91
|
+
qombra.login()
|
|
92
|
+
model = qombra.Model.from_id("«the model id from earlier»")
|
|
93
|
+
predictions = model.predict(new_rows)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Session management
|
|
97
|
+
|
|
98
|
+
Every call needs an authenticated session. `qombra.login()` opens a browser
|
|
99
|
+
window where you sign in on the web app and approve the SDK; the resulting
|
|
100
|
+
token lives in your OS keyring and expires after 12 hours. Close a session
|
|
101
|
+
explicitly, or scope it with `with` (leaving the block revokes the token):
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
qombra.login()
|
|
105
|
+
with qombra.Qombra() as client:
|
|
106
|
+
model = client.fit(df, target="price")
|
|
107
|
+
print(client.whoami()) # remaining quotas
|
|
108
|
+
# token revoked here
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
No browser available (SSH, CI)? Use `qombra.login(headless=True)` and
|
|
112
|
+
copy-paste the code shown on the consent page. In automated environments you
|
|
113
|
+
can also provide a token via the `QOMBRA_API_TOKEN` environment variable.
|
|
114
|
+
|
|
115
|
+
### The full pipeline in one call
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
result = qombra.auto_run(df, "Predict which customers churn in the next 30 days")
|
|
119
|
+
print(result) # phases, target, test metric
|
|
120
|
+
preds = result.model.predict(new_rows)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`auto_run` drives the same agent workflow as the web app (ingest →
|
|
124
|
+
preprocessing → target confirmation → training) without a human in the loop.
|
|
125
|
+
Expect minutes to hours; the created analysis is fully browsable in the web
|
|
126
|
+
app afterwards.
|
|
127
|
+
|
|
128
|
+
### Managing stored artifacts
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
qombra.list_models() # all trained models in your account
|
|
132
|
+
qombra.delete_model(model) # irreversible
|
|
133
|
+
qombra.list_preprocessing_results()
|
|
134
|
+
qombra.delete_preprocessing_result(job_id)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Error handling
|
|
138
|
+
|
|
139
|
+
All errors derive from `qombra.QombraError`:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
try:
|
|
143
|
+
model = qombra.fit(df, target="revenue")
|
|
144
|
+
except qombra.AuthenticationError:
|
|
145
|
+
qombra.login() # token expired (12h) — sign in again
|
|
146
|
+
except qombra.QuotaExceededError as e:
|
|
147
|
+
print("Usage limit reached:", e)
|
|
148
|
+
except qombra.ValidationError as e:
|
|
149
|
+
print("Bad input:", e.code, e)
|
|
150
|
+
except qombra.JobTimeoutError as e:
|
|
151
|
+
print("Still training server-side, job:", e.job_id)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Notable classes: `AuthenticationError`, `QuotaExceededError`,
|
|
155
|
+
`ValidationError` (with a machine-readable `.code`), `PayloadTooLargeError`,
|
|
156
|
+
`NotFoundError`, `JobFailedError`, `JobTimeoutError`, `NetworkError`,
|
|
157
|
+
`ServerError`.
|
|
158
|
+
|
|
159
|
+
## Data format & metering
|
|
160
|
+
|
|
161
|
+
Dataframes travel as parquet with plain scalar columns (numbers, booleans,
|
|
162
|
+
strings, dates, timestamps, decimals; pandas categoricals are fine) — cast
|
|
163
|
+
mixed-type `object` columns before upload. Uploads are size-capped and calls
|
|
164
|
+
are rate-limited: an oversized upload raises `PayloadTooLargeError` (reduce or
|
|
165
|
+
batch it), rapid-fire calls raise `RateLimitedError`.
|
|
166
|
+
|
|
167
|
+
All SDK usage counts toward your account's usage limits: each `fit`/`auto_run`
|
|
168
|
+
consumes analysis quota, and instruction-guided preprocessing consumes
|
|
169
|
+
chat/LLM-token quota. Check remaining quotas with `qombra.whoami()`.
|
|
170
|
+
|
|
171
|
+
## Support
|
|
172
|
+
|
|
173
|
+
Questions and issues: [www.qombra.com](https://www.qombra.com) — or reach out
|
|
174
|
+
at [hey@qombra.com](mailto:hey@qombra.com).
|
qombra-0.2.0/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# qombra
|
|
2
|
+
|
|
3
|
+
Python client for [Qombra](https://www.qombra.com) — data analysis, AI-guided
|
|
4
|
+
preprocessing, AutoML training, inference, and SHAP explainability, all running
|
|
5
|
+
on the Qombra platform through your account.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install qombra
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quickstart
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import pandas as pd
|
|
15
|
+
import qombra
|
|
16
|
+
|
|
17
|
+
qombra.login() # opens the browser; approve the SDK session (valid 12 hours)
|
|
18
|
+
|
|
19
|
+
df = pd.read_csv("customers.csv")
|
|
20
|
+
|
|
21
|
+
# 1. Dataset statistics (analyzes a ≤1000-row sample with the fewest NaNs)
|
|
22
|
+
report = qombra.analyze(df)
|
|
23
|
+
print(report.summary, report.warnings)
|
|
24
|
+
|
|
25
|
+
# 2. Preprocessing with a natural-language instruction
|
|
26
|
+
result = qombra.preprocessing(df, "drop duplicate rows and outliers in price")
|
|
27
|
+
print(result) # summary, actions, warnings
|
|
28
|
+
clean_df = result.df
|
|
29
|
+
|
|
30
|
+
# 3. Training — the model stays on the server, addressed by id
|
|
31
|
+
model = qombra.fit(clean_df, target="churn_30d")
|
|
32
|
+
print(model.id, model.metrics)
|
|
33
|
+
# Optional: pick the evaluation metric and the compute budget yourself
|
|
34
|
+
model = qombra.fit(clean_df, target="churn_30d", metric="roc_auc", effort="high")
|
|
35
|
+
|
|
36
|
+
# 4. Inference
|
|
37
|
+
predictions = model.predict(clean_df.head(100))
|
|
38
|
+
|
|
39
|
+
# 5. Explainability (SHAP)
|
|
40
|
+
print(model.explain())
|
|
41
|
+
|
|
42
|
+
qombra.logout() # revoke the session token
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Later, in another session — no retraining
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
import qombra
|
|
49
|
+
|
|
50
|
+
qombra.login()
|
|
51
|
+
model = qombra.Model.from_id("«the model id from earlier»")
|
|
52
|
+
predictions = model.predict(new_rows)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Session management
|
|
56
|
+
|
|
57
|
+
Every call needs an authenticated session. `qombra.login()` opens a browser
|
|
58
|
+
window where you sign in on the web app and approve the SDK; the resulting
|
|
59
|
+
token lives in your OS keyring and expires after 12 hours. Close a session
|
|
60
|
+
explicitly, or scope it with `with` (leaving the block revokes the token):
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
qombra.login()
|
|
64
|
+
with qombra.Qombra() as client:
|
|
65
|
+
model = client.fit(df, target="price")
|
|
66
|
+
print(client.whoami()) # remaining quotas
|
|
67
|
+
# token revoked here
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
No browser available (SSH, CI)? Use `qombra.login(headless=True)` and
|
|
71
|
+
copy-paste the code shown on the consent page. In automated environments you
|
|
72
|
+
can also provide a token via the `QOMBRA_API_TOKEN` environment variable.
|
|
73
|
+
|
|
74
|
+
### The full pipeline in one call
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
result = qombra.auto_run(df, "Predict which customers churn in the next 30 days")
|
|
78
|
+
print(result) # phases, target, test metric
|
|
79
|
+
preds = result.model.predict(new_rows)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`auto_run` drives the same agent workflow as the web app (ingest →
|
|
83
|
+
preprocessing → target confirmation → training) without a human in the loop.
|
|
84
|
+
Expect minutes to hours; the created analysis is fully browsable in the web
|
|
85
|
+
app afterwards.
|
|
86
|
+
|
|
87
|
+
### Managing stored artifacts
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
qombra.list_models() # all trained models in your account
|
|
91
|
+
qombra.delete_model(model) # irreversible
|
|
92
|
+
qombra.list_preprocessing_results()
|
|
93
|
+
qombra.delete_preprocessing_result(job_id)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Error handling
|
|
97
|
+
|
|
98
|
+
All errors derive from `qombra.QombraError`:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
try:
|
|
102
|
+
model = qombra.fit(df, target="revenue")
|
|
103
|
+
except qombra.AuthenticationError:
|
|
104
|
+
qombra.login() # token expired (12h) — sign in again
|
|
105
|
+
except qombra.QuotaExceededError as e:
|
|
106
|
+
print("Usage limit reached:", e)
|
|
107
|
+
except qombra.ValidationError as e:
|
|
108
|
+
print("Bad input:", e.code, e)
|
|
109
|
+
except qombra.JobTimeoutError as e:
|
|
110
|
+
print("Still training server-side, job:", e.job_id)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Notable classes: `AuthenticationError`, `QuotaExceededError`,
|
|
114
|
+
`ValidationError` (with a machine-readable `.code`), `PayloadTooLargeError`,
|
|
115
|
+
`NotFoundError`, `JobFailedError`, `JobTimeoutError`, `NetworkError`,
|
|
116
|
+
`ServerError`.
|
|
117
|
+
|
|
118
|
+
## Data format & metering
|
|
119
|
+
|
|
120
|
+
Dataframes travel as parquet with plain scalar columns (numbers, booleans,
|
|
121
|
+
strings, dates, timestamps, decimals; pandas categoricals are fine) — cast
|
|
122
|
+
mixed-type `object` columns before upload. Uploads are size-capped and calls
|
|
123
|
+
are rate-limited: an oversized upload raises `PayloadTooLargeError` (reduce or
|
|
124
|
+
batch it), rapid-fire calls raise `RateLimitedError`.
|
|
125
|
+
|
|
126
|
+
All SDK usage counts toward your account's usage limits: each `fit`/`auto_run`
|
|
127
|
+
consumes analysis quota, and instruction-guided preprocessing consumes
|
|
128
|
+
chat/LLM-token quota. Check remaining quotas with `qombra.whoami()`.
|
|
129
|
+
|
|
130
|
+
## Support
|
|
131
|
+
|
|
132
|
+
Questions and issues: [www.qombra.com](https://www.qombra.com) — or reach out
|
|
133
|
+
at [hey@qombra.com](mailto:hey@qombra.com).
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "qombra"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Python client for the Qombra data-analysis and AutoML platform."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { file = "LICENSE" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [{ name = "Qombra Team" }]
|
|
13
|
+
keywords = ["automl", "tabular", "machine-learning", "data-analysis", "shap"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Intended Audience :: Science/Research",
|
|
18
|
+
"License :: Other/Proprietary License",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
25
|
+
"Typing :: Typed",
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"httpx>=0.27",
|
|
29
|
+
"pandas>=2.0",
|
|
30
|
+
"pyarrow>=14",
|
|
31
|
+
"keyring>=24",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
Homepage = "https://www.qombra.com"
|
|
36
|
+
Documentation = "https://www.qombra.com/api/docs"
|
|
37
|
+
|
|
38
|
+
[project.optional-dependencies]
|
|
39
|
+
dev = [
|
|
40
|
+
"pytest>=8",
|
|
41
|
+
"respx>=0.21",
|
|
42
|
+
"mypy>=1.10",
|
|
43
|
+
"ruff>=0.5",
|
|
44
|
+
"python-dotenv>=1.0",
|
|
45
|
+
"build",
|
|
46
|
+
"twine",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[tool.hatch.build.targets.wheel]
|
|
50
|
+
packages = ["src/qombra"]
|
|
51
|
+
|
|
52
|
+
[tool.hatch.build.targets.sdist]
|
|
53
|
+
# Ship only what users need; DEVELOPMENT.md and tests stay internal.
|
|
54
|
+
exclude = ["tests/", "DEVELOPMENT.md", ".gitignore", ".DS_Store"]
|
|
55
|
+
|
|
56
|
+
[tool.ruff]
|
|
57
|
+
line-length = 110
|
|
58
|
+
target-version = "py310"
|
|
59
|
+
|
|
60
|
+
[tool.ruff.lint]
|
|
61
|
+
# PYI034 wants typing.Self, which needs Python >= 3.11; we support 3.10.
|
|
62
|
+
ignore = ["PYI034"]
|
|
63
|
+
|
|
64
|
+
[tool.mypy]
|
|
65
|
+
# Runtime support is 3.10+, but modern numpy stubs need >=3.12 syntax to check.
|
|
66
|
+
python_version = "3.12"
|
|
67
|
+
strict = false
|
|
68
|
+
ignore_missing_imports = true
|
|
69
|
+
|
|
70
|
+
[tool.pytest.ini_options]
|
|
71
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"""qombra — Python client for the Qombra data-analysis and AutoML platform.
|
|
2
|
+
|
|
3
|
+
Quickstart::
|
|
4
|
+
|
|
5
|
+
import qombra
|
|
6
|
+
|
|
7
|
+
qombra.login() # browser sign-in, 12h session
|
|
8
|
+
|
|
9
|
+
report = qombra.analyze(df) # dataset statistics
|
|
10
|
+
clean = qombra.preprocessing(df, "drop outliers in price")
|
|
11
|
+
model = qombra.fit(clean.df, target="price")
|
|
12
|
+
predictions = model.predict(new_df)
|
|
13
|
+
print(model.explain()) # SHAP bar chart
|
|
14
|
+
|
|
15
|
+
qombra.logout() # revoke the session
|
|
16
|
+
|
|
17
|
+
All calls go through an authenticated session against https://www.qombra.com
|
|
18
|
+
and count toward your account's usage limits.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import pandas as pd
|
|
24
|
+
|
|
25
|
+
from ._auth import TokenInfo, login, logout
|
|
26
|
+
from ._client import Qombra, get_default_client, reset_default_client
|
|
27
|
+
from ._errors import (
|
|
28
|
+
AuthenticationError,
|
|
29
|
+
JobFailedError,
|
|
30
|
+
JobTimeoutError,
|
|
31
|
+
LoginDeniedError,
|
|
32
|
+
LoginTimeoutError,
|
|
33
|
+
NetworkError,
|
|
34
|
+
NotFoundError,
|
|
35
|
+
PayloadTooLargeError,
|
|
36
|
+
QombraError,
|
|
37
|
+
QuotaExceededError,
|
|
38
|
+
RateLimitedError,
|
|
39
|
+
ServerError,
|
|
40
|
+
ValidationError,
|
|
41
|
+
)
|
|
42
|
+
from ._results import (
|
|
43
|
+
AnalysisReport,
|
|
44
|
+
AutoRunResult,
|
|
45
|
+
Explanation,
|
|
46
|
+
Model,
|
|
47
|
+
ModelInfo,
|
|
48
|
+
PreprocessingResult,
|
|
49
|
+
PreprocessingResultInfo,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
__version__ = "0.2.0"
|
|
53
|
+
|
|
54
|
+
__all__ = [
|
|
55
|
+
"AnalysisReport",
|
|
56
|
+
"AuthenticationError",
|
|
57
|
+
"AutoRunResult",
|
|
58
|
+
"Explanation",
|
|
59
|
+
"JobFailedError",
|
|
60
|
+
"JobTimeoutError",
|
|
61
|
+
"LoginDeniedError",
|
|
62
|
+
"LoginTimeoutError",
|
|
63
|
+
"Model",
|
|
64
|
+
"ModelInfo",
|
|
65
|
+
"NetworkError",
|
|
66
|
+
"NotFoundError",
|
|
67
|
+
"PayloadTooLargeError",
|
|
68
|
+
"PreprocessingResult",
|
|
69
|
+
"PreprocessingResultInfo",
|
|
70
|
+
"Qombra",
|
|
71
|
+
"QombraError",
|
|
72
|
+
"QuotaExceededError",
|
|
73
|
+
"RateLimitedError",
|
|
74
|
+
"ServerError",
|
|
75
|
+
"TokenInfo",
|
|
76
|
+
"ValidationError",
|
|
77
|
+
"__version__",
|
|
78
|
+
"analyze",
|
|
79
|
+
"auto_run",
|
|
80
|
+
"delete_model",
|
|
81
|
+
"delete_preprocessing_result",
|
|
82
|
+
"explain",
|
|
83
|
+
"fit",
|
|
84
|
+
"get_default_client",
|
|
85
|
+
"list_models",
|
|
86
|
+
"list_preprocessing_results",
|
|
87
|
+
"login",
|
|
88
|
+
"logout",
|
|
89
|
+
"predict",
|
|
90
|
+
"preprocessing",
|
|
91
|
+
"reset_default_client",
|
|
92
|
+
"whoami",
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# Module-level convenience functions delegating to the default client. Each is
|
|
97
|
+
# documented on the corresponding Qombra method.
|
|
98
|
+
|
|
99
|
+
def analyze(df: pd.DataFrame, excluded_columns: list[str] | None = None) -> AnalysisReport:
|
|
100
|
+
"""Dataset statistics for a ≤1000-row least-NaN sample. See :meth:`Qombra.analyze`."""
|
|
101
|
+
return get_default_client().analyze(df, excluded_columns)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def preprocessing(df: pd.DataFrame, instruction: str, *, timeout: float = 1500.0) -> PreprocessingResult:
|
|
105
|
+
"""Server-side, instruction-guided preprocessing. See :meth:`Qombra.preprocessing`."""
|
|
106
|
+
return get_default_client().preprocessing(df, instruction, timeout=timeout)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def fit(df: pd.DataFrame, target: str, *, metric: str | None = None,
|
|
110
|
+
effort: str | None = None, timeout: float = 1800.0) -> Model:
|
|
111
|
+
"""Train a model server-side. See :meth:`Qombra.fit`."""
|
|
112
|
+
return get_default_client().fit(df, target, metric=metric, effort=effort, timeout=timeout)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def auto_run(df: pd.DataFrame, prompt: str, *, user_context: str = "",
|
|
116
|
+
preprocessing_mode: str = "deterministic", max_nudges: int = 3,
|
|
117
|
+
auto_approve: bool = True, name: str | None = None,
|
|
118
|
+
timeout: float = 7200.0) -> AutoRunResult:
|
|
119
|
+
"""Full autonomous pipeline run. See :meth:`Qombra.auto_run`."""
|
|
120
|
+
return get_default_client().auto_run(
|
|
121
|
+
df, prompt, user_context=user_context, preprocessing_mode=preprocessing_mode,
|
|
122
|
+
max_nudges=max_nudges, auto_approve=auto_approve, name=name, timeout=timeout,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def predict(model_or_id: Model | str, df: pd.DataFrame) -> pd.Series:
|
|
127
|
+
"""Predict with a trained model. See :meth:`Qombra.predict`."""
|
|
128
|
+
return get_default_client().predict(model_or_id, df)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def explain(model_or_id: Model | str, df: pd.DataFrame | None = None, *,
|
|
132
|
+
timeout: float = 900.0) -> Explanation:
|
|
133
|
+
"""SHAP explainability for a trained model. See :meth:`Qombra.explain`."""
|
|
134
|
+
return get_default_client().explain(model_or_id, df, timeout=timeout)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def list_models(created_via: str = "sdk") -> list[ModelInfo]:
|
|
138
|
+
"""List this account's trained models ('sdk' | 'web' | 'all'). See :meth:`Qombra.list_models`."""
|
|
139
|
+
return get_default_client().list_models(created_via)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def delete_model(model_or_id: Model | str) -> None:
|
|
143
|
+
"""Delete a trained model permanently. See :meth:`Qombra.delete_model`."""
|
|
144
|
+
get_default_client().delete_model(model_or_id)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def list_preprocessing_results() -> list[PreprocessingResultInfo]:
|
|
148
|
+
"""List stored preprocessing results. See :meth:`Qombra.list_preprocessing_results`."""
|
|
149
|
+
return get_default_client().list_preprocessing_results()
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def delete_preprocessing_result(job_id: str) -> None:
|
|
153
|
+
"""Delete a stored preprocessing result permanently. See :meth:`Qombra.delete_preprocessing_result`."""
|
|
154
|
+
get_default_client().delete_preprocessing_result(job_id)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def whoami() -> dict:
|
|
158
|
+
"""Return account email, token expiry, and remaining quotas. See :meth:`Qombra.whoami`."""
|
|
159
|
+
return get_default_client().whoami()
|