Alpa.Pagination (AlpaEx v1.0.3)

View Source

Pagination helpers for Alpaca API list endpoints.

Fetches results from paginated endpoints. Currently supports single-page fetching with configurable limits. Multi-page token-based pagination will be added when API functions are updated to return next_page_token.

The fetch function should return {:ok, result} where result is either:

  • A map containing a "next_page_token" key (raw API response format) and data under a known key. The data key is specified via the :data_key option.
  • A plain list (single-page result, no further pagination).

Usage

# Fetch results (respects :limit option)
{:ok, orders} = Alpa.Pagination.all(&Alpa.Trading.Orders.list/1, status: "closed", limit: 500)

# Fetch all bars across pages using raw API responses
Alpa.Pagination.all(
  fn opts ->
    Alpa.Client.get_data("/v2/stocks/AAPL/bars", opts)
  end,
  data_key: "bars",
  params: %{timeframe: "1Day", start: "2024-01-01T00:00:00Z"}
)

# Stream pages lazily
Alpa.Pagination.stream(
  fn opts ->
    Alpa.Client.get_data("/v2/stocks/AAPL/bars", opts)
  end,
  data_key: "bars",
  params: %{timeframe: "1Day", start: "2024-01-01T00:00:00Z"}
)
|> Stream.take(100)
|> Enum.to_list()

Limitations

Alpaca's API uses next_page_token for pagination, but the SDK's API functions currently return only the parsed results without the token. Until the response format is extended to include pagination metadata, all/2 and stream/2 fetch a single page per call. Use the :limit option to control how many results are returned.

Summary

Functions

Fetch all results from a paginated endpoint.

Create a lazy stream of results from a paginated endpoint.

Functions

all(fetch_fn, opts \\ [])

@spec all(
  (keyword() -> {:ok, map() | list()} | {:error, term()}),
  keyword()
) :: {:ok, list()} | {:error, term()}

Fetch all results from a paginated endpoint.

Calls the given function with the provided options and returns all results.

Parameters

  • fetch_fn - A function that accepts a keyword list of options and returns {:ok, results} or {:error, error}. The results can be a map (with "next_page_token") or a plain list.
  • opts - Options to pass to the fetch function

Options

  • :max_pages - Maximum number of pages to fetch (default: 100)
  • :data_key - The key in the response map that holds the data list (e.g., "bars", "trades", "quotes", "orders"). Required when working with map responses that contain next_page_token.

Examples

iex> Alpa.Pagination.all(&Alpa.Trading.Orders.list/1, status: "closed", limit: 500)
{:ok, [%Alpa.Models.Order{}, ...]}

iex> Alpa.Pagination.all(
...>   fn opts -> Alpa.Client.get_data("/v2/stocks/AAPL/bars", opts) end,
...>   data_key: "bars",
...>   params: %{timeframe: "1Day"}
...> )
{:ok, [%{"t" => "...", "o" => 150.0, ...}, ...]}

stream(fetch_fn, opts \\ [])

@spec stream(
  (keyword() -> {:ok, map() | list()} | {:error, term()}),
  keyword()
) :: Enumerable.t()

Create a lazy stream of results from a paginated endpoint.

Returns a Stream that fetches a page on demand. Each element in the stream is an individual result item (not a page).

Options

  • :data_key - The key in the response map that holds the data list. Required for map responses with next_page_token.

Examples

Alpa.Pagination.stream(
  fn opts -> Alpa.Client.get_data("/v2/stocks/AAPL/bars", opts) end,
  data_key: "bars",
  params: %{timeframe: "1Day"}
)
|> Stream.take(50)
|> Enum.each(&IO.inspect/1)