| name | plugin-config |
| description | Creates plugin configuration using NemoConfig with environment variables and YAML file support. Use when adding plugin configuration fields, reading config values at runtime, setting up test config overrides, or understanding the env var naming formula. Trigger keywords: config, configuration, NemoConfig, env var, environment variable, plugin_name, NMP_CONFIG, YAML config, config override, test config. |
Plugin Configuration (NemoConfig)
Defining Config
Both plugin_name AND plugin_description are required ClassVar[str] fields. Omitting either raises TypeError at class-definition time.
from typing import ClassVar
from pydantic import Field
from nemo_platform_plugin.config import NemoConfig
class MyPluginConfig(NemoConfig):
plugin_name: ClassVar[str] = "my-plugin"
plugin_description: ClassVar[str] = "Configuration for my plugin."
debug: bool = Field(default=False)
max_workers: int = Field(default=4)
log_level: str = Field(default="INFO")
Environment Variable Formula
NMP_<SAFE_NAME>_<FIELD> where SAFE_NAME = plugin_name uppercased with non-word chars replaced by _.
plugin_name | Env prefix | Field | Env var |
|---|
"my-plugin" | NMP_MY_PLUGIN_ | debug | NMP_MY_PLUGIN_DEBUG |
"agents" | NMP_AGENTS_ | runner_backend | NMP_AGENTS_RUNNER_BACKEND |
"example" | NMP_EXAMPLE_ | greeting_style | NMP_EXAMPLE_GREETING_STYLE |
Nested fields use _ as delimiter:
NMP_AGENTS_CONTROLLER_INTERVAL_SECONDS=10
NMP_AGENTS_CONTROLLER_PORT_RANGE_START=49152
YAML Config File
Config key in /etc/nmp/config.yaml equals plugin_name:
my_plugin:
debug: true
max_workers: 8
Override config file location: NMP_CONFIG_FILE_PATH=/my/custom/config.yaml
Priority Order
- Environment variables (
NMP_MY_PLUGIN_*) — highest
- Config file (
/etc/nmp/config.yaml)
- Pydantic field defaults — lowest
Accessing Config
config = MyPluginConfig.get()
from nemo_platform_plugin.config import get_nemo_config
config = get_nemo_config(MyPluginConfig)
Both return the same cached singleton. Multiple calls in the same process return the same instance.
Example — ExampleConfig from example-plugin (verbatim)
from typing import ClassVar, Literal
from nemo_platform_plugin.config import NemoConfig
from pydantic import Field
class ExampleConfig(NemoConfig):
plugin_name: ClassVar[str] = "example"
plugin_description: ClassVar[str] = "Configuration for the NeMo Platform example plugin."
greeting_style: Literal["formal", "casual"] = Field(
default="formal",
description=(
"Controls the tone of /hello/{name} responses. "
'"formal" → "Hello, {name}." "casual" → "Hey, {name}!"'
" Set NMP_EXAMPLE_GREETING_STYLE to override."
),
)
log_requests: bool = Field(
default=False,
description=(
"When True, each request to the items list endpoint emits a "
"structured INFO log line including the workspace and page number. "
"Set NMP_EXAMPLE_LOG_REQUESTS=true to enable."
),
)
Usage across multiple components (no wiring needed):
config = ExampleConfig.get()
Nested Config Models
Use a plain BaseModel (NOT NemoConfig) for nested sections:
from pydantic import BaseModel, Field
from nemo_platform_plugin.config import NemoConfig
class ControllerConfig(BaseModel):
interval_seconds: int = Field(default=5)
health_check_timeout_seconds: int = Field(default=120)
class AgentsConfig(NemoConfig):
plugin_name: ClassVar[str] = "agents"
plugin_description: ClassVar[str] = "Configuration for the NeMo Platform agents plugin."
controller: ControllerConfig = Field(default_factory=ControllerConfig)
runner_backend: str = Field(default="in_memory")
Access nested fields: AgentsConfig.get().controller.interval_seconds
Set nested via env: NMP_AGENTS_CONTROLLER_INTERVAL_SECONDS=10
Test Override Pattern
from nemo_platform_plugin.config import (
set_nemo_config_override,
clear_nemo_config_override,
clear_nemo_config_overrides,
)
def test_casual_greeting():
set_nemo_config_override(ExampleConfig(greeting_style="casual"))
try:
config = ExampleConfig.get()
assert config.greeting_style == "casual"
finally:
clear_nemo_config_override(ExampleConfig)
import pytest
@pytest.fixture(autouse=True)
def reset_config():
yield
clear_nemo_config_overrides()
Gotchas
plugin_name must be kebab-case: "my-plugin" not "my_plugin". Use the same value as your CLI entry-point key. The env prefix replaces - with _ automatically.
- Both
plugin_name AND plugin_description required: TypeError at class-definition time if either is missing or empty.
- Do NOT call
MyPluginConfig() directly: This bypasses env/file loading. Always use MyPluginConfig.get() or get_nemo_config(MyPluginConfig).
- Do NOT set
model_config manually: The _NemoConfigMeta metaclass sets it before Pydantic builds the schema. Setting it manually will be overridden and may leave the schema inconsistent.
- Config is cached per process: In tests, always clean up with
clear_nemo_config_override(cls) or clear_nemo_config_overrides(). Failing to do so pollutes subsequent tests.
- Abstract intermediates: A class that declares neither
plugin_name nor plugin_description is treated as an abstract intermediate (exempt from validation). Declaring plugin_description without plugin_name raises TypeError — you cannot partially fill the requirement.