QombraPython SDK

Qombra Python SDK

Programmatic access to Qombra: dataset statistics, AI-guided preprocessing (QAgent), Model training (QBrain), inference, and SHAP explainability.

pip install qombra

The qombra package is the supported way to use the Qombra API: it handles authentication, dataframe transport, and long-running jobs for you. Requires Python ≥ 3.10; works with pandas DataFrames throughout. All usage counts toward your account's usage limits.

Authentication

qombra.login() opens a browser window where you sign in on the Qombra web app and approve the SDK session. The resulting token is kept in your OS keyring is valid for 12 hours, and is stored server-side only as a hash. Every SDK call runs through this authenticated session.

import qombra

qombra.login()          # browser opens; approve → "logged in as you@corp.com, expires at …"
…                     # work
qombra.logout()         # revoke the token server-side + clear the keyring

Quickstart

import pandas as pd
import qombra

qombra.login()

df = pd.read_csv("customers.csv")

report = qombra.analyze(df)                                  # dataset statistics
result = qombra.preprocessing(df, "drop outliers in price")  # AI preprocessing
model  = qombra.fit(result.df, target="churn_30d")           # trained by QBrain
preds  = model.predict(new_rows)                             # inference
print(model.explain())                                       # SHAP bar chart

# later, in a new Python session — no retraining:
model = qombra.Model.from_id("<model.id>")
preds = model.predict(more_rows)

run = qombra.auto_run(df, "Predict which customers churn")   # full pipeline in one call
qombra.logout()

Functions

Module-level functions share one default client; the Qombra class offers the same methods on an explicit, closable session. Long-running calls (preprocessing, fit, explain, auto_run) block while a server-side job runs and take a timeout (seconds) — on JobTimeoutError the job continues server-side and its results still land in your account.

qombra.login(base_url=None, *, headless=False, open_browser=True, timeout=180.0) TokenInfo

qombra.logout(base_url=None) None

Open the browser to sign in, and hand the session back when you are done.

Parameters

base_url str = None
API base URL override. Defaults to the Qombra production API.
headless bool = False
No browser available (SSH, CI): print the consent URL and prompt for the code shown after approval.
open_browser bool = True
Set False to print the URL instead of opening a window; the local callback still runs.
timeout float = 180.0
Seconds to wait for the browser round-trip.

Returns

TokenInfo
The session that was opened. The token is stored in your OS keyring and valid for 12 hours; every later call picks it up automatically. .email · .expires_at

Raises

LoginDeniedError
You clicked Deny on the consent page.
LoginTimeoutError
The browser flow did not finish within timeout.
AuthenticationError
The sign-in could not be completed.
NetworkError
The server could not be reached.

Notes

Set QOMBRA_API_TOKEN in the environment to skip the browser entirely (CI, scheduled jobs). logout() revokes the token server-side and clears the keyring; it is safe to call when not logged in.

qombra.analyze(df, excluded_columns=None) AnalysisReport sync

Get statistics and data-quality warnings for a dataframe.

Parameters

df DataFrame
The data to analyze. The SDK uploads a sample of up to 1000 rows with the fewest NaN values, keeping their original order.
excluded_columns list[str] = None
Columns to leave out of the analysis.

Returns

AnalysisReport
Per-column statistics and histograms, MIC correlations between columns, and quality warnings (PII-like, constant, ID-like, class imbalance, duplicate rows). .features · .correlations · .warnings · .summary · .duplicates · .imbalances

Raises

ValidationError
The dataframe is empty or cannot be serialized (e.g. mixed-type object columns).
AuthenticationError
Not logged in, or the 12-hour session expired.

qombra.preprocessing(df, instruction, *, timeout=1500.0) PreprocessingResult job

Clean and reshape a dataframe with QAgent, following your instruction in plain language. The result is directly usable with qombra.fit, i.e. QBrain.

Parameters

df DataFrame
The raw data.
instruction str
What to do, in plain language — e.g. "drop duplicate rows and one-hot encode region".
timeout float = 1500.0
Client-side wait limit in seconds. Expect minutes; the work continues server-side either way.

Returns

PreprocessingResult
A model-ready dataframe — leakage columns dropped, very-high-cardinality categoricals capped, and non-feature columns (identifiers, raw dates) removed — so it can go straight into fit. Printed to the console on completion and stored in your account. .df · .summary · .warnings · .actions_taken · .excluded_columns · .job_id

Raises

JobFailedError
Preprocessing failed server-side; .code says why.
JobTimeoutError
timeout elapsed — the job keeps running and its result lands in your account.
QuotaExceededError
Chat-message or output-token quota exhausted.

Notes

The agent's work is charged to your account's LLM output-token limit, and the call also spends one chat message — the same budget the web app's chat consumes. A single call is charged once, no matter how many stages it runs internally. See qombra.whoami() for what is left.

