Keyboard shortcuts

Press or to navigate between chapters

Press ⌘K or Ctrl+K to search

Press ? to show this help

Press Esc to hide this help

Appendix D: Configuration Schema

Strato is configured via pyproject.toml under the [tool.strato] namespace. All configuration is optional – Strato provides sensible defaults for zero-config operation.

[tool.strato] – Core Configuration

KeyTypeDefaultDescription
src_rootslist[str]Auto-detectedSource roots for first-party code detection. Paths relative to pyproject.toml.
python_versionstr"3.9"Python version used to configure vendored ty. Affects syntax, stdlib stubs, conditional type definitions, and escape hatch recognition (e.g., asyncio.to_thread requires 3.9+). Valid: "3.7".."3.15".
excludelist[str][]Glob patterns for paths to exclude (e.g., "tests/**").
intervention_strategystr"first-party-deepest"Error reporting strategy. Options: "first-party-deepest", "async-boundary".
severitystr"error"Diagnostic severity. Options: "error", "warning". Diagnostics produce exit code 1 regardless of selected severity.
cache_dirstr".strato_cache"Cache directory (relative to pyproject.toml).
cache_enabledbooltrueEnable/disable caching.
stub_pathslist[str][]Additional directories to search for .pyi stubs with @blocking annotations. These paths are passed to ty as environment.extra-paths, not as project roots.
output_formatstr"text"Output format. Options: "text", "json", "sarif".

[tool.strato.blocking] – Blocking Function Database

KeyTypeDefaultDescription
addlist[object][]Custom blocking functions. Each: { name, help, category }.
removelist[str][]Remove built-in entries by qualified name.
blocking_moduleslist[str][]Mark all resolved call targets under these module prefixes as blocking using module-boundary prefix matching.

add entry fields:

  • name (required): Fully qualified function name (e.g., "redis.Redis.get")
  • help (required): Human-readable fix suggestion
  • category (required): One of: "sleep", "network-io", "file-io", "subprocess", "database-io", "user-input", "other"

[tool.strato.executor-wrappers] – Custom Escape Hatches

Key-value pairs where the key is the qualified wrapper name and the value specifies which parameter receives the callable:

"qualified.wrapper.name" = { callable_param = <int | str> }
  • Integer: Positional parameter index (0-based)
  • String: Keyword argument name

Wrapper names are TOML keys, so each qualified wrapper name can appear at most once. Duplicate keys are invalid TOML and are rejected by the TOML parser before Strato-specific validation runs.

Precedence: @unblocker annotation > config entry.

Validation Rules

CheckError Message
src_roots path missingSource root '{path}' does not exist
Invalid python_versionInvalid python_version: must be '3.7'...'3.15'
Invalid intervention_strategyInvalid strategy: must be 'first-party-deepest' or 'async-boundary'
Invalid severityInvalid severity: must be 'error' or 'warning'
Invalid output_formatInvalid output_format: must be 'text', 'json', or 'sarif'
Missing name in blocking.addBlocking entry missing required field 'name'
Invalid categoryUnknown category '{cat}'. Valid: sleep, network-io, file-io, subprocess, database-io, user-input, other
Missing callable_paramExecutor wrapper '{name}' missing required field 'callable_param'
Invalid callable_paramExecutor wrapper '{name}' callable_param must be an integer index or keyword name

When python_version is valid but excludes a built-in escape hatch, Strato does not silently apply that escape hatch. For example, asyncio.to_thread under python_version = "3.8" emits a warning and is not marked as executor-protected. The callable argument remains a callable reference, not a direct call expression, so Strato still does not report it as direct blocking merely because protection was unavailable.

Complete Annotated Example

[tool.strato]
src_roots = ["src", "lib"]
python_version = "3.11"
exclude = [
    "tests/**",
    "migrations/**",
    "**/conftest.py",
]
intervention_strategy = "first-party-deepest"
severity = "error"
cache_dir = ".strato_cache"
cache_enabled = true
stub_paths = ["stubs/"]
output_format = "text"


[tool.strato.blocking]
add = [
    { name = "redis.Redis.get", help = "Use aioredis", category = "network-io" },
    { name = "redis.Redis.set", help = "Use aioredis", category = "network-io" },
    { name = "mylib.slow_computation", help = "Use asyncio.to_thread()", category = "other" },
]
remove = [
    "builtins.open",  # Our open() is monkeypatched to be async-safe
]
blocking_modules = [
    "legacy_sync_module",
]


[tool.strato.executor-wrappers]
# Third-party wrappers
"asgiref.sync.sync_to_async" = { callable_param = 0 }

# Project-specific wrappers
"myproject.utils.offload" = { callable_param = 0 }
"myproject.async_helpers.run_blocking" = { callable_param = "func" }