Floating Rock cascading configuration resolver
Project description
fr_config - Floating Rock Cascading Config Resolver
fr_config is a hierarchical cascading config resolver that resolves configs based on hierarchy structure and schema.
This allows for a high degree of control over how configurations are loaded based on where they are in the filesystem.
Configs will load in the order of variant/default, parent.variant/parent.default until they either hit the root paths or a $parent redirect. A redirect allows for configs to jump or reference a shared directory.
For example a package config may have a manifests directory that can be referenced at any level of the hierarchy.
A Cascade is how the configs are applied via the schema. eg: given a list value, how is that resolved across configs? Do we append? prepend? replace?
If that list contains objects do we replace those? just where they conflict? or perhaps recursively update.
This cascade allows us to use the same config layer to apply to many data types while maintaining type coherence.
fr_config was designed to work with fr_env_resolver, Floating Rocks rez-based environment resolver for loading context dependent package lists.
Context Path Resolve
Contexts are .frconfigs that live in any directory, When a path is loaded, the variables "cascade" backwards up the tree for a final resolve.
This allows for per shot/asset variations.
It's important to note this is not restricted to production dirs, any directory can be used to cascade.
The process here is the same for Environment Contexts (packages, variables) and Tool Contexts (The subenvironment used by tools in the launcher)
Variants
Inside the config resolve is something called "variants", By default, there is a "default" variant associated with each level in the hierarchy, but additional variants can be added to produce variations such as per department.
These variations are used in anything deriving from fr_config. Meaning you can have a variant for a context, manifest, workflow or tool.
If a variant is specified to a loader, it will attempt to load that variant any time it is available before loading the default variant. You cannot skip loading the default, if that is required then leave it blank and only use variants to provide details.
Features
- Hierarchical Configuration: Configs follow a filesystem path for resolving
- Schema Validation: JSON Schema-based validation with custom type system
- Version Management: Built-in versioning with tags (published, latest, deprecated, etc.)
- Data Merging: Configurable cascade modes (replace, update, append, prepend)
- Multi-Variant Support: Support for different configuration variants (departments, tasks, etc)
Quick Start
Important Note Any code inside the _internal/ folder is not gaurenteed to persist across versions and should not be used directly outside of debugging.
Installation
Local Installation
If you have the source code locally, navigate to the project directory and install it:
cd /path/to/fr_config
pip install .
or with rez:
cd /path/to/fr_config
rez-pip install .
Remote Installation
To install directly from this Git repository:
pip install git+https://github.com/FloatingRockStudio/fr_config.git
or with rez:
rez-pip install git+https://github.com/FloatingRockStudio/fr_config.git
Loading Configuration
from fr_config import ConfigLoader
# Load config from a specific path
config = ConfigLoader("simple", "/path/to/project")
# Access configuration data
fps = config.value("fps")
resolution = config.value("resolution")
tools = config.value("tools", []) # With default value if not specified in schema
# Get all configuration keys
keys = config.keys()
key_paths = config.key_paths() # Returns nested paths like "/playblast_settings/overscan"
Loading Specific Variants/Tags
# Load development variant
config = ConfigLoader("simple", "/path", variant="dev")
# Load with specific tags, first one in list that matches is used (if no wip, then latest is used)
config = ConfigLoader("simple", "/path", tags=["wip", "latest"])
# Load multiple variants, this will load /path/prod.fr_config then /path/default.fr_config.
config = ConfigLoader("simple", "/path", variant=["prod", "default"])
# If a string is passed then it will automatically change to [variant, "default"]
config = ConfigLoader("simple", "/path", variant="prod")
Writing Configuration
from fr_config import ConfigWriter
# Create or modify a config
writer = ConfigWriter("simple", "/path/to/project")
writer.set_data("fps", 30.0)
writer.set_data("resolution", [1920, 1080])
writer.commit("Updated resolution and fps") # Save changes to disk
Schema Definition
fr_config uses json5 files to store schema, this allows for comments to be added in complex schemas
{
__version__: 1,
fps: {type: "float", default: 24.0},
resolution: {
type: "array",
length: 2,
items: {type: "int"}
},
publish_defaults: {
type: "object",
publish_type: {type: "string", default: "Publish"},
handles: {
type: "array",
items: {type: "int"},
default: [0, 0]
}
},
tools: {
type: "array",
cascade: "append",
items: {type: "string"}
}
}
Data Flow
fr_config follows a hierarchical resolution pattern:
- Path Resolution: Starting from the specified path, walks up the directory tree
- Config Discovery: Looks for
.fr_config/<name>/<variant>/directories - Version Selection: Chooses the appropriate version based on tags (published > latest)
- Schema Loading: Loads and validates against the schema file
- Data Cascading: Merges configurations based on cascade and schema rules
- Value Resolution: Resolves environment variables and applies type structure
Directory Structure Example
project/
├── .fr_config/
│ └── simple/
│ └── default/
│ ├── v1.fr_config
│ ├── v2.fr_config
│ ├── v3.fr_config
│ └── .v2.published
├── shots/
│ └── seq001/
│ └── shot010/
│ └── .fr_config/
│ └── simple/
│ ├── default/
│ │ └── v1.fr_config
│ └── animation/
│ └── v1.fr_config
└── schema/
└── simple.fr_schema
Data Cascade Example
Given the directory structure above, loading the animation variant config from shots/seq001/shot010 will:
- Load
shots/seq001/shot010/.fr_config/simple/variant/v1.fr_config - Load
shots/seq001/shot010/.fr_config/simple/default/v1.fr_config - Load
project/.fr_config/simple/default/v2.fr_config(published version) - Merge them according to cascade rules
Configuration File Format
fr_config files use JSON5 format with special keys:
{
// Reference parent config for inheritance
"$parent": "${FR_PROJECTS_DIR}/../shared_config",
// Regular configuration data
fps: 30.0,
resolution: [1920, 1080],
// Complex cascading example
environment_variables: {
PATH: {
cascade: "append",
separator: "%pathsep%", // Platform-specific path separator
value: "/additional/bin/path"
}
},
// Array with uniqueness constraints
packages: {
cascade: "append",
unique: true,
value: ["new-package-1.0+", "another-package-2.1+"]
}
}
Schema System
Data Types
string: Text valuesint: Integer numbersfloat: Floating-point numbersbool: Boolean true/falsearray: Lists of valuesobject: Nested structures
Cascade Modes
replace: Replace entire value (default for primitives)update: Merge object keys (default for objects)append: Add to end of array/stringprepend: Add to beginning of array/string
Custom Types
Define reusable types in schema:
{
__types__: {
package: {
type: "string",
compare: "^([_a-zA-Z0-9]+)-.*" // Regex for uniqueness comparison
},
environ: {
type: "string",
separator: "%pathsep%"
}
},
packages: {
type: "array",
cascade: "append",
unique: true,
items: {type: "package"}
},
PATH: {type: "environ"}
}
Environment Setup
Set environment variables for schema and root path discovery:
# Path to schema files
export FR_CONFIG_SCHEMA_PATH="/path/to/schemas:/another/schema/path"
# Root paths that terminate config hierarchy traversal
export FR_CONFIG_ROOT_PATHS="/projects/root:/shared/configs"
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fr_config-0.2.1.tar.gz.
File metadata
- Download URL: fr_config-0.2.1.tar.gz
- Upload date:
- Size: 99.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0eadb185b506deec46d91faf8fe3719858f239ddd0d987b84fd723055636f2e
|
|
| MD5 |
aff8250fc5140c8c615cafb9af15f50e
|
|
| BLAKE2b-256 |
222c38a9e9a3641cc2050d89396d1ff93bba9195d12a3239663e3c5a84071b4a
|
File details
Details for the file fr_config-0.2.1-py3-none-any.whl.
File metadata
- Download URL: fr_config-0.2.1-py3-none-any.whl
- Upload date:
- Size: 29.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4469608f9c7d2bd294c29f2e3e216baa53c5705bb920aa3a7252e75dfcf77500
|
|
| MD5 |
154311d05ec039119687463beaecd1aa
|
|
| BLAKE2b-256 |
8760f00ebb8d4ee6185708982e75532e9d434d712b2976c138b7a24a43817e41
|