Install
/sdk/, and the console Quickstart tab shows the exact current URL.
The package requires Python 3.11 or 3.12. It depends on httpx>=0.27, numpy>=1.26 and
pandas>=2.2.
Configure
api_key= and base_url= to the constructor.
__version__ is derived from the git tag the wheel was built at, so it names the commit you
installed. In an unbuilt source tree with no installed metadata it reads '0+unknown'.
Hollerith
Only
api_key is positional. Everything else is keyword-only.
base_url has no default. If neither the argument nor HOLLERITH_BASE_URL is set, the
constructor raises a plain ValueError — not a HollerithError, so an except HollerithError
block will not catch it.
The key is resolved first. A missing key therefore raises
AuthenticationError(code="missing_api_key") before the base_url check ever runs.
Shared keyword arguments
These five recur across most methods, with two exceptions to hold on to.fit does not take
on_progress, and FitHandle.wait() retries a warming worker only when you pass on_warming.
on_warming is called with one argument — the ServiceUnavailableError that was swallowed.
A hook written as lambda: print("warming") raises TypeError on the first cold start.
on_progress is accepted by predict, predict_proba, evaluate, forecast and both
handles’ wait(). It is not accepted by fit, which passes only on_warming down to the
fit handle.
fit
Pass either
fit(df, target="col") or fit(X, y). Passing both raises ValueError, and
passing neither raises ValueError.
Returns self when wait=True, so you can chain. Returns a FitHandle when
wait=False.
- The task is inferred from the target unless you override it. A non-numeric or boolean target is classification, and so is an integral numeric target with 20 or fewer distinct values.
- Classification reads at most 160 distinct labels. A 161st raises
ValidationError(dataset_too_large) client-side, before anything is uploaded. - The 5,000,000,000-byte compressed upload ceiling is not checked locally. An oversize
payload is serialized and gzipped, then rejected at the presign step with
payload_too_large. Nothing reaches storage.
wait=False changes:
- No context is bound.
fitted_context_id_staysNoneand the nextpredictre-uploads the whole training table inline. evaluate=Trueis silently dropped. The early return happens before the evaluation is started. There is no error and no warning.
ValidationError for a missing target column (missing_target_column), an
all-null target (unsupported_task), no feature columns (schema_mismatch), an empty frame
(malformed_csv) or any limit breach (dataset_too_large). It raises ValueError for the
calling-convention mistakes above, TimeoutError on deadline, and the typed HollerithError
for the code the fit job failed with.
predict
A DataFrame must carry every column named in
feature_names_in_; extra columns are dropped
and the rest are reordered to match. An array-like is assumed to be in the fitted column
order.
Returns a plain Python list when wait=True and quantiles is None. Not an ndarray,
not a Series — preds[0] is the label or number for the first row.
quantiles=, it returns a pandas.DataFrame with a prediction column holding the mean,
plus one column per level the engine scored.
frame[0.1] raises KeyError; you have to index
with "0.1".
With wait=False you get a PredictionHandle in every case, including with quantiles=. The
handle’s result carries .quantiles and .quantile_levels as raw lists, and no DataFrame is
ever assembled for you.
Raised before anything is submitted:
RuntimeError("call fit() or Hollerith.from_fitted_context() before predict()")when nothing is fitted.ValueErrorwhenquantilesis passed for a classification task.ValidationErrorfor rows missing a fitted feature column or of the wrong width (schema_mismatch), an empty frame (malformed_csv), or more than 200,000 rows (dataset_too_large).
TimeoutErroron the deadline.NotFoundError(training_ref_expired) if the job was purged before its result was read.- The typed
HollerithErrorcarried by a failed job.
predict_proba
Returns a
numpy.ndarray of shape (n_rows, n_classes) and dtype float64. Columns are
ordered by classes_, so proba[:, clf.classes_.index("fraud")] is one label’s column.
This method always blocks. There is no wait=False.
It overwrites classes_ with the engine’s ordering before returning, so the array and the
attribute stay aligned. Read classes_ after the call, not before.
Raises ValueError("predict_proba is only available for classification") for a regression
task, plus everything predict raises.
evaluate
ValidationError (dataset_too_large).
Returns an EvaluationResult, a frozen dataclass, and also stores it on evaluation_.
RuntimeError("call fit() before predict()") if fit was never called on this
client. A client built by from_fitted_context has no training table in memory, so it can
never evaluate.
It otherwise raises the same set as predict: ValidationError on a limit breach,
TimeoutError on deadline, NotFoundError on a purged job, and the typed error a failed job
carried.
submit
predict(wait=False) calls.
At most 200,000 scored rows, checked client-side before the upload. A breach raises
ValidationError (dataset_too_large).
Returns a PredictionHandle. It raises the same submit-time errors as predict —
RuntimeError, ValueError for classification quantiles, and ValidationError for a schema
or limit problem.
forecast
Pass exactly one of
prediction_length or future. Every column that is not the timestamp,
target or series column is treated as a covariate.
Returns a pandas.DataFrame with a mean column plus one string-labelled column per
quantile level. A single series is indexed by timestamp; with item_id= the index is a
MultiIndex of (item_id, timestamp), and the timestamp level is datetime-typed either way.
- Output rows are capped at 200,000. They are counted as
prediction_length × series count, or aslen(future)when you pass a future frame. - Covariate columns are capped at 2,000.
- No
fitis involved.forecastnever uses a fitted context, so nothing about fit-once, predict-many applies to it.
TypeError if context or future is not a DataFrame, and ValueError for a
horizon that is not exactly one of the two options, a non-positive prediction_length, a
quantile outside (0, 1), a missing timestamp or target column, or a future frame missing a
covariate.
from_fitted_context
The other arguments are the constructor’s and mean the same thing. There is no
server_context argument here, because a resumed client is context-backed by definition.
This is a network call. It fetches the context, checks its status, and binds its schema onto
the new client.
Returns a Hollerith with feature_names_in_, n_features_in_, n_rows_in_,
target_name_, task_, fitted_context_id_ and fitted_context_expires_at_ already set.
- Raises
NotFoundErrorif the context is not ready. The code isfitted_context_expiredwhen its status isexpiredordeleted, andfitted_context_not_foundfor any other non-ready status. - Contexts live for 7 days. After that, fit again — there is no way to extend one.
fitted
True once fit has staged a training table or a context is
bound, and False on a fresh client.
Instance attributes
sklearn convention: a trailing underscore means the attribute appears as a result of fitting, not at construction. Reading one before it is set raisesAttributeError.
Two of these surprise people.
- A resumed client has no
classes_.from_fitted_contextbinds the schema, which does not carry the label set. The attribute appears the first timepredict_probaruns. predict_probaoverwritesclasses_. It replaces the sorted list fromfitwith the engine’s ordering, so the probability columns and the labels stay aligned.
fitted_context_id_ is a raw document id. It carries no ctx_ prefix and you should treat it
as opaque.
Use hasattr(clf, "evaluation_") to test for an evaluation. It is False after a plain fit,
and False after fit(evaluate=True, wait=False).
PredictionHandle
Returned bysubmit() and by predict(wait=False).
wait() blocks to a terminal state and returns a PredictionResult.
PredictionResult
What a finished prediction job scored. It carriespredictions, task, classes,
probabilities, quantiles and quantile_levels, and fields the task did not produce are
None.
predictions is row-aligned with the rows you submitted. classes is the label order the
engine used, which is what makes probabilities interpretable.
PredictionJob
The status view you get fromhandle.job, handle.refresh() and every on_progress call. It
is a frozen dataclass of hashes and counts, never data.
It carries id, status, task, train_rows, output_rows, cols, target_column,
engine_version, created_at, duration_ms, input_hash and error. It also exposes
rows, the sum of train_rows and output_rows.
FitHandle
Returned byfit(wait=False).
FitHandle.wait() takes no on_progress. It returns the FittedContext once its status is
ready, and raises the context’s typed error otherwise.
- Waiting does not bind the context to your client. To predict against a context you
polled yourself, pass its id to
from_fitted_context. FitHandle.wait()only retries a warming worker when you passon_warming. Without the hook, a retryableServiceUnavailableErrorpropagates instead of being waited out.PredictionHandle.wait()retries either way.
FittedContext
The server-side artifact a fit produces, read throughFitHandle.context or
FitHandle.refresh().
It carries id, status, task, train_rows, cols, target_column, feature_columns,
engine_version, artifact_schema_version, train_hash, artifact_hash, created_at,
expires_at, last_used_at, created_by_job_id and error, plus a done property.
read_csv and read_csv_text
The reader is forgiving about form and strict about structure. It sniffs the delimiter from
the header line among comma, tab, semicolon and pipe, with comma winning ties.
- Encoding is resolved from the byte-order mark first, which pins UTF-8 or UTF-16 unambiguously. With no mark it tries UTF-8, then Windows-1252, and stops there rather than silencing a real encoding problem.
- Blank lines are dropped. A row of empty fields is kept and width-checked, and line numbers stay correct across quoted multiline fields.
str. No dtype inference is performed, which means a
numeric target read this way infers as classification. Cast the columns you need, or pass
task="regression" to fit.
CSV parse errors
Every failure raisesValidationError with code malformed_csv, and the problem field names
the 1-based source line or the column position at fault. Dataset contents never appear in the
message — only structure.
- Ragged row —
Line 3 has 2 fields but the header defines 3 columns. - Duplicate header name — names the repeated column.
- Blank header name — names the 1-based column position.
- Empty input, or a header with no data rows.
- Undecodable bytes — names the byte position that failed under UTF-8.
- Unreadable path — a missing file or a permissions problem, not an
OSError.
Exceptions
HollerithError and eight subclasses, one per error category. Catch a
subclass to handle one category, or HollerithError to handle them all.
Exception attributes
Every instance carries the same seven attributes.str(err) renders the problem followed by indented Cause, Fix, Docs and Request lines,
so printing a caught error gives a readable report.
The category selects the class; the code is what you branch on. The full catalogue of codes,
their HTTP statuses and which four are retryable is in Errors.
- Three exceptions are not
HollerithErrorat all.ValueErrorcovers calling mistakes,TypeErrora wrongly typed forecast frame, andTimeoutErrora lapsed deadline. - There is no backoff-retry layer. The SDK retries a retryable
ServiceUnavailableErrorinside the poll loop at a fixedpoll_interval, and nothing else.
Also exported
The names above are what most code touches.hollerith.__all__ carries more, and these are
supported.
- Ingest and inference helpers —
infer_task,prepare_training_data,TrainingData,Task. - Request dataclasses —
PredictionRequest,FitRequest,ContextPredictionRequest,EvaluationRequest,ForecastRequest. The views they return are documented above. - Transport seam —
Transport, the protocol you implement to substitute one, andHttpTransport, the HTTPS implementation. - Config helpers —
resolve_api_key,API_KEY_ENV_VAR,BASE_URL_ENV_VAR. - Error helpers —
error_from_payloadbuilds the typed exception for a wire envelope, andraise_for_payloadraises it.
Checklist
- Set
HOLLERITH_API_KEYandHOLLERITH_BASE_URL, or pass both to the constructor. - Check
task_afterfitif your target is numeric and low-cardinality. - Index quantile columns with strings:
frame["0.5"], neverframe[0.5]. - Read
classes_afterpredict_proba, not before. - Give
on_warmingone parameter. - Persist
fitted_context_id_if you want to resume, and re-fit after 7 days.
Next
- Quickstart — first prediction in about a minute
- The fitted context — fit once, predict many
- Errors — every code, status and fix
- Limits and quotas — every ceiling and where it is checked