Implementation Details#

This page documents specific implementation decisions and their rationale.

ARCANA Default ID — Priority Chain#

When ARCANA IDs are configured across multiple sources, the library determines the "default" entry in the dict returned by load_arcana_ids() using the following priority chain:

Priority

Source

Rationale

1

SAIA_ARCANA_ID in env / .env

Environment-specific override. The .env file is per-deployment (development, staging, production) and takes precedence over static configuration.

2

[saia.arcana] default in config.toml

Explicit default in the structured configuration file.

3

First element of [saia.arcana] ids in config.toml

Implicit default: when no explicit default is declared, the first entry in the array is treated as primary.

4

First SAIA_ARCANA_ID_XX env var (insertion order)

Lowest priority. Numbered env vars are a fallback for environments where config.toml is unavailable.

All sources are merged into a single dict. The priority chain only determines which value receives the "default" key:

from saia_python import load_arcana_ids

ids = load_arcana_ids()
# {
#     'default': 'user/Primary-Arcana',      # from priority chain
#     '0': 'user/First-Arcana',               # from config.toml ids array
#     '1': 'user/Second-Arcana',              # from config.toml ids array
#     'project_a': 'user/ProjectA-Arcana',    # from config.toml labels
#     '01': 'user/Numbered-Arcana',           # from SAIA_ARCANA_ID_01
# }

ARCANA Name vs Full ID#

The SAIA platform distinguishes two identifier formats:

  • Name (e.g. My-Arcana-abc123) — used by the management REST API (get, upload, delete_file, generate_index).

  • Full ID (e.g. saiauser123/My-Arcana-abc123, owner/name format) — used by the chat endpoint for RAG context injection.

The library handles this distinction transparently. Management methods (get(), upload(), etc.) accept either format and extract the name portion via extract_arcana_name(). The chat method passes the full ID as-is.

Values from load_arcana_ids() can be passed directly to any method without format conversion.

Owner Prefix Resolution#

When load_arcana_ids() encounters an ARCANA ID without a / (i.e. a plain name like MyArcana instead of saiauser123/MyArcana), it automatically prepends the configured username:

# config.toml:
# [saia]
# username = "saiauser123"
# [saia.arcana]
# default = "MyArcana"

ids = load_arcana_ids()
# ids["default"] == "saiauser123/MyArcana"

The username is resolved from (in order): SAIA_USERNAME env var, SAIA_USERNAME in .env, or [saia] username in config.toml.

If an ID has no / and no username is configured, load_arcana_ids() raises a ValueError with a message indicating which IDs are missing the owner prefix and how to set the username.

ARCANA Creation — UUID Suffix#

The SAIA API creates arcanas with the exact name provided. The web UI appends a UUID4 suffix (e.g. MyArcana-a1b2c3d4-e5f6-...) to avoid name collisions. Since the API does not do this automatically, the library provides client-side UUID generation via the append_uuid parameter:

# With UUID suffix (default) — mirrors web UI behavior
result = client.arcana.create("MyArcana")
# result["name"] == "MyArcana-a1b2c3d4-e5f6-7890-abcd-ef1234567890"

# Without UUID suffix
result = client.arcana.create("MyArcana", append_uuid=False)
# result["name"] == "MyArcana"

The append_uuid=True default is deliberate: arcana names are global within a user’s namespace, and collisions produce opaque API errors.

Both create() and delete() accept an update_toml=True parameter to automatically add or remove the arcana ID in config.toml:

# Create and register in config.toml under [saia.arcana] ids
client.arcana.create("MyArcana", update_toml=True)

# Create and register under [saia.arcana.labels]
client.arcana.create("MyArcana", update_toml=True, toml_label="project_a")

# Delete and remove from config.toml
client.arcana.delete("saiauser123/MyArcana-...", update_toml=True)

OpenAI Compatibility Layer#

The create_openai_client() factory and SAIAClient.openai property return an openai.OpenAI instance pointed at the SAIA base URL. This enables direct use of the OpenAI Python SDK and ecosystem tools (RAGAS, LangChain, instructor) without manual credential extraction.

The factory reuses the same resolution functions as SAIAClient:

  • load_api_key() for the API key

  • resolve_base_url() for the base URL

The openai package is an optional dependency (pip install saia-python[openai]). Accessing .openai without it raises an ImportError with install instructions.

Endpoint compatibility:

OpenAI SDK Endpoint

Status

Notes

chat.completions.create()

Works

Streaming, tool calling

models.list()

Works

Returns SAIA model IDs

embeddings.create()

Works

e5-mistral-7b-instruct, multilingual-e5-large-instruct, qwen3-embedding-4b

audio.transcriptions

N/A

Use SAIAClient.voice instead

images.generate()

N/A

Not available

Dual API Design#

Both calling styles (object-oriented and functional) are supported without code duplication. The functional wrappers instantiate a temporary SAIAClient per call, which means each invocation creates a new requests.Session with its own TCP connection pool.

For detailed explanation and performance considerations, see Architectural Overview.