Skip to content

Settings

Process-wide configuration, sourced from environment variables. Settings cover the task consumer concurrency and timings, the broker and database connections, the HTTP client user agent, pagination defaults, the console backdoor and the stack sampler.

It can be imported from fluid.settings:

from fluid.settings import get_settings

settings = get_settings()
settings.max_concurrent_tasks

The environment is read the first time get_settings is called, not at import time, so an application can populate the environment before the first access. The instance is then cached for the lifetime of the process.

Environment variable names

Most fields are read from FLUID_<FIELD_NAME>, and names are case insensitive, so FLUID_MAX_CONCURRENT_TASKS and fluid_max_concurrent_tasks both set max_concurrent_tasks.

A few fields keep a conventional external name instead, with no prefix:

Field Environment variable
app_name APP_NAME
env PYTHON_ENV
log_level LOG_LEVEL
log_handler LOG_HANDLER
python_log_format PYTHON_LOG_FORMAT
database DATABASE
redis_default_url REDIS_DEFAULT_URL
redis_max_connections MAX_REDIS_CONNECTIONS

Warning

The prefixed form does not work for the fields in the table above. Setting FLUID_APP_NAME has no effect, the value is read from APP_NAME only.

The prefix itself can be changed with FLUID_ENV_PREFIX, which is read when fluid.settings is imported, so it has to be set before the first import of the library:

FLUID_ENV_PREFIX=svc_ SVC_MAX_CONCURRENT_TASKS=10 python -m myapp serve

Derived defaults

Three values are computed after the environment is read, when they are not set explicitly:

  • broker_url falls back to redis_default_url, so pointing REDIS_DEFAULT_URL at a Redis instance is enough to move the task queue with it.
  • http_user_agent falls back to python/{app_name}.
  • log_level is upper cased, so LOG_LEVEL=info and LOG_LEVEL=INFO are equivalent.

Reading settings in tests

get_settings caches its result, so a test that changes the environment has to clear the cache for the change to take effect:

import os

from fluid.settings import get_settings

os.environ["FLUID_MAX_CONCURRENT_TASKS"] = "1"
get_settings.cache_clear()

API reference

fluid.settings.Settings

Bases: BaseSettings

Lazy application settings sourced from environment variables.

Settings are read from the environment the first time get_settings is called, not at import time. Access the resolved values either via the cached instance or, for backwards compatibility, via upper-case module attributes (settings.APP_NAME), both of which resolve lazily.

model_config class-attribute instance-attribute

model_config = SettingsConfigDict(
    case_sensitive=False,
    extra="ignore",
    env_prefix=ENV_PREFIX,
)

app_name class-attribute instance-attribute

app_name = Field(
    default="fluid", validation_alias="APP_NAME"
)

env class-attribute instance-attribute

env = Field(default='dev', validation_alias='PYTHON_ENV')

log_level class-attribute instance-attribute

log_level = Field(
    default="info", validation_alias="LOG_LEVEL"
)

log_handler class-attribute instance-attribute

log_handler = Field(
    default="plain", validation_alias="LOG_HANDLER"
)

python_log_format class-attribute instance-attribute

python_log_format = Field(
    default="%(asctime)s %(levelname)s %(name)s %(message)s",
    validation_alias="PYTHON_LOG_FORMAT",
)

database class-attribute instance-attribute

database = Field(
    default="postgresql+asyncpg://postgres:postgres@localhost:5432/fluid",
    validation_alias="DATABASE",
)

redis_default_url class-attribute instance-attribute

redis_default_url = Field(
    default="redis://localhost:6379",
    validation_alias="REDIS_DEFAULT_URL",
)

stopping_grace_period class-attribute instance-attribute

stopping_grace_period = 10

max_concurrent_tasks class-attribute instance-attribute

max_concurrent_tasks = Field(
    default=5,
    description="Maximum number of concurrent tasks per TaskConsumer",
)

sleep_millis class-attribute instance-attribute

sleep_millis = 1000

scheduler_heartbeat_millis class-attribute instance-attribute

scheduler_heartbeat_millis = 100

broker_url class-attribute instance-attribute

broker_url = ''

redis_max_connections class-attribute instance-attribute

redis_max_connections = Field(
    default=5, validation_alias="MAX_REDIS_CONNECTIONS"
)

database_schema class-attribute instance-attribute

database_schema = None

dbpool_max_size class-attribute instance-attribute

dbpool_max_size = 10

dbpool_max_overflow class-attribute instance-attribute

dbpool_max_overflow = 10

dbecho class-attribute instance-attribute

dbecho = False

http_user_agent class-attribute instance-attribute

http_user_agent = ''

default_pagination_limit class-attribute instance-attribute

default_pagination_limit = 250

default_pagination_max_limit class-attribute instance-attribute

default_pagination_max_limit = 500

backdoor_port class-attribute instance-attribute

backdoor_port = 8087

flamegraph_executable class-attribute instance-attribute

flamegraph_executable = 'flamegraph.pl'

stack_sampler_period_seconds class-attribute instance-attribute

stack_sampler_period_seconds = 1

fluid.settings.get_settings cached

get_settings()

Return the process-wide Settings instance.

The instance is built on first call (reading the environment then) and cached for the lifetime of the process. Call get_settings.cache_clear() to force a re-read, which is mostly useful in tests.

Source code in fluid/settings.py
@lru_cache(maxsize=1)
def get_settings() -> Settings:
    """Return the process-wide [Settings][fluid.settings.Settings] instance.

    The instance is built on first call (reading the environment then) and
    cached for the lifetime of the process. Call ``get_settings.cache_clear()``
    to force a re-read, which is mostly useful in tests.
    """
    return Settings()