ExOura.RateLimiter (ex_oura v2.0.0)

View Source

Handles rate limiting for Oura API requests.

The Oura API has the following rate limits:

  • Daily: 5000 requests per day
  • Per-minute: 300 requests per minute

This module tracks these limits and prevents requests when limits are exceeded. It also provides functionality to parse rate limit headers from API responses.

Summary

Functions

Checks if a request can be made without exceeding rate limits. Returns {:ok, 0} immediately if rate limiting is disabled.

Returns a specification to start this module under a supervisor.

Checks if rate limiting is enabled in the configuration.

Gets current rate limit status for debugging/monitoring. Returns nil if rate limiting is disabled.

Records that a request was made (for internal tracking). Does nothing if rate limiting is disabled.

Starts the rate limiter GenServer.

Updates rate limit information from API response headers. Does nothing if rate limiting is disabled.

Types

check_result()

@type check_result() ::
  {:ok, non_neg_integer()} | {:error, {:rate_limited, integer()}}

rate_limit_state()

@type rate_limit_state() :: %{
  remaining: non_neg_integer(),
  reset_time: integer() | nil,
  per_minute_remaining: non_neg_integer(),
  per_minute_reset: integer() | nil,
  last_request_time: integer()
}

Functions

check_rate_limit()

@spec check_rate_limit() :: check_result()

Checks if a request can be made without exceeding rate limits. Returns {:ok, 0} immediately if rate limiting is disabled.

Returns

  • {:ok, delay} - Request can be made, with optional delay in milliseconds
  • {:error, {:rate_limited, retry_after}} - Request should be delayed, retry_after in seconds

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

enabled?()

@spec enabled?() :: boolean()

Checks if rate limiting is enabled in the configuration.

get_status()

@spec get_status() :: rate_limit_state() | nil

Gets current rate limit status for debugging/monitoring. Returns nil if rate limiting is disabled.

record_request()

@spec record_request() :: :ok

Records that a request was made (for internal tracking). Does nothing if rate limiting is disabled.

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Starts the rate limiter GenServer.

Options

  • :daily_limit - Daily request limit (default: 5000)
  • :per_minute_limit - Per-minute request limit (default: 300)
  • :name - GenServer name (default: MODULE)

update_rate_limit_headers(headers)

@spec update_rate_limit_headers(map() | list()) :: :ok

Updates rate limit information from API response headers. Does nothing if rate limiting is disabled.

Expected headers:

  • "x-ratelimit-limit" - Daily limit
  • "x-ratelimit-remaining" - Daily remaining
  • "x-ratelimit-reset" - Daily reset time (Unix timestamp)
  • "x-ratelimit-limit-minute" - Per-minute limit
  • "x-ratelimit-remaining-minute" - Per-minute remaining
  • "x-ratelimit-reset-minute" - Per-minute reset time (Unix timestamp)