Using the SDK
Creating a client
DimeSchedulerClient is the single entry point. It needs an API key and, optionally, an environment:
from dimescheduler import DimeSchedulerClient, Environment
client = DimeSchedulerClient(api_key="MY_API_KEY") # production
client = DimeSchedulerClient(api_key="MY_API_KEY", environment=Environment.Sandbox)
The client owns an httpx.Client under the hood and should be closed when you're done. Use it as a context manager so the connection pool is released for you:
with DimeSchedulerClient(api_key="MY_API_KEY") as client:
client.categories.create({"name": "INSTALL", "displayName": "Install", "color": "#22d3ee"})
For long-lived processes (web apps, workers) instantiate the client once at startup and reuse it across requests.
Domain-grouped accessors
Every entity hangs off a typed accessor on the client. The naming mirrors the .NET and JavaScript SDKs 1:1, with idiomatic snake_case:
client.categories # /category
client.appointments # /appointment
client.jobs # /job
client.tasks # /task
client.resources # /resource
client.filter_groups # /filterGroup
client.filter_values # /filterValue
client.messages # /message
client.notifications # /notification
CRUD-shaped entities (most of them) expose create / update / delete / get_all:
client.categories.create(category)
client.categories.update(category)
client.categories.delete(category)
client.categories.get_all()
Endpoints with their own shape get purpose-built methods:
client.appointments.get(start_date, end_date, resources=["R1", "R2"])
client.notifications.get(page=1, limit=50, sort="createdAt:desc")
client.geocoding.geocode_text("221B Baker Street", "GB")
client.optimization.field_service(request)
client.messages.send({"text": "Heads up!", "severity": "Warning"})
For the full list of accessors, see the API reference or the client source.
Results, not exceptions
Every call returns a Result:
result = client.categories.get_all()
result.ok # True on 2xx
result.data # parsed JSON body on success, else None
result.error # parsed JSON error body on 4xx/5xx, else None
result.response # underlying httpx.Response - headers, status code, raw bytes
The dispatcher never raises on non-2xx - you decide how to react. If you'd rather work with exceptions, call raise_for_error():
from dimescheduler import RateLimitError, ValidationError
result = client.categories.create(category)
try:
result.raise_for_error()
except RateLimitError as e:
time.sleep(e.retry_after or 1)
except ValidationError as e:
log.warning("bad payload: %s", e.body)
The typed exception hierarchy covers ValidationError (400/422), AuthenticationError (401), AuthorizationError (403), NotFoundError (404), ConflictError (409), RateLimitError (429), ServerError (5xx), and NetworkError (transport failures).
Retries
The SDK retries transient failures by default: connection errors, timeouts, and HTTP 408 / 429 / 500 / 502 / 503 / 504. Backoff is exponential with full jitter, capped at 30 seconds, and Retry-After is honoured.
Override the policy via RetryConfig:
from dimescheduler import DimeSchedulerClient, RetryConfig
client = DimeSchedulerClient(
api_key="MY_API_KEY",
retry=RetryConfig(max_retries=5, initial_delay_s=1.0, max_delay_s=60.0),
)
Disable retries entirely with retry=False.
Timeouts and cancellation
The client-level timeout (default 30 s) applies to every request. Override it for a single call:
client.imports.run(payload, timeout=120.0) # 120 s
client.imports.run(payload, timeout=httpx.Timeout(60.0, connect=5.0))
client.imports.run(payload, timeout=None) # wait indefinitely
Omit timeout to inherit the client-level default.