API Reference

Auto-generated from source docstrings via sphinx.ext.autodoc.

Public API

class ffai_workflow_adapters.AttachmentSync(data_dir, api_key)

Bases: object

Download Airtable attachments with local caching and checksum tracking.

Maintains a checksums.json sidecar file that records Airtable attachment sizes and extracted-text checksums from the previous run. On repeat runs, attachments whose Airtable size has not changed are skipped entirely (no network I/O, no text extraction).

Parameters:
  • data_dir (str | Path) – Directory for downloaded files and checksums.json.

  • api_key (str) – Airtable API key (used as Bearer token for downloads).

classify(records, file_field='File')

Split records into unchanged (skip) and needs-work lists.

Compares Airtable attachment size against stored airtable_size. Matching sizes are assumed unchanged.

Parameters:
  • records (list[dict[str, Any]]) – Airtable record dicts (from table.all()).

  • file_field (str) – Name of the attachment field. Defaults to "File".

Returns:

(unchanged, needs_work) tuples of flattened attachment dicts.

Return type:

tuple[list[dict[str, Any]], list[dict[str, Any]]]

download(url, filename)

Download an attachment to the data directory.

Parameters:
  • url (str) – Temporary Airtable attachment URL.

  • filename (str) – Local filename to save as.

Returns:

Path to the downloaded file.

Return type:

Path

record(filename, airtable_size, checksum, text_len)

Store checksum metadata for a processed file.

Parameters:
  • filename (str)

  • airtable_size (int)

  • checksum (str)

  • text_len (int)

Return type:

None

save()
Return type:

None

property stored: dict[str, dict[str, Any]]
class ffai_workflow_adapters.DocumentSync(attachment_sync, extract_fn)

Bases: object

Coordinate download, extraction, and indexing of documents for RAG.

Implements a three-tier dedup strategy:

  1. Size check — Compare Airtable attachment size with stored size.

  2. ChromaDB check — Compare stored checksum against vector store metadata.

  3. Index checkrag.aindex(checksum=...) skips if checksum matches.

Tier 1 avoids network I/O. Tier 2 avoids text extraction. Tier 3 avoids embedding computation. An unchanged document on a repeat run touches zero I/O across all tiers.

Parameters:
  • attachment_sync (Any) – An AttachmentSync instance for file management.

  • extract_fn (Any) – Callable (filepath) -> str that extracts text from a file.

process_records(records, rag, file_field='File')

Process all Airtable records through the dedup pipeline.

Parameters:
  • records (list[dict[str, Any]]) – Airtable record dicts (from table.all()).

  • rag (Any) – An ffai.rag.RAG instance.

  • file_field (str) – Name of the attachment field.

Returns:

Dict with keys documents, downloaded, extracted, fully_skipped, indexed, skipped.

Return type:

dict[str, Any]

ffai_workflow_adapters.get_config()

Return the singleton Config instance, creating it on first call.

The Config is loaded from YAML files, environment variables (using __ as nested delimiter), and constructor defaults. Subsequent calls return the same instance until reload_config is called.

Return type:

Config

ffai_workflow_adapters.litellm_generate_fn(model, api_key, temperature=0.5, max_tokens=1024)

Create a sync generate_fn for RAG.aquery() backed by litellm.

Returns a callable that calls litellm.completion() and wraps the response in a GenerationResult with usage, cost, and timing metadata. This is required because returning a plain string from generate_fn causes aquery() to silently set usage, cost_usd, and duration_ms to None / 0.0.

Parameters:
  • model (str) – LiteLLM model string (e.g. "mistral/mistral-small-latest").

  • api_key (str) – API key for the model provider.

  • temperature (float) – Sampling temperature. Defaults to 0.5.

  • max_tokens (int) – Maximum tokens in the response. Defaults to 1024.

Returns:

A sync callable (prompt: str) -> GenerationResult suitable for passing to rag.aquery(prompt, generate_fn=...).

Return type:

Callable[[str], Any]

ffai_workflow_adapters.load_workflow_airtable(base_id, table_name, *, adapter=None, api_key=None, api_key_env=None, view=None, name='unnamed', description='', defaults=None, clients=None, tools=None)

Load a workflow from an Airtable table into a ffai WorkflowSpec.

Reads all records from the specified table, applies field mapping from the resolved adapter config, validates required columns, and delegates to ffai’s load_workflow_rows. Includes rate limiting, circuit breaking, and retry with exponential backoff.

Parameters:
  • base_id (str) – Airtable base ID.

  • table_name (str) – Table name within the base.

  • adapter (str | None) – Named adapter variant from config/adapters.yaml. When provided, overrides field maps and passthrough columns.

  • api_key (str | None) – Airtable API key. Falls back to the environment variable named by api_key_env.

  • api_key_env (str | None) – Environment variable name holding the API key. Defaults to the adapter config’s api_key_env.

  • view (str | None) – Airtable view name to filter records. Defaults to the adapter config’s default_view.

  • name (str) – Workflow name assigned to the resulting WorkflowSpec.

  • description (str) – Workflow description for the resulting WorkflowSpec.

  • defaults (dict[str, Any] | None) – Default values merged into each row (model, temperature, etc.).

  • clients (dict[str, dict[str, Any] | str] | None) – Client definitions passed through to ffai.

  • tools (dict[str, dict[str, Any]] | None) – Tool definitions passed through to ffai.

Returns:

A ffai WorkflowSpec ready for execution.

Raises:

TabularLoadError – If pyairtable is not installed, the API key is missing, the table is empty, or required columns are absent.

Return type:

Any

ffai_workflow_adapters.load_workflow_csv(path, *, delimiter=',', adapter=None, name='unnamed', description='', defaults=None, clients=None, tools=None)

Load a workflow from a CSV or TSV file into a ffai WorkflowSpec.

Reads the file using csv.DictReader, applies field mapping from the resolved adapter config, validates required columns, and delegates to ffai’s load_workflow_rows. Warns about unrecognized columns.

Parameters:
  • path (str | Path) – Path to the CSV/TSV file.

  • delimiter (str) – Field delimiter. "," for CSV, "\t" for TSV.

  • adapter (str | None) – Named adapter variant from config/adapters.yaml.

  • name (str) – Workflow name assigned to the resulting WorkflowSpec.

  • description (str) – Workflow description for the resulting WorkflowSpec.

  • defaults (dict[str, Any] | None) – Default values merged into each row.

  • clients (dict[str, dict[str, Any] | str] | None) – Client definitions passed through to ffai.

  • tools (dict[str, dict[str, Any]] | None) – Tool definitions passed through to ffai.

Returns:

A ffai WorkflowSpec ready for execution.

Raises:

TabularLoadError – If the file is not found, has no data rows, or required columns are missing.

Return type:

Any

ffai_workflow_adapters.load_workflow_excel(path, *, sheet=None, adapter=None, name='unnamed', description='', defaults=None, clients=None, tools=None)

Load a workflow from an Excel file into a ffai WorkflowSpec.

Reads the specified sheet, applies field mapping from the resolved adapter config, validates required columns, and delegates to ffai’s load_workflow_rows. Warns about unrecognized columns.

Parameters:
  • path (str | Path) – Path to the .xlsx file.

  • sheet (str | int | None) – Sheet name or index. Defaults to the active sheet.

  • adapter (str | None) – Named adapter variant from config/adapters.yaml. When provided, overrides field maps and passthrough columns.

  • name (str) – Workflow name assigned to the resulting WorkflowSpec.

  • description (str) – Workflow description for the resulting WorkflowSpec.

  • defaults (dict[str, Any] | None) – Default values merged into each row (model, temperature, etc.).

  • clients (dict[str, dict[str, Any] | str] | None) – Client definitions passed through to ffai.

  • tools (dict[str, dict[str, Any]] | None) – Tool definitions passed through to ffai.

Returns:

A ffai WorkflowSpec ready for execution.

Raises:

TabularLoadError – If openpyxl is not installed, the file is not found, the sheet has no header row, there are no data rows, or required columns are missing.

Return type:

Any

ffai_workflow_adapters.load_workflow_google_sheets(spreadsheet_id, *, worksheet=None, adapter=None, auth_method=None, credentials_file=None, credentials_env=None, authorized_user_file=None, authorized_user_env=None, api_key=None, api_key_env=None, name='unnamed', description='', defaults=None, clients=None, tools=None)

Load a workflow from a Google Sheets spreadsheet into a ffai WorkflowSpec.

Reads all records from the specified worksheet, applies field mapping from the resolved adapter config, validates required columns, and delegates to ffai’s load_workflow_rows. Includes rate limiting, circuit breaking, and retry with exponential backoff.

Parameters:
  • spreadsheet_id (str) – Google Sheets spreadsheet ID (from the URL).

  • worksheet (str | int | None) – Worksheet name or index. Defaults to the first worksheet.

  • adapter (str | None) – Named adapter variant from config/adapters.yaml.

  • auth_method (Literal['service_account', 'oauth', 'api_key'] | None) – Authentication method — "service_account" (default), "oauth", or "api_key". Overrides the config setting.

  • credentials_file (str | None) – Path to credentials JSON file (service account or OAuth credentials).

  • credentials_env (str | None) – Environment variable name holding the credentials file path. Defaults to GOOGLE_SHEETS_CREDENTIALS.

  • authorized_user_file (str | None) – Path to authorized user JSON file (OAuth only).

  • authorized_user_env (str | None) – Environment variable name holding the authorized user file path (OAuth only).

  • api_key (str | None) – Google API key string (api_key auth only, public sheets).

  • api_key_env (str | None) – Environment variable name holding the API key.

  • name (str) – Workflow name assigned to the resulting WorkflowSpec.

  • description (str) – Workflow description for the resulting WorkflowSpec.

  • defaults (dict[str, Any] | None) – Default values merged into each row.

  • clients (dict[str, dict[str, Any] | str] | None) – Client definitions passed through to ffai.

  • tools (dict[str, dict[str, Any]] | None) – Tool definitions passed through to ffai.

Returns:

A ffai WorkflowSpec ready for execution.

Raises:

TabularLoadError – If gspread is not installed, credentials are missing, the worksheet is empty, or required columns are absent.

Return type:

Any

ffai_workflow_adapters.load_workflow_ods(path, *, sheet=None, adapter=None, name='unnamed', description='', defaults=None, clients=None, tools=None)

Load a workflow from an ODS file into a ffai WorkflowSpec.

Reads the specified sheet, applies field mapping from the resolved adapter config, validates required columns, and delegates to ffai’s load_workflow_rows. Warns about unrecognized columns.

Parameters:
  • path (str | Path) – Path to the .ods file.

  • sheet (str | int | None) – Sheet name or index. Defaults to the first sheet.

  • adapter (str | None) – Named adapter variant from config/adapters.yaml.

  • name (str) – Workflow name assigned to the resulting WorkflowSpec.

  • description (str) – Workflow description for the resulting WorkflowSpec.

  • defaults (dict[str, Any] | None) – Default values merged into each row.

  • clients (dict[str, dict[str, Any] | str] | None) – Client definitions passed through to ffai.

  • tools (dict[str, dict[str, Any]] | None) – Tool definitions passed through to ffai.

Returns:

A ffai WorkflowSpec ready for execution.

Raises:

TabularLoadError – If odfpy is not installed, the file is not found, the sheet has no header row, there are no data rows, or required columns are missing.

Return type:

Any

ffai_workflow_adapters.load_workflow_tsv(path, *, adapter=None, name='unnamed', description='', defaults=None, clients=None, tools=None)

Load a workflow from a TSV file. Equivalent to load_workflow_csv with delimiter='\t'.

Parameters:
Return type:

Any

ffai_workflow_adapters.reload_config()

Discard the cached Config and reload from all sources.

Re-reads YAML files and environment variables. Use after changing config files or env vars at runtime.

Returns:

The freshly loaded Config instance.

Return type:

Config

ffai_workflow_adapters.sha256_of_text(text)

Return the SHA-256 hex digest of a string.

Parameters:

text (str)

Return type:

str

ffai_workflow_adapters.write_workflow_results(base_id, table_name, result, *, adapter=None, api_key=None, api_key_env=None, spec=None, run_id=None)

Write workflow execution results back to an Airtable table.

Creates one record per workflow step with fields for status, response, model, token usage, cost, and duration. Supports passthrough columns from the source spec and extra output columns with template resolution.

Parameters:
  • base_id (str) – Airtable base ID.

  • table_name (str) – Target table name for writing results.

  • result (Any) – A ffai WorkflowResult containing step results.

  • adapter (str | None) – Named adapter variant for output field mapping.

  • api_key (str | None) – Airtable API key. Falls back to environment variable.

  • api_key_env (str | None) – Environment variable name holding the API key.

  • spec (Any | None) – The original WorkflowSpec (used for passthrough column data).

  • run_id (str | None) – Unique run identifier. Auto-generated if not provided.

Returns:

List of created Airtable records as dicts.

Raises:

TabularLoadError – If pyairtable is not installed, the API key is missing, or the circuit breaker is open.

Return type:

list[dict[str, Any]]

ffai_workflow_adapters.write_workflow_results_csv(result, path=None, *, delimiter=',', adapter=None, spec=None, run_id=None)

Write workflow execution results to a CSV or TSV file.

Creates one row per workflow step with columns for status, response, model, token usage, cost, and duration. If the file exists, appends data rows without duplicating the header. Supports passthrough columns from the source spec and extra output columns with template resolution.

Parameters:
  • result (Any) – A ffai WorkflowResult containing step results.

  • path (str | Path | None) – Output file path. Falls back to the adapter config’s output_path.

  • delimiter (str) – Field delimiter. "," for CSV, "\t" for TSV.

  • adapter (str | None) – Named adapter variant for output field mapping.

  • spec (Any | None) – The original WorkflowSpec (used for passthrough column data).

  • run_id (str | None) – Unique run identifier. Auto-generated if not provided.

Returns:

The file path written to, as a string.

Raises:

ValueError – If no output path is specified.

Return type:

str

ffai_workflow_adapters.write_workflow_results_excel(result, path=None, *, sheet=None, adapter=None, spec=None, run_id=None)

Write workflow execution results to an Excel file.

Creates one row per workflow step with columns for status, response, model, token usage, cost, and duration. Appends to an existing sheet or creates a new file. Supports passthrough columns from the source spec and extra output columns with template resolution.

Parameters:
  • result (Any) – A ffai WorkflowResult containing step results.

  • path (str | Path | None) – Output file path. Falls back to the adapter config’s output_path.

  • sheet (str | None) – Sheet name for results. Defaults to the adapter config’s output_sheet or “Results”.

  • adapter (str | None) – Named adapter variant for output field mapping.

  • spec (Any | None) – The original WorkflowSpec (used for passthrough column data).

  • run_id (str | None) – Unique run identifier. Auto-generated if not provided.

Returns:

The file path written to, as a string.

Raises:
  • TabularLoadError – If openpyxl is not installed.

  • ValueError – If no output path is specified.

Return type:

str

ffai_workflow_adapters.write_workflow_results_google_sheets(spreadsheet_id, result, *, worksheet=None, adapter=None, auth_method=None, credentials_file=None, credentials_env=None, authorized_user_file=None, authorized_user_env=None, api_key=None, api_key_env=None, spec=None, run_id=None)

Write workflow execution results to a Google Sheets spreadsheet.

Appends one row per workflow step to the specified worksheet. Creates the worksheet if it doesn’t exist. Supports passthrough columns from the source spec and extra output columns with template resolution.

Parameters:
  • spreadsheet_id (str) – Google Sheets spreadsheet ID (from the URL).

  • result (Any) – A ffai WorkflowResult containing step results.

  • worksheet (str | None) – Worksheet name for results. Defaults to the adapter config’s output_worksheet or “Results”.

  • adapter (str | None) – Named adapter variant for output field mapping.

  • auth_method (Literal['service_account', 'oauth', 'api_key'] | None) – Authentication method — "service_account" (default), "oauth", or "api_key". Overrides the config setting.

  • credentials_file (str | None) – Path to credentials JSON file (service account or OAuth credentials).

  • credentials_env (str | None) – Environment variable name holding the credentials file path.

  • authorized_user_file (str | None) – Path to authorized user JSON file (OAuth only).

  • authorized_user_env (str | None) – Environment variable name holding the authorized user file path (OAuth only).

  • api_key (str | None) – Google API key string (api_key auth only, public sheets).

  • api_key_env (str | None) – Environment variable name holding the API key.

  • spec (Any | None) – The original WorkflowSpec (used for passthrough column data).

  • run_id (str | None) – Unique run identifier. Auto-generated if not provided.

Returns:

List of row lists that were appended.

Raises:

TabularLoadError – If gspread is not installed or credentials are missing.

Return type:

list[list[Any]]

ffai_workflow_adapters.write_workflow_results_ods(result, path=None, *, sheet=None, adapter=None, spec=None, run_id=None)

Write workflow execution results to an ODS file.

Creates one row per workflow step with columns for status, response, model, token usage, cost, and duration. Always creates a new file. Supports passthrough columns from the source spec and extra output columns with template resolution.

Parameters:
  • result (Any) – A ffai WorkflowResult containing step results.

  • path (str | Path | None) – Output file path. Falls back to the adapter config’s output_path.

  • sheet (str | None) – Sheet name for results. Defaults to the adapter config’s output_sheet or “Results”.

  • adapter (str | None) – Named adapter variant for output field mapping.

  • spec (Any | None) – The original WorkflowSpec (used for passthrough column data).

  • run_id (str | None) – Unique run identifier. Auto-generated if not provided.

Returns:

The file path written to, as a string.

Raises:
  • TabularLoadError – If odfpy is not installed.

  • ValueError – If no output path is specified.

Return type:

str

ffai_workflow_adapters.write_workflow_results_tsv(result, path=None, *, adapter=None, spec=None, run_id=None)

Write results to a TSV file. Equivalent to write_workflow_results_csv with delimiter='\t'.

Parameters:
  • result (Any)

  • path (str | Path | None)

  • adapter (str | None)

  • spec (Any | None)

  • run_id (str | None)

Return type:

str

Configuration

Configuration loading from YAML files, environment variables, and constructor kwargs.

class ffai_workflow_adapters.config.AdaptersConfig(_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, *, airtable=<factory>, csv_adapter=<factory>, excel=<factory>, google_sheets=<factory>, ods=<factory>, **values)

Bases: BaseSettings

Per-adapter configuration grouped by adapter type.

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)

  • airtable (AirtableAdapterConfig)

  • csv_adapter (CsvAdapterConfig)

  • excel (ExcelAdapterConfig)

  • google_sheets (GoogleSheetsAdapterConfig)

  • ods (OdsAdapterConfig)

  • values (Any)

airtable: AirtableAdapterConfig
csv_adapter: CsvAdapterConfig
excel: ExcelAdapterConfig
google_sheets: GoogleSheetsAdapterConfig
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'allow', '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].

ods: OdsAdapterConfig
class ffai_workflow_adapters.config.AirtableAdapterConfig(_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, *, input_field_map=<factory>, output_field_map=<factory>, passthrough_columns=<factory>, extra_output_columns=<factory>, named=<factory>, api_key_env='AIRTABLE_API_KEY', base_id_env='AIRTABLE_BASE_ID', default_view='')

Bases: _FieldMappedAdapterConfig

Airtable adapter settings including field maps and API key resolution.

Variables:
  • api_key_env (str) – Environment variable name for the Airtable API key.

  • base_id_env (str) – Environment variable name for the Airtable base ID.

  • default_view (str) – Default Airtable view to filter records.

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)

  • input_field_map (dict[str, str])

  • output_field_map (dict[str, str])

  • passthrough_columns (list[str])

  • extra_output_columns (dict[str, str])

  • named (dict[str, dict[str, Any]])

  • api_key_env (str)

  • base_id_env (str)

  • default_view (str)

api_key_env: str
base_id_env: str
default_view: str
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

class ffai_workflow_adapters.config.BatchConfig(_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, *, chunk_size=10, max_concurrency=3)

Bases: BaseSettings

Batch write concurrency settings.

Variables:
  • chunk_size (int) – Records per batch write call.

  • max_concurrency (int) – Maximum concurrent write threads.

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)

  • chunk_size (int)

  • max_concurrency (int)

chunk_size: int
max_concurrency: int
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

class ffai_workflow_adapters.config.CircuitBreakerConfig(_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, *, failure_threshold=5, recovery_timeout_seconds=30.0, half_open_max_calls=3)

Bases: BaseSettings

Circuit breaker failure protection settings.

Variables:
  • failure_threshold (int) – Consecutive failures before opening.

  • recovery_timeout_seconds (float) – Seconds in open state before half-open.

  • half_open_max_calls (int) – Probe calls allowed in half-open state.

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)

  • failure_threshold (int)

  • recovery_timeout_seconds (float)

  • half_open_max_calls (int)

failure_threshold: int
half_open_max_calls: int
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

recovery_timeout_seconds: float
class ffai_workflow_adapters.config.ClientTypeConfig(_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, *, client_class='', type='litellm', api_key_env='', provider_prefix='', default_model='', fallbacks=<factory>)

Bases: BaseSettings

Definition of a single LLM client type.

