Plugin Configuration
FrameX configuration has two layers:
- runtime configuration for the whole service
- plugin-specific configuration under
plugins.<plugin_name>
This chapter focuses on the settings you are most likely to use in real projects.
Where Configuration Comes From
FrameX loads settings from these sources:
- environment variables
.env.env.prodconfig.toml[tool.framex]inpyproject.toml
In the current implementation, environment variables take highest priority. config.toml and [tool.framex] are useful project-level defaults.
CLI options are then applied before startup, so flags such as --port, --load-plugins, and --load-builtin-plugins can override configuration at runtime.
Minimal config.toml
For most projects, config.toml is the clearest place to start.
Example:
load_builtin_plugins = ["echo"]
load_plugins = ["your_project.plugins.foo"]
[server]
host = "127.0.0.1"
port = 8080
use_ray = false
enable_proxy = false
[plugins.foo]
debug = true
The most common top-level fields are:
load_builtin_pluginsload_pluginsserverpluginsauth
Most Common Runtime Settings
In normal usage, the most important settings are:
server.hostserver.portserver.use_rayserver.enable_proxyload_builtin_pluginsload_pluginsplugins.<plugin_name>auth.rules
You do not need to understand every field in the global Settings model before using FrameX productively. Most projects only touch a small subset.
Plugin-Specific Configuration
Plugin-specific settings live under:
[plugins.<plugin_name>]
Example:
[plugins.foo]
debug = true
timeout = 30
This keeps plugin settings separate from global runtime settings.
Typed Plugin Configuration
If a plugin wants typed configuration, it can declare a Pydantic model and attach it through config_class in PluginMetadata.
Define a config model
from pydantic import BaseModel
class FooConfig(BaseModel):
debug: bool = False
timeout: int = 30
Attach it to plugin metadata
__plugin_meta__ = PluginMetadata(
name="foo",
version=VERSION,
description="A minimal example plugin",
author="you",
url="https://github.com/touale/FrameX-kit",
required_remote_apis=[],
config_class=FooConfig,
)
Read it inside the plugin
from framex.plugin import get_plugin_config
settings = get_plugin_config("foo", FooConfig)
If no config is provided for that plugin, FrameX returns the config model with its default values and logs a warning.
Example: Plugin Config in config.toml
If the plugin is named foo, the matching config block looks like this:
[plugins.foo]
debug = true
timeout = 30
That block is what get_plugin_config("foo", FooConfig) reads.
Environment Variables
Nested settings can also be provided through environment variables with __ as the separator.
Examples:
export SERVER__PORT=9000
export SERVER__ENABLE_PROXY=true
export PLUGINS__FOO__DEBUG=true
Because the current settings model uses case_sensitive=False, you do not need to rely on lowercase-only keys.
When to Use Which Format
Use config.toml when:
- you want readable project defaults
- the configuration is hierarchical
- you want plugin settings grouped clearly in version control
Use environment variables when:
- deployment environments need different overrides
- secrets or environment-specific values should not live in the repo
- CI, containers, or runtime platforms inject settings dynamically
A practical pattern is:
- keep stable defaults in
config.toml - use environment variables for deployment-specific overrides
Rule of Thumb
Keep this mental model:
server.*configures the runtimeload_pluginsandload_builtin_pluginscontrol what gets loadedplugins.<plugin_name>configures one pluginconfig_class+get_plugin_config(...)gives that plugin typed settings
That is enough for most real FrameX projects.