Picnic (Picnic v0.1.0)

Copy Markdown View Source

An Elixir client for Picnic's unofficial supermarket API.

The API is undocumented and changes without notice; this library is built around that fact. It may break at any time and using it may violate Picnic's terms of service — be a good citizen and don't hammer the endpoints.

Usage

client = Picnic.Client.new(country: :nl)
{:ok, client} = Picnic.login(client, "user@example.com", "password")

{:ok, results} = Picnic.search(client, "melk")
{:ok, cart} = Picnic.add_to_cart(client, "s1019822", count: 2)
{:ok, deliveries} = Picnic.deliveries(client)

The client is a plain struct — no process, no global state. Login returns a new client carrying the token; persist client.auth_token and rebuild with Picnic.Client.new(auth_token: token) to skip login next time. For managed auth with automatic re-login, see the optional Picnic.Session.

The escape hatch: request/4

Because the API drifts ahead of any library, the generic passthrough is a first-class part of the public surface, not a debug affordance:

Picnic.request(client, :get, "/user")
Picnic.request(client, :post, "/cart/add_product", json: %{product_id: id, count: 2})

It reaches any endpoint — including ones this library hasn't modelled or ones Picnic adds tomorrow. The named functions below are conveniences layered on top of it; they are never the only way in.

Results, drift, and :raw

Every function returns {:ok, result} | {:error, %Picnic.Error{}}; the bang variants raise the Picnic.Error instead. Results are plain maps by default. Pass as: :struct for loose typed structs — and note that every struct keeps the complete, untouched payload under :raw, which is your lifeline when Picnic ships a field the structs don't know about yet. See Picnic.Decode for the full drift-handling rules.

Summary

Functions

Same as clear_cart/2 but raises on error.

Same as deliveries/2 but raises on error.

Same as get_cart/2 but raises on error.

Fetches the account profile. See Picnic.Resources.User.get/2.

Same as get_user/2 but raises on error.

Logs in and returns a client carrying the auth token.

Same as recipe/3 but raises on error.

Same as recipes/2 but raises on error.

Generic passthrough to any API endpoint — see the module documentation.

Same as search/3 but raises on error.

Types

result()

@type result() :: {:ok, term()} | {:error, Picnic.Error.t()}

Functions

add_to_cart(client, product_id, opts \\ [])

@spec add_to_cart(Picnic.Client.t(), String.t(), keyword()) :: result()

Adds a product to the cart. See Picnic.Resources.Cart.add/3.

add_to_cart!(client, product_id, opts \\ [])

@spec add_to_cart!(Picnic.Client.t(), String.t(), keyword()) :: term()

Same as add_to_cart/3 but raises on error.

clear_cart(client, opts \\ [])

@spec clear_cart(
  Picnic.Client.t(),
  keyword()
) :: result()

Empties the cart. See Picnic.Resources.Cart.clear/2.

clear_cart!(client, opts \\ [])

@spec clear_cart!(
  Picnic.Client.t(),
  keyword()
) :: term()

Same as clear_cart/2 but raises on error.

deliveries(client, opts \\ [])

@spec deliveries(
  Picnic.Client.t(),
  keyword()
) :: result()

Lists deliveries. See Picnic.Resources.Deliveries.list/2.

deliveries!(client, opts \\ [])

@spec deliveries!(
  Picnic.Client.t(),
  keyword()
) :: term()

Same as deliveries/2 but raises on error.

delivery(client, delivery_id, opts \\ [])

@spec delivery(Picnic.Client.t(), String.t(), keyword()) :: result()

Fetches one delivery. See Picnic.Resources.Deliveries.get/3.

delivery!(client, delivery_id, opts \\ [])

@spec delivery!(Picnic.Client.t(), String.t(), keyword()) :: term()

Same as delivery/3 but raises on error.

delivery_position(client, delivery_id, opts \\ [])

@spec delivery_position(Picnic.Client.t(), String.t(), keyword()) :: result()

Fetches a delivery's live position. See Picnic.Resources.Deliveries.position/3.

delivery_position!(client, delivery_id, opts \\ [])

@spec delivery_position!(Picnic.Client.t(), String.t(), keyword()) :: term()

Same as delivery_position/3 but raises on error.

get_cart(client, opts \\ [])

@spec get_cart(
  Picnic.Client.t(),
  keyword()
) :: result()

Fetches the shopping cart. See Picnic.Resources.Cart.get/2.

get_cart!(client, opts \\ [])

@spec get_cart!(
  Picnic.Client.t(),
  keyword()
) :: term()

Same as get_cart/2 but raises on error.

get_user(client, opts \\ [])

@spec get_user(
  Picnic.Client.t(),
  keyword()
) :: result()

Fetches the account profile. See Picnic.Resources.User.get/2.

get_user!(client, opts \\ [])

@spec get_user!(
  Picnic.Client.t(),
  keyword()
) :: term()

Same as get_user/2 but raises on error.

login(client, email, password, opts \\ [])

@spec login(Picnic.Client.t(), String.t(), String.t(), keyword()) ::
  {:ok, Picnic.Client.t()} | {:error, Picnic.Error.t()}

Logs in and returns a client carrying the auth token.

Accounts with two-factor authentication get {:error, %Picnic.Error{reason: :two_factor_required}}; pass send_2fa: true to request the code as part of logging in. See Picnic.Auth for the handshake.

login!(client, email, password, opts \\ [])

@spec login!(Picnic.Client.t(), String.t(), String.t(), keyword()) ::
  Picnic.Client.t()

Same as login/4 but raises on error.

recipe(client, recipe_id, opts \\ [])

@spec recipe(Picnic.Client.t(), String.t(), keyword()) :: result()

Fetches one recipe. See Picnic.Resources.Recipes.get/3.

recipe!(client, recipe_id, opts \\ [])

@spec recipe!(Picnic.Client.t(), String.t(), keyword()) :: term()

Same as recipe/3 but raises on error.

recipes(client, opts \\ [])

@spec recipes(
  Picnic.Client.t(),
  keyword()
) :: result()

Lists recipes. See Picnic.Resources.Recipes.list/2.

recipes!(client, opts \\ [])

@spec recipes!(
  Picnic.Client.t(),
  keyword()
) :: term()

Same as recipes/2 but raises on error.

remove_from_cart(client, product_id, opts \\ [])

@spec remove_from_cart(Picnic.Client.t(), String.t(), keyword()) :: result()

Removes a product from the cart. See Picnic.Resources.Cart.remove/3.

remove_from_cart!(client, product_id, opts \\ [])

@spec remove_from_cart!(Picnic.Client.t(), String.t(), keyword()) :: term()

Same as remove_from_cart/3 but raises on error.

request(client, method, path, opts \\ [])

@spec request(Picnic.Client.t(), Picnic.HTTP.method(), String.t(), keyword()) ::
  result()

Generic passthrough to any API endpoint — see the module documentation.

opts takes anything Req.request/1 accepts, most usefully :json and :params.

request!(client, method, path, opts \\ [])

@spec request!(Picnic.Client.t(), Picnic.HTTP.method(), String.t(), keyword()) ::
  term()

Same as request/4 but raises on error.

search(client, term, opts \\ [])

@spec search(Picnic.Client.t(), String.t(), keyword()) :: result()

Searches the product catalogue. See Picnic.Resources.Search.search/3.

search!(client, term, opts \\ [])

@spec search!(Picnic.Client.t(), String.t(), keyword()) :: term()

Same as search/3 but raises on error.