Variables:
  • client_class (str) – Python class name for the client.

  • type (Literal['native', 'litellm']) – Provider type (“native” or “litellm”).

  • api_key_env (str) – Environment variable name for the API key.

  • provider_prefix (str) – LiteLLM model string prefix.

  • default_model (str) – Default model identifier.

  • fallbacks (list[str]) – Ordered list of fallback model identifiers.

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)

  • client_class (str)

  • type (Literal['native', 'litellm'])

  • api_key_env (str)

  • provider_prefix (str)

  • default_model (str)

  • fallbacks (list[str])

api_key_env: str
client_class: str
default_model: str
fallbacks: list[str]
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

provider_prefix: str
type: Literal['native', 'litellm']
class ffai_workflow_adapters.config.ClientsConfig(_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, *, default_client='litellm-mistral-small', client_types=<factory>, **values)

Bases: BaseSettings

LLM client definitions and default client selection.

Variables:
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)

  • default_client (str)

  • client_types (dict[str, ClientTypeConfig])

  • values (Any)

client_types: dict[str, ClientTypeConfig]
default_client: str
get_available_client_types()

Return the names of all configured client types.

Return type:

list[str]

get_client_type(name)

Look up a client type configuration by name.

Parameters:

name (str)

Return type:

ClientTypeConfig | 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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'allow', '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].

class ffai_workflow_adapters.config.Config(_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, *, logging=<factory>, retry=<factory>, resilience=<factory>, adapters=<factory>, clients=<factory>)

Bases: BaseSettings

Root configuration model loaded from YAML, env vars, and kwargs.

Priority order: constructor kwargs > environment variables (__ delimiter) > YAML files in config/.

Variables:
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)

  • logging (LoggingConfig)

  • retry (RetryConfig)

  • resilience (ResilienceConfig)

  • adapters (AdaptersConfig)

  • clients (ClientsConfig)

adapters: AdaptersConfig
clients: ClientsConfig
get_adapter_api_key(adapter_name)

Resolve the API key for an adapter from its environment variable.

Parameters:

adapter_name (str) – Adapter name (e.g. “airtable”, “excel”).

Returns:

The API key string, or None if the adapter or env var is not configured.

Return type:

str | None

get_available_client_types()

Return the names of all configured client types.

Return type:

list[str]

get_client_type_config(name)

Look up a client type configuration by name.

Parameters:

name (str)

Return type:

ClientTypeConfig | None

get_default_client_type()

Return the name of the default client type.

Return type:

str

logging: LoggingConfig
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': '__', 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', '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].

resilience: ResilienceConfig
retry: RetryConfig
classmethod settings_customise_sources(settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings)

Define the sources and their order for loading the settings values.

Parameters:
  • settings_cls (type[BaseSettings]) – The Settings class.

  • init_settings (PydanticBaseSettingsSource) – The InitSettingsSource instance.

  • env_settings (PydanticBaseSettingsSource) – The EnvSettingsSource instance.

  • dotenv_settings (PydanticBaseSettingsSource) – The DotEnvSettingsSource instance.

  • file_secret_settings (PydanticBaseSettingsSource) – The SecretsSettingsSource instance.

Returns:

A tuple containing the sources and their order for loading the settings values.

Return type:

tuple[PydanticBaseSettingsSource, …]

class ffai_workflow_adapters.config.CsvAdapterConfig(_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, *, input_field_map=<factory>, output_field_map=<factory>, passthrough_columns=<factory>, extra_output_columns=<factory>, named=<factory>, output_path=None, delimiter=', ')

Bases: _FieldMappedAdapterConfig

CSV/TSV adapter settings.

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)

  • input_field_map (dict[str, str])

  • output_field_map (dict[str, str])

  • passthrough_columns (list[str])

  • extra_output_columns (dict[str, str])

  • named (dict[str, dict[str, Any]])

  • output_path (str | None)

  • delimiter (str)

delimiter: str
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

output_path: str | None
class ffai_workflow_adapters.config.ExcelAdapterConfig(_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, *, input_field_map=<factory>, output_field_map=<factory>, passthrough_columns=<factory>, extra_output_columns=<factory>, named=<factory>, output_path=None, output_sheet='Results')

Bases: _FieldMappedAdapterConfig

Excel adapter settings including output path and sheet name.

Variables:
  • output_path (str | None) – Default output file path for write operations.

  • output_sheet (str) – Default sheet name for write results.

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)

  • input_field_map (dict[str, str])

  • output_field_map (dict[str, str])

  • passthrough_columns (list[str])

  • extra_output_columns (dict[str, str])

  • named (dict[str, dict[str, Any]])

  • output_path (str | None)

  • output_sheet (str)

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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

output_path: str | None
output_sheet: str
class ffai_workflow_adapters.config.GoogleSheetsAdapterConfig(_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, *, input_field_map=<factory>, output_field_map=<factory>, passthrough_columns=<factory>, extra_output_columns=<factory>, named=<factory>, auth_method='service_account', credentials_env='GOOGLE_SHEETS_CREDENTIALS', authorized_user_env='GOOGLE_SHEETS_AUTHORIZED_USER', api_key_env='GOOGLE_SHEETS_API_KEY', output_worksheet='Results')

Bases: _FieldMappedAdapterConfig

Google Sheets adapter settings including credentials and worksheet.

