Configuration

All settings are env-vars prefixed with SFMAPI_. They’re parsed by a single Pydantic Settings class:

class app.core.config.Settings(_case_sensitive=None, _nested_model_default_partial_update=None, _env_prefix=None, _env_prefix_target=None, _env_file=PosixPath('.'), _env_file_encoding=None, _env_ignore_empty=None, _env_nested_delimiter=None, _env_nested_max_split=None, _env_parse_none_str=None, _env_parse_enums=None, _cli_prog_name=None, _cli_parse_args=None, _cli_settings_source=None, _cli_parse_none_str=None, _cli_hide_none_type=None, _cli_avoid_json=None, _cli_enforce_required=None, _cli_use_class_docs_for_groups=None, _cli_exit_on_error=None, _cli_prefix=None, _cli_flag_prefix_char=None, _cli_implicit_flags=None, _cli_ignore_unknown_args=None, _cli_kebab_case=None, _cli_shortcuts=None, _secrets_dir=None, _build_sources=None, *, env='dev', db_url='sqlite+aiosqlite:///./sfmapi.db', redis_url='redis://localhost:6379/0', workspace_root=PosixPath('workspaces'), blob_root=PosixPath('workspaces/_blobs'), s3_cache_root=PosixPath('workspaces/_cache/s3'), blob_backend='fs', blob_s3_bucket=None, blob_s3_prefix='', blob_s3_region=None, blob_s3_endpoint_url=None, queue_backend='arq', ephemeral=False, default_tenant='default', auth_mode='none', runtime_version_id='unknown', seed=0, log_level='INFO', upload_chunk_max_bytes=8388608, upload_expiry_hours=24, lease_ttl_seconds=30, janitor_interval_seconds=10, snapshot_keep_last=3, inline_tasks=False, cors_origins='*', cors_allow_credentials=False, thumbnail_default_size=256, thumbnail_max_size=2048, oneshot_max_request_bytes=52428800, spec_url='https://sfmapi.github.io/spec', profile_requests=False, profile_min_ms=0.0, profile_top_n=20, profile_sort_by='cumulative', profile_dir=None, warm_capabilities=False, auto_load_backend_plugins=False, mcp_mode='off', mcp_enabled=False, mcp_mount_path='/mcp', mcp_tenant_id=None)[source]

Bases: BaseSettings

