HTTP client for the snippet-browsing slice of the Qx Portal API
at /api/v1.
Wraps Req so the snippet Smart Cell never touches HTTP details directly. Maps the documented error shapes to plain tuples the cell can pattern-match on.
Hardware-execution endpoints (/api/v1/transpile) live in
Qx.Hardware.Portal upstream — kino_qx delegates through
Kino.Qx.run!/2 rather than calling them directly.
All functions take a config map:
%{
token: "qx_live_...",
base_url: "https://qxportal.dev"
}Error mapping
| HTTP | Returned |
|---|---|
| 200 OK | {:ok, decoded_data} |
| 401 | {:error, :unauthorized} |
| 404 | {:error, :not_found} |
429 + retry-after header | {:error, {:rate_limited, secs}} |
| Other 4xx/5xx | {:error, {:http, status, body}} |
| Network / Req exception | {:error, {:network, reason}} |
Summary
Types
Configuration map for every client call.
The shape returned by /api/v1/me.
Full snippet as returned by /api/v1/snippets/:id.
Single snippet summary as returned by /api/v1/snippets.
Functions
Returns one snippet with bodies.
Returns the caller's snippets, newest first. List view (no bodies).
Confirms a token is valid and returns the authenticated identity.
Types
Configuration map for every client call.
The shape returned by /api/v1/me.
@type snippet() :: %{ id: integer(), name: String.t(), visibility: String.t(), share_url: String.t() | nil, qasm_content: String.t(), elixir_content: String.t(), inserted_at: String.t(), updated_at: String.t() }
Full snippet as returned by /api/v1/snippets/:id.
@type snippet_summary() :: %{ id: integer(), name: String.t(), visibility: String.t(), share_url: String.t() | nil, inserted_at: String.t(), updated_at: String.t() }
Single snippet summary as returned by /api/v1/snippets.
Functions
Returns one snippet with bodies.
@spec list_snippets(config()) :: {:ok, [snippet_summary()]} | {:error, term()}
Returns the caller's snippets, newest first. List view (no bodies).
Confirms a token is valid and returns the authenticated identity.