Variables:
  • auth_method (Literal['service_account', 'oauth', 'api_key']) – Authentication method — "service_account" (default), "oauth", or "api_key".

  • credentials_env (str) – Environment variable holding the path to the service account JSON file (for service_account auth) or the path to the OAuth credentials JSON file (for oauth auth).

  • authorized_user_env (str) – Environment variable holding the path to the authorized user JSON file (for oauth auth). Optional — gspread stores authorized credentials after the first browser login.

  • api_key_env (str) – Environment variable holding the API key string (for api_key auth). Only works with public spreadsheets.

  • output_worksheet (str) – Default worksheet name for write results.

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)

  • input_field_map (dict[str, str])

  • output_field_map (dict[str, str])

  • passthrough_columns (list[str])

  • extra_output_columns (dict[str, str])

  • named (dict[str, dict[str, Any]])

  • auth_method (Literal['service_account', 'oauth', 'api_key'])

  • credentials_env (str)

  • authorized_user_env (str)

  • api_key_env (str)

  • output_worksheet (str)

api_key_env: str
auth_method: Literal['service_account', 'oauth', 'api_key']
authorized_user_env: str
credentials_env: str
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

output_worksheet: str
class ffai_workflow_adapters.config.LoggingConfig(_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, *, directory='logs', filename='workflow_adapters.log', level='INFO', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', rotation=<factory>)

Bases: BaseSettings

Logging output configuration (directory, level, format, rotation).

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)

  • directory (str)

  • filename (str)

  • level (str)

  • format (str)

  • rotation (LoggingRotationConfig)

directory: str
filename: str
format: str
level: str
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

rotation: LoggingRotationConfig
class ffai_workflow_adapters.config.LoggingRotationConfig(_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, *, when='midnight', interval=1, backup_count=10)

Bases: BaseSettings

Log file rotation schedule settings.

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)

  • when (str)

  • interval (int)

  • backup_count (int)

backup_count: int
interval: int
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

when: str
class ffai_workflow_adapters.config.OdsAdapterConfig(_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, *, input_field_map=<factory>, output_field_map=<factory>, passthrough_columns=<factory>, extra_output_columns=<factory>, named=<factory>, output_path=None, output_sheet='Results')

Bases: _FieldMappedAdapterConfig

ODS adapter settings.

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)

  • input_field_map (dict[str, str])

  • output_field_map (dict[str, str])

  • passthrough_columns (list[str])

  • extra_output_columns (dict[str, str])

  • named (dict[str, dict[str, Any]])

  • output_path (str | None)

  • output_sheet (str)

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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

output_path: str | None
output_sheet: str
class ffai_workflow_adapters.config.RateLimitConfig(_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, *, requests_per_second=5.0, burst=10)

Bases: BaseSettings

Token bucket rate limiting settings.

Variables:
  • requests_per_second (float) – Token refill rate.

  • burst (int) – Maximum tokens (also initial count).

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)

  • requests_per_second (float)

  • burst (int)

burst: int
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

requests_per_second: float
class ffai_workflow_adapters.config.ResilienceConfig(_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, *, rate_limit=<factory>, circuit_breaker=<factory>, batch=<factory>)

Bases: BaseSettings

Combined resilience settings: rate limiting, circuit breaking, and batching.

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)

  • rate_limit (RateLimitConfig)

  • circuit_breaker (CircuitBreakerConfig)

  • batch (BatchConfig)

batch: BatchConfig
circuit_breaker: CircuitBreakerConfig
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

rate_limit: RateLimitConfig
class ffai_workflow_adapters.config.RetryConfig(_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, *, max_attempts=3, min_wait_seconds=1.0, max_wait_seconds=60.0, exponential_base=2.0, exponential_jitter=True, retry_on_status_codes=<factory>)

Bases: BaseSettings

Retry behavior for transient API failures.

Variables:
  • max_attempts (int) – Maximum retry attempts per call.

  • min_wait_seconds (float) – Minimum wait between retries.

  • max_wait_seconds (float) – Maximum wait between retries.

  • exponential_base (float) – Base for exponential backoff calculation.

  • exponential_jitter (bool) – If True, randomize wait time by +/- 50%.

  • retry_on_status_codes (list[int]) – HTTP status codes that trigger retry.

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)

  • max_attempts (int)

  • min_wait_seconds (float)

  • max_wait_seconds (float)

  • exponential_base (float)

  • exponential_jitter (bool)

  • retry_on_status_codes (list[int])

exponential_base: float
exponential_jitter: bool
max_attempts: int
max_wait_seconds: float
min_wait_seconds: float
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': None, 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': '', 'env_prefix_target': 'variable', 'extra': 'forbid', '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].

retry_on_status_codes: list[int]
class ffai_workflow_adapters.config.YamlConfigSource(settings_cls, yaml_data)

Bases: PydanticBaseSettingsSource

Pydantic settings source that reads values from a YAML dict.

Parameters:
  • settings_cls (type[BaseSettings])

  • yaml_data (dict[str, Any])

get_field_value(field, field_name)

Gets the value, the key for model creation, and a flag to determine whether value is complex.

This is an abstract method that should be overridden in every settings source classes.

Parameters:
  • field (Any) – The field.

  • field_name (str) – The field name.

Returns:

A tuple that contains the value, key and a flag to determine whether value is complex.

Return type:

tuple[Any, str, bool]

ffai_workflow_adapters.config.get_config()

Return the singleton Config instance, creating it on first call.

The Config is loaded from YAML files, environment variables (using __ as nested delimiter), and constructor defaults. Subsequent calls return the same instance until reload_config is called.

Return type:

Config

ffai_workflow_adapters.config.reload_config()

Discard the cached Config and reload from all sources.

