Skip to main content

Python wrapper for the undocumented Tablo 4th Gen API

Project description

tablo-api

PyPI version Python 3.11+ License: MIT CI

Unofficial Python wrapper for the undocumented Tablo 4th Gen (LighthouseTV) API. Use at your own risk — Nuvyyo may change endpoints without notice.


Features

  • Cloud authentication via lighthousetv.ewscloud.com
  • Local device discovery (IP + port returned by cloud)
  • OTA/OTT channel listing from the cloud guide
  • Live-stream URLs via HMAC-MD5 signed local device requests
  • Fully typed with Pydantic v2 models

Supported Hardware

Device Supported
Tablo 4th Gen (2023+)
Tablo 2nd / 3rd Gen ❌ (different API, no auth required)

Installation

pip install tablo-api

Requires Python 3.11+.


Quick Start

from tablo_api import TabloAuth, TabloClient

# 1. Authenticate and discover local devices
auth = TabloAuth("you@example.com", "your-password")
devices = auth.discover()
print(devices)
# [TabloDevice(sid='SID_5087B8536004', name='Living Room Tablo', ...)]

# 2. Connect to the first device
client = TabloClient(devices[0])

# 3. List OTA channels
channels = client.channels()
for ch in channels:
    print(ch.display_name, "-", ch.network)
# 4.1 KFOR - NBC
# 5.1 KOCO - ABC

# 4. Start a live stream (returns HLS playlist URL)
stream = client.watch(channels[0])
print(stream.playlist_url)
# http://192.168.1.100:8885/stream/abc.m3u8

# 5. Feed to ffmpeg
import subprocess
subprocess.run(["ffmpeg", "-i", stream.playlist_url, "-c", "copy", "out.ts"])

API Reference

TabloAuth(email, password, timeout=15)

Authenticates with the Tablo cloud.

Method Returns Description
discover() list[TabloDevice] Log in and return all linked devices
make_device_auth(method, path, body="") (auth_header, date_header) HMAC-MD5 auth for local requests
device_date() str RFC 1123 UTC timestamp

TabloClient(device, timeout=15)

Interacts with a single device.

Method Returns Description
channels(include_ott=False) list[TabloChannel] OTA channel listing from cloud guide
watch(channel) TabloStream Start live stream, returns HLS URL
ping() str Device SID via unauthenticated /ping
server_info() dict Raw /server/info (requires auth)

Models

TabloDevice(sid, name, local_url, lighthouse_token)
TabloChannel(identifier, call_sign, major, minor, network, kind)
TabloStream(channel_identifier, playlist_url, token, expires, keepalive)

How It Works

Tablo 4th Gen dropped the open local API used by earlier hardware. All auth now goes through Nuvyyo's cloud (lighthousetv.ewscloud.com):

  1. POST /api/v2/login/ — email + password → Bearer token
  2. GET /api/v2/account/ — device list with local IP/port
  3. POST /api/v2/account/select/ — device-scoped Lighthouse token
  4. GET /api/v2/account/{lighthouse_token}/guide/channels/ — channel guide
  5. POST http://{local_ip}:8885/guide/channels/{id}/watch — HMAC-MD5 signed → HLS URL

The HMAC-MD5 signing scheme was reverse-engineered from the Tablo iOS app by the tablo2plex project.


Security Notes

  • Credentials are never stored by this library. Cache or store them yourself using a secure mechanism (e.g. system keychain).
  • All cloud traffic uses HTTPS.
  • Local device traffic uses plain HTTP (port 8885) — do not use over untrusted networks.
  • The HMAC signing keys are static values embedded in the official Tablo app. They are not secret in the cryptographic sense; they only prevent trivially unauthenticated local requests.

Contributing

Bug reports and PRs are welcome! Please open an issue before starting large changes.

git clone https://github.com/trevor-viljoen/tablo-api
pip install -e ".[dev]"
pytest

Support

If this saves you time, consider buying me a coffee:

PayPal GitHub Sponsors


License

MIT — see LICENSE.

This project is not affiliated with Nuvyyo Inc. or Tablo. "Tablo" is a trademark of Nuvyyo Inc.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tablo_api-0.1.2.tar.gz (13.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tablo_api-0.1.2-py3-none-any.whl (9.6 kB view details)

Uploaded Python 3

File details

Details for the file tablo_api-0.1.2.tar.gz.

File metadata

  • Download URL: tablo_api-0.1.2.tar.gz
  • Upload date:
  • Size: 13.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tablo_api-0.1.2.tar.gz
Algorithm Hash digest
SHA256 25b3f5983e8da1886c95c897505e74db0a7a9cb21193f5ce80cbfcd3462ccad4
MD5 7a923c729a85b301247e70619a35b58a
BLAKE2b-256 b3586fe0ff078774d2e00bc1f40c89c9c28b025fbb6d41a95c8f2778cbc4e7d1

See more details on using hashes here.

Provenance

The following attestation bundles were made for tablo_api-0.1.2.tar.gz:

Publisher: publish.yml on trevor-viljoen/tablo-api

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tablo_api-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: tablo_api-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 9.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tablo_api-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 017977d1dcc0d7f0a510d7e0de0d423cd51fa73acb31ccc39871c7a2baf44dae
MD5 5a127c534617ae1cc4f1d7ef86af8a03
BLAKE2b-256 874540c9748de651520797a0da0bd2edb767df461bfb54e981461db10de96d9d

See more details on using hashes here.

Provenance

The following attestation bundles were made for tablo_api-0.1.2-py3-none-any.whl:

Publisher: publish.yml on trevor-viljoen/tablo-api

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page