Example

result = qombra.preprocessing(df, "drop outliers in price and one-hot encode region")
print(result.excluded_columns)   # ['passenger_id', 'signup_ts']
model = qombra.fit(result.df, target="churn_30d")

qombra.fit(df, target, *, metric=None, effort=None, timeout=1800.0) Model job

Train a QBrain model to predict one column, and get back a handle to it.

Parameters

df DataFrame
Training data including the target column. Rows whose target is missing are excluded from fitting automatically — they become the model's instant predictions.
target str
Name of the column to predict. Classification or regression is decided by the engine from the column itself.
metric str | None = None
Evaluation metric the engine tunes, selects and reports on. Unset keeps the task default — accuracy for classification, MAPE for regression — together with an automatic class-imbalance safeguard that an explicit metric disables. Classification: accuracy · roc_auc · f1_micro · log_loss · qwk. Regression: mape · rmse · rmsle · mae · median_ae · smape. The metric must fit the task the engine infers from the target column; a mismatch fails the training job with the reason.
effort str | None = None
Compute budget for the run: low · medium · high · auto (derived from data size and available resources). Higher levels train fewer candidates at greater depth and take longer. Unset keeps the server's default.
timeout float = 1800.0
Client-side wait limit in seconds. Training can take many minutes on large data.

Returns

Model
A handle to the trained model. The model itself stays on the server and is addressed by its id, so you can reconstruct it in any later session with Model.from_id(...). .predict(df) · .explain() · .instant_predictions · .metrics · .id

Raises

ValidationError
The target column is missing, too few rows carry a target value, or metric / effort is not one of the values above.
QuotaExceededError
Analysis quota exhausted.
JobFailedError
Training failed server-side (including a metric that does not fit the inferred task).
JobTimeoutError
timeout elapsed — training continues server-side.

Example

model = qombra.fit(train_df, target="churn_30d")
# a rare positive class: rank by ROC AUC, spend more compute
model = qombra.fit(train_df, target="churn_30d", metric="roc_auc", effort="high")
print(model.metrics["test_metric"])     # 0.87
predictions = model.predict(new_rows)

Notes

Training runs on QBrain, Qombra's proprietary tabular foundation model. This is the same engine behind every prediction in the web app. No manual model selection or tuning is needed.

Each call counts toward your analysis quota.

qombra.predict(model_or_id, df) pandas.Series sync

Predict on new samples with a trained model.

Parameters

model_or_id Model | str
A model object, or the id string of one.
df DataFrame
Rows to score. Columns are aligned to training automatically: extras are ignored, missing feature columns are treated as NaN (with a warning), and a target column, if present, is dropped. Predict in batches for very large frames.

Returns

pandas.Series
One prediction per input row, named "<target>_prediction" and aligned to df.index, so it can be assigned straight back onto your dataframe.

Raises

ValidationError
The dataframe shares no columns with the model's training features.
NotFoundError
The model does not exist for this account (e.g. it was deleted).

Example

new_rows["churn_risk"] = qombra.predict(model, new_rows)
# identical to model.predict(new_rows)

qombra.explain(model_or_id, df=None, *, timeout=900.0) Explanation job

Find out which features drive a model's predictions.

Parameters

model_or_id Model | str
A model object, or the id string of one.
df DataFrame = None
Rows to explain. Omitted, the model's training data is used. SHAP runs on a representative sample with a fixed random seed, so repeated calls agree.
timeout float = 900.0
Client-side wait limit in seconds.

Returns

Explanation
SHAP values per feature, plus a console bar chart when printed. print(...) · .mean_abs_shap · .to_frame() · .relationships · .base_value

Raises

JobFailedError
SHAP computation failed server-side.
JobTimeoutError
timeout elapsed — the job keeps running server-side.
NotFoundError
The model does not exist for this account.

qombra.auto_run(df, prompt, *, user_context="", preprocessing_mode="deterministic", max_nudges=3, auto_approve=True, name=None, timeout=7200.0) AutoRunResult job

Hand a dataframe and a question to the agent, and get a trained model back. This runs the full data science workflow as a user would do in the Qombra platform.

Parameters

df DataFrame
The raw data — preprocessing is part of the run.
prompt str
What to analyze or predict, in plain language.
user_context str = ""
Business context for the agent: what the data means, how it was collected, what matters.
preprocessing_mode str = "deterministic"
"deterministic" for the standard pipeline, "rlm_only" for the AI agent.
max_nudges int = 3
How often (0–5) a waiting agent is auto-answered before the run stops.
auto_approve bool = True
Approve the agent's analysis plan automatically instead of stopping for confirmation.
name str = None
Analysis name in the web app. Defaults to the start of the prompt.
timeout float = 7200.0
Client-side wait limit in seconds. Expect minutes to hours.