Re-reads YAML files and environment variables. Use after changing config files or env vars at runtime.

Returns:

The freshly loaded Config instance.

Return type:

Config

Validation

Shared schema validation for tabular workflow data.

ffai_workflow_adapters._validation.validate_schema(rows, source_label)

Verify that workflow rows contain required fields and valid numeric types.

Checks that at least one row has name and prompt columns. If temperature or max_tokens columns are present, validates that their values are numeric. Raises with row-level detail identifying the offending field and its actual value.

Parameters:
  • rows (list[dict[str, Any]]) – List of row dicts from the tabular source.

  • source_label (str) – Human-readable label for error messages (e.g., the file path or table name).

Raises:

TabularLoadError – If required columns are missing or numeric fields contain non-numeric values.

Return type:

None

Resilience

Resilience primitives for rate limiting, circuit breaking, and retry logic.

class ffai_workflow_adapters._resilience.CircuitBreaker(failure_threshold=5, recovery_timeout_seconds=30.0, half_open_max_calls=3)

Bases: object

Thread-safe circuit breaker with closed/open/half-open states.

Allows calls while closed. After failure_threshold consecutive failures, transitions to open and rejects calls for recovery_timeout_seconds. Then enters half-open, allowing a limited number of probe calls before deciding to close or re-open.

Parameters:
  • failure_threshold (int) – Consecutive failures before opening.

  • recovery_timeout_seconds (float) – Seconds to wait in open state before transitioning to half-open.

  • half_open_max_calls (int) – Number of probe calls allowed in half-open state before deciding.

allow()

Check whether a call is allowed under current breaker state.

Transitions from open to half-open after the recovery timeout. Limits calls in half-open state to half_open_max_calls.

Returns:

True if the call is allowed, False if rejected.

Return type:

bool

property failures: int
record_failure()

Record a failed call, opening the breaker if threshold is reached.

Return type:

None

record_success()

Record a successful call, closing the breaker if half-open.

Return type:

None

property state: CircuitState
class ffai_workflow_adapters._resilience.CircuitState(*values)

Bases: Enum

States for the circuit breaker state machine.

CLOSED = 1
HALF_OPEN = 3
OPEN = 2
class ffai_workflow_adapters._resilience.ResilientCaller(bucket, breaker, retry_max_attempts=3, retry_min_wait=1.0, retry_max_wait=60.0, retry_exponential_base=2.0, retry_jitter=True, retry_on_status_codes=None, acquire_timeout=30.0)

Bases: object

Compose rate limiting, circuit breaking, and retry into one caller.

Thread-safe. Each call goes through: circuit breaker check, rate limit acquire, then retry-wrapped execution. Failures are recorded in the circuit breaker; successes reset the failure counter.

Parameters:
  • bucket (TokenBucket) – TokenBucket for rate limiting.

  • breaker (CircuitBreaker) – CircuitBreaker for failure protection.

  • retry_max_attempts (int) – Maximum retry attempts per call.

  • retry_min_wait (float) – Minimum wait between retries in seconds.

  • retry_max_wait (float) – Maximum wait between retries in seconds.

  • retry_exponential_base (float) – Base for exponential backoff.

  • retry_jitter (bool) – If True, randomize retry wait time.

  • retry_on_status_codes (list[int] | None) – HTTP status codes that trigger retry.

  • acquire_timeout (float) – Maximum seconds to wait for a rate limit token.

call(fn, *args, **kwargs)

Execute fn through rate limiting, circuit breaking, and retry.

Parameters:
  • fn (Callable[[...], Any]) – Callable to execute.

  • *args (Any) – Positional arguments forwarded to fn.

  • **kwargs (Any) – Keyword arguments forwarded to fn.

Returns:

The return value of fn.

Raises:

TabularLoadError – If the circuit breaker is open or rate limit acquire times out.

Return type:

Any

class ffai_workflow_adapters._resilience.TokenBucket(rate, burst)

Bases: object

Token bucket rate limiter with thread-safe acquire.

Tokens refill at a constant rate up to burst capacity. Blocks the calling thread when no tokens are available until one becomes available or the timeout expires.

Parameters:
  • rate (float) – Tokens added per second.

  • burst (int) – Maximum token capacity (also the initial token count).

acquire(timeout=30.0)

Block until a token is available or the timeout expires.

Parameters:

timeout (float) – Maximum seconds to wait. Raises TabularLoadError if no token becomes available in time.

Raises:

TabularLoadError – If the acquire times out.

Return type:

None

ffai_workflow_adapters._resilience.batched(iterable, size)

Yield successive chunks of size from iterable.

Parameters:
  • iterable (list[Any]) – List to split into chunks.

  • size (int) – Maximum chunk size.

Yields:

Lists of at most size elements.

Return type:

Any

ffai_workflow_adapters._resilience.with_retry(max_attempts=3, min_wait=1.0, max_wait=60.0, exponential_base=2.0, jitter=True, retry_on_status_codes=None)

Decorator that retries a function with exponential backoff.

Only retries on exceptions that carry a response.status_code matching one of retry_on_status_codes. Other exceptions are re-raised immediately.

Parameters:
  • max_attempts (int) – Maximum number of attempts including the first call.

  • min_wait (float) – Minimum wait in seconds between retries.

  • max_wait (float) – Maximum wait in seconds between retries.

  • exponential_base (float) – Base for exponential backoff calculation.

  • jitter (bool) – If True, randomize wait time by +/- 50%.

  • retry_on_status_codes (list[int] | None) – HTTP status codes that trigger a retry.

