fal

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2026 License: BSD-3-Clause Imports: 22 Imported by: 0

README

fal-go

CI Coverage Status Go Reference Go Report Card License

A Go client for fal.ai, a 1:1 behavioral port of the official Python client (fal-client). Same wire protocol, same method surface, idiomatic Go ergonomics: one *fal.Client, context.Context on every call, functional options, and iter.Seq2 iterators.

Requires Go 1.26+.

go get github.com/valksor/fal-go

Getting a key

Create a key in the fal dashboard and expose it as FAL_KEY. Prefer a .env file or direnv over an inline FAL_KEY=… go run … (which lands in shell history):

echo 'FAL_KEY=your-key' > .env

Credentials are resolved in this order: explicit WithKey, FAL_KEY, FAL_KEY_ID + FAL_KEY_SECRET, then the ~/.fal/auth0_token login token (auto-refreshed).

Quick start

ctx := context.Background()
result, err := fal.Subscribe(ctx, "fal-ai/fast-sdxl",
    map[string]any{"prompt": "a cat riding a bicycle"},
    fal.WithLogs(true),
    fal.OnQueueUpdate(func(s fal.Status) {
        if q, ok := s.(fal.Queued); ok {
            log.Printf("queued at %d", q.Position)
        }
    }),
)

The package-level functions (fal.Subscribe, fal.Run, ...) delegate to a shared default client. Construct your own with fal.New(...) for custom keys, HTTP clients, or timeouts.

Result types

API results are dynamic JSON, returned as any (mirroring Python). Decode into a typed struct with the generic helper:

out, err := fal.As[MyResult](result)

Status values

Status is a sealed interface; the only cases are Queued, InProgress and Completed:

switch v := s.(type) {
case fal.Queued:     // v.Position
case fal.InProgress: // v.Logs
case fal.Completed:  // v.Metrics, v.Error
}

Streaming (SSE)

Stream returns an iter.Seq2[map[string]any, error]. Break on error — the error is yielded as the final pair, and breaking closes the connection:

for event, err := range c.Stream(ctx, "fal-ai/some-app", input) {
    if err != nil {
        log.Printf("stream error: %v", err)
        break
    }
    fmt.Println(event)
}

Uploads

Upload, UploadFile and UploadImage return a public URL. The default backend chain is the fal CDN (fal_v3) with a GCS (fal) fallback — i.e. ["fal_v3", "fal"], matching the Python client — and multipart for files over 100 MB. Configure the chain with WithRepository / WithFallbackRepository (valid values: "fal_v3" CDN, "fal" GCS; "cdn" is a deprecated alias for "fal_v3"). The next backend is tried on any failure of the previous one; WithFallbackRepository() with no arguments disables the default fallback. Large uploads routed to fal_v3 go multipart and are returned directly without falling back.

url, err := c.UploadFile(ctx, "input.png")

Realtime

Realtime opens a msgpack WebSocket connection; WSConnect is the lower-level raw-connection escape hatch.

conn, err := c.Realtime(ctx, "fal-ai/some-app")
defer conn.Close()
conn.Send(ctx, map[string]any{"prompt": "hi"})
msg, err := conn.Recv(ctx)

Security note: by default the realtime JWT is placed in the WebSocket URL query string (matching the Python client), which intermediaries may log. Use WithJWT(false) to send it as an Authorization header instead.

Working with handles

Subscribe and Run are the primary paths. For finer control, Submit returns a *RequestHandle you can poll yourself (handle.Status, handle.IterEvents, handle.Get, handle.Cancel). GetHandle(application, requestID) reconstructs a handle for a request you already have an id for.

Errors

Type Meaning
*fal.Error generic client error
*fal.HTTPError non-2xx API response (StatusCode, ErrorType; headers redacted)
*fal.TimeoutError Subscribe exceeded its client timeout
*fal.MissingCredentialsError no credentials could be resolved
*fal.RealtimeError server error frame on a realtime connection

Inspect with errors.As.

Package layout

The top-level fal package is the entry point — construct a *fal.Client (or use the package-level functions) and call its flat methods. Everything it returns and accepts is re-exported here, so importing github.com/valksor/fal-go alone is enough for normal use.

The implementation is organized into focused, public sub-packages that share one HTTP core; import them directly only if you want a narrower dependency:

Package Responsibility
transport HTTP engine: request building, retry/backoff, CDN token cache
auth credential resolution (key, key-id+secret, login-token refresh)
option functional options (WithX/OnX) and the resolved CallOptions
run, queue, stream, upload, realtime the feature operations
appid, status, storage, encode, errs leaf types and helpers (errs is so named to avoid shadowing the stdlib errors)

The fal.* names (fal.Status, fal.RequestHandle, fal.WithLogs, …) are aliases/re-exports of these packages' symbols, so they stay interchangeable — e.g. errors.As(err, new(*fal.HTTPError)) matches an error built inside transport.

The stable, supported surface is the top-level fal package. The sub-packages are public for narrower dependencies, but a few of their symbols are plumbing rather than API: build a client only with fal.New (do not construct transport.Core yourself), and treat option.CallOptions as an internal resolution type — configure calls with the fal.WithX options, not by building a CallOptions directly.

Migrating from the Python fal-client

Python Go
fal_client.run(app, args) fal.Run(ctx, app, args)
fal_client.submit(app, args) fal.Submit(ctx, app, args)
fal_client.subscribe(app, args, on_queue_update=fn) fal.Subscribe(ctx, app, args, fal.OnQueueUpdate(fn))
fal_client.status(app, id, with_logs=True) fal.StatusOf(ctx, app, id, true)
fal_client.result(app, id) fal.Result(ctx, app, id)
fal_client.cancel(app, id) fal.Cancel(ctx, app, id)
fal_client.stream(app, args) for ev, err := range fal.Stream(ctx, app, args)
fal_client.upload_file(path) fal.UploadFile(ctx, path)
fal_client.realtime(app) fal.Realtime(ctx, app)
keyword args (path=, hint=, ...) options (fal.WithPath, fal.WithHint, ...)
Queued / InProgress / Completed same, as a sealed Status interface

The module-level status() is renamed StatusOf in Go because Status is also the result type name.

Documentation

Overview

Package fal is a Go client for fal.ai, a 1:1 behavioral port of the official Python client (fal-client / fal_client).

The primary type is Client. Package-level functions (Run, Submit, Subscribe, Stream, Upload, ...) delegate to a lazily-initialized default Client and mirror the module-level functions of the Python SDK. Every I/O method takes a context.Context as its first argument.

Client is a thin facade: it holds a shared *transport.Core (HTTP engine, retry, CDN tokens) and an *auth.Manager (credentials), and the feature areas live in sub-packages (run, queue, stream, upload, realtime). The public surface here is flat, matching the Python client.

Index

Examples

Constants

View Source
const (
	ExpireNever     = storage.ExpireNever
	ExpireImmediate = storage.ExpireImmediate
	Expire1h        = storage.Expire1h
	Expire1d        = storage.Expire1d
	Expire7d        = storage.Expire7d
	Expire30d       = storage.Expire30d
	Expire1y        = storage.Expire1y

	ACLHide   = storage.ACLHide
	ACLForbid = storage.ACLForbid
	ACLAllow  = storage.ACLAllow
)
View Source
const (
	FormatJPEG = encode.FormatJPEG
	FormatPNG  = encode.FormatPNG
)
View Source
const (
	DefaultPollInterval            = option.DefaultPollInterval
	DefaultRealtimeTokenExpiration = option.DefaultRealtimeTokenExpiration
	PriorityNormal                 = option.PriorityNormal
	PriorityLow                    = option.PriorityLow
)

Defaults and priority values (see package option).

View Source
const DefaultTimeout = 120 * time.Second

DefaultTimeout is the per-request HTTP timeout used when none is configured.

View Source
const Version = "0.1.0"

Version is the module version, reported in the User-Agent header.

Variables