Parameters:
  • _case_sensitive (bool | None)

  • _nested_model_default_partial_update (bool | None)

  • _env_prefix (str | None)

  • _env_prefix_target (EnvPrefixTarget | None)

  • _env_file (DotenvType | None)

  • _env_file_encoding (str | None)

  • _env_ignore_empty (bool | None)

  • _env_nested_delimiter (str | None)

  • _env_nested_max_split (int | None)

  • _env_parse_none_str (str | None)

  • _env_parse_enums (bool | None)

  • _cli_prog_name (str | None)

  • _cli_parse_args (bool | list[str] | tuple[str, ...] | None)

  • _cli_settings_source (CliSettingsSource[Any] | None)

  • _cli_parse_none_str (str | None)

  • _cli_hide_none_type (bool | None)

  • _cli_avoid_json (bool | None)

  • _cli_enforce_required (bool | None)

  • _cli_use_class_docs_for_groups (bool | None)

  • _cli_exit_on_error (bool | None)

  • _cli_prefix (str | None)

  • _cli_flag_prefix_char (str | None)

  • _cli_implicit_flags (bool | Literal['dual', 'toggle'] | None)

  • _cli_ignore_unknown_args (bool | None)

  • _cli_kebab_case (bool | Literal['all', 'no_enums'] | None)

  • _cli_shortcuts (Mapping[str, str | list[str]] | None)

  • _secrets_dir (PathType | None)

  • _build_sources (tuple[tuple[PydanticBaseSettingsSource, ...], dict[str, Any]] | None)

  • env (Literal['dev', 'test', 'prod'])

  • db_url (str)

  • redis_url (str)

  • workspace_root (Path)

  • blob_root (Path)

  • s3_cache_root (Path)

  • blob_backend (Literal['fs', 's3', 'memory'])

  • blob_s3_bucket (str | None)

  • blob_s3_prefix (str)

  • blob_s3_region (str | None)

  • blob_s3_endpoint_url (str | None)

  • queue_backend (Literal['arq', 'inline'])

  • ephemeral (bool)

  • default_tenant (str)

  • auth_mode (Literal['none', 'api_key'])

  • runtime_version_id (str)

  • seed (int)

  • log_level (Literal['DEBUG', 'INFO', 'WARNING', 'ERROR'])

  • upload_chunk_max_bytes (int)

  • upload_expiry_hours (int)

  • lease_ttl_seconds (int)

  • janitor_interval_seconds (int)

  • snapshot_keep_last (int)

  • inline_tasks (bool)

  • cors_origins (str)

  • cors_allow_credentials (bool)

  • thumbnail_default_size (int)

  • thumbnail_max_size (int)

  • oneshot_max_request_bytes (int)

  • spec_url (str | None)

  • profile_requests (bool)

  • profile_min_ms (float)

  • profile_top_n (int)

  • profile_sort_by (Literal['cumulative', 'tottime', 'time', 'calls'])

  • profile_dir (Path | None)

  • warm_capabilities (bool)

  • auto_load_backend_plugins (bool)

  • mcp_mode (Literal['off', 'local', 'stdio', 'http'])

  • mcp_enabled (bool)

  • mcp_mount_path (str)

  • mcp_tenant_id (str | None)

model_config = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': '.env', 'env_file_encoding': 'utf-8', 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': 'SFMAPI_', 'env_prefix_target': 'variable', 'extra': 'ignore', 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

env: Literal['dev', 'test', 'prod']
db_url: str
redis_url: str
workspace_root: Path
blob_root: Path
s3_cache_root: Path
blob_backend: Literal['fs', 's3', 'memory']
blob_s3_bucket: str | None
blob_s3_prefix: str
blob_s3_region: str | None
blob_s3_endpoint_url: str | None
queue_backend: Literal['arq', 'inline']
ephemeral: bool
default_tenant: str
auth_mode: Literal['none', 'api_key']
runtime_version_id: str
seed: int
log_level: Literal['DEBUG', 'INFO', 'WARNING', 'ERROR']
upload_chunk_max_bytes: int
upload_expiry_hours: int
lease_ttl_seconds: int
janitor_interval_seconds: int
snapshot_keep_last: int
inline_tasks: bool
cors_origins: str
cors_allow_credentials: bool
thumbnail_default_size: int
thumbnail_max_size: int
oneshot_max_request_bytes: int
spec_url: str | None
profile_requests: bool
profile_min_ms: float
profile_top_n: int
profile_sort_by: Literal['cumulative', 'tottime', 'time', 'calls']
profile_dir: Path | None
warm_capabilities: bool
auto_load_backend_plugins: bool
mcp_mode: Literal['off', 'local', 'stdio', 'http']
mcp_enabled: bool
mcp_mount_path: str
mcp_tenant_id: str | None
model_post_init(_ctx)[source]

Override this method to perform additional initialization after __init__ and model_construct. This is useful if you want to do some validation that requires the entire model to be initialized.

Parameters:

_ctx (object)

Return type:

None

ensure_dirs()[source]
Return type:

None

cors_origin_list()[source]
Return type:

list[str]

mcp_api_enabled()[source]

Return whether the FastAPI app should mount the MCP adapter.

Return type:

bool

normalized_mcp_mount_path()[source]

Return a root-relative MCP mount path without a trailing slash.

Return type:

str

Common bundles

Single-host dev (default)

SFMAPI_ENV=dev
SFMAPI_DB_URL=sqlite+aiosqlite:///./sfmapi.db
SFMAPI_AUTH_MODE=none
SFMAPI_INLINE_TASKS=false

