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.
@@ -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()