Skip to content

Quick start

Initialize a pump and dispense 500 µL from the media reservoir to a chip. You'll need your Habitat device's API URL and, for the Python examples, the SDK installed — see Access.

1. Set up

curl (or any HTTP client) is all you need — no extra install required.

pip install openculture

Requires Python 3.10+. Runtime dependencies: httpx, pydantic v2.

Add the Open Culture connector once (see MCP), then just ask Claude in plain language — no code, no URLs. The steps below show what to say.

2. Check the server

curl http://mistyforest.local:8000/health

Expected: a JSON object with device, drivers, and status fields.

from openculture import HabitatClient

with HabitatClient("http://mistyforest.local:8000") as h:
    health = h.system.health()
    print(health.device_name, health.driver_ready)

HabitatClient is a context manager — it owns its connection pool and closes it on exit. The default per-request timeout is 300 s to accommodate long pump moves.

Ask: "Is MistyForest ready?"

3. List pumps

curl http://mistyforest.local:8000/pumps/

A MistyForest-class device has two pumps: address 0 (Dispense) and address 1 (Aspirate).

with HabitatClient("http://mistyforest.local:8000") as h:
    for pump in h.pumps.list():
        print(pump.addr, pump.name, pump.ready)

h.pumps.list() returns a list[PumpStatus] with typed fields — your editor will autocomplete addr, valve_position, syringe_volume_ul, etc.

Ask: "What pumps does MistyForest have, and are they ready?"

4. Initialize pump 0

Pumps must be initialized before use. Initialization homes the plunger and valve.

curl -X POST http://mistyforest.local:8000/pumps/0/initialize
with HabitatClient("http://mistyforest.local:8000") as h:
    result = h.pumps.initialize(0)
    assert result.success

Ask: "Initialize pump 0 on MistyForest." Claude proposes the action and waits for your approval before it runs.

5. Dispense 500 µL

curl -X POST http://mistyforest.local:8000/routines/dispense \
  -H "Content-Type: application/json" \
  -d '{"params": {"volume_ul": 500.0, "chip_id": "chip_A", "source_role": "media"}}'
from openculture import HabitatClient
from openculture.client.habitat.models import ExecuteRoutineRequest

with HabitatClient("http://mistyforest.local:8000") as h:
    result = h.routines.execute_routine(
        "dispense",
        request=ExecuteRoutineRequest(
            params={"volume_ul": 500.0, "chip_id": "chip_A", "source_role": "media"}
        ),
    )
    print(result)

The dispense routine is the workflow-level call — it draws from a media port, switches the valve to the chip port, and dispenses in one call. For lower-level plunger control, POST /pumps/{addr}/dispense (h.pumps.dispense(addr, request)) moves the plunger directly.

Ask: "Dispense 500 µL of media to chip_A on MistyForest." Claude proposes the operation and waits for your approval before anything moves.

6. Observe the result

curl http://mistyforest.local:8000/pumps/0

The plunger position should reflect the dispense.

with HabitatClient("http://mistyforest.local:8000") as h:
    pump = h.pumps.get(0)
    print("plunger:", pump.plunger_position_ul, "µL")
    print("valve:  ", pump.valve_position)

Ask: "What's pump 0's plunger position on MistyForest?"

Error handling

Non-2xx responses return a JSON body with a detail field:

curl -s http://mistyforest.local:8000/pumps/99
# → {"detail": "Pump 99 not found"}  (404)

Non-2xx responses raise HabitatAPIError, which carries the parsed detail field:

from openculture import HabitatClient, HabitatAPIError

try:
    with HabitatClient("http://mistyforest.local:8000") as h:
        h.system.set_port_chip(pump_name="bad-name", port_number=99)
except HabitatAPIError as exc:
    print("status:", exc.response.status_code)
    print("detail:", exc.detail)

HabitatAPIError extends httpx.HTTPStatusError, so existing httpx error-handling still works.

When something fails, Claude relays it in plain language — e.g. that pump 99 doesn't exist, or which safety interlock blocked an action — and suggests a fix. Actuating tools always wait for your approval first.

Where next

  • Explore every endpoint interactively in Try it.
  • Read the API overview for conventions, units, and error shapes.
  • Drive your Habitat device in natural language with MCP.