Documentation
¶
Overview ¶
Package client provides a typed Go client for the Beamdrop S3-compatible API.
The client handles HMAC-SHA256 request signing, bucket and object operations, and both client-side and server-side presigned URL generation.
Example usage:
ctx := context.Background()
client, err := client.New(client.Config{
BaseURL: "http://localhost:7777",
AccessKeyID: "BDK_abc123",
SecretKey: "sk_secret",
})
if err != nil {
log.Fatal(err)
}
// Create or reuse a bucket
_, err = client.CreateBucketIfNotExists(ctx, "my-bucket")
if err != nil {
log.Fatal(err)
}
// Upload an object
_, err = client.PutObject(ctx, "my-bucket", "path/to/file.txt", []byte("hello world"))
if err != nil {
log.Fatal(err)
}
// Download an object
obj, err := client.GetObject(ctx, "my-bucket", "path/to/file.txt")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(obj.Body))
Index ¶
- Variables
- type APIError
- type BucketCreated
- type BucketInfo
- type BucketList
- type Client
- func (c *Client) BucketExists(ctx context.Context, name string) (bool, error)
- func (c *Client) CreateBucket(ctx context.Context, name string) (*BucketCreated, error)
- func (c *Client) CreateBucketIfNotExists(ctx context.Context, name string) (*BucketCreated, error)
- func (c *Client) CreatePresignedURL(ctx context.Context, request CreatePresignedURLRequest) (*PresignedURL, error)
- func (c *Client) DeleteBucket(ctx context.Context, name string) error
- func (c *Client) DeleteObject(ctx context.Context, bucket, key string) error
- func (c *Client) DeletePresignedURL(ctx context.Context, token string) error
- func (c *Client) GetObject(ctx context.Context, bucket, key string) (*ObjectBody, error)
- func (c *Client) GetPresignedURL(ctx context.Context, token string) (*PresignedURL, error)
- func (c *Client) HeadObject(ctx context.Context, bucket, key string) (*ObjectMetadata, error)
- func (c *Client) ListBuckets(ctx context.Context) (*BucketList, error)
- func (c *Client) ListObjects(ctx context.Context, bucket string, options ListObjectsOptions) (*ObjectList, error)
- func (c *Client) ListPresignedURLs(ctx context.Context) (*PresignedURLList, error)
- func (c *Client) ObjectExists(ctx context.Context, bucket, key string) (bool, error)
- func (c *Client) PresignObjectURL(method, bucket, key string, expiresAt time.Time) (string, error)
- func (c *Client) PutObject(ctx context.Context, bucket, key string, body []byte) (*ObjectCreated, error)
- func (c *Client) PutObjectReader(ctx context.Context, bucket, key string, body io.Reader) (*ObjectCreated, error)
- type CommonPrefix
- type Config
- type CreatePresignedURLRequest
- type ListObjectsOptions
- type ObjectBody
- type ObjectCreated
- type ObjectInfo
- type ObjectList
- type ObjectMetadata
- type PresignedURL
- type PresignedURLList
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidBaseURL indicates that the provided BaseURL is empty, malformed, or missing scheme/host. ErrInvalidBaseURL = errors.New("invalid base URL") // ErrMissingCredentials indicates that AccessKeyID and SecretKey are required but not both provided. // If one is provided, both must be provided. ErrMissingCredentials = errors.New("missing beamdrop credentials") // ErrInvalidPath indicates that an internal request path is invalid or empty. ErrInvalidPath = errors.New("invalid path") )
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
// StatusCode is the HTTP status code of the response (e.g., 404, 409, 429).
StatusCode int `json:"-"`
// Code is the machine-readable error code (e.g., "BUCKET_NOT_FOUND", "RATE_LIMIT_EXCEEDED").
Code string `json:"code,omitempty"`
// Category is the error category (e.g., "NOT_FOUND", "CONFLICT", "RATE_LIMIT").
Category string `json:"category,omitempty"`
// Message is the human-readable error message.
Message string `json:"message,omitempty"`
// Details is optional structured data providing additional context about the error.
Details map[string]any `json:"details,omitempty"`
// Retryable indicates whether the operation can be safely retried.
// True for rate limiting and service unavailable errors.
Retryable bool `json:"-"`
// RetryAfter is the recommended number of seconds to wait before retrying.
// Set from the Retry-After response header if present.
RetryAfter int `json:"-"`
// Body is the raw response body for debugging and inspection.
Body []byte `json:"-"`
}
APIError represents a structured error response from the Beamdrop API. It includes the HTTP status code, error code, category, human-readable message, and retry information.
type BucketCreated ¶
type BucketCreated struct {
// Bucket is the name of the bucket.
Bucket string `json:"bucket"`
// Created is the RFC3339 timestamp when the bucket was created (only if newly created).
Created string `json:"created,omitempty"`
// Exists indicates whether the bucket already existed (used in CreateBucketIfNotExists response).
Exists bool `json:"exists,omitempty"`
// Location is the API path to the bucket resource.
Location string `json:"location"`
}
BucketCreated is the response from CreateBucket and CreateBucketIfNotExists.
type BucketInfo ¶
BucketInfo represents metadata about a single bucket.
type BucketList ¶
type BucketList struct {
// Buckets is a slice of all accessible buckets.
Buckets []BucketInfo `json:"buckets"`
// Count is the total number of buckets.
Count int `json:"count"`
}
BucketList is the response from ListBuckets.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a typed Beamdrop S3-compatible API client. It handles HMAC-SHA256 request signing, response decoding, and error handling. All methods accept a context for cancellation and timeouts.
func New ¶
New creates and returns a new Beamdrop API client configured with the provided Config. It validates the base URL and initializes default values for HTTPClient, Now, and UserAgent if not provided.
Returns an error if the base URL is invalid or empty.
func (*Client) BucketExists ¶
BucketExists checks whether a bucket exists using a HEAD request. Returns true if the bucket exists, false if it returns a 404, or an error for other failures.
func (*Client) CreateBucket ¶
CreateBucket creates a new bucket with the given name. Returns an error if the bucket already exists (status 409) or if the name is invalid. See CreateBucketIfNotExists for an idempotent variant.
func (*Client) CreateBucketIfNotExists ¶
CreateBucketIfNotExists creates a bucket if it does not already exist, returning an idempotent operation. Returns 201 Created if the bucket was newly created, or 200 OK with exists=true if it already existed. Recommended for initialization and bootstrap use cases.
func (*Client) CreatePresignedURL ¶
func (c *Client) CreatePresignedURL(ctx context.Context, request CreatePresignedURLRequest) (*PresignedURL, error)
CreatePresignedURL creates a server-side presigned URL with optional download limits and revocation support. The URL is stored in Beamdrop's presigned URL registry and can be revoked at any time. ExpiresIn is specified in seconds; if nil, the URL never expires (depends on server policy). MaxDownloads limits the number of times the presigned URL can be used; if nil, unlimited. Returns a PresignedURL containing the token and the full URL.
func (*Client) DeleteBucket ¶
DeleteBucket deletes an empty bucket. Returns an error if the bucket is not found (404) or if it contains objects (409). Delete all objects in the bucket before calling this method.
func (*Client) DeleteObject ¶
DeleteObject deletes an object from a bucket. Returns an error if the object is not found (404) or if the deletion fails.
func (*Client) DeletePresignedURL ¶
DeletePresignedURL revokes a server-side presigned URL by its token. The URL becomes invalid immediately and cannot be used for access.
func (*Client) GetObject ¶
GetObject downloads an object from a bucket with the given key. The entire object is read into memory and returned in ObjectBody.Body. For very large objects, consider using a presigned URL and a standard HTTP client instead.
func (*Client) GetPresignedURL ¶
GetPresignedURL retrieves a single server-side presigned URL by its token. Returns an error if the token is not found or has expired.
func (*Client) HeadObject ¶
HeadObject retrieves metadata about an object without downloading the body. Returns content type, length, ETag, and last modified timestamp.
func (*Client) ListBuckets ¶
func (c *Client) ListBuckets(ctx context.Context) (*BucketList, error)
ListBuckets returns a list of all buckets accessible with the configured credentials. Returns BucketList containing bucket names and creation timestamps.
func (*Client) ListObjects ¶
func (c *Client) ListObjects(ctx context.Context, bucket string, options ListObjectsOptions) (*ObjectList, error)
ListObjects lists objects in a bucket with optional prefix, delimiter, and max key limit. Supports S3-style hierarchical listing with delimiters and common prefixes. MaxKeys defaults to 1000 if not specified.
func (*Client) ListPresignedURLs ¶
func (c *Client) ListPresignedURLs(ctx context.Context) (*PresignedURLList, error)
ListPresignedURLs lists all server-side presigned URLs created with this API key. Returns a PresignedURLList containing all tokens, buckets, keys, and metadata.
func (*Client) ObjectExists ¶
ObjectExists checks whether an object exists using a HEAD request. Returns true if the object exists, false if it returns a 404, or an error for other failures.
func (*Client) PresignObjectURL ¶
PresignObjectURL generates a client-side presigned URL for direct access to an object. The URL is self-contained, signed using your secret key, and does not require server involvement. Method should be "GET" or "PUT". The expiresAt timestamp is in UTC. Note: key rotation will invalidate existing presigned URLs generated this way. For more control over expiration and revocation, use CreatePresignedURL (server-side).
func (*Client) PutObject ¶
func (c *Client) PutObject(ctx context.Context, bucket, key string, body []byte) (*ObjectCreated, error)
PutObject uploads an object (file) to a bucket with the given key (path). The body is provided as a byte slice. For streaming uploads, use PutObjectReader. Returns object metadata including ETag and size on success.
func (*Client) PutObjectReader ¶
func (c *Client) PutObjectReader(ctx context.Context, bucket, key string, body io.Reader) (*ObjectCreated, error)
PutObjectReader uploads an object from an io.Reader, supporting streaming for large files. The reader is consumed completely during upload. Provide a buffered or seekable reader for retries. Returns object metadata including ETag and size on success.
type CommonPrefix ¶
type CommonPrefix struct {
// Prefix is the shared prefix string for a group of objects.
Prefix string `json:"prefix"`
}
CommonPrefix represents a common prefix (directory-like grouping) in a ListObjects result.
type Config ¶
type Config struct {
// BaseURL is the base URL of the Beamdrop server (required).
// Example: "http://localhost:7777" or "https://files.example.com".
BaseURL string
// AccessKeyID is the public API access key identifier (optional for anonymous access).
// Format: "BDK_xxxx" where xxxx is the key ID.
AccessKeyID string
// SecretKey is the private API secret key (required if AccessKeyID is set).
// Format: "sk_xxxx" where xxxx is the secret key material.
SecretKey string
// HTTPClient is the underlying HTTP client used for requests (optional).
// If nil, a default client with 2-minute timeout is used.
HTTPClient *http.Client
// Now is a function that returns the current time in UTC (optional).
// Used for generating request timestamps. If nil, time.Now().UTC() is used.
// Primarily for testing and time mocking.
Now func() time.Time
// UserAgent is the User-Agent header sent with requests (optional).
// If empty, defaults to "beamdrop-go-client/0.1".
UserAgent string
}
Config holds the configuration for creating a new Beamdrop API client.
type CreatePresignedURLRequest ¶
type CreatePresignedURLRequest struct {
// Bucket is the target bucket name (required).
Bucket string `json:"bucket"`
// Key is the target object key/path (required).
Key string `json:"key"`
// Method is the HTTP method for the presigned URL ("GET" or "PUT"; defaults to "GET").
Method string `json:"method,omitempty"`
// ExpiresIn is the expiration time in seconds from now (optional).
// If nil, the presigned URL never expires (subject to server policy).
ExpiresIn *int64 `json:"expiresIn,omitempty"`
// MaxDownloads limits the number of times the presigned URL can be used (optional).
// If nil, the URL is unlimited in use.
MaxDownloads *int `json:"maxDownloads,omitempty"`
}
CreatePresignedURLRequest configures a CreatePresignedURL request.
type ListObjectsOptions ¶
type ListObjectsOptions struct {
// Prefix filters the listing to objects whose keys start with this string.
Prefix string
// Delimiter groups objects by this separator (commonly "/" for hierarchical listing).
Delimiter string
// MaxKeys limits the number of objects returned (default 1000 if not specified).
MaxKeys int
}
ListObjectsOptions configures a ListObjects request.
type ObjectBody ¶
type ObjectBody struct {
// ObjectMetadata contains headers like content type, length, and ETag.
ObjectMetadata
// Body is the complete object content as a byte slice.
Body []byte
}
ObjectBody is the response from GetObject, containing both metadata and the object body.
type ObjectCreated ¶
type ObjectCreated struct {
// Bucket is the bucket where the object was stored.
Bucket string `json:"bucket"`
// Key is the object's path/key.
Key string `json:"key"`
// ETag is the MD5 hash of the uploaded content.
ETag string `json:"etag"`
// Size is the total size of the uploaded object in bytes.
Size int64 `json:"size"`
// URL is the API path to the object resource.
URL string `json:"url"`
}
ObjectCreated is the response from PutObject and PutObjectReader.
type ObjectInfo ¶
type ObjectInfo struct {
// Key is the object's path/key within the bucket.
Key string `json:"key"`
// Size is the object's size in bytes.
Size int64 `json:"size"`
// LastModified is the RFC3339 timestamp of the last modification.
LastModified time.Time `json:"lastModified"`
// ETag is the MD5 hash of the object content, useful for detecting changes.
ETag string `json:"etag"`
// ContentType is the MIME type detected from the object key extension.
ContentType string `json:"contentType,omitempty"`
}
ObjectInfo represents metadata about a single object in a bucket.
type ObjectList ¶
type ObjectList struct {
// Bucket is the bucket being listed.
Bucket string `json:"bucket"`
// Prefix is the prefix filter used in the request.
Prefix string `json:"prefix"`
// Delimiter is the delimiter used for grouping (typically "/").
Delimiter string `json:"delimiter,omitempty"`
// MaxKeys is the maximum number of keys requested.
MaxKeys int `json:"maxKeys"`
// IsTruncated indicates whether there are more results to fetch.
IsTruncated bool `json:"isTruncated"`
// Contents is the list of objects matching the prefix and delimiter.
Contents []ObjectInfo `json:"contents"`
// CommonPrefixes is a list of shared prefixes (for hierarchical listing with a delimiter).
CommonPrefixes []CommonPrefix `json:"commonPrefixes,omitempty"`
}
ObjectList is the response from ListObjects. It includes both object listings and common prefixes (for hierarchical S3-style listing).
type ObjectMetadata ¶
type ObjectMetadata struct {
// ContentType is the MIME type of the object.
ContentType string
// ContentLength is the size of the object in bytes.
ContentLength int64
// ETag is the MD5 hash of the object content.
ETag string
// LastModified is the RFC1123 formatted timestamp of the last modification.
LastModified string
}
ObjectMetadata contains HTTP headers from a HEAD or GET request for an object.
type PresignedURL ¶
type PresignedURL struct {
// ID is the unique database identifier (internal).
ID uint `json:"id,omitempty"`
// Token is the unique token for this presigned URL (used in /dl/{token}).
Token string `json:"token"`
// URL is the full presigned URL (including scheme, host, path, and parameters).
URL string `json:"url,omitempty"`
// Bucket is the target bucket name.
Bucket string `json:"bucket"`
// Key is the target object key/path.
Key string `json:"key"`
// Method is the HTTP method allowed for this presigned URL.
Method string `json:"method"`
// ExpiresAt is the expiration timestamp in RFC3339 format (nil if never expires).
ExpiresAt *time.Time `json:"expiresAt,omitempty"`
// MaxDownloads is the maximum number of times this URL can be used (nil if unlimited).
MaxDownloads *int `json:"maxDownloads,omitempty"`
// DownloadCount is the current number of times the presigned URL has been used.
DownloadCount int `json:"downloadCount,omitempty"`
// CreatedBy is the access key ID that created this presigned URL.
CreatedBy string `json:"createdBy,omitempty"`
// CreatedAt is the RFC3339 timestamp when this presigned URL was created.
CreatedAt time.Time `json:"createdAt"`
// Message is an optional message from the server (e.g., error details).
Message string `json:"message,omitempty"`
}
PresignedURL represents a server-side presigned URL record in Beamdrop's registry.
type PresignedURLList ¶
type PresignedURLList struct {
// URLs is the list of all presigned URL records.
URLs []PresignedURL `json:"urls"`
// Count is the total number of presigned URLs.
Count int `json:"count"`
}
PresignedURLList is the response from ListPresignedURLs.