Subscriber Guide¶
A step-by-step guide for building an app that receives live events from Dory using the Python SDK.
The Big Picture¶
Dory is a platform that streams events from cameras and sensors (things like moving, person, accidents). As a subscriber, you tell Dory three things:
- What you care about — a list of event types.
- Where you care about it — a list of geohash regions (short codes for areas on a map).
- How the raw sensor data should be processed — a lens, which is a named group of processor templates your organization configures in the Dory portal.
Dory then delivers matching events to your app in real time, as plain Python dictionaries handed to a callback function you write. You don't manage queues, brokers, or connections — the SDK does that.
Prerequisites¶
- Python 3.7+
- Access to the Dory portal (to get credentials and create a lens)
Step 1: Get Credentials¶
Your app authenticates with a client ID and client secret (an "app client"), created in the Dory portal. Ask your organization admin to create one for you if you don't see the option.
Save both values — the secret is only shown once. Then set them in your shell:
(You can also pass them directly to DoryClient(client_id=..., client_secret=...), but environment variables keep secrets out of your code.)
Step 2: Create a Lens¶
In the Dory portal, go to Lenses and create one (or pick an existing one). A lens groups the processor templates that turn raw sensor data into the events you'll receive. Note its alias (e.g. demo-lens) — you'll pass it when subscribing.
The lens must belong to the same organization as your app client.
Step 3: Install the SDK¶
The SDK isn't on PyPI yet. From a clone of this repository:
This installs the dory package along with its dependencies (pika, requests).
Step 4: Write Your App¶
The minimal subscriber:
import time
from dory import DoryClient
def handle_event(event: dict):
# This is YOUR app logic — every matching event arrives here.
print(f"Event received: {event}")
client = DoryClient() # reads DORY_CLIENT_ID / DORY_CLIENT_SECRET from the environment
subscription_id = client.rabbitmq.subscribe(
event_types=["moving", "person"], # what
geohash_regions=["dhxpfr5"], # where
lens_alias="demo-lens", # how (from Step 2)
callback=handle_event,
)
# Events arrive on a background thread — keep your program alive.
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
pass
client.rabbitmq.unsubscribe(subscription_id)
client.close()
Run it, trigger some activity in your region, and watch events print.
For a fuller version with graceful shutdown handling, see examples/example.py.
Step 5: Discover What's Available¶
Not sure which event types or regions exist? Ask the platform:
The SDK also validates your event_types against this list when you subscribe, so typos fail fast with a clear message.
Key Concepts in 30 Seconds¶
Geohashes. A geohash is a short string encoding a rectangular area — each extra character makes the area smaller (d is a huge region, dhxpfr5 is a city block or so). Your subscription matches any sensor whose location falls inside the geohashes you list. Use a tool like geohash.softeng.co to find codes for your area.
Lenses. Sensors produce raw data; processor templates turn it into meaningful events. A lens is your organization's named selection of those templates. Different lenses can process the same sensors differently, so the lens you pick determines what your events look like.
Subscriptions. Each subscribe() call creates a server-side subscription and returns its ID. You can create several with different filters and callbacks on the same client. They live server-side until you unsubscribe().
Managing Subscriptions¶
# See everything your app client has running (including from past sessions)
subs = client.list_subscriptions()
for sub in subs:
print(sub["id"], sub["name"], sub["status"])
# Clean up one by ID — works on IDs from list_subscriptions() too
client.rabbitmq.unsubscribe(sub_id)
# Or clean up everything created in this session
client.close()
Give subscriptions a recognizable name to make them easy to spot later:
Troubleshooting¶
| Symptom | Likely cause |
|---|---|
The lens '<alias>' was not found in your organization |
Typo in the alias, or the lens belongs to a different organization — check the portal's Lenses page |
subscribe() returns None with a printed message |
The request was valid, but there was nothing to create — e.g. no sensors in your geohash regions, or the lens has no templates supporting your event types |
Unknown event type(s): [...] |
Event type isn't supported — check the valid list in the error message or via client.metadata.get() |
Failed to initialize client / auth errors |
DORY_CLIENT_ID / DORY_CLIENT_SECRET not set or wrong |
| Subscribed successfully but no events arrive | Often normal — nothing is happening in your region. Try broader geohashes (shorter codes) or more event types |
| Events stop after a while | Your process exited or lost connectivity — the consumer runs on a daemon thread, so keep the main thread alive |
Where to Go Next¶
- examples/example.py — complete working subscriber with graceful shutdown
- README.md — SDK configuration details (custom API URLs, Cognito domain)