QombraPython SDK

Qombra Python SDK

Programmatic access to Qombra: dataset statistics, AI-guided preprocessing (QAgent, an AI system whose responses are generated by a language model), Model training (QBrain), inference, zero-shot time series forecasting, 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

Two ways in, for the two ways people use the API. Both send the same bearer credential and reach the same endpoints; they differ only in how long the credential lives and where it comes from.

Interactive: Token through 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.

import qombra

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

Production: Access through API key

A scheduled retrain or an inference service cannot open a browser every twelve hours. An API key never expires: it works until you revoke it, and needs no sign-in. Create one in the Qombra app under Account → API keys, then put it in your deployment's environment:

export QOMBRA_API_KEY=qbk_…
import qombra

preds = qombra.predict(model_id, new_rows)    # no login() call
API keys are available on accounts enabled for production access. The API keys tab appears in your account once Qombra switches it on; get in touch to have it enabled.

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, "Which customers will churn soon?") # full pipeline in one call
print(run.answer)                                            # "142 customers are at risk of churning."
qombra.logout()

Async usage

From qombra 0.5.0, asyncio applications (web services, agents, anything running an event loop) can use AsyncQombra. It mirrors the whole client surface as coroutines, so uploads and job polling yield to the event loop instead of blocking it:

import qombra

async with qombra.AsyncQombra() as client:        # or AsyncQombra(api_key=...)
    model = await client.fit(train_df, target="churn_30d")
    preds = await model.predict(new_rows)         # an AsyncModel, awaitable too
    fc    = await client.forecast(sales, target="units", horizon=14, id_column="store")

Endpoints, credentials, parameters, validation, retries, timeouts, warnings, result types and metering are identical to the sync client, so everything documented below applies unchanged; only the waiting differs. qombra.login() itself stays synchronous (it drives a browser round-trip): run it before entering the event loop, or pass api_key=. Cancelling the task awaiting fit() / forecast() / auto_run() sends the same best-effort server-side cancel as Ctrl+C does in the sync client.

In notebooks and plain scripts, stay with the sync client: a blocking fit() is exactly what a script wants, and there is no event loop to keep responsive.

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, predict, forecast, explain, auto_run) block while a server-side job runs and take a timeout (seconds); on JobTimeoutError the job continues server-side; models still land in your account, and a finished forecast or auto-run can be collected with forecast_result(job_id) / auto_run_result(job_id).

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

logout() ends the session server-side and clears the keyring; it is safe to call when not logged in, and it never touches a production API key. For unattended systems, skip login() entirely and set QOMBRA_API_KEY; see Production use.

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, finetuning=None, timeout=10800.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 optimizes and reports on. Unset keeps the task default (accuracy for classification, MAPE for regression). Setting it explicitly may weaken imbalance mitigation as the system will always stick to the selected metric and therefore does not fine-tune with balanced metrics. 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. Also accepts auto (derived from data size); unset keeps the server's default.
EffortTrade-off
lowFor fast iteration.
mediumFor simpler everyday tasks. Good trade-off between runtime/cost and performance.
highHigh performance, still a good trade-off between runtime/cost and performance.
maxUsually only limited increments in performance over high at significantly higher cost. For use-cases where even tiny increments in performance yield significant returns.
finetuning bool | None = None
True additionally fine-tunes QBrain on your training data. The fine-tuned model is only kept if it scores better on held-out data, so the result is never worse than without it, but training takes longer. Not available for targets with more than 10 classes.
timeout float = 10800.0
Client-side wait limit in seconds. Defaults to three hours; the server itself trains for up to five. A run that outlives the wait raises JobTimeoutError while the server finishes it, and the model lands in your account as usual. Pass timeout=18000 to always end the call with a model. Training that reaches the server's five-hour cap does not fail: the best model reached by then is returned with .truncated set.

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(...). If training ran into the server's time limit it does not fail: the model reflects the best state reached by then, .truncated is true and a UserWarning is emitted; a re-run with a lower effort may finish, one with more time may do better. If finetuning was requested but could not run, the model is trained without it: .finetuning_skipped holds the reason and a UserWarning is emitted. .predict(df) · .explain() · .instant_predictions · .metrics · .truncated · .finetuning_skipped · .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, or finetuning is not a boolean.
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 and the model lands in your account.

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")
# squeeze out more: fine-tune QBrain on your data
model = qombra.fit(train_df, target="churn_30d", finetuning=True)
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, *, return_probabilities=False) → pandas.Series | pandas.DataFrame 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.
return_probabilities bool = False
Classification models only. Also return the class probabilities behind each prediction.

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.
pandas.DataFrame
With return_probabilities=True: aligned to df.index, with "<target>_prediction" and one "<target>_proba_<class>" column per class. The probabilities of a row sum to 1.

