Python SDK
The official Odento Python SDK provides both synchronous and asynchronous interfaces with full type hints and Pydantic models. Requires Python 3.9 or later.
Installation
Requestbash
pip install odento-sdk
# or with poetry
poetry add odento-sdk
# or with pipenv
pipenv install odento-sdkInitialization
Initialize the client with your API key credentials. Load keys from environment variables — never hardcode them in your source.
Requestpython
import os
from odento import Odento
client = Odento(
key_id=os.environ["ODENTO_API_KEY_ID"], # ok_live_...
key_secret=os.environ["ODENTO_API_KEY_SECRET"], # os_...
)
# Optionally override the base URL (for staging)
staging_client = Odento(
key_id=os.environ["ODENTO_API_KEY_ID"],
key_secret=os.environ["ODENTO_API_KEY_SECRET"],
base_url="https://staging-api.odento.app",
)JWT Authentication
For user-facing applications, authenticate with email and password. The SDK automatically manages token storage and refresh:
Requestpython
from odento import Odento
client = Odento()
# Login — SDK stores tokens internally
client.auth.login(
email="dr.sharma@dentalkare.in",
password="your-secure-password",
)
# All subsequent calls use the stored access token
# The SDK automatically refreshes when the token expiresUsage Examples
List Patients
Requestpython
# List patients with pagination
result = client.patients.list(limit=10, status="active")
for patient in result.items:
print(patient.id, patient.first_name, patient.last_name)
print(result.pagination.has_more)
# Iterate through all pages
cursor = result.pagination.next_cursor
while result.pagination.has_more:
result = client.patients.list(limit=10, cursor=cursor)
for patient in result.items:
print(patient.id, patient.first_name)
cursor = result.pagination.next_cursorCreate a Patient
Requestpython
patient = client.patients.create(
first_name="Priya",
last_name="Sharma",
email="priya.sharma@example.com",
phone="+919876543210",
date_of_birth="1990-05-15",
gender="female",
address={
"street": "12 MG Road",
"city": "Bengaluru",
"state": "Karnataka",
"postal_code": "560001",
"country": "India",
},
)
print(patient.id) # pat_5f8d3a2b1c9e4a7bCreate an Appointment
Requestpython
appointment = client.appointments.create(
patient_id="pat_5f8d3a2b1c9e4a7b",
dentist_id="usr_abc123",
start_time="2025-01-22T10:00:00Z",
end_time="2025-01-22T11:00:00Z",
type="consultation",
location_id="loc_xyz789",
notes="Routine checkup",
)
print(appointment.id) # apt_7a3b9c1d2e5f8a4bCreate an Invoice
Requestpython
invoice = client.billing.invoices.create(
patient_id="pat_5f8d3a2b1c9e4a7b",
items=[
{"description": "Dental consultation", "quantity": 1, "unit_price": 50000},
{"description": "Scaling and polishing", "quantity": 1, "unit_price": 150000},
],
due_date="2025-02-01",
)
print(invoice.id, invoice.number, invoice.total) # inv_... INV-2025-0042 236000Async Usage
The SDK provides a fully async interface via AsyncOdento. Use it with asyncio for concurrent applications:
Requestpython
import asyncio
import os
from odento import AsyncOdento
async def main():
client = AsyncOdento(
key_id=os.environ["ODENTO_API_KEY_ID"],
key_secret=os.environ["ODENTO_API_KEY_SECRET"],
)
# Concurrent requests
patients, appointments = await asyncio.gather(
client.patients.list(limit=10),
client.appointments.list(status="scheduled"),
)
print(f"{len(patients.items)} patients, {len(appointments.items)} appointments")
asyncio.run(main())Error Handling
The SDK raises typed exceptions. Catch them by error code to handle specific cases:
Requestpython
from odento import Odento
from odento.exceptions import OdentoError, RateLimitError, ValidationError
try:
patient = client.patients.create(
first_name="Priya",
# missing required fields...
)
except ValidationError as e:
print(f"Validation failed: {e.message}")
for detail in e.details:
print(f" {detail['field']}: {detail['message']}")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
except OdentoError as e:
print(f"API error ({e.code}): {e.message}")Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
| key_id | str | — | API key ID (ok_live_*) |
| key_secret | str | — | API key secret (os_*) |
| base_url | str | api.odento.app | Base URL for API requests |
| timeout | int | 30 | Request timeout in seconds |
| max_retries | int | 3 | Max retries for 5xx and 429 errors |
| auto_refresh | bool | True | Auto-refresh JWT tokens before expiry |
Was this page helpful?
Help us improve our documentation