Skip to content

Repository files navigation

TrackSeries.TVMaze.Client

A .NET client for the public TVMaze API, built on IHttpClientFactory.

The package targets .NET 10 and .NET 8 and provides:

  • Clients grouped by TVMaze endpoint area.
  • Dependency injection and IHttpClientFactory integration.
  • Shared client-side rate limiting.
  • The standard .NET HTTP resilience pipeline, including retries, timeouts, rate limiting, circuit breaking, and Retry-After support.
  • ActivitySource, metrics, and structured logging instrumentation.

Installation

dotnet add package TrackSeries.TVMaze.Client

Usage

Register the client and provide a User-Agent that identifies your application:

services.AddTVMazeClient(options =>
{
    options.UserAgent = "MyApplication/1.0 (+https://example.com)";
});

Options can also be loaded from configuration:

{
  "TVMaze": {
    "BaseAddress": "https://api.tvmaze.com/",
    "UserAgent": "MyApplication/1.0 (+https://example.com)",
    "MaxRequestsPerWindow": 20,
    "RateLimitWindow": "00:00:10"
  }
}
services.AddTVMazeClientFromConfiguration(configuration.GetSection("TVMaze"));

Inject ITVMazeClient and use the grouped endpoint clients:

public sealed class ShowService(ITVMazeClient tvMaze)
{
    public async Task<Show?> FindAsync(string imdbId, CancellationToken cancellationToken)
    {
        return await tvMaze.Lookup.GetShowByImdbAsync(imdbId, cancellationToken);
    }
}
var results = await tvMaze.Search.SearchShowsAsync("The Expanse", cancellationToken);
var episodes = await tvMaze.Shows.GetEpisodesAsync(showId, cancellationToken: cancellationToken);
var recentUpdates = await tvMaze.Updates.GetShowUpdatesSinceAsync(
    TVMazeUpdatePeriod.Day,
    cancellationToken);

Single-resource endpoints return null for HTTP 404. Collection endpoints return an empty list for HTTP 404. Other unsuccessful responses throw HttpRequestException after the resilience pipeline is exhausted.

Episode air-time precision

For some global or web-channel episodes, TVMaze returns an empty airtime while still providing a synthetic or default airstamp. Treat an episode timestamp as precise only when both Airtime is nonblank and Airstamp is non-null. Otherwise, preserve the date-only Airdate semantics; do not infer precision from Airstamp alone or by checking for a particular time of day.

Resilience

TVMaze guarantees at least 20 requests every 10 seconds per IP address. The package applies that limit across all endpoint clients created by the same dependency injection container.

Defaults can be changed during registration:

services.AddTVMazeClient(options =>
{
    options.UserAgent = "MyApplication/1.0";
    options.MaxRequestsPerWindow = 20;
    options.RateLimitWindow = TimeSpan.FromSeconds(10);
});

The returned IHttpClientBuilder can be used for additional HttpClient configuration and handlers. Handlers appended to the default registration run inside the resilience pipeline and therefore execute once per attempt:

services
    .AddTVMazeClient(options => options.UserAgent = "MyApplication/1.0")
    .AddHttpMessageHandler<MyHandler>();

To own the complete resilience pipeline, disable the library default and add exactly one application pipeline:

services
    .AddTVMazeClient(
        TVMazeResilienceMode.None,
        options => options.UserAgent = "MyApplication/1.0")
    .AddHttpMessageHandler<MyHandler>()
    .AddStandardResilienceHandler(options =>
    {
        options.Retry.MaxRetryAttempts = 2;
    });

TVMazeResilienceMode.None also disables the library's TVMaze-specific rate limiter. Use this mode when resilience is configured globally or when adding a custom resilience handler; stacking resilience pipelines multiplies attempts and delays.

Observability

The client emits activities and metrics under TrackSeries.TVMaze.Client.

Instrument Type
tvmaze.client.requests Counter
tvmaze.client.failures Counter
tvmaze.client.duration Histogram (seconds)

Expected HTTP 404 responses and caller cancellations are not recorded as failures.

Install the optional integration package to register the instrumentation with OpenTelemetry:

dotnet add package TrackSeries.TVMaze.Client.OpenTelemetry
services
    .AddOpenTelemetry()
    .AddTVMazeClientInstrumentation();

Configure exporters, resources, and sampling in the application as usual. The standard HttpClient instrumentation can be enabled alongside this integration to observe individual HTTP attempts, while the TVMaze activity represents the logical request across retries.

Services that only need the stable source and meter names can reference the lightweight TrackSeries.TVMaze.Client.Diagnostics package without pulling in the client or OpenTelemetry dependencies.

License and TVMaze attribution

This client library is licensed under the MIT license.

Data returned by the TVMaze API is made available under CC BY-SA 4.0. Applications using TVMaze data are responsible for complying with its attribution and ShareAlike requirements. TVMaze resource URLs returned by the API can be used for attribution.

References

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages