Getting Started with the ROAK SDK
This guide is aimed at first-time users. It covers the most common flows in a simple and clear way.
Current release status: Beta (v0.1.0).
What You Need
Python 3.10 through 3.12
A virtual environment (
venvor.venv)A ROAK username and password
Access to a ROAK environment URL (e.g.
https://dev.roak.com)
Installation
Create and activate a virtual environment first, then install the SDK in editable mode:
python -m venv .venv
On Windows:
.\.venv\Scripts\Activate.ps1
On macOS/Linux:
source .venv/bin/activate
pip install -e .
For development tools (pytest, dotenv, pandas):
pip install -e ".[dev]"
The supported runtime versions are intentionally narrow so that the same setup works reliably across the team.
Setting Up Credentials
Store your credentials in a .env file:
ROAK_USERNAME=your_username
ROAK_PASSWORD=your_password
ROAK_BASE_URL=https://dev.roak.com
Load them in your script:
import os
from dotenv import load_dotenv
load_dotenv()
ROAK_USERNAME = os.getenv("ROAK_USERNAME")
ROAK_PASSWORD = os.getenv("ROAK_PASSWORD")
ROAK_BASE_URL = os.getenv("ROAK_BASE_URL", "https://dev.roak.com")
Connecting
from roak_sdk import Roak
roak = Roak(
username=ROAK_USERNAME,
password=ROAK_PASSWORD,
base_url=ROAK_BASE_URL,
)
Add debug=True to see the HTTP requests being made — useful when troubleshooting:
roak = Roak(username=ROAK_USERNAME, password=ROAK_PASSWORD, base_url=ROAK_BASE_URL, debug=True)
You can also control request timeouts when creating the SDK instance. Pass a custom
timeout in seconds, or disable timeouts entirely with None or -1 if you know a
query can take a long time:
roak = Roak(
username=ROAK_USERNAME,
password=ROAK_PASSWORD,
base_url=ROAK_BASE_URL,
request_timeout=60,
)
roak_no_timeout = Roak(
username=ROAK_USERNAME,
password=ROAK_PASSWORD,
base_url=ROAK_BASE_URL,
request_timeout=-1,
)
If you need to change it after creation, call:
roak.set_request_timeout(120)
roak.set_request_timeout(-1)
Getting Well Data
This is the most common use case for companies with groundwater monitoring wells.
from datetime import datetime, timezone
START_DATE = datetime(2024, 6, 1, tzinfo=timezone.utc)
END_DATE = datetime(2024, 6, 2, tzinfo=timezone.utc)
# Navigate: project → well → data
project = roak.get_project_by_name("My Project")
well = project.get_well_by_guid("548006ef-28bd-4b0e-9f17-8234e1db9f64")
data = well.get_data(start_datetime=START_DATE, end_datetime=END_DATE)
If you already know the well GUID and do not need project context first, you can look it up directly from the facade:
well = roak.get_well_by_guid("<your_well_guid>")
data = well.get_data(start_datetime=START_DATE, end_datetime=END_DATE)
To request specific data feeds only:
data = well.get_data(
start_datetime=START_DATE,
end_datetime=END_DATE,
feeds=["diverPressure", "diverTemperature"],
)
Well Data Through a Site
Sites work like projects — they share the same methods.
site = roak.get_site_by_name("Home")
wells = site.get_wells()
print([well.name for well in wells])
data = wells[0].get_data(start_datetime=START_DATE, end_datetime=END_DATE)
You can also inspect the latest known value for all feeds on a well:
latest = wells[0].get_last_values()
# Returns: [{"feedname": "...", "last_value": "...", "unit": "...", "record_time": ...}, ...]
Drilling Rig and Borehole Data
For drilling companies wanting to compare borehole efficiency across rigs.
from datetime import datetime, timezone
START = datetime(2024, 4, 11, tzinfo=timezone.utc)
END = datetime(2026, 4, 12, tzinfo=timezone.utc)
rig = roak.get_rig_by_name("SOLSA_MWD")
boreholes = rig.get_boreholes()
borehole = rig.get_borehole_by_name("test aq1")
feeds = borehole.get_feeds()
data = borehole.get_data(
feeds=["rotation_pressure", "torque"],
start_datetime=START,
end_datetime=END,
)
Borehole data keyed by time and depth is available via:
import pandas as pd
depth_data = borehole.get_depth_data()
df = pd.DataFrame(depth_data)
print(df.head())
If you already know the borehole GUID or exact name, you can also access it directly from the facade:
borehole = roak.get_borehole_by_guid("<your-borehole-guid>")
alternative = roak.get_borehole_by_name(
"test aq1",
allow_first_match=True,
)
You can also list account-wide wells and boreholes directly:
wells = roak.get_wells()
boreholes = roak.get_boreholes()
Modem-Only Access
For users who only know their modem IDs and have no project/well context.
modem = roak.get_modem_by_guid("51418045")
# Get data from all child devices attached to this modem
data = modem.get_data_through_children(
feeds=["diverPressure", "diverTemperature", "baroPressure", "baroTemperature"],
start_datetime=START_DATE,
end_datetime=END_DATE,
)
# Or target a specific child device directly
children = modem.get_children()
diver = next(x for x in children if x.name == "FY747")
diver_data = diver.get_data(
feeds=["diverPressure", "diverTemperature"],
start_datetime=START_DATE,
end_datetime=END_DATE,
)
Multi-Tenant Access
Some ROAK accounts span multiple tenants. Pass the main ROAK URL and your multi-tenant credentials when connecting — the rest of the API works the same way.
roak = Roak(
username=MULTI_TENANT_USERNAME,
password=MULTI_TENANT_PASSWORD,
tenant="MAIN"
)
Handling Ambiguous Name Lookups
By default, a name lookup that matches more than one result raises an error:
# Raises ValueError if "Home" matches multiple sites
site = roak.get_site_by_name("Home")
If you know you want the first match, pass allow_first_match=True:
site = roak.get_site_by_name("Home", allow_first_match=True)
Common Errors
Error |
Cause |
Fix |
|---|---|---|
|
Called |
Always pass both |
|
Passed a naive |
Add |
|
Name lookup returned more than one match |
Use a more specific name or pass |
Where to Go Next
Use the sidebar to navigate the full API Reference — all user-facing classes and methods are documented there with parameter descriptions and examples.