Raises

ValidationError
The dataframe shares no columns with the model's training features, or return_probabilities was requested for a regression model (code="probabilities_unavailable").
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)

# Classification: labels plus one probability column per class
probs = qombra.predict(model, new_rows, return_probabilities=True)
probs[["churn_prediction", "churn_proba_yes"]].head()

qombra.forecast(df, target, horizon, *, timestamp_column="timestamp", id_column=None, future=None, freq=None, quantiles=(0.05, 0.5, 0.95), groups=None, non_negative=False, timeout=8100.0) → Forecast job

qombra.forecast_result(job_id) → Forecast sync

Forecast univariate or multivariate time series ahead. The model is zero-shot, so there is nothing to train and no model to keep, hence no model ID is returned.

Parameters

df DataFrame
History in long format: one row per observation with a timestamp column, the target column(s), and optionally an id column (one series per distinct id) and further columns, which are used as past covariates. Timestamps may be datetimes, dates or date strings; gaps are filled and duplicate timestamps collapsed (last one wins). Series shorter than 3 observations are skipped and reported in .warnings.
target str | list[str]
Numeric column(s) to forecast. Several targets are forecast jointly per series; see the note below.
horizon int
Steps ahead, in the data's own frequency (at most 1,024).
timestamp_column str = "timestamp"
Name of the time column.
id_column str | None = None
Column identifying each series. Leave unset for a single series.
future DataFrame | None = None
Known future values of covariates (prices, promotions, holidays): the id and timestamp columns plus the covariate columns, one row per series per forecast step, starting right after each series' last observation. Every covariate here must also exist in df; columns of df that are absent here are treated as past-only.
freq str | None = None
Pandas frequency alias ("D", "h", "W-MON", "MS", …). Inferred per series when unset; pass it when the data is too gappy to infer from.
quantiles sequence[float] = (0.05, 0.5, 0.95)
Prediction-interval levels to return next to the point forecast: any number of values between 0.01 and 0.99; 0.5 is always included. Each level adds a column to the result, so many levels count against the forecast-values limit below.
groups dict[str, list] | None = None
{"north": ["s1", "s2"], …}: series in a group inform each other's forecast, which helps related series with short histories. Unset, every series is forecast independently. Requires id_column.
non_negative bool = False
Floor the forecast and every quantile at 0 (counts, demand).
timeout float = 8100.0
Client-side wait limit in seconds, sized to outlive the server's worst case (queueing plus the run) so the default wait always ends with a result.

Returns

Forecast
.frame is long over series, target and timestamp: the id column (if any), the timestamp column, target, forecast (the median) and one forecast_qXX column per requested quantile. .wide() pivots it to timestamps × series. .frame · .wide() · .warnings · .horizon · .freq · .job_id

Raises

ValidationError
Before anything runs: a missing column (missing_column), a non-numeric target (invalid_target_dtype), a numeric timestamp column (invalid_timestamps), a future frame that does not cover every series and step (future_misaligned), or a request above the limits below (horizon_too_long, too_many_series, too_many_columns, too_many_points, too_many_output_values).
QuotaExceededError
Hourly prediction/forecast limit reached (details carry retry_after_sec).
JobFailedError
The engine refused the data once it looked at it: irregular_timestamps (no single regular frequency; pass freq), no_usable_series, unsupported_covariate (a date-typed covariate), unknown_series / overlapping_groups; or engine_unavailable when no capacity is free; retry later.
JobTimeoutError
timeout elapsed; the job continues server-side. Collect it later with qombra.forecast_result(e.job_id).

Example

# sales.csv: store, date, units, price, promo  (one row per store and day)
fc = qombra.forecast(sales, target="units", horizon=14,
                     timestamp_column="date", id_column="store",
                     future=planned_prices,            # store, date, price, promo for the next 14 days
                     groups={"north": ["s1", "s2", "s3"]},
                     non_negative=True)
fc.frame.head()            # store, date, target, forecast, forecast_q05, forecast_q50, forecast_q95
fc.wide()                  # one column per store, one row per forecast day
fc.wide(quantile=0.95)     # the upper band
print(fc.warnings)

Notes

Forecasting runs on QBrain, zero-shot: the engine reads each series' history directly, so there is no training step, no model id, and nothing to delete afterwards. Each call counts toward the hourly prediction/forecast limit and spends no analysis or token quota.

Covariates can be numeric or categorical (strings, booleans); date-typed covariates are rejected; derive features from them instead. All targets of a series share the same covariates and are forecast jointly. If a covariate applies to only one target, model that target as its own series (its own id) instead; it then gets its own covariates but is forecast independently of the others, since information is shared only within a series or a group.

Quantile levels off the engine's native grid are interpolated between the neighbouring native levels. Timezone-aware timestamps are converted to UTC. Each series' history is truncated to its most recent 8,192 steps.

Limit per callValue
Series (distinct ids)10,000
Value columns per series (targets + covariates)100
Horizon1,024 steps
Data points (history rows × value columns, after truncation)20,000,000
Forecast values (series × horizon × targets × (1 + quantile levels))10,000,000

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: the first 200, in the order sent (a warning says so when more are sent). Omitted, a representative sample of the model's training data is used, 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, *, timeout=7200.0) → AutoRunResult job

qombra.auto_run_result(job_id) → AutoRunResult sync

Hand your data and a question to the agent, and get the answer back: a one-sentence answer, the predictions, the quality metric and the driving factors. This runs the full data science workflow as a data scientist would: Data cleaning & pre-processing, model training and prediction as well as explainability. It works for predictive, time-series and causal questions alike.

Parameters

df DataFrame | list | dict
The raw data; preprocessing is part of the run. One dataframe, or up to 5 related ones as a list or a {"name": df} dict (100,000 rows in total, 500 columns each); the dict names are shown to the agent, which helps it relate the tables.
prompt str
What to analyze or predict, in plain language.
timeout float = 7200.0
Client-side wait limit in seconds.
Runs typically take 3-10 minutes, depending on task complexity and dataset size.

Returns

AutoRunResult
The answer plus everything behind it, with a ready-to-use model when one was trained. .answer · .predictions · .accuracy · .driving_factors · .model

Raises

JobFailedError
The run stalled or produced no model or estimate; the partial report is on the exception's .result.
JobTimeoutError
timeout elapsed; the run continues server-side. Collect it later with qombra.auto_run_result(job_id).
QuotaExceededError
Analysis, chat-message, or output-token quota exhausted.

Example