Returns:

A decorator that wraps the target function with retry logic.

Return type:

Callable[[…], Any]

Airtable Adapter

Airtable load/write adapter for ffai workflow execution.

ffai_workflow_adapters.airtable.load_workflow_airtable(base_id, table_name, *, adapter=None, api_key=None, api_key_env=None, view=None, name='unnamed', description='', defaults=None, clients=None, tools=None)

Load a workflow from an Airtable table into a ffai WorkflowSpec.

Reads all records from the specified table, applies field mapping from the resolved adapter config, validates required columns, and delegates to ffai’s load_workflow_rows. Includes rate limiting, circuit breaking, and retry with exponential backoff.

Parameters:
  • base_id (str) – Airtable base ID.

  • table_name (str) – Table name within the base.

  • adapter (str | None) – Named adapter variant from config/adapters.yaml. When provided, overrides field maps and passthrough columns.

  • api_key (str | None) – Airtable API key. Falls back to the environment variable named by api_key_env.

  • api_key_env (str | None) – Environment variable name holding the API key. Defaults to the adapter config’s api_key_env.

  • view (str | None) – Airtable view name to filter records. Defaults to the adapter config’s default_view.

  • name (str) – Workflow name assigned to the resulting WorkflowSpec.

  • description (str) – Workflow description for the resulting WorkflowSpec.

  • defaults (dict[str, Any] | None) – Default values merged into each row (model, temperature, etc.).

  • clients (dict[str, dict[str, Any] | str] | None) – Client definitions passed through to ffai.

  • tools (dict[str, dict[str, Any]] | None) – Tool definitions passed through to ffai.

Returns:

A ffai WorkflowSpec ready for execution.

Raises:

TabularLoadError – If pyairtable is not installed, the API key is missing, the table is empty, or required columns are absent.

Return type:

Any

ffai_workflow_adapters.airtable.write_workflow_results(base_id, table_name, result, *, adapter=None, api_key=None, api_key_env=None, spec=None, run_id=None)

Write workflow execution results back to an Airtable table.

Creates one record per workflow step with fields for status, response, model, token usage, cost, and duration. Supports passthrough columns from the source spec and extra output columns with template resolution.

Parameters:
  • base_id (str) – Airtable base ID.

  • table_name (str) – Target table name for writing results.

  • result (Any) – A ffai WorkflowResult containing step results.

  • adapter (str | None) – Named adapter variant for output field mapping.

  • api_key (str | None) – Airtable API key. Falls back to environment variable.

  • api_key_env (str | None) – Environment variable name holding the API key.

  • spec (Any | None) – The original WorkflowSpec (used for passthrough column data).

  • run_id (str | None) – Unique run identifier. Auto-generated if not provided.

Returns:

List of created Airtable records as dicts.

Raises:

TabularLoadError – If pyairtable is not installed, the API key is missing, or the circuit breaker is open.

Return type:

list[dict[str, Any]]

Excel Adapter

Excel load/write adapter for ffai workflow execution.

ffai_workflow_adapters.excel.load_workflow_excel(path, *, sheet=None, adapter=None, name='unnamed', description='', defaults=None, clients=None, tools=None)

Load a workflow from an Excel file into a ffai WorkflowSpec.

Reads the specified sheet, applies field mapping from the resolved adapter config, validates required columns, and delegates to ffai’s load_workflow_rows. Warns about unrecognized columns.

Parameters:
  • path (str | Path) – Path to the .xlsx file.

  • sheet (str | int | None) – Sheet name or index. Defaults to the active sheet.

  • adapter (str | None) – Named adapter variant from config/adapters.yaml. When provided, overrides field maps and passthrough columns.

  • name (str) – Workflow name assigned to the resulting WorkflowSpec.

  • description (str) – Workflow description for the resulting WorkflowSpec.

  • defaults (dict[str, Any] | None) – Default values merged into each row (model, temperature, etc.).

  • clients (dict[str, dict[str, Any] | str] | None) – Client definitions passed through to ffai.

  • tools (dict[str, dict[str, Any]] | None) – Tool definitions passed through to ffai.

Returns:

A ffai WorkflowSpec ready for execution.

Raises:

TabularLoadError – If openpyxl is not installed, the file is not found, the sheet has no header row, there are no data rows, or required columns are missing.

Return type:

Any

ffai_workflow_adapters.excel.write_workflow_results_excel(result, path=None, *, sheet=None, adapter=None, spec=None, run_id=None)

Write workflow execution results to an Excel file.

Creates one row per workflow step with columns for status, response, model, token usage, cost, and duration. Appends to an existing sheet or creates a new file. Supports passthrough columns from the source spec and extra output columns with template resolution.

Parameters:
  • result (Any) – A ffai WorkflowResult containing step results.

  • path (str | Path | None) – Output file path. Falls back to the adapter config’s output_path.

  • sheet (str | None) – Sheet name for results. Defaults to the adapter config’s output_sheet or “Results”.

  • adapter (str | None) – Named adapter variant for output field mapping.

  • spec (Any | None) – The original WorkflowSpec (used for passthrough column data).

  • run_id (str | None) – Unique run identifier. Auto-generated if not provided.

Returns:

The file path written to, as a string.

Raises:
  • TabularLoadError – If openpyxl is not installed.

  • ValueError – If no output path is specified.

Return type:

str

Templates

Template variable resolution for extra output columns.