SolwynConfig
The complete SDK configuration reference — constructor arguments, every SolwynConfig field, the full environment-variable table, precedence, and validation.
import os
from anthropic import Anthropic
from openai import OpenAI
from solwyn import Solwyn
client = Solwyn(
OpenAI(),
model="gpt-4o",
api_key=os.environ["SOLWYN_API_KEY"],
budget_mode="hard_deny",
fail_open=False,
fallback=[(Anthropic(), "claude-sonnet-4-5", {"max_tokens": 1024})],
circuit_breaker_failure_threshold=5,
)Configuration is passed as keyword arguments to Solwyn() or AsyncSolwyn(). A handful of arguments shape the failover chain and are handled by the client wrapper; the rest map directly onto SolwynConfig fields, many of which also read a SOLWYN_-prefixed environment variable.
SolwynConfig is a Pydantic BaseModel that validates all SDK configuration. You never construct it directly — the wrapper assembles the failover chain (providers, default_params) from the client, model=, fallback=, and default_params= arguments, then constructs and validates the config.
This page is the single source for every configuration option and every environment variable.
Constructor arguments
These keyword-only arguments are handled by the client wrapper itself — they are not raw SolwynConfig fields, and none has an environment variable:
| Argument | Type | Default | Description |
|---|---|---|---|
client | provider client | required (positional) | The LLM client to wrap. Provider is auto-detected (client type, base_url host, Azure client class, or conventional local port). |
api_key | str | None | from env | Solwyn project API key. Falls back to SOLWYN_API_KEY. |
model | str | None | None | Model for the primary entry. Optional for single-provider use (the per-call model wins); set it when configuring a fallback chain. |
provider | str | None | None | Explicit provider identity for the primary entry when auto-detection cannot name the endpoint (e.g. provider="vllm" on a non-default port). Relabels within the client's API dialect only — unknown or dialect-mismatched values raise ConfigurationError. Constructor-only, no env var. |
fallback | list[tuple] | [] | Failover chain entries: (client, model), (client, model, default_params), or (client, model, default_params, provider). See Provider Failover. |
default_params | dict | {} | Global fill-absent request params applied to every entry (per-entry default_params wins). |
selection_policy | SelectionPolicy | None | HealthBasedPolicy | Candidate ordering policy: HealthBasedPolicy (default) or LatencyPolicy. |
**config_kwargs | Any SolwynConfig field below. |
Precedence
Constructor keyword arguments take precedence over environment variables, which take precedence over defaults:
Constructor kwargs > SOLWYN_* env vars > DefaultsIf a field is provided in both the constructor and an environment variable, the constructor value wins.
One runtime exception, new in 0.3.0: on plans without the failover-tuning entitlement, a plan-scoped Cloud directive can advisorily override the seven failover and circuit-breaker tuning fields — failover_total_timeout, failover_idempotency, same_provider_retries, circuit_breaker_recovery_timeout_jitter, circuit_breaker_failure_threshold, circuit_breaker_recovery_timeout, and circuit_breaker_success_threshold — replacing them with SDK defaults at runtime. The override is reversible and applies to no other field; constructor-over-env precedence is unchanged everywhere else. See Plan-scoped tuning entitlement.
Field reference
Required fields
This field must be supplied either as a constructor keyword argument or via the corresponding environment variable. The kwarg defaults to None, and the env-var loader runs before validation, so passing nothing is fine as long as the environment is populated.
| Field | Type | Env var | Validation |
|---|---|---|---|
api_key | str | SOLWYN_API_KEY | Must match sk_proj_<64 lowercase hex chars>. ASCII-only, no path traversal. |
Invalid formats raise ConfigurationError immediately at construction time, with the field attribute set to the failing field name.
Core settings
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
api_url | str | "https://api.solwyn.ai" | SOLWYN_API_URL | Solwyn Cloud API endpoint. |
fail_open | bool | True | SOLWYN_FAIL_OPEN | Allow LLM calls when Solwyn Cloud is unreachable. |
budget_mode | BudgetMode | "alert_only" | SOLWYN_BUDGET_MODE | "alert_only": warn on budget exhaustion. "hard_deny": block calls. |
budget_mode values
| Value | Behavior |
|---|---|
"alert_only" | Default. Logs a warning when budget is exhausted but allows the call. |
"hard_deny" | Raises BudgetExceededError and blocks the call before it reaches the provider. |
fail_open values
| Value | Behavior when Solwyn Cloud is unreachable |
|---|---|
True | LLM calls proceed with local usage tracking. Warning logged. |
False | Calls are denied when the budget check cannot be completed. |
The SOLWYN_FAIL_OPEN environment variable accepts true, 1, yes (case-insensitive) for True, and any other value for False.
Provider failover chain
These fields are assembled by the client wrapper from your client / model= / fallback= / default_params= arguments. They are constructor-only — none is read from the environment.
| Field | Type | Default | Description |
|---|---|---|---|
providers | list[ProviderEntry] | required (≥1) | The [primary, *fallbacks] chain. providers[0] is the wrapped client; the rest are fallbacks in attempt order. |
default_params | dict[str, Any] | {} | Global fill-absent request params (per-entry default_params wins). |
failover_total_timeout | float | 30.0 | Wall-clock deadline (seconds) for the entire chain walk. |
failover_idempotency | "safe" | "never" | "always" | "safe" | Failover aggressiveness after an ambiguous (post-send) failure. |
same_provider_retries | int | 0 | Same-provider 429 Retry-After retries before cross-provider failover. |
circuit_breaker_recovery_timeout_jitter | float | 0.2 | Fractional jitter on the recovery timeout so instances don't probe in lockstep. |
ProviderEntry carries provider, model, and default_params only — never an api_key or base_url. Provider credentials live on your client objects.
See Provider Failover for the full failover model, including the per-call solwyn_idempotent override.
Circuit breaker
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
circuit_breaker_failure_threshold | int | 3 | SOLWYN_CIRCUIT_BREAKER_FAILURE_THRESHOLD | Consecutive failures before the circuit opens. |
circuit_breaker_recovery_timeout | int | 60 | SOLWYN_CIRCUIT_BREAKER_RECOVERY_TIMEOUT | Seconds before a half-open recovery probe. |
circuit_breaker_success_threshold | int | 2 | SOLWYN_CIRCUIT_BREAKER_SUCCESS_THRESHOLD | Successes in half-open state needed to close the circuit. |
breaker_reporting_enabled | bool | True | SOLWYN_BREAKER_REPORTING_ENABLED | Report per-provider breaker state to Solwyn Cloud for dashboard visibility (SDK v0.3.0+). Advisory telemetry only — enforcement stays process-local. See Breaker state reporting. |
Lower failure_threshold values react faster to outages but may trigger on transient errors. Lower recovery_timeout values recover faster but may probe before the provider is ready.
Budget
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
budget_check_cache_ttl | int | 5 | SOLWYN_BUDGET_CHECK_CACHE_TTL | Seconds to cache budget check "allowed" responses. Denied responses are never cached. |
Lower values provide more responsive enforcement at the cost of more API round-trips. Higher values reduce traffic but may allow brief overspend.
Reporter
The metadata reporter sends token-usage events to Solwyn Cloud in batches:
| Field | Type | Default | Env var | Description |
|---|---|---|---|---|
reporter_batch_size | int | 50 | SOLWYN_REPORTER_BATCH_SIZE | Maximum usage events per batch. |
reporter_flush_interval | float | 5.0 | SOLWYN_REPORTER_FLUSH_INTERVAL | Seconds between automatic batch flushes. |
reporter_max_queue_size | int | 10000 | SOLWYN_REPORTER_MAX_QUEUE_SIZE | Maximum events in the in-process queue; when full, the oldest events are dropped. |
reporter_max_in_flight | int | 3 | SOLWYN_REPORTER_MAX_IN_FLIGHT | Maximum concurrent HTTP requests for batch delivery. |
Tuning guidance:
- High-throughput applications: increase
reporter_batch_sizeandreporter_max_queue_sizeto reduce HTTP overhead. - Low-latency applications: decrease
reporter_flush_intervalfor faster dashboard updates. - Memory-constrained environments: decrease
reporter_max_queue_sizeto limit memory usage.
Environment variables
This is the complete, site-wide list of environment variables the SDK reads. Only the fields below are populated from the environment — the failover chain (fallback, model, provider, default_params, selection_policy) and the failover knobs are constructor-only. The prefix is always SOLWYN_, and the suffix is the uppercase field name:
api_key -> SOLWYN_API_KEY
api_url -> SOLWYN_API_URL
fail_open -> SOLWYN_FAIL_OPEN
budget_mode -> SOLWYN_BUDGET_MODE
circuit_breaker_failure_threshold -> SOLWYN_CIRCUIT_BREAKER_FAILURE_THRESHOLD
circuit_breaker_recovery_timeout -> SOLWYN_CIRCUIT_BREAKER_RECOVERY_TIMEOUT
circuit_breaker_success_threshold -> SOLWYN_CIRCUIT_BREAKER_SUCCESS_THRESHOLD
breaker_reporting_enabled -> SOLWYN_BREAKER_REPORTING_ENABLED
budget_check_cache_ttl -> SOLWYN_BUDGET_CHECK_CACHE_TTL
reporter_batch_size -> SOLWYN_REPORTER_BATCH_SIZE
reporter_flush_interval -> SOLWYN_REPORTER_FLUSH_INTERVAL
reporter_max_queue_size -> SOLWYN_REPORTER_MAX_QUEUE_SIZE
reporter_max_in_flight -> SOLWYN_REPORTER_MAX_IN_FLIGHTConstructor values take precedence over environment variables, which take precedence over defaults.
Boolean coercion
The SOLWYN_FAIL_OPEN and SOLWYN_BREAKER_REPORTING_ENABLED environment variables are coerced to booleans: true, 1, yes (case-insensitive) map to True. All other values map to False.
Validation
Credential format validation
The api_key is validated after construction:
- API key: must match the regex
^sk_proj_[a-f0-9]{64}$
Security checks applied:
- Unicode NFC normalization (prevents homograph attacks)
- ASCII-only enforcement (prevents encoding exploits)
- Path traversal rejection (
..,/,\are rejected)
Invalid formats raise ConfigurationError with the field attribute set to the failing field name.
Provider chain validation
The config requires at least one entry in providers. An empty chain raises ConfigurationError on the providers field. In normal use the wrapped client always supplies the primary entry, so this is satisfied automatically.
Extra field rejection
SolwynConfig uses Pydantic's extra="forbid" mode. Any unrecognized keyword argument is rejected:
import os
from openai import OpenAI
from solwyn import Solwyn
# Rejected -- "typo_field" is not recognized.
# The removed fallback_model / primary_provider options are also rejected here.
client = Solwyn(
OpenAI(),
api_key=os.environ["SOLWYN_API_KEY"],
typo_field="value",
)Use fallback=[...] for failover (see Provider Failover); the primary provider is always auto-detected from the wrapped client.
Enum values
BudgetMode
| Value | Description |
|---|---|
"alert_only" | Log warning on budget exhaustion, allow calls. |
"hard_deny" | Raise BudgetExceededError, block calls. |
ProviderName
The first four values are native API dialects (Bedrock's Converse API is its own dialect). The rest are OpenAI-compatible providers: they speak the Chat Completions dialect but are distinct providers for attribution, pricing, budget enforcement, and circuit breaking.
| Value | Description |
|---|---|
"openai" | OpenAI provider (native dialect). |
"anthropic" | Anthropic provider (native dialect). |
"google" | Google Gemini provider (native dialect). |
"bedrock" | Amazon Bedrock provider — Converse API (native dialect). |
"xai" | xAI (Grok), via api.x.ai. |
"deepseek" | DeepSeek, via api.deepseek.com. |
"mistral" | Mistral, via api.mistral.ai. |
"qwen" | Qwen (DashScope compatible mode). |
"zai" | Z.AI, via api.z.ai (the GLM model family). |
"groq" | Groq, via api.groq.com. |
"together" | Together AI. |
"fireworks" | Fireworks, via api.fireworks.ai. |
"perplexity" | Perplexity (Sonar), via api.perplexity.ai. |
"azure_openai" | Azure OpenAI (host suffix or AzureOpenAI client class). |
"openrouter" | OpenRouter, via openrouter.ai. |
"ollama" | Ollama (conventional local port 11434). |
"vllm" | vLLM (conventional local port 8000). |
"lmstudio" | LM Studio (conventional local port 1234). |
"openai_compatible" | Generic catch-all for any unrecognized OpenAI-compatible endpoint (custom proxies, new vendors). |
CircuitState
| Value | Description |
|---|---|
"closed" | Normal operation — requests flow through. |
"open" | Failing — the router fails over to the next candidate. |
"half_open" | Testing recovery with probe requests. |
FailoverReason
| Value | Description |
|---|---|
"circuit_open" | The primary's breaker was open and was skipped (never attempted). |
"primary_error" | The primary was attempted and raised before a fallback succeeded. |
"model_fallback" | A same-provider model swap served the call. |
Example: full configuration
import os
from anthropic import Anthropic
from openai import OpenAI
from solwyn import Solwyn, LatencyPolicy
client = Solwyn(
OpenAI(),
# Primary entry
model="gpt-4o",
# Required
api_key=os.environ["SOLWYN_API_KEY"],
# Core
api_url="https://api.solwyn.ai",
budget_mode="hard_deny",
fail_open=False,
# Failover chain
fallback=[(Anthropic(), "claude-sonnet-4-5", {"max_tokens": 1024})],
default_params={"temperature": 0.7},
selection_policy=LatencyPolicy(),
failover_total_timeout=20.0,
failover_idempotency="safe",
same_provider_retries=1,
# Circuit breaker
circuit_breaker_failure_threshold=5,
circuit_breaker_recovery_timeout=30,
circuit_breaker_success_threshold=3,
# Budget
budget_check_cache_ttl=10,
# Reporter
reporter_batch_size=100,
reporter_flush_interval=2.0,
reporter_max_queue_size=20000,
reporter_max_in_flight=5,
)