Skip to main content

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)

Source distribution for gravi-model-client 0.11.0
File Size Uploaded
gravi_model_client-0.11.0.tar.gz 46.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gravi-model-client 0.11.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.11.0 This release

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page