api

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 13, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package api provides the HTTP client wrapper for the Melange public API: transport chain (auth, retry, debug), error-envelope decoding, and the hand-written calls that will later be replaced by a generated client.

Index

Constants

View Source
const DefaultRequestTimeout = 30 * time.Second

DefaultRequestTimeout bounds one ordinary Melange API call, including retries and response-body reads. Long-running conversion waits and signed storage transfers use their own independent budgets.

Variables

This section is empty.

Functions

func ErrorFrom

func ErrorFrom(status int, header http.Header, body []byte) error

ErrorFrom converts an already-read response into an error: nil for 2xx, otherwise an *Error decoded from the server error envelope (with a status-derived fallback for non-envelope bodies). It is the uniform way to surface non-2xx results from generated-client responses, which carry the body as bytes.

func GenError

func GenError(status int, httpResp *http.Response, body []byte) error

GenError converts a generated-client response into an error: nil for 2xx, otherwise an *Error via ErrorFrom. It is THE way to surface non-2xx results from generated responses; it tolerates a nil HTTPResponse.

func HandleResponse

func HandleResponse(resp *http.Response) error

HandleResponse returns nil for 2xx responses (leaving the body untouched); otherwise it consumes the body and returns an *Error. Exported so callers using Do directly can reuse the envelope decoding.

func NewIdempotencyKey added in v0.4.0

func NewIdempotencyKey() string

NewIdempotencyKey returns a random UUIDv4. Sent as Idempotency-Key on replay-safe mutations (per ADR-5: create/complete/reissue/cancel of upload sessions, imports, download authorizations) so this package's retry transport may safely replay them: retryEligible treats any request carrying an Idempotency-Key header as replay-safe.

The key format is part of the replay contract with the backend and must not change: the server deduplicates on the exact key string, so one logical operation retried after a 5xx must present the same bytes.

func NewIdempotencyKeyParam added in v0.4.0

func NewIdempotencyKeyParam() *gen.IdempotencyKey

NewIdempotencyKeyParam returns a fresh key as the pointer type the generated params structs take. The key is generated once per logical call, so the retry transport replays the same key on 5xx retries instead of starting a second operation or charging twice.

func WithNoRetryOn429

func WithNoRetryOn429(ctx context.Context) context.Context

WithNoRetryOn429 returns a context that exempts the request from the transport's 429 retry policy. Billable calls use this: a quota 429 is not transient at retry timescales, so sitting through the backoff schedule only delays the quota error. Transient 5xx and connection errors are still retried as usual.

func WithReplaySafe

func WithReplaySafe(ctx context.Context) context.Context

WithReplaySafe explicitly permits retrying a replayable PUT/PATCH request. Callers must only use it for set-style operations where replaying the exact body cannot apply the mutation twice.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is an HTTP client for the Melange public API. The transport chain is (outermost first): auth -> retry -> debug -> base.

func NewClient

func NewClient(opts Options) (*Client, error)

NewClient builds a Client from opts.

func (*Client) Do

func (c *Client) Do(ctx context.Context, method, path string, body io.Reader, headers map[string]string) (*http.Response, error)

Do sends a request to a path relative to the client's host (e.g. "/v1/me", optionally with a query string like "/v1/repos?limit=5") and returns the raw response. The caller owns the response body.

func (*Client) Gen

func (c *Client) Gen() (*gen.ClientWithResponses, error)

Gen returns a generated OpenAPI client bound to this client's host that rides the same transport chain (auth -> retry -> debug), so every generated call carries the Bearer token, User-Agent, and retry behavior.

Convert non-2xx generated responses with GenError:

if err := api.GenError(resp.StatusCode(), resp.HTTPResponse, resp.Body); err != nil {
	return err
}

func (*Client) GetBillingPlan added in v0.2.0

func (c *Client) GetBillingPlan(ctx context.Context) (*gen.BillingPlanResponse, error)

GetBillingPlan fetches the effective billing plan for the client's token via the generated client. Shared by the plan command and auth status.

func (*Client) GetMe

func (c *Client) GetMe(ctx context.Context) (*gen.MeResponse, error)

GetMe fetches the identity behind the client's token via the generated client. Shared by auth commands and account-name resolution.

func (*Client) ImportModelZtcPackage added in v0.8.0

func (c *Client) ImportModelZtcPackage(ctx context.Context, accountName, repoName, hfRepo string) (*gen.ImportModelResponse, []byte, error)

ImportModelZtcPackage triggers the non-llama.cpp ZTC package conversion path for a HuggingFace repo, mirroring the web UI's staff-only endpoint. It rides this client's transport chain (auth -> retry -> debug) exactly like the generated ImportModel call. It returns the decoded response, the raw response bytes (for --json/--jq output), and a GenError-converted error.

It deliberately sends NO Idempotency-Key. The server route does not read one (unlike import_model, which resolves a key and replays), the spec declares no such parameter for it, and the route disables its own HF dedup by forcing skip_hf_revision_lookup. Sending the header would only make retryEligible true, so a 502/503/504 or connection blip would replay the POST into a SECOND import and a second credit hold — a silent double charge. Without the header the POST is not retried and a transient failure surfaces for the caller to re-run deliberately. Restore the key once the route honors it.

BACKEND: the public route is POST /v1/repos/{account_name}/{repo_name}/models/ztc-package with body {"uri": "<hf_repo>"}, aligned to the existing import route. The path lives here alone, so adjust this one line if the backend exposes a different route.

func (*Client) RequestTimeout

func (c *Client) RequestTimeout() time.Duration

RequestTimeout reports the configured ordinary API request budget.

type Error

type Error struct {
	StatusCode int
	Type       string // e.g. authentication_error, rate_limit_error, invalid_request_error
	Code       string // machine-readable refusal code, e.g. credit_balance_exhausted; "" when absent
	Message    string
	Fields     []FieldError
	// ActiveUploadID is populated by upload-session conflict responses. It is
	// optional so clients remain compatible with servers that predate the
	// structured conflict field.
	ActiveUploadID string
	RequestID      string        // top-level request_id, or X-Request-ID header fallback
	RetryAfter     time.Duration // parsed Retry-After header, 0 if absent
}

Error is a non-2xx response from the Melange API, decoded from the server error envelope when present.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface.

func (*Error) Retryable

func (e *Error) Retryable() bool

Retryable reports whether the request may be safely retried.

type FieldError

type FieldError struct {
	Field   string `json:"field"`
	Message string `json:"message"`
}

FieldError describes a single invalid field in a request.

type Options

type Options struct {
	Host      string            // base URL, e.g. "https://api.zetic.ai"; scheme defaults to https
	Token     string            // Bearer token; empty = unauthenticated
	UserAgent string            // e.g. "melange-cli/1.0.0 (darwin; arm64)"
	Debug     io.Writer         // nil = debug logging off
	Transport http.RoundTripper // base transport; nil = http.DefaultTransport
	Timeout   time.Duration     // per API request; 0 = DefaultRequestTimeout
}

Options configures a Client.

Directories

Path Synopsis
Package gen provides primitives to interact with the openapi HTTP API.
Package gen provides primitives to interact with the openapi HTTP API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL