Skip to content

Create configuration in code

Configure PyRel in Python when settings need to come from your code instead of only from raiconfig.yaml. This guide shows when programmatic configuration is the right fit, how to choose between dictionaries and typed config classes, how to build a validated config, how to select a runtime profile, and how to apply one-off overrides safely.

  • You have access to a Snowflake account with the RelationalAI Native App installed. If you are unsure, contact your Snowflake administrator.
  • You have a working PyRel installation. See Set Up Your Environment for instructions.

This guide covers the Load and validate configuration step in the PyRel workflow:

1. Load and validateconfiguration2. Build modeland query3. SubmitRelationalAI job4. Run job withreasoners5. Materializeresults

Use programmatic configuration to build the full Config object in Python or to override discovered defaults for the current process. If you want PyRel to discover and validate configuration from a file, see Load configuration from files.

To create a Config instance, call create_config() with config sections as keyword arguments. You can provide config sections as plain Python dictionaries or as typed config objects.

Both approaches call create_config() and return the same validated Config object. You pass the result to Model the same way either way.

Choose the style that best matches how you are building the settings:

ApproachChoose it when
Typed config objectsYou want IDE type hints, constructor arguments, and a more Python-native style.
Plain dictionariesYou want code that closely mirrors raiconfig.yaml, or you need to build sections and keys dynamically.

Use this style when you want the closest match to the shape of raiconfig.yaml:

import os
from relationalai.config import create_config
from relationalai.semantics import Model
cfg = create_config(
connections={
"sf": {
"type": "snowflake",
"authenticator": "username_password",
"account": os.environ["SNOWFLAKE_ACCOUNT"],
"warehouse": os.environ["SNOWFLAKE_WAREHOUSE"],
"user": os.environ["SNOWFLAKE_USER"],
"password": os.environ["SNOWFLAKE_PASSWORD"],
},
},
default_connection="sf",
)
# Use the config
m = Model("MyModel", config=cfg)

Use this style when you want IDE type hints and constructor-style validation:

import os
from relationalai.config import UsernamePasswordAuth, create_config
from relationalai.semantics import Model
cfg = create_config(
connections={
"sf": UsernamePasswordAuth(
account=os.environ["SNOWFLAKE_ACCOUNT"],
warehouse=os.environ["SNOWFLAKE_WAREHOUSE"],
user=os.environ["SNOWFLAKE_USER"],
password=os.environ["SNOWFLAKE_PASSWORD"],
),
},
default_connection="sf",
)
# Use the config
m = Model("MyModel", config=cfg)

Override file-based configuration with programmatic config

Section titled “Override file-based configuration with programmatic config”

You can keep a raiconfig.yaml for shared defaults and override only what changes at runtime. Use this when you want consistent defaults but still need per-run tweaks in tests, CI, or notebooks. Programmatic overrides only affect the current Python process.

Call create_config() with the active_profile argument to choose which named override from the file’s profile section to apply in this process. The profile name must already exist in that profile section.

from relationalai.config import create_config
from relationalai.semantics import Model
cfg = create_config(active_profile="prod")
# Verify the selected profile and a field that differs across profiles
m = Model("MyModel", config=cfg)
print(m.config.active_profile)
print(m.config.connections["snowflake"].warehouse)

Replace snowflake and warehouse with the connection name and field that differ across your profiles.

Apply one-off runtime overrides without editing files

Section titled “Apply one-off runtime overrides without editing files”

Pass explicit keyword arguments to create_config() to override file-based values for this process:

from relationalai.config import create_config
from relationalai.semantics import Model
cfg = create_config(
execution={
"metrics": True,
}
)
# Verify the override took effect
m = Model("MyModel", config=cfg)
print(m.config.execution.metrics)

For tests, prefer passing connections=... and any other settings you need so your test suite does not depend on a developer machine’s config files. This keeps tests hermetic and avoids surprises from a user’s local configuration. If you want to test file discovery behavior, treat that as an integration test and set up the expected files explicitly.