gravi-model-client
Python client for Gravitate's demand and supply optimization models.
Installation
pip install gravi-model-client
Usage
from gravi_model_client import GraviModelClient, ModelRunRequest, OptimizationInput
async with GraviModelClient(api_key="your-api-key", base_url="https://...") as client:
# Health check
await client.health_check()
# Run demand model inline — blocks for the whole solve
result = await client.run_demand_model(request)
# Run TSD (supply) model inline — blocks for the whole solve
result = await client.run_tsd_model(optimization)
run_demand_model and run_tsd_model hold the HTTP request open for the length of
the solve. They raise ModelRequestInvalid when the server rejects the body, with
one readable line per field error in .issues and the error body verbatim in
.payload — read payload["detail"][i]["ctx"] for the structured detail behind a
rejection, such as the store, tank, period and volume on an over-capacity delivery.
Queue-based models
Every model can also be run through the job queue, where a worker picks the run up
and the client polls for it. The run_*_model_async methods handle the whole
queue → poll → fetch lifecycle and block until the result is ready:
from gravi_model_client import GraviModelClient
async with GraviModelClient(api_key="your-api-key") as client:
demand = await client.run_demand_model_async(demand_request) # -> ModelResultResponse
ltl = await client.run_ltl_model_async(ltl_request) # -> LtlModelResultResponse
vrp = await client.run_vrp_model_async(vrp_request) # -> VrpModelResultResponse
osa = await client.run_osa_model_async(osa_input) # -> OsaAPIResponse
tsd = await client.run_tsd_model_async(tsd_input) # -> OptimizationAPIResponse
They raise ModelRunError if the run fails or is cancelled, and ModelRunTimeout
if it doesn't finish within timeout (default 300s, 900s for TSD; tune
poll_interval too).
For fire-and-forget / webhook workflows, use the primitives instead. Each model has the same trio:
| Model | Queue | Status | Fetch result |
|---|---|---|---|
| Demand | queue_demand_model |
get_demand_job_status |
get_demand_model_run_response |
| LTL | queue_ltl_model |
get_ltl_job_status |
get_ltl_model_run_response |
| VRP | queue_vrp_model |
get_vrp_job_status |
get_vrp_model_run_response |
| OSA | queue_osa_model |
get_osa_job_status |
get_osa_model_run_response |
| TSD | queue_tsd_model |
get_tsd_job_status |
get_tsd_model_run_response |
The result fetch raises ModelResultNotReady while a run is still queued or
running, and ModelRunError once it has ended failed or cancelled — so a caller
polling the fetch directly can tell "come back later" from "this will never
succeed".
Job administration
get_job_details, get_ltl_job_details and get_tsd_job_details return a
JobDetails with the job's status alongside the request and response stored on the
server — that is where to read back the input a finished run was given.
cancel_demand_jobs, cancel_ltl_jobs, cancel_osa_jobs and cancel_tsd_jobs
cancel every job under a history_id; get_queue_stats, get_ltl_queue_stats and
get_tsd_queue_stats report queue depth; clear_files and clear_ltl_files delete
the server's temporary request and response files.
Retries
Every request retries transient failures — connection errors, timeouts, 429 and 5xx — with jittered exponential backoff:
GraviModelClient(api_key, retries=3, retry_backoff=1.0, retry_backoff_max=20.0)
retries=0 disables it. The queue endpoints are deliberately more conservative:
a failure that may have reached the server is not replayed, because that would
enqueue the same solve twice. Only a connection failure, which provably never
arrived, is retried there.
The result fetch additionally retries a 404. A server without the 202/409 readiness codes answers 404 for the whole window between the worker writing the result file and the API pod seeing it; anywhere else a 404 is taken at face value.
Models
This package is the single source of truth for all pydantic models used by both the client and the server. Import models directly:
from gravi_model_client.demand import ModelRunRequest, StoreRequest, TankRequest, VolumeRange
from gravi_model_client.tsd import OptimizationInput, Directive, Site, Tank
Metadata
Release files for gravi-model-client 0.11.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gravi_model_client-0.11.0.tar.gz | 46.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gravi_model_client-0.11.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 81.0 kB
Release files / gravi_model_client-0.11.0.tar.gz
| Download URL | gravi_model_client-0.11.0.tar.gz |
|---|---|
| Size | 46.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8969df7fa4e58f7f54d814a3ba8b5e1eb3041cb6a6edffc56fb74c4bcf3efdbf
|
|
BLAKE2b-256 checksum How to use checksums |
2bbfd6ade78d6ddebf97b1d3ce18c30ff2bc0ce0c6d43e368a2e72f3e2fa1741
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency logRelease files / gravi_model_client-0.11.0-py3-none-any.whl
| Download URL | gravi_model_client-0.11.0-py3-none-any.whl |
|---|---|
| Size | 34.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
38bc9a60fc85b0b3d0e88ec051a194deaf9bff262d17be988873645179a516c0
|
|
BLAKE2b-256 checksum How to use checksums |
6bacc4b124bc6c115cf0bda8b4d19dc67de7a5f567c46a8b9b0307b3fbf54847
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency log