Skip to main content

Client

Struct Client 

Source
pub struct Client { /* private fields */ }
Expand description

Client for Pathbase API

HTTP API for Pathbase — repositories, agent trace paths, computation graphs, and anonymous share links.

Stability. v1 endpoints are stable in shape; additive changes (new fields, new endpoints, broader query params) ship without a version bump. Breaking changes get a new prefix (/api/v2/...) and a deprecation window.

Spec format. OpenAPI 3.1, served live at /api/v1/openapi.json.

Versioning header. Every response carries an X-Pathbase-Version header with the running build’s identifier (<semver>+<git-sha>). The spec does not enumerate it per operation; consumers may read it from any response to pin or correlate.

Auth. Most endpoints require a pat_… bearer token (see bearerAuth). Obtain one through the CLI grant flow (POST /api/v1/auth/cli/request-grant then POST /api/v1/auth/cli/redeem). Unauthenticated endpoints — the Anon namespace, public profile reads — are clearly tagged. Per-operation security annotations reflect the actual gate.

Version: 1.1.0

Implementations§

Source§

impl Client

Source

pub fn new(baseurl: &str) -> Self

Create a new client.

baseurl is the base URL provided to the internal reqwest::Client, and should include a scheme and hostname, as well as port and a path stem if applicable.

Source

pub fn new_with_client(baseurl: &str, client: Client) -> Self

Construct a new client with an existing reqwest::Client, allowing more control over its configuration.

baseurl is the base URL provided to the internal reqwest::Client, and should include a scheme and hostname, as well as port and a path stem if applicable.

Source§

impl Client

Source

pub async fn cli_redeem<'a>( &'a self, body: &'a RedeemBody, ) -> Result<ResponseValue<RedeemResponse>, Error<ApiErrorResponse>>

Redeem a CLI pairing grant for a long-lived bearer token

Second leg of the CLI pairing flow (see /api/v1/auth/cli/request-grant for the full sequence). The CLI posts the code the user typed; the server normalizes case and whitespace, consumes the grant, and — on a still-valid grant — returns the bearer token plus user. Single-use; subsequent redemptions of the same code return 401.

No authentication is required to call this endpoint; the grant code IS the authentication. A code that is unknown, expired, or already redeemed all collapse to 401 Unauthorized so the response cannot be used to probe for valid codes — the three failure modes are deliberately indistinguishable.

Sends a POST request to /api/v1/auth/cli/redeem

Arguments:

  • body: The grant code the user pasted into the CLI. Case and surrounding whitespace are normalized server-side.
Source

pub async fn cli_request_grant<'a>( &'a self, ) -> Result<ResponseValue<CliGrantResponse>, Error<ApiErrorResponse>>

Mint a short-lived grant code for pairing the pathbase CLI to this browser session

Pairing flow.

  1. Browser (already authenticated) calls this endpoint and displays the returned code to the user.
  2. User pastes the code into a CLI prompt (pathbase login).
  3. CLI POSTs the code to /api/v1/auth/cli/redeem.
  4. Server consumes the grant and returns { token, user } to the CLI.
  5. CLI stores token and sends it as Authorization: Bearer <token> on every subsequent API call.

The grant is single-use and expires after a short window. Multiple grants may be active concurrently; redeeming one has no effect on existing tokens.

Sends a POST request to /api/v1/auth/cli/request-grant

Source

pub async fn list_sessions<'a>( &'a self, ) -> Result<ResponseValue<Vec<SessionSummary>>, Error<ApiErrorResponse>>

List the authenticated user’s active sessions

Returns one entry per session owned by the caller — both browser logins and CLI tokens. Includes an is_current flag so the UI can mark which entry is the caller’s own session.

Used by the settings UI to render “active devices/CLIs” with a per-entry revoke button (which calls DELETE /api/v1/auth/sessions/{id}).

Sends a GET request to /api/v1/auth/sessions

Source

pub async fn revoke_session<'a>( &'a self, id: &'a Uuid, ) -> Result<ResponseValue<()>, Error<ApiErrorResponse>>

Revoke one of the caller’s sessions

Ends the session identified by {id}, immediately invalidating its token. The caller can revoke any of their own sessions, including the one that issued this request — doing so will end the current login. Sessions belonging to other users are reported as 404 Not Found (no leakage of “exists but isn’t yours”).

Sends a DELETE request to /api/v1/auth/sessions/{id}

Arguments:

  • id: ID of the session to revoke. Obtain from GET /api/v1/auth/sessions. Revoking your current session ends the request’s own login.
Source

pub async fn create_anon_graph<'a>( &'a self, body: &'a UploadGraphBody, ) -> Result<ResponseValue<GraphDocumentResponse>, Error<ApiErrorResponse>>

Upload a graph anonymously as the anon user. No authentication required; the resulting graph is always Unlisted and reachable only via the returned share URL

Sends a POST request to /api/v1/u/anon/repos/pathstash/graphs

Arguments:

  • body: Toolpath Graph document. The body’s visibility field is ignored; anon uploads are always Unlisted.
Source

pub async fn get_me<'a>( &'a self, ) -> Result<ResponseValue<User>, Error<ApiErrorResponse>>

Return the authenticated user’s full profile

Canonical “who am I?” endpoint. Returns the user matching the caller’s bearer token. The returned shape matches the public GET /api/v1/u/{username} response with one difference: email is included here because the caller is reading their own profile.

Sends a GET request to /api/v1/u/me

Source

pub async fn update_me<'a>( &'a self, body: &'a UpdateProfileBody, ) -> Result<ResponseValue<User>, Error<ApiErrorResponse>>

Replace the authenticated user’s editable profile fields

PUT semantics: the body is the new state. Fields not present (or null) are cleared. Username and email are not editable here. Returns the updated user.

Sends a PUT request to /api/v1/u/me

Arguments:

  • body: Complete new state of the editable profile fields. Missing or null clears the field — send the current value to preserve it.
Source

pub async fn list_repos<'a>( &'a self, owner: &'a str, limit: Option<u64>, ) -> Result<ResponseValue<Vec<Repo>>, Error<()>>

List repositories owned by {owner}. The DB layer applies the visibility filter in SQL using the resolved Viewer: owners get all three states (Public + Unlisted + Private); non-owners get Public only. There is no caller-side branching, and no helper that returns “everything” without a viewer

Sends a GET request to /api/v1/u/{owner}/repos

Arguments:

  • owner: Owner username
  • limit: Optional. Server-bounded; out-of-range values are clamped silently.
Source

pub async fn create_repo<'a>( &'a self, owner: &'a str, body: &'a CreateRepoBody, ) -> Result<ResponseValue<Repo>, Error<ApiErrorResponse>>

Create a new repository owned by the authenticated user

The new repo’s owner is taken from the session — there is no way to create a repo on behalf of someone else through this endpoint. (Owner usernames in URLs are read-only metadata; ownership is set once at creation.) The repo defaults to public visibility.

Returns the created Repo with its server-assigned UUID and timestamps.

Sends a POST request to /api/v1/u/{owner}/repos

Arguments:

  • owner: Owner username
  • body: Name and optional description for the new repo. Owner is implicit (the authenticated user).
Source

pub async fn get_repo<'a>( &'a self, owner: &'a str, repo: &'a str, ) -> Result<ResponseValue<Repo>, Error<ApiErrorResponse>>

Fetch a repository by (owner, name)

Public read; no authentication required. Returns the Repo including description, README, visibility flag, and timestamps. To list a repo’s paths or graphs, follow up with the corresponding /paths and /graphs collection endpoints.

Owner aliases. The literal me resolves to the authenticated viewer (401 if unauthenticated) — /u/me/repos/{repo} is the same as /u/{your-username}/repos/{repo} without needing your own username. anon is the seeded system namespace; its pathstash repo is reachable here like any other Unlisted repo.

Visibility. can_read is enforced: Public returns to anyone, Unlisted (system-managed; URL-addressable) returns to anyone, Private returns only to the owner — others get 404. Repos are addressed by guessable name, so there’s no share-by-link at this level for Private repos. (Per-graph/per-path share-by-link inside Public repos is unaffected — those still gate on their own visibility.)

Sends a GET request to /api/v1/u/{owner}/repos/{repo}

Arguments:

  • owner: Owner username. The literal me resolves to the authenticated viewer (401 if unauthenticated).
  • repo: Repository name (unique per owner).
Source

pub async fn update_repo<'a>( &'a self, owner: &'a str, repo: &'a str, body: &'a UpdateRepoBody, ) -> Result<ResponseValue<Repo>, Error<ApiErrorResponse>>

Replace a repository’s editable fields (name, description, README)

Owner-only: the authenticated user must match {owner}. The literal me resolves to the authenticated viewer’s own namespace.

PUT semantics: the body is the new state. To preserve any field, send its current value; missing or null clears the nullable fields. Visibility is changed through the separate /visibility sub-resource. Renaming changes the canonical URL of the repo (and every nested resource), so callers should expect old links to 404 afterward.

Sends a PUT request to /api/v1/u/{owner}/repos/{repo}

Arguments:

  • owner: Owner username; must match the authenticated user. The literal me resolves to the authenticated viewer.
  • repo: Repository name (current — pre-rename).
  • body: Complete new state of the editable repo fields. name is required; missing/null clears description and readme. Send back the current values to preserve them.
Source

pub async fn delete_repo<'a>( &'a self, owner: &'a str, repo: &'a str, ) -> Result<ResponseValue<()>, Error<ApiErrorResponse>>

Delete a repository and all its contents

Owner-only. Removes the repo and all paths and graphs in it. Irreversible. The literal me resolves to the authenticated viewer’s own namespace.

Sends a DELETE request to /api/v1/u/{owner}/repos/{repo}

Arguments:

  • owner: Owner username; must match the authenticated user. The literal me resolves to the authenticated viewer.
  • repo: Repository name.
Source

pub async fn list_graphs<'a>( &'a self, owner: &'a str, repo: &'a str, limit: Option<u64>, ) -> Result<ResponseValue<Vec<GraphSummaryResponse>>, Error<ApiErrorResponse>>

List graphs in a repository

Returns up to ?limit= graphs under {owner}/{repo}, ordered by creation time. The DB layer applies the visibility filter in SQL using the resolved Viewer: the owner sees all three states (Public + Unlisted + Private) so the UI can render the unlisted pill and offer a show/hide toggle; everyone else sees only Public. Non-public graphs remain reachable by direct UUID share-link regardless of listing visibility.

Sends a GET request to /api/v1/u/{owner}/repos/{repo}/graphs

Arguments:

  • owner: Username of the repository’s owner.
  • repo: Repository name within the owner’s namespace.
  • limit: Optional. Server-bounded; out-of-range values are clamped silently.
Source

pub async fn create_graph<'a>( &'a self, owner: &'a str, repo: &'a str, body: &'a UploadGraphBody, ) -> Result<ResponseValue<GraphDocumentResponse>, Error<ApiErrorResponse>>

Create a graph from a multi-path toolpath document

Inline path entries (full path objects) are admitted into the same workspace as the graph (deduped by toolpath ID; an existing match is linked rather than re-created). Refs to existing paths ({ "$ref": "..." } entries) are kept as ID references and not re-stored.

Caller must own {owner}/{repo}. The document field must parse as a toolpath v1 Graph.

Sends a POST request to /api/v1/u/{owner}/repos/{repo}/graphs

Arguments:

  • owner: Username of the repository’s owner. Must match the authenticated caller.
  • repo: Repository name within the owner’s namespace.
  • body: Multi-path toolpath Graph document, optional display name, and visibility (public/unlisted/private, default unlisted). Inline paths are admitted into the workspace; refs are kept as ID references.
Source

pub async fn get_graph<'a>( &'a self, owner: &'a str, repo: &'a str, id: &'a Uuid, ) -> Result<ResponseValue<GraphDocumentResponse>, Error<ApiErrorResponse>>

Fetch a single graph with its full reconstructed multi-path document. Public and Unlisted graphs are readable by anyone (possession of the UUID is the share token for Unlisted); Private graphs require the caller to authenticate as the owner. Non-owner reads of a Private graph return 404 — same response as “doesn’t exist” so the gate doesn’t leak existence

Responses carry an ETag; conditional requests using If-None-Match return 304 Not Modified when the representation is unchanged.

Sends a GET request to /api/v1/u/{owner}/repos/{repo}/graphs/{id}

Arguments:

  • owner: Username of the repository’s owner.
  • repo: Repository name within the owner’s namespace.
  • id: Graph UUID. For Unlisted graphs the UUID is the share token; Private graphs additionally require owner authentication.
Source

pub async fn delete_graph<'a>( &'a self, owner: &'a str, repo: &'a str, id: &'a Uuid, ) -> Result<ResponseValue<()>, Error<ApiErrorResponse>>

Delete a graph. Owner only — knowing the UUID is enough to read (it’s the share token) but not enough to mutate

Sends a DELETE request to /api/v1/u/{owner}/repos/{repo}/graphs/{id}

Arguments:

  • owner: Owner username — must match the authenticated caller.
  • repo: Repository name.
  • id: Graph UUID.
Source

pub async fn download_graph<'a>( &'a self, owner: &'a str, repo: &'a str, id: &'a Uuid, ) -> Result<ResponseValue<Map<String, Value>>, Error<ApiErrorResponse>>

Stream the graph’s reconstructed Graph document as raw JSON — the inverse of POST .../graphs. Public and Unlisted graphs download for anyone with the UUID; Private graphs require owner authentication and 404 for everyone else (mirrors “doesn’t exist”)

Sends a GET request to /api/v1/u/{owner}/repos/{repo}/graphs/{id}/download

Source

pub async fn list_graph_paths<'a>( &'a self, owner: &'a str, repo: &'a str, id: &'a Uuid, limit: Option<u64>, ) -> Result<ResponseValue<Vec<TracePathSummaryResponse>>, Error<ApiErrorResponse>>

List the paths that belong to a graph, in graph-defined order. If the parent graph is readable to the caller (Public/Unlisted, or Private for the owner), all of its constituent paths are returned; the parent’s UUID is the share token. A Private graph 404s for non-owners — same as the per-graph GET

Sends a GET request to /api/v1/u/{owner}/repos/{repo}/graphs/{id}/paths

Arguments:

  • owner
  • repo
  • id
  • limit: Optional. Server-bounded; out-of-range values are clamped silently.
Source

pub async fn get_graph_path<'a>( &'a self, owner: &'a str, repo: &'a str, id: &'a Uuid, path_id: &'a Uuid, ) -> Result<ResponseValue<TracePathDocumentResponse>, Error<ApiErrorResponse>>

Fetch a constituent path with its full reconstructed document. Conditional via If-None-Match

Sends a GET request to /api/v1/u/{owner}/repos/{repo}/graphs/{id}/paths/{path_id}

Source

pub async fn delete_graph_path<'a>( &'a self, owner: &'a str, repo: &'a str, id: &'a Uuid, path_id: &'a Uuid, ) -> Result<ResponseValue<()>, Error<()>>

Delete a constituent path. Owner only. Cascades to its step rows AND removes the junction row from this graph

Sends a DELETE request to /api/v1/u/{owner}/repos/{repo}/graphs/{id}/paths/{path_id}

Source

pub async fn update_graph_path<'a>( &'a self, owner: &'a str, repo: &'a str, id: &'a Uuid, path_id: &'a Uuid, body: &'a UpdateGraphPathBody, ) -> Result<ResponseValue<TracePathResponse>, Error<ApiErrorResponse>>

Patch a constituent path’s mutable fields — currently just visibility. Owner only

Sends a PATCH request to /api/v1/u/{owner}/repos/{repo}/graphs/{id}/paths/{path_id}

Source

pub async fn get_graph_path_chat<'a>( &'a self, owner: &'a str, repo: &'a str, id: &'a Uuid, path_id: &'a Uuid, include_html: Option<bool>, ) -> Result<ResponseValue<ChatProjection>, Error<()>>

Render the path’s HEAD-ancestor chain as a chat-projection — a densely-indexed, pre-classified, optionally pre-rendered transcript

Sends a GET request to /api/v1/u/{owner}/repos/{repo}/graphs/{id}/paths/{path_id}/chat

Arguments:

  • owner
  • repo
  • id
  • path_id
  • include_html: Render text and thinking fields to sanitized HTML server-side. Defaults to true; set false for lighter payloads when the client renders markdown lazily.
Source

pub async fn update_graph_visibility<'a>( &'a self, owner: &'a str, repo: &'a str, id: &'a Uuid, body: &'a UpdateGraphVisibilityBody, ) -> Result<ResponseValue<GraphResponse>, Error<ApiErrorResponse>>

Toggle a graph’s public/secret visibility. Owner only

Sends a PATCH request to /api/v1/u/{owner}/repos/{repo}/graphs/{id}/visibility

Source

pub async fn update_repo_visibility<'a>( &'a self, owner: &'a str, repo: &'a str, body: &'a RepoVisibilityBody, ) -> Result<ResponseValue<Repo>, Error<ApiErrorResponse>>

Flip a repo’s visibility between public and private. The unlisted state is system-only — owner cannot set it, and any repo currently unlisted (e.g., the seeded pathstash) is locked

Sends a PATCH request to /api/v1/u/{owner}/repos/{repo}/visibility

Arguments:

  • owner: Owner username; must match the authenticated user. The literal me resolves to the authenticated viewer.
  • repo: Repository name.
  • body: New visibility. Repos accept public or private only — unlisted is system-only.
Source

pub async fn get_user<'a>( &'a self, username: &'a str, ) -> Result<ResponseValue<User>, Error<ApiErrorResponse>>

Look up a user’s public profile by username

No authentication required. Returns the same User shape as /u/me with one guarantee: email is always null here — that field is only ever populated for the caller’s own profile via GET /api/v1/u/me.

Reserved namespaces. The literal usernames me and anon are reserved and always return 404 from this endpoint. Use GET /api/v1/u/me for the calling user and /api/v1/u/anon/... for anonymous content.

Sends a GET request to /api/v1/u/{username}

Arguments:

  • username: Public username. Lowercase ASCII alphanumerics with -/_. The literal me resolves to the authenticated viewer (401 if unauthenticated). anon is the seeded system namespace; its profile is not browseable.

Trait Implementations§

Source§

impl ClientHooks for &Client

Source§

async fn pre<E>( &self, request: &mut Request, info: &OperationInfo, ) -> Result<(), Error<E>>

Runs prior to the execution of the request. This may be used to modify the request before it is transmitted.
Source§

async fn post<E>( &self, result: &Result<Response, Error>, info: &OperationInfo, ) -> Result<(), Error<E>>

Runs after completion of the request.
Source§

async fn exec( &self, request: Request, info: &OperationInfo, ) -> Result<Response, Error>

Execute the request. Note that for almost any reasonable implementation this will include code equivalent to this: Read more
Source§

impl ClientInfo<()> for Client

Source§

fn api_version() -> &'static str

Get the version of this API. Read more
Source§

fn baseurl(&self) -> &str

Get the base URL to which requests are made.
Source§

fn client(&self) -> &Client

Get the internal reqwest::Client used to make requests.
Source§

fn inner(&self) -> &()

Get the inner value of type T if one is specified.
Source§

impl Clone for Client

Source§

fn clone(&self) -> Client

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Client

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more