Returns

AutoRunResult
The run report, with a ready-to-use model when training succeeded. The analysis is fully browsable in the web app afterwards. .model · .confirmed_target · .metrics · .analysis_id · .timing

Raises

JobFailedError
The run stalled or trained no model; the partial report is on the exception's .result.
JobTimeoutError
timeout elapsed — the run continues server-side.
QuotaExceededError
Analysis, chat-message, or output-token quota exhausted.

Example

run = qombra.auto_run(df, "Predict which customers churn in the next 30 days")
print(run)                              # phases, target, test metric
predictions = run.model.predict(new_rows)

qombra.list_models(created_via="sdk") list[ModelInfo]

qombra.delete_model(model_or_id) None

qombra.list_preprocessing_results() list[PreprocessingResultInfo]

qombra.delete_preprocessing_result(job_id) None

See what is stored in your account, and remove what you no longer need.

Parameters

created_via str = "sdk"
Which models to list: "sdk" for models you trained through this package, "web" for those trained in the web app, "all" for both.
model_or_id Model | str
The model to delete.
job_id str
The stored preprocessing result to delete — results[i].job_id.

Returns

list[ModelInfo]
Newest first. An ordinary list that renders as a table when displayed — index and iterate it as usual, and use models[i].model_id for the full id. Long listings show the newest entries, an ellipsis, and the oldest one; the list itself always holds every row.
None
Deletion is permanent — model files and stored result dataframes included — and does not refund quota.

Raises

NotFoundError
No such model or result for this account.
ValidationError
created_via is not one of the three accepted values.

Example

>>> qombra.list_models(created_via="all")
2 models in your account
#  id         target         task            model    metric    train   test  rows     created
─  ─────────  ─────────────  ──────────────  ───────  ────────  ─────  ─────  ───────  ────────────────
0  0624f7fb…  Final_Outcome  classification  qbrain   accuracy  0.985  1.000  132/34   2026-08-17 19:07
1  ab12cd34…  Survived       classification  qbrain   accuracy  0.891  0.816  712/179  2026-08-24 11:12

qombra.whoami() dict sync

Check who you are signed in as and what quota is left.

Returns

dict
{"email", "expires_at", "limits": {"remaining_analyses", "remaining_chat_messages", "remaining_output_tokens"}}. A limit of None means unlimited. Also the cheapest way to confirm your session still works before starting a long run.

Classes

qombra.Qombra(base_url=None, token=None, timeout=30.0)

An explicit, closable session — the same calls as the module-level functions, scoped to a with block.

Parameters

base_url str = None
API base URL override.
token str = None
Explicit API token, skipping the environment and keyring lookup.
timeout float = 30.0
Default per-request timeout in seconds. Uploads and long operations use larger internal limits.

Methods

analyze · preprocessing · fit
predict · explain · auto_run
Identical to the module-level functions, bound to this session.
list_models · delete_model
list_preprocessing_results
Inventory management — see list_* / delete_*.
whoami() → dict
Account email, session expiry, and remaining quota.
close(revoke=True)
Revoke the token server-side and clear the keyring. revoke=False only closes the connection pool and keeps the token usable.

Example

qombra.login()
with qombra.Qombra() as client:
    model = client.fit(train_df, target="churn")
    print(client.whoami())
# leaving the block revokes the token — the session is closed for good

Notes

Token resolution order: the token argument → QOMBRA_API_TOKEN → the OS keyring written by login().

qombra.Model

A trained QBrain model living on the Qombra server. An instance doesn't contain the model itself but a reference to it.
A Model instance can be re-created using the model id (see below).

Attributes

id str
Stable model id. Pass it to Model.from_id(...) in any later session.
target_column str
The column this model predicts.
task_type str
"classification" or "regression", decided by the engine from the target column.
model_type str
The model behind this fit — "qbrain" for anything trained through this package.
feature_columns list[str]
Columns used at training time; prediction aligns incoming data to these.
metrics dict
train_metric / test_metric with their *_metric_name, n_train_samples, n_test_samples, training_time_sec, and mode_collapse (true when the model predicted a single class for everything).
instant_predictions DataFrame
The predictions training made automatically for rows whose target was missing: training_row (position in the training data), the feature columns, and <target>_prediction. Empty when no targets were missing. Fetched on first access, then cached.
created_at · created_via str
When it was trained, and whether through the SDK or the web app.

Methods

Model.from_id(model_id) Model
Reconstruct a model in a new session — no retraining.
predict(df) → Series
Score new rows; see predict.
explain(df=None) Explanation
Feature attributions; see explain.

Example

model = qombra.Model.from_id("<model_id>")   # any later session
preds = model.predict(new_rows)
print(model.explain())

qombra.PreprocessingResult

What preprocessing() did, and the dataframe it produced.

Attributes

df DataFrame
The model-ready data: leakage and non-feature columns removed, ready for fit.
summary str
What was done, in prose.
warnings list[str]
Issues raised during preprocessing.
actions_taken list[str]
The individual cleaning and merging steps, in order.
excluded_columns list[str]
Non-feature columns removed from df — keep them from your original dataframe if you need to join predictions back to source rows.
job_id str
Handle for delete_preprocessing_result().

Notes

print(result) renders the summary, actions, warnings, and resulting shape — done automatically when preprocessing finishes.

qombra.AnalysisReport

What analyze() found in your data.

Attributes

features list[dict]
Per-column type, statistics, and histogram.
correlations list[dict]
MIC correlation per column pair: {col1, col2, value}.
warnings list[dict]
Quality issues: {column, issue, severity, hint}.
summary dict
Row, column, and per-type counts.
duplicates dict
Duplicate-row count and rate.
imbalances list[dict]
Binary columns with a very small minority class.
n_rows_analyzed int
Size of the analyzed sample.

qombra.Explanation

Which features drive a model's predictions, and in which direction.

Attributes

mean_abs_shap Series
Mean |SHAP| per feature, sorted — the headline importance ranking.
relationships list[str]
Human-readable direction hints, e.g. "sqft up → price up".
feature_names list[str]
Features in the order the value matrices use.
shap_values · feature_values list[list[float]]
Raw per-sample attributions and the feature values they belong to.
base_value float
The model's expected output before any feature contribution.
n_samples int
How many rows were explained.

Methods

to_frame() → DataFrame
SHAP values as a dataframe, one row per explained sample.

Example

>>> print(model.explain())
Feature importance (mean |SHAP|) — task: regression, target: price
sqft_living   ████████████████████████  0.4123
grade         █████████████             0.2210
lat           ███████                   0.1187
base value: 540123.4

qombra.AutoRunResult

The report of an auto_run(), with the model it trained.

Attributes

model Model | None
Ready to predict with when training succeeded; None when the run produced no model.
confirmed_target str
The column the agent settled on predicting.
metrics dict
The winning model's scores.
analysis_id int
The analysis created by the run — open it in the web app to see the full conversation.
status · current_phase · turns
Where the agent ended up and how many turns it took.
use_case_type str
How the agent classified the problem.
token_usage · timing dict
LLM cost and a per-phase time breakdown.

Notes

print(run) gives a one-glance summary of phase, target, and test metric.

qombra.ModelInfo · qombra.PreprocessingResultInfo · qombra.TokenInfo

Lightweight rows returned inside the table-rendering lists (see list_models) and by login().

Attributes

ModelInfo
model_id, target_column, task_type, model_type, metrics, created_at, created_via.
PreprocessingResultInfo
job_id, summary, n_rows, n_cols, created_at, has_data.
TokenInfo
token, expires_at, email.

Errors

Everything raised by the package derives from qombra.QombraError, so one except qombra.QombraError catches it all; catch subclasses for targeted handling:

try:
    model = qombra.fit(df, target="revenue")
except qombra.AuthenticationError:
    qombra.login()                        # 12h session expired — sign in again, then retry
except qombra.QuotaExceededError as e:
    print("usage limit reached:", e)      # check qombra.whoami()["limits"]
except qombra.ValidationError as e:
    print("bad input:", e.code, e)        # machine code + human message
except qombra.JobTimeoutError as e:
    print("still running server-side, job:", e.job_id)
ExceptionRaised when
AuthenticationErrorNo token, or it expired / was revoked. Subclasses: LoginDeniedError (Deny clicked in the browser), LoginTimeoutError (consent flow timed out).
QuotaExceededErrorAn account usage limit is exhausted (analyses, chat messages, output tokens).
RateLimitedErrorToo many requests in a short window; retry later.
ValidationErrorInvalid input — carries a machine-readable .code (e.g. missing_target, insufficient_rows, no_overlapping_features, unsupported_column_type) and .details. Subclass PayloadTooLargeError: the upload is too large — reduce or batch it.
NotFoundErrorThe model / stored result does not exist for this account (e.g. deleted).
JobFailedErrorA server-side run failed — .code (e.g. preprocessing_failed, training_failed, auto_run_failed, job_lost after a server restart: retry), .job_id, and any partial .result.
JobTimeoutErrorYour client-side timeout elapsed; the job keeps running server-side (.job_id).
NetworkError ServerErrorServer unreachable / unexpected server failure. Read-style requests are retried automatically before this surfaces.

Data format & metering

The SDK talks to the Qombra API under the hood. Raw HTTP access is unsupported — the endpoint surface may change between SDK releases; use the package.