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
- func ErrorFrom(status int, header http.Header, body []byte) error
- func GenError(status int, httpResp *http.Response, body []byte) error
- func HandleResponse(resp *http.Response) error
- func NewIdempotencyKey() string
- func NewIdempotencyKeyParam() *gen.IdempotencyKey
- func WithNoRetryOn429(ctx context.Context) context.Context
- func WithReplaySafe(ctx context.Context) context.Context
- type Client
- func (c *Client) Do(ctx context.Context, method, path string, body io.Reader, ...) (*http.Response, error)
- func (c *Client) Gen() (*gen.ClientWithResponses, error)
- func (c *Client) GetBillingPlan(ctx context.Context) (*gen.BillingPlanResponse, error)
- func (c *Client) GetMe(ctx context.Context) (*gen.MeResponse, error)
- func (c *Client) RequestTimeout() time.Duration
- type Error
- type FieldError
- type Options
Constants ¶
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 ¶
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 ¶
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 ¶
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 ¶
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.
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 (*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
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 ¶
GetMe fetches the identity behind the client's token via the generated client. Shared by auth commands and account-name resolution.
func (*Client) RequestTimeout ¶
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
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.
type FieldError ¶
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.