View Source
var (
	// WithPath sets the sub-path appended to the application endpoint
	// (Run/Submit/Subscribe/Stream/Realtime).
	WithPath = option.WithPath
	// WithHint sets the X-Fal-Runner-Hint header (Run/Submit/Subscribe).
	WithHint = option.WithHint
	// WithHeaders sets extra request headers (Run/Submit/Subscribe).
	WithHeaders = option.WithHeaders
	// WithStartTimeout sets the server-side queue wait limit (Run/Submit/Subscribe).
	WithStartTimeout = option.WithStartTimeout
	// WithTimeout sets the client-side HTTP timeout for a single call (Run/Stream).
	WithTimeout = option.WithTimeout
	// WithPriority sets the X-Fal-Queue-Priority header (Submit/Subscribe).
	WithPriority = option.WithPriority
	// WithWebhookURL registers a fal_webhook callback URL on Submit.
	WithWebhookURL = option.WithWebhookURL
	// WithLogs requests logs in status updates during Subscribe.
	WithLogs = option.WithLogs
	// WithInterval sets the queue poll interval for Subscribe.
	WithInterval = option.WithInterval
	// WithClientTimeout bounds the total Subscribe operation (returns *TimeoutError).
	WithClientTimeout = option.WithClientTimeout
	// OnEnqueue registers a callback invoked once with the request id (Subscribe).
	OnEnqueue = option.OnEnqueue
	// OnQueueUpdate registers a callback invoked on every status poll (Subscribe).
	OnQueueUpdate = option.OnQueueUpdate
	// WithRepository selects the primary upload backend ("fal_v3" or "fal").
	WithRepository = option.WithRepository
	// WithFallbackRepository sets the ordered upload fallback backends; no args disables the default.
	WithFallbackRepository = option.WithFallbackRepository
	// WithLifecycle sets the storage lifecycle/ACL of the uploaded object.
	WithLifecycle = option.WithLifecycle
	// WithJWT toggles JWT-in-URL auth for realtime connections (default true).
	WithJWT = option.WithJWT
	// WithMaxBuffering sets the server-side realtime buffering window (1-60).
	WithMaxBuffering = option.WithMaxBuffering
	// WithTokenExpiration sets the realtime JWT expiration in seconds.
	WithTokenExpiration = option.WithTokenExpiration
	// WithEncodeMessage overrides the realtime outbound message encoder (default msgpack).
	WithEncodeMessage = option.WithEncodeMessage
	// WithDecodeMessage overrides the realtime inbound message decoder (default msgpack).
	WithDecodeMessage = option.WithDecodeMessage
)

Functional options, re-exported from package option so callers use them as fal.WithPath, fal.WithLogs, etc. They are var bindings (not wrapper functions) because several options satisfy more than one per-method interface, which a single wrapper return type could not preserve. Each carries its own doc comment so it documents under fal.* on pkg.go.dev; see package option for the canonical definitions.

Functions

func As

func As[T any](result any) (T, error)

As decodes a dynamic result (as returned by Run/Subscribe/Result) into a typed value via a JSON round-trip. It is a Go-idiomatic convenience over the Python-parity any return type.

out, err := fal.As[MyResult](result)
Example

As decodes a dynamic result into a typed struct.

package main

import (
	fal "github.com/valksor/fal-go"
)

func main() { //nolint:testableexamples // illustrative decode over placeholder data; no deterministic output to assert
	type sdxlResult struct {
		Images []struct {
			URL string `json:"url"`
		} `json:"images"`
	}
	var raw any // returned by Run/Subscribe/Result
	out, err := fal.As[sdxlResult](raw)
	if err != nil {
		panic(err)
	}
	_ = out
}

func Cancel

func Cancel(ctx context.Context, application, requestID string) error

Cancel calls Default().Cancel. It mirrors fal_client.cancel.

func Encode

func Encode(data []byte, contentType string) string

Encode returns a base64 data URI for the given bytes. See encode.Encode.

func EncodeFile

func EncodeFile(path string) (string, error)

EncodeFile reads a file and returns a base64 data URI. See encode.EncodeFile.

func EncodeImage

func EncodeImage(img image.Image, format ImageFormat) (string, error)

EncodeImage encodes an image and returns a base64 data URI. See encode.EncodeImage.

func Result

func Result(ctx context.Context, application, requestID string) (any, error)

Result calls Default().Result. It mirrors fal_client.result.

func Run

func Run(ctx context.Context, application string, arguments any, opts ...RunOption) (any, error)

Run calls Default().Run. It mirrors fal_client.run.

func Stream

func Stream(ctx context.Context, application string, arguments any, opts ...StreamOption) iter.Seq2[map[string]any, error]

Stream calls Default().Stream. It mirrors fal_client.stream.

func Subscribe

func Subscribe(ctx context.Context, application string, arguments any, opts ...SubscribeOption) (any, error)

Subscribe calls Default().Subscribe. It mirrors fal_client.subscribe.

Example

Subscribe submits a request and blocks until the result is ready, reporting queue progress through a callback.

package main

import (
	"context"
	"fmt"

	fal "github.com/valksor/fal-go"
)

func main() { //nolint:testableexamples // illustrative network call; no deterministic output to assert
	ctx := context.Background()
	result, err := fal.Subscribe(
		ctx, "fal-ai/fast-sdxl",
		map[string]any{"prompt": "a cat riding a bicycle"},
		fal.WithLogs(true),
		fal.OnQueueUpdate(func(s fal.Status) {
			switch v := s.(type) {
			case fal.Queued:
				fmt.Println("queued at", v.Position)
			case fal.InProgress:
				fmt.Println("in progress")
			case fal.Completed:
				fmt.Println("done")
			}
		}),
	)
	if err != nil {
		panic(err)
	}
	_ = result
}

func Upload

func Upload(ctx context.Context, data []byte, contentType, fileName string, opts ...UploadOption) (string, error)

Upload calls Default().Upload. It mirrors fal_client.upload.

func UploadFile

func UploadFile(ctx context.Context, path string, opts ...UploadOption) (string, error)

UploadFile calls Default().UploadFile. It mirrors fal_client.upload_file.

func UploadImage

func UploadImage(ctx context.Context, img image.Image, format ImageFormat, opts ...UploadOption) (string, error)

UploadImage calls Default().UploadImage. It mirrors fal_client.upload_image.

Pass FormatJPEG or FormatPNG for an explicit call; the zero value (empty ImageFormat) defaults to JPEG.

func WSConnect

func WSConnect(ctx context.Context, application string, opts ...RealtimeOption) (*websocket.Conn, error)

WSConnect calls Default().WSConnect. It mirrors fal_client.ws_connect.

Types

type AppID

type AppID = appid.AppID

Application identifier (see package appid).

func ParseAppID

func ParseAppID(endpoint string) (AppID, error)

ParseAppID parses an endpoint id such as "fal-ai/fast-sdxl". See appid.Parse.

type Client

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

Client is a fal.ai API client. The zero value is not usable; construct one with New. A Client is safe for concurrent use by multiple goroutines.

func Default

func Default() *Client

Default returns the shared package-level client used by the top-level functions (Run, Submit, Subscribe, ...).

func New

func New(opts ...ClientOption) *Client

New creates a Client. With no options it resolves credentials and endpoints from the environment.

func (*Client) Cancel

func (c *Client) Cancel(ctx context.Context, application, requestID string) error

Cancel cancels a request by id. It mirrors fal_client.cancel.

func (*Client) GetHandle

func (c *Client) GetHandle(application, requestID string) (*RequestHandle, error)

GetHandle reconstructs a handle from an application id and request id. It mirrors SyncClient.get_handle.

func (*Client) Realtime

func (c *Client) Realtime(ctx context.Context, application string, opts ...RealtimeOption) (*RealtimeConnection, error)

Realtime opens a realtime connection to an application. It mirrors fal_client.realtime / SyncClient.realtime.

func (*Client) Result

func (c *Client) Result(ctx context.Context, application, requestID string) (any, error)

Result polls a request by id until completion and returns its result. It mirrors fal_client.result.

func (*Client) Run

func (c *Client) Run(ctx context.Context, application string, arguments any, opts ...RunOption) (any, error)

Run executes an application synchronously and returns its result. It mirrors fal_client.run / SyncClient.run.

func (*Client) Status

func (c *Client) Status(ctx context.Context, application, requestID string, withLogs bool) (Status, error)

Status fetches the status of a request by id. It mirrors fal_client.status.

func (*Client) Stream

func (c *Client) Stream(ctx context.Context, application string, arguments any, opts ...StreamOption) iter.Seq2[map[string]any, error]

Stream opens a Server-Sent Events stream and yields each decoded JSON event. It mirrors fal_client.stream / SyncClient.stream.

Example

Stream consumes Server-Sent Events; break-on-error is mandatory.

package main

import (
	"context"
	"fmt"

	fal "github.com/valksor/fal-go"
)

func main() { //nolint:testableexamples // illustrative network stream; no deterministic output to assert
	ctx := context.Background()
	c := fal.New()
	for event, err := range c.Stream(ctx, "fal-ai/some-streaming-app", map[string]any{}) {
		if err != nil {
			fmt.Println("stream error:", err)

			break
		}
		fmt.Println(event)
	}
}

func (*Client) Submit

func (c *Client) Submit(ctx context.Context, application string, arguments any, opts ...SubmitOption) (*RequestHandle, error)

Submit enqueues a request and returns a handle to poll it. It mirrors fal_client.submit / SyncClient.submit.

func (*Client) Subscribe

func (c *Client) Subscribe(ctx context.Context, application string, arguments any, opts ...SubscribeOption) (any, error)

Subscribe submits a request and polls until completion, returning the result. It mirrors fal_client.subscribe / SyncClient.subscribe.

func (*Client) Upload

func (c *Client) Upload(ctx context.Context, data []byte, contentType, fileName string, opts ...UploadOption) (string, error)

Upload uploads raw data and returns its public URL. It mirrors fal_client.upload / SyncClient.upload.

func (*Client) UploadFile

func (c *Client) UploadFile(ctx context.Context, path string, opts ...UploadOption) (string, error)

UploadFile uploads a local file and returns its public URL. It mirrors fal_client.upload_file.

func (*Client) UploadImage

func (c *Client) UploadImage(ctx context.Context, img image.Image, format ImageFormat, opts ...UploadOption) (string, error)

UploadImage encodes an image and uploads it. It mirrors fal_client.upload_image.

func (*Client) WSConnect

func (c *Client) WSConnect(ctx context.Context, application string, opts ...RealtimeOption) (*websocket.Conn, error)

WSConnect opens a raw WebSocket connection to an application. It mirrors fal_client.ws_connect.

type ClientOption

type ClientOption func(*config)

ClientOption configures a Client.

func WithDefaultTimeout

func WithDefaultTimeout(d time.Duration) ClientOption

WithDefaultTimeout sets the default per-request HTTP timeout.

func WithHTTPClient

func WithHTTPClient(h *http.Client) ClientOption

WithHTTPClient sets the underlying *http.Client.

func WithKey

func WithKey(key string) ClientOption

WithKey sets an explicit fal key, overriding environment resolution.

type Completed

type Completed = status.Completed

Status types (see package status).

type Error

type Error = errs.Error

Error types (see package errs).

type HTTPError

type HTTPError = errs.HTTPError

Error types (see package errs).

type ImageFormat

type ImageFormat = encode.ImageFormat

Image encoding (see package encode). ImageFormat lives in encode because both EncodeImage and UploadImage take it.

type InProgress

type InProgress = status.InProgress

Status types (see package status).

type MissingCredentialsError

type MissingCredentialsError = errs.MissingCredentialsError

Error types (see package errs).

type ObjectExpiration

type ObjectExpiration = storage.ObjectExpiration

Storage configuration (see package storage).

type Queued

type Queued = status.Queued

Status types (see package status).

type RealtimeConnection

type RealtimeConnection = realtime.Connection

Queue and realtime types (see packages queue and realtime).