run = qombra.auto_run(df, "Which customers will churn soon?")
print(run.answer)                       # "142 customers are at risk of churning."
run.predictions.to_csv("at_risk.csv")   # the rows the model predicted for
print(run.accuracy, run.accuracy_metric)
print(run.driving_factors[:3])          # top SHAP features

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, api_key=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.
api_key str = None
Explicit credential (a production API key or a session 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 · forecast · 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

Credential resolution order: the api_key argument → QOMBRA_API_KEY → the OS keyring written by login(). The same slot takes either kind, so interactive and production code differ only in where the credential comes from.

Calls block the calling thread while they wait; in an asyncio application use AsyncQombra instead.

qombra.AsyncQombra(base_url=None, api_key=None, timeout=30.0)

The asyncio counterpart of Qombra: the same calls as coroutines, scoped to an async with block. Parameters as for Qombra.

Methods

await analyze · preprocessing · fit
predict · forecast · explain · auto_run
Identical to the functions above (same parameters, result types, warnings and errors), awaited instead of blocking. Calls that return a model handle return an AsyncModel.
await list_models · delete_model · stop
forecast_result · auto_run_result · whoami · …
Every other method mirrors the sync client one-to-one.
await aclose(revoke=True)
Close the session; called automatically when the async with block ends. Same revoke semantics as Qombra.close(): a production API key is never revoked.

Example

async with qombra.AsyncQombra() as client:
    model = await client.fit(train_df, target="churn")
    print(await client.whoami())
# leaving the block closes the session

Notes

Available from qombra 0.5.0. Credential resolution is identical to Qombra; qombra.login() stays synchronous; run it before entering the event loop, or pass api_key=. Cancelling the task awaiting fit() / forecast() / auto_run() sends the same best-effort server-side cancel as Ctrl+C does in the sync client.

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).
truncated bool
True when training reached the server's time limit and the model reflects the best state reached by then (also shown in the model's repr). A re-run may do better.
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, return_probabilities=False) → Series | DataFrame
Score new rows, optionally with class probabilities; 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.AsyncModel

The model handle returned by AsyncQombra: a Model with the same attributes, whose server-reaching members are coroutines.

Methods

await AsyncModel.from_id(model_id, client) → AsyncModel
Reconstruct a model in a new session. Unlike Model.from_id, the AsyncQombra client is required; there is no module-level default async client. Equivalent to await client.model(model_id).
await predict(df) → Series
Score new rows; see predict.
await explain(df=None) → Explanation
Feature attributions; see explain.
await instant_predictions() → DataFrame
The predictions training made for rows whose target was missing; a method here, not a property as on Model, since a property cannot be awaited. Fetched on first call, then cached.

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.Forecast

What forecast() produced.

Attributes

frame DataFrame
Long format: the id column (when one was given), the timestamp column, target, forecast (the median) and one forecast_qXX column per requested quantile (forecast_q05 for 0.05, forecast_q02_5 for 0.025).
horizon int · freq str
Steps forecast and the frequency the engine resolved (e.g. "D").
quantiles list[float]
The levels present in frame, always including 0.5.
n_series int · n_skipped int
Series forecast, and series skipped for having too little history.
warnings list[str]
What was fixed on the way: duplicates dropped, gaps filled, series skipped or truncated, groups chunked.
job_id str
Handle for forecast_result().

Methods

wide(target=None, quantile=None) → DataFrame
Timestamps × series for one target (the only/first one by default): the point forecast, or the given quantile level.

Notes

print(forecast) gives series, steps, frequency and any warnings.

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 answer an auto_run() produced, with everything behind it.

Attributes

answer str
A one-sentence answer to the prompt, e.g. "142 customers are at risk of churning."
predictions DataFrame | None
The rows the model predicted for (for a forecast, the forecast rows); None when the run had nothing to predict.
accuracy · accuracy_metric
The model's test score and the metric it is measured in, picked per task (e.g. accuracy for classification, R2 for regression, backtest MAPE for forecasts). None for causal runs.
driving_factors list[dict]
Top features by mean absolute SHAP, [{"feature", "importance"}, ...]. Empty when unavailable (e.g. time-series forecasts).
effect dict | None
For causal questions only: the estimated effect with point, ci_low/ci_high, p_value, confidence_grade and the refutation-test tally.
confirmed_target str
The column the agent settled on predicting.
use_case_type str
How the agent classified the problem (tabular, time_series, causal).
model Model | None
Ready to predict with when training succeeded; None for causal and zero-shot time-series runs.
n_predictions · warnings · job_id
Row count behind predictions, non-fatal degradations, and the job handle.
details dict
The full run report (phases, turns, raw metrics, token usage, timing); populated for staff accounts and in dev mode, otherwise empty.

Notes

print(run) gives a one-glance summary: the answer, the metric, and the top drivers.

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, future_misaligned) 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, irregular_timestamps, engine_unavailable, 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.