tautulli 3.2.0
tautulli: ^3.2.0 copied to clipboard
A Dart client for the Tautulli API. Provides typed access to activity, history, libraries, users, and more for Plex media server monitoring.
tautulli #
A Dart client for the Tautulli API.
Installation #
dart pub add tautulli
Or add manually to pubspec.yaml:
dependencies:
tautulli: ^3.2.0
Quick Start #
import 'package:tautulli/tautulli.dart';
void main() async {
final client = TautulliClient(
connection: const TautulliConnection(
protocol: 'http',
domain: '192.168.0.2:8181',
apiKey: 'your_api_key',
),
);
try {
final activity = await client.activity.getActivity();
print('Streaming: ${activity.streamCount} sessions');
final history = await client.history.getHistory(length: 10);
for (final entry in history.data) {
print('${entry.title} watched by ${entry.friendlyName}');
}
} on TautulliAuthException {
print('Invalid API key or authorization required');
} on TautulliConnectionException {
print('Could not reach Tautulli server');
} finally {
client.close();
}
}
Services #
All API commands are accessible through namespaced service properties on TautulliClient:
| Property | Description |
|---|---|
client.activity |
Current playback sessions |
client.devices |
Mobile device registration |
client.exports |
Export metadata and download exports |
client.graphs |
Time-series chart data |
client.history |
Watch history and home statistics |
client.images |
Image proxy URL construction |
client.libraries |
Library/section management and media info |
client.logs |
Tautulli and Plex log retrieval |
client.media |
Metadata, search, rating keys |
client.network |
GeoIP and WHOIS lookups |
client.newsletters |
Newsletter configuration and delivery |
client.notifications |
Notifier configuration and notification log |
client.users |
User management and statistics |
client.api |
API documentation endpoints |
client.plex |
Plex Media Server identity and status |
client.tautulli |
Tautulli settings, info, backups, and restart |
Custom HTTP Client #
Pass a custom http.Client for SSL certificate handling or testing:
import 'dart:io';
import 'package:http/io_client.dart';
// Self-signed certificate support (native platforms only)
final httpClient = HttpClient()
..badCertificateCallback = (cert, host, port) => allowedHosts.contains(host);
final client = TautulliClient(
connection: const TautulliConnection(
protocol: 'http',
domain: '192.168.0.2:8181',
apiKey: 'your_api_key',
),
httpClient: IOClient(httpClient),
);
Native only. This example uses
dart:ioandIOClient, which don't exist on the web — see Platform Support below.
Client ownership. An
httpClientyou inject is yours to manage:client.close()will not close it. Close it yourself when you're done. When you don't pass one, the client creates its own andclose()disposes it.
Platform Support #
Runs on the Dart VM, Flutter (Android/iOS/desktop), server, and Flutter web / WASM. Two things differ on the web:
- Custom HTTP clients and self-signed certificates are native-only.
dart:io,IOClient, andbadCertificateCallbackare unavailable on the web (the browser controls TLS), so self-signed certificates cannot be accepted and the defaultBrowserClientis used. Connection failures surface asTautulliConnectionException— the finerTautulliCertVerificationExceptionmapping is native-only. - CORS. With the default query-parameter auth the client sends simple GET
requests. Request headers (opt-in
ApiKeyLocation.header, or customheadersonTautulliConnection) make requests non-simple and trigger a CORS preflight, which Tautulli answers from v2.18.0 onward — so both work from the browser on every supported server.
Security #
By default the API key is sent as the apikey query parameter. Setting
apiKeyLocation: ApiKeyLocation.header on the connection sends it as an
X-Api-Key header instead, keeping the key out of URLs and therefore out of
server access logs, proxy logs, and browser tooling. Header auth is supported
by every server version this package targets, so it is worth enabling.
Two caveats regardless of mode: image URLs from buildImageUrl() always embed
the key as a query parameter (an <img> tag cannot send headers), and you
should use protocol: 'https' in production so the key and every response are
encrypted in transit.
Dates #
All model DateTime values are in UTC (they come from Unix epoch
timestamps). Call .toLocal() before displaying them:
final entry = history.data.first;
print(entry.date?.toLocal());
Exception Handling #
All exceptions extend the sealed TautulliException class:
| Exception | Thrown when |
|---|---|
TautulliConnectionException |
Network unreachable or socket error |
TautulliAuthException |
HTTP 401 or "Authorization Required" response |
TautulliInvalidApiKeyException |
Tautulli returns "Invalid apikey" |
TautulliServerException |
Non-200, non-401 HTTP status |
TautulliBadResponseException |
Malformed JSON or unexpected response structure |
TautulliTimeoutException |
Request exceeds configured timeout |
TautulliVersionException |
Server rejects register_device for being below the requested min_version |
TautulliCertExpiredException |
TLS certificate has expired |
TautulliCertVerificationException |
TLS certificate verification failed |
TautulliProtocolException |
Protocol is not http or https |
TautulliTerminateStreamException |
Stream termination command failed |
Testing #
Inject a MockClient from package:http/testing.dart to unit-test code that calls
Tautulli without making real network requests:
import 'package:http/testing.dart';
import 'package:http/http.dart' as http;
import 'package:tautulli/tautulli.dart';
final mockClient = MockClient((request) async {
return http.Response(
'{"response":{"result":"success","data":{"stream_count":2,"sessions":[]}}}',
200,
);
});
final client = TautulliClient(
connection: const TautulliConnection(
protocol: 'http',
domain: '192.168.0.2:8181',
apiKey: 'your_api_key',
),
httpClient: mockClient,
);
API Reference #
All commands are documented in the Tautulli API Reference.
- Requires Tautulli v2.18.0 or newer
- Last audited against: v2.18.1
Older servers are not supported: v2.18.0 removed several parameters this client sends.
importConfig() and importDatabase() are not implemented and throw
UnimplementedError.
License #
GPL-3.0-or-later