Production (web tier in docker compose)

SFMAPI_ENV=prod
SFMAPI_DB_URL=postgresql+psycopg://sfm:secret@postgres:5432/sfmapi
SFMAPI_QUEUE_BACKEND=arq
SFMAPI_REDIS_URL=redis://redis:6379/0
SFMAPI_WORKSPACE_ROOT=/workspaces
SFMAPI_BLOB_BACKEND=fs
SFMAPI_AUTH_MODE=api_key
SFMAPI_LOG_LEVEL=INFO

Worker (Windows + CUDA)

SFMAPI_DB_URL=postgresql+psycopg://sfm:secret@db.internal:5432/sfmapi
SFMAPI_REDIS_URL=redis://redis.internal:6379/0
SFMAPI_QUEUE_BACKEND=arq
SFMAPI_BACKEND=<registered-backend-name>
SFMAPI_RUNTIME_VERSION_ID=<backend-runtime-fingerprint>
SFMAPI_LEASE_TTL_SECONDS=30
SFMAPI_INLINE_TASKS=false
CUDA_VISIBLE_DEVICES=0

Backend packages may define their own engine, CUDA, model, or runtime environment variables. sfmapi selects the registered backend name and uses SFMAPI_RUNTIME_VERSION_ID as an extra cache-key salt; backend packages usually compute this value from their own engine, CUDA, and build metadata.

Notable knobs

Env var

Default

What it does

SFMAPI_INLINE_TASKS

false

Run tasks in-process (test mode)

SFMAPI_LEASE_TTL_SECONDS

30

Per-task lease TTL

SFMAPI_JANITOR_INTERVAL_SECONDS

10

Reclaim expired leases

SFMAPI_SNAPSHOT_KEEP_LAST

3

GC keeps last N + final

SFMAPI_UPLOAD_CHUNK_MAX_BYTES

8 MiB

Max single PATCH chunk

SFMAPI_UPLOAD_EXPIRY_HOURS

24

Open uploads GC’d after this

SFMAPI_BACKEND

unset

Registered backend name to select at startup

SFMAPI_RUNTIME_VERSION_ID

unknown

Extra cache-key salt exposed in /v1/version

SFMAPI_PROFILE_REQUESTS

false

Enable per-request cProfile instrumentation

SFMAPI_PROFILE_MIN_MS

0

Only log profiles for requests at/above this duration

SFMAPI_PROFILE_TOP_N

20

Number of profiler rows included in each profile log

SFMAPI_PROFILE_SORT_BY

cumulative

pstats sort key: cumulative, tottime, time, or calls

SFMAPI_PROFILE_DIR

unset

Optional directory for raw .prof request dumps

SFMAPI_WARM_CAPABILITIES

false

Probe and cache /v1/capabilities during startup

SFMAPI_MCP_MODE

off

MCP mode: off, local, stdio, or http; local mounts MCP into the API process

SFMAPI_MCP_ENABLED

false

Backward-compatible alias for mounting the optional FastMCP adapter into the API process

SFMAPI_MCP_MOUNT_PATH

/mcp

Mount path for the MCP endpoint and status routes

SFMAPI_MCP_TENANT_ID

unset

Required MCP tenant scope when SFMAPI_AUTH_MODE=api_key

Request profiling

Enable request profiling only during diagnosis:

SFMAPI_PROFILE_REQUESTS=true \
SFMAPI_PROFILE_MIN_MS=100 \
SFMAPI_PROFILE_DIR=./profiles \
uv run uvicorn sfmapi.runtime:create_app --factory

Profiled responses include a Server-Timing: app;dur=<ms> header. Requests at or above SFMAPI_PROFILE_MIN_MS emit a structured request.profiled log with the top functions from cProfile; when SFMAPI_PROFILE_DIR is set, the same threshold controls raw .prof dumps. Inspect dumps with python -m pstats ./profiles/<file>.prof.