func Realtime

func Realtime(ctx context.Context, application string, opts ...RealtimeOption) (*RealtimeConnection, error)

Realtime calls Default().Realtime. It mirrors fal_client.realtime.

type RealtimeError

type RealtimeError = realtime.Error

Queue and realtime types (see packages queue and realtime).

type RealtimeOption

type RealtimeOption = option.RealtimeOption

Per-method option interfaces (see package option).

type RequestHandle

type RequestHandle = queue.Handle

Queue and realtime types (see packages queue and realtime).

func GetHandle

func GetHandle(application, requestID string) (*RequestHandle, error)

GetHandle calls Default().GetHandle. It mirrors fal_client.get_handle.

It takes no context because it performs no I/O — it only parses the application id and constructs the request URLs. The returned handle's methods take a context.

func Submit

func Submit(ctx context.Context, application string, arguments any, opts ...SubmitOption) (*RequestHandle, error)

Submit calls Default().Submit. It mirrors fal_client.submit.

type RunOption

type RunOption = option.RunOption

Per-method option interfaces (see package option).

type Status

type Status = status.Status

Status types (see package status).

func StatusOf

func StatusOf(ctx context.Context, application, requestID string, withLogs bool) (Status, error)

StatusOf calls Default().Status. It mirrors fal_client.status (renamed to avoid colliding with the Status type).

type StorageACL

type StorageACL = storage.ACL

Storage configuration (see package storage).

type StorageACLDecision

type StorageACLDecision = storage.ACLDecision

Storage configuration (see package storage).

type StorageACLRule

type StorageACLRule = storage.ACLRule

Storage configuration (see package storage).

type StorageSettings

type StorageSettings = storage.Settings

Storage configuration (see package storage).

type StreamOption

type StreamOption = option.StreamOption

Per-method option interfaces (see package option).

type SubmitOption

type SubmitOption = option.SubmitOption

Per-method option interfaces (see package option).

type SubscribeOption

type SubscribeOption = option.SubscribeOption

Per-method option interfaces (see package option).

type TimeoutError

type TimeoutError = errs.TimeoutError

Error types (see package errs).

type UploadOption

type UploadOption = option.UploadOption

Per-method option interfaces (see package option).

Directories

Path Synopsis
Package appid parses and normalizes fal application identifiers.
Package appid parses and normalizes fal application identifiers.
Package auth resolves fal credentials and produces the Authorization header.
Package auth resolves fal credentials and produces the Authorization header.
Package encode produces base64 data URIs for inline file and image payloads.
Package encode produces base64 data URIs for inline file and image payloads.
Package errs holds the SDK's error types.
Package errs holds the SDK's error types.
Package option holds the functional options for the fal client and the resolved CallOptions struct the feature packages consume.
Package option holds the functional options for the fal client and the resolved CallOptions struct the feature packages consume.
Package queue implements the asynchronous queue lifecycle: submit, poll, fetch result, cancel and subscribe.
Package queue implements the asynchronous queue lifecycle: submit, poll, fetch result, cancel and subscribe.
Package realtime implements bidirectional WebSocket connections to fal apps.
Package realtime implements bidirectional WebSocket connections to fal apps.
Package run implements direct (non-queued) application execution.
Package run implements direct (non-queued) application execution.
Package status holds the sealed queue status type and its three cases.
Package status holds the sealed queue status type and its three cases.
Package storage holds the upload lifecycle and access-control configuration types.
Package storage holds the upload lifecycle and access-control configuration types.
Package stream implements Server-Sent Events streaming.
Package stream implements Server-Sent Events streaming.
Package transport is the SDK's HTTP engine: request building (with auth and User-Agent), the retry loop, JSON decoding, and the CDN token cache.
Package transport is the SDK's HTTP engine: request building (with auth and User-Agent), the retry loop, JSON decoding, and the CDN token cache.
Package upload implements file and image uploads to the fal storage backends, including the multipart path for large files.
Package upload implements file and image uploads to the fal storage backends, including the multipart path for large files.

Jump to

Keyboard shortcuts

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