Settings
Settings give the ability to change how OpenPype behaves in certain situations. Settings are split into 3 categories system settings, project anatomy and project settings. Project anatomy and project settings are grouped into a single category but there is a technical difference (explained later). Only difference in system and project settings is that system settings can't be technically handled on a project level or their values must be available no matter in which project the values are received. Settings have headless entities or settings UI.
There is one more category local settings but they don't have ability to be changed or defined easily. Local settings can change how settings work per machine, can affect both system and project settings but they're hardcoded for predefined values at this moment.
Settings schemas
System and project settings are defined by settings schemas. Schema defines the structure of output value, what value types output will contain, how settings are stored and how its UI input will look.
Settings values
Output of settings is a json serializable value. There are 3 possible types of value default values, studio overrides and project overrides. Default values must be always available for all settings schemas, their values are stored to code. Default values are what everyone who just installed OpenPype will use as default values. It is good practice to set example values but they should be actually relevant.
Setting overrides is what makes settings a powerful tool. Overrides contain only a part of settings with additional metadata that describe which parts of settings values should be replaced from overrides values. Using overrides gives the ability to save only specific values and use default values for rest. It is super useful in project settings which have up to 2 levels of overrides. In project settings are used default values as base on which are applied studio overrides and then project overrides. In practice it is possible to save only studio overrides which affect all projects. Changes in studio overrides are then propagated to all projects without project overrides. But values can be locked on project level so studio overrides are not used.
Settings storage
As was mentioned default values are stored into repository files. Overrides are stored in the Mongo database. The value in mongo contain only overrides with metadata so their content on it's own is useless and must be used with combination of default values. System settings and project settings are stored into special collection. Single document represents one set of overrides with OpenPype version for which is stored. Settings are versioned and are loaded in specific order - current OpenPype version overrides or first lower available. If there are any overrides with the same or lower version then the first higher version is used. If there are any overrides then no overrides are applied.
Project anatomy is stored into a project document thus is not versioned and its values are always overridden. Any changes in anatomy schema may have a drastic effect on production and OpenPype updates.
Settings schema items
As was mentioned schema items define output type of values, how they are stored and how they look in UI.
schemas are (by default) defined by json files
OpenPype core system settings schemas are stored in
~/openpype/settings/entities/schemas/system_schema/
and project settings in~/openpype/settings/entities/schemas/projects_schema/
- both contain
schema_main.json
which are entry points
- both contain
OpenPype modules/addons can define their settings schemas using
BaseModuleSettingsDef
in that case some functionality may be slightly modifiedsingle schema item is represented by dictionary (object) in json which has
"type"
key.- type is only common key which is required for all schema items
each item may have "input modifiers" (other keys in dictionary) and they may be required or optional based on the type
there are special keys across all items
"is_file"
- this key is used when defaults values are stored in the file. Its value matches the filename where values are stored- key is validated, must be unique in hierarchy otherwise it won't be possible to store default values
- make sense to fill it only if it's value if
true
"is_group"
- define that all values under a key in settings hierarchy will be overridden if any value is modified- this key is not allowed for all inputs as they may not have technical ability to handle it
- key is validated, must be unique in hierarchy and is automatically filled on last possible item if is not defined in schemas
- make sense to fill it only if it's value if
true
all entities can have set
"tooltip"
key with description which will be shown in UI on hover
Inner schema
Settings schemas are big json files which would become unmanageable if they were in a single file. To be able to split them into multiple files to help organize them special types schema
and template
were added. Both types are related to a different file by filename. If a json file contains a dictionary it is considered as schema
if it contains a list it is considered as a template
.
schema
Schema item is replaced by content of entered schema name. It is recommended that the schema file is used only once in settings hierarchy. Templates are meant for reusing.
- schema must have
"name"
key which is name of schema that should be used
{
"type": "schema",
"name": "my_schema_name"
}
template
Templates are almost the same as schema items but can contain one or more items which can be formatted with additional data or some keys can be skipped if needed. Templates are meant for reusing the same schemas with ability to modify content.
- legacy name is
schema_template
(still usable) - template must have
"name"
key which is name of template file that should be used - to fill formatting keys use
"template_data"
- all items in template, except
__default_values__
, will replacetemplate
item in original schema - template may contain other templates
// Example template json file content
[
{
// Define default values for formatting values
// - gives ability to set the value but have default value
"__default_values__": {
"multipath_executables": true
}
}, {
"type": "raw-json",
"label": "{host_label} Environments",
"key": "{host_name}_environments"
}, {
"type": "path",
"key": "{host_name}_executables",
"label": "{host_label} - Full paths to executables",
"multiplatform": "{multipath_executables}",
"multipath": true
}
]
// Example usage of the template in schema
{
"type": "dict",
"key": "template_examples",
"label": "Schema template examples",
"children": [
{
"type": "template",
"name": "example_template",
"template_data": [
{
"host_label": "Maya 2019",
"host_name": "maya_2019",
"multipath_executables": false
},
{
"host_label": "Maya 2020",
"host_name": "maya_2020"
},
{
"host_label": "Maya 2021",
"host_name": "maya_2021"
}
]
}
]
}
// The same schema defined without templates
{
"type": "dict",
"key": "template_examples",
"label": "Schema template examples",
"children": [
{
"type": "raw-json",
"label": "Maya 2019 Environments",
"key": "maya_2019_environments"
}, {
"type": "path",
"key": "maya_2019_executables",
"label": "Maya 2019 - Full paths to executables",
"multiplatform": false,
"multipath": true
}, {
"type": "raw-json",
"label": "Maya 2020 Environments",
"key": "maya_2020_environments"
}, {
"type": "path",
"key": "maya_2020_executables",
"label": "Maya 2020 - Full paths to executables",
"multiplatform": true,
"multipath": true
}, {
"type": "raw-json",
"label": "Maya 2021 Environments",
"key": "maya_2021_environments"
}, {
"type": "path",
"key": "maya_2021_executables",
"label": "Maya 2021 - Full paths to executables",
"multiplatform": true,
"multipath": true
}
]
}
Template data can be used only to fill templates in values but not in keys. It is also possible to define default values for unfilled fields to do so one of the items in the list must be a dictionary with key "default_values"` and value as dictionary with default key: values (as in example above).
{
...
// Allowed
"key": "{to_fill}"
...
// Not allowed
"{to_fill}": "value"
...
}
Because formatting values can be only string it is possible to use formatting values which are replaced with different types.
// Template data
{
"template_data": {
"executable_multiplatform": {
"type": "schema",
"name": "my_multiplatform_schema"
}
}
}
// Template content
{
...
// Allowed - value is replaced with dictionary
"multiplatform": "{executable_multiplatform}"
...
// Not allowed - there is no way how it could be replaced
"multiplatform": "{executable_multiplatform}_enhanced_string"
...
}
dynamic_schema
Dynamic schema item marks a place in settings schema where schemas defined by BaseModuleSettingsDef
can be placed.
- example:
{
"type": "dynamic_schema",
"name": "project_settings/global"
}
BaseModuleSettingsDef
with implementedget_settings_schemas
can return a dictionary where key defines a dynamic schema name and value schemas that will be put there- dynamic schemas work almost the same way as templates
- one item can be replaced by multiple items (or by 0 items)
- goal is to dynamically load settings of OpenPype modules without having their schemas or default values in core repository
- values of these schemas are saved using the
BaseModuleSettingsDef
methods
- values of these schemas are saved using the
- we recommend to use
JsonFilesSettingsDef
which has full implementation of storing default values to json files- requires only to implement method
get_settings_root_path
which should return path to root directory where settings schema can be found and default values will be saved
- requires only to implement method
Basic Dictionary inputs
These inputs wraps another inputs into {key: value} relation
dict
- this is dictionary type wrapping more inputs with keys defined in schema
- may be used as dynamic children (e.g. in list or dict-modifiable)
- in that case the only key modifier is
children
which is a list of its keys - USAGE: e.g. List of dictionaries where each dictionary has the same structure.
- in that case the only key modifier is
- if is not used as dynamic children then must have defined
"key"
under which are it's values stored - may be with or without
"label"
(only for GUI)"label"
must be set to be able to mark item as group with"is_group"
key set to True
- item with label can visually wrap its children
- this option is enabled by default to turn off set
"use_label_wrap"
toFalse
- label wrap is by default collapsible
- that can be set with key
"collapsible"
toTrue
/False
- with key
"collapsed"
asTrue
/False
can be set that is collapsed when GUI is opened (Default:False
)
- that can be set with key
- it is possible to add lighter background with
"highlight_content"
(Default:False
)- lighter background has limits of maximum applies after 3-4 nested highlighted items there is not much difference in the color
- output is dictionary
{the "key": children values}
- this option is enabled by default to turn off set
// Example
{
"key": "applications",
"type": "dict",
"label": "Applications",
"collapsible": true,
"highlight_content": true,
"is_group": true,
"is_file": true,
"children": [
...ITEMS...
]
}
// Without label
{
"type": "dict",
"key": "global",
"children": [
...ITEMS...
]
}
// When used as widget
{
"type": "list",
"key": "profiles",
"label": "Profiles",
"object_type": {
"type": "dict",
"children": [
{
"key": "families",
"label": "Families",
"type": "list",
"object_type": "text"
}, {
"key": "hosts",
"label": "Hosts",
"type": "list",
"object_type": "text"
}
...
]
}
}
dict-roots
- entity can be used only in Project settings
- keys of dictionary are based on current project roots
- they are not updated "live" it is required to save root changes and then
modify values on this entity
TODO do live updates
{
"type": "dict-roots",
"key": "roots",
"label": "Roots",
"object_type": {
"type": "path",
"multiplatform": true,
"multipath": false
}
}
dict-conditional
- is similar to
dict
but has always available one enum entity- the enum entity has single selection and it's value define other children entities
- each value of enumerator have defined children that will be used
- there is no way how to have shared entities across multiple enum items
- value from enumerator is also stored next to other values
- to define the key under which will be enum value stored use
enum_key
enum_key
must match key regex and any enum item can't have children with same keyenum_label
is label of the entity for UI purposes
- to define the key under which will be enum value stored use
- enum items are define with
enum_children
- it's a list where each item represents single item for the enum
- all items in
enum_children
must have at leastkey
key which represents value stored underenum_key
- enum items can define
label
for UI purposes - most important part is that item can define
children
key where are definitions of it's children (children
value works the same way as indict
)
- to set default value for
enum_key
set it withenum_default
- entity must have defined
"label"
if is not used as widget - is set as group if any parent is not group (can't have children as group)
- may be with or without
"label"
(only for GUI)"label"
must be set to be able to mark item as group with"is_group"
key set to True
- item with label can visually wrap its children
- this option is enabled by default to turn off set
"use_label_wrap"
toFalse
- label wrap is by default collapsible
- that can be set with key
"collapsible"
toTrue
/False
- with key
"collapsed"
asTrue
/False
can be set that is collapsed when GUI is opened (Default:False
)
- that can be set with key
- it is possible to add lighter background with
"highlight_content"
(Default:False
)- lighter background has limits of maximum applies after 3-4 nested highlighted items there is not much difference in the color
- this option is enabled by default to turn off set
- for UI purposes was added
enum_is_horizontal
which will make combobox appear next to children inputs instead of on top of them (Default:False
)- this has extended ability of
enum_on_right
which will move combobox to right side next to children widgets (Default:False
)
- this has extended ability of
- output is dictionary
{the "key": children values}
- using this type as template item for list type can be used to create infinite hierarchies
// Example
{
"type": "dict-conditional",
"key": "my_key",
"label": "My Key",
"enum_key": "type",
"enum_label": "label",
"enum_children": [
// Each item must be a dictionary with 'key'
{
"key": "action",
"label": "Action",
"children": [
{
"type": "text",
"key": "key",
"label": "Key"
},
{
"type": "text",
"key": "label",
"label": "Label"
},
{
"type": "text",
"key": "command",
"label": "Command"
}
]
},
{
"key": "menu",
"label": "Menu",
"children": [
{
"key": "children",
"label": "Children",
"type": "list",
"object_type": "text"
}
]
},
{
// Separator does not have children as "separator" value is enough
"key": "separator",
"label": "Separator"
}
]
}
How output of the schema could look like on save:
{
"type": "separator"
}
{
"type": "action",
"key": "action_1",
"label": "Action 1",
"command": "run command -arg"
}
{
"type": "menu",
"children": [
"child_1",
"child_2"
]
}
Inputs for setting any kind of value (Pure
inputs)
- all inputs must have defined
"key"
if are not used as dynamic item- they can also have defined
"label"
- they can also have defined
boolean
- simple checkbox, nothing more to set
{
"type": "boolean",
"key": "my_boolean_key",
"label": "Do you want to use Pype?"
}
number
- number input, can be used for both integer and float
- key
"decimal"
defines how many decimal places will be used, 0 is for integer input (Default:0
) - key
"minimum"
as minimum allowed number to enter (Default:-99999
) - key
"maximum"
as maximum allowed number to enter (Default:99999
)
- key
- key
"steps"
will change single step value of UI inputs (using arrows and wheel scroll) - for UI it is possible to show slider to enable this option set
show_slider
totrue
{
"type": "number",
"key": "fps",
"label": "Frame rate (FPS)"
"decimal": 2,
"minimum": 1,
"maximum": 300000
}
{
"type": "number",
"key": "ratio",
"label": "Ratio"
"decimal": 3,
"minimum": 0,
"maximum": 1,
"show_slider": true
}
text
- simple text input
- key
"multiline"
allows to enter multiple lines of text (Default:False
) - key
"placeholder"
allows to show text inside input when is empty (Default:None
)
- key
{
"type": "text",
"key": "deadline_pool",
"label": "Deadline pool"
}
path-input
- Do not use this input in schema please (use
path
instead) - this input is implemented to add additional features to text input
- this is meant to be used in proxy input
path
raw-json
- a little bit enhanced text input for raw json
- can store dictionary (
{}
) or list ([]
) but not both- by default stores dictionary to change it to list set
is_list
toTrue
- by default stores dictionary to change it to list set
- has validations of json format
- output can be stored as string
- this is to allow any keys in dictionary
- set key
store_as_string
totrue
- code using that setting must expected that value is string and use json module to convert it to python types
{
"type": "raw-json",
"key": "profiles",
"label": "Extract Review profiles",
"is_list": true
}
enum
- enumeration of values that are predefined in schema
- multiselection can be allowed with setting key
"multiselection"
toTrue
(Default:False
) - values are defined under value of key
"enum_items"
as list- each item in list is simple dictionary where value is label and key is value which will be stored
- should be possible to enter single dictionary if order of items doesn't matter
- it is possible to set default selected value/s with
default
attribute- it is recommended to use this option only in single selection mode
- at the end this option is used only when defying default settings value or in dynamic items
{
"key": "tags",
"label": "Tags",
"type": "enum",
"multiselection": true,
"enum_items": [
{"burnin": "Add burnins"},
{"ftrackreview": "Add to Ftrack"},
{"delete": "Delete output"},
{"slate-frame": "Add slate frame"},
{"no-handles": "Skip handle frames"}
]
}
anatomy-templates-enum
- enumeration of all available anatomy template keys
- have only single selection mode
- it is possible to define default value
default
"work"
is used if default value is not specified
- enum values are not updated on the fly it is required to save templates and reset settings to recache values
{
"key": "host",
"label": "Host name",
"type": "anatomy-templates-enum",
"default": "publish"
}
hosts-enum
- enumeration of available hosts
- multiselection can be allowed with setting key
"multiselection"
toTrue
(Default:False
) - it is possible to add empty value (represented with empty string) with setting
"use_empty_value"
toTrue
(Default:False
) - it is possible to set
"custom_labels"
for host names where key""
is empty value (Default:{}
) - to filter host names it is required to define
"hosts_filter"
which is list of host names that will be available- do not pass empty string if
use_empty_value
is enabled - ignoring host names would be more dangerous in some cases
- do not pass empty string if
{
"key": "host",
"label": "Host name",
"type": "hosts-enum",
"multiselection": false,
"use_empty_value": true,
"custom_labels": {
"": "N/A",
"nuke": "Nuke"
},
"hosts_filter": [
"nuke"
]
}
apps-enum
- enumeration of available application and their variants from system settings
- applications without host name are excluded
- can be used only in project settings
- has only
multiselection
- used only in project anatomy
{
"type": "apps-enum",
"key": "applications",
"label": "Applications"
}
tools-enum
- enumeration of available tools and their variants from system settings
- can be used only in project settings
- has only
multiselection
- used only in project anatomy
{
"type": "tools-enum",
"key": "tools_env",
"label": "Tools"
}
task-types-enum
- enumeration of task types from current project
- enum values are not updated on the fly and modifications of task types on project require save and reset to be propagated to this enum
- has set
multiselection
toTrue
but can be changed toFalse
in schema
deadline_url-enum
- deadline module specific enumerator using deadline system settings to fill it's values
- TODO: move this type to deadline module
Inputs for setting value using Pure inputs
- these inputs also have required
"key"
- attribute
"label"
is required in few conditions- when item is marked
as_group
or whenuse_label_wrap
- when item is marked
- they use Pure inputs "as widgets"
list
- output is list
- items can be added and removed
- items in list must be the same type
- to wrap item in collapsible widget with label on top set
use_label_wrap
toTrue
- when this is used
collapsible
andcollapsed
can be set (same asdict
item does)
- when this is used
- type of items is defined with key
"object_type"
- there are 2 possible ways how to set the type:
1.) dictionary with item modifiers (
number
input hasminimum
,maximum
anddecimals
) in that case item type must be set as value of"type"
(example below) 2.) item type name as string without modifiers (e.g. text) 3.) enhancement of 1.) there is also support oftemplate
type but be careful about endless loop of templates- goal of using `template` is to easily change same item definitions in multiple lists
1.) with item modifiers
{
"type": "list",
"key": "exclude_ports",
"label": "Exclude ports",
"object_type": {
"type": "number", # number item type
"minimum": 1, # minimum modifier
"maximum": 65535 # maximum modifier
}
}
2.) without modifiers
{
"type": "list",
"key": "exclude_ports",
"label": "Exclude ports",
"object_type": "text"
}
3.) with template definition
// Schema of list item where template is used
{
"type": "list",
"key": "menu_items",
"label": "Menu Items",
"object_type": {
"type": "template",
"name": "template_object_example"
}
}
// WARNING:
// In this example the template use itself inside which will work in `list`
// but may cause an issue in other entity types (e.g. `dict`).
'template_object_example.json' :
[
{
"type": "dict-conditional",
"use_label_wrap": true,
"collapsible": true,
"key": "menu_items",
"label": "Menu items",
"enum_key": "type",
"enum_label": "Type",
"enum_children": [
{
"key": "action",
"label": "Action",
"children": [
{
"type": "text",
"key": "key",
"label": "Key"
}
]
}, {
"key": "menu",
"label": "Menu",
"children": [
{
"key": "children",
"label": "Children",
"type": "list",
"object_type": {
"type": "template",
"name": "template_object_example"
}
}
]
}
]
}
]
dict-modifiable
- one of dictionary inputs, this is only used as value input
- items in this input can be removed and added same way as in
list
input - value items in dictionary must be the same type
- required keys may be defined under
"required_keys"
- required keys must be defined as a list (e.g.
["key_1"]
) and are moved to the top - these keys can't be removed or edited (it is possible to edit label if item is collapsible)
- required keys must be defined as a list (e.g.
- type of items is defined with key
"object_type"
- there are 2 possible ways how to set the object type (Examples below):
- just a type name as string without modifiers (e.g.
"text"
) - full types with modifiers as dictionary(
number
input hasminimum
,maximum
anddecimals
) in that case item type must be set as value of"type"
- this input can be collapsible
"use_label_wrap"
must be set toTrue
(Default behavior)- that can be set with key
"collapsible"
asTrue
/False
(Default:True
)- with key
"collapsed"
asTrue
/False
can be set that is collapsed when GUI is opened (Default:False
)
- with key
- Object type without modifiers
{
"type": "dict-modifiable",
"object_type": "text",
"is_group": true,
"key": "templates_mapping",
"label": "Deadline - Templates mapping",
"is_file": true
}
- Object type with item modifiers
{
"type": "dict-modifiable",
"object_type": {
"type": "number",
"minimum": 0,
"maximum": 300
},
"is_group": true,
"key": "templates_mapping",
"label": "Deadline - Templates mapping",
"is_file": true
}
path
- input for paths, use
path-input
internally - has 2 input modifiers
"multiplatform"
and"multipath"
"multiplatform"
- adds"windows"
,"linux"
and"darwin"
path inputs (result is dictionary)"multipath"
- it is possible to enter multiple paths- if both are enabled result is dictionary with lists
{
"type": "path",
"key": "ffmpeg_path",
"label": "FFmpeg path",
"multiplatform": true,
"multipath": true
}
list-strict
- input for strict number of items in list
- each child item can be different type with different possible modifiers
- it is possible to display them in horizontal or vertical layout
- key
"horizontal"
asTrue
/False
(Default:True
)
- key
- each child may have defined
"label"
which is shown next to input- label does not reflect modifications or overrides (TODO)
- children item are defined under key
"object_types"
which is list of dictionaries- key
"children"
is not used because is used for hierarchy validations in schema
- key
- USAGE: For colors, transformations, etc. Custom number and different modifiers give ability to define if color is HUE or RGB, 0-255, 0-1, 0-100 etc.
{
"type": "list-strict",
"key": "color",
"label": "Color",
"object_types": [
{
"label": "Red",
"type": "number",
"minimum": 0,
"maximum": 255,
"decimal": 0
}, {
"label": "Green",
"type": "number",
"minimum": 0,
"maximum": 255,
"decimal": 0
}, {
"label": "Blue",
"type": "number",
"minimum": 0,
"maximum": 255,
"decimal": 0
}, {
"label": "Alpha",
"type": "number",
"minimum": 0,
"maximum": 1,
"decimal": 6
}
]
}
color
- pre implemented entity to store and load color values
- entity store and expect list of 4 integers in range 0-255
- integers represents rgba [Red, Green, Blue, Alpha]
- has modifier
"use_alpha"
which can beTrue
/False
- alpha is always
255
if set toTrue
and alpha slider is not visible in UI
- alpha is always
{
"type": "color",
"key": "bg_color",
"label": "Background Color"
}
Anatomy
Anatomy represents data stored on project document. Item cares about Project Anatomy.
anatomy
- entity is just enhanced dict item
- anatomy has always all keys overridden with overrides
Noninteractive items
Items used only for UI purposes.
label
- add label with note or explanations
- it is possible to use html tags inside the label
- set
work_wrap
totrue
/false
if you want to enable word wrapping in UI (default:false
)
{
"type": "label",
"label": "<span style=\"color:#FF0000\";>RED LABEL:</span> Normal label"
}
separator
- legacy name is
splitter
(still usable) - visual separator of items (more divider than separator)
{
"type": "separator"
}
Proxy wrappers
- should wrap multiple inputs only visually
- these do not have
"key"
key and do not allow to have"is_file"
or"is_group"
modifiers enabled - can't be used as a widget (first item in e.g.
list
,dict-modifiable
, etc.)
form
- wraps inputs into form look layout
- should be used only for Pure inputs
{
"type": "dict-form",
"children": [
{
"type": "text",
"key": "deadline_department",
"label": "Deadline apartment"
}, {
"type": "number",
"key": "deadline_priority",
"label": "Deadline priority"
}, {
...
}
]
}
collapsible-wrap
- wraps inputs into collapsible widget
- looks like
dict
but does not hold"key"
- looks like
- should be used only for Pure inputs
{
"type": "collapsible-wrap",
"label": "Collapsible example"
"children": [
{
"type": "text",
"key": "_example_input_collapsible",
"label": "Example input in collapsible wrapper"
}, {
...
}
]
}
How to add new settings
Always start with modifying or adding a new schema and don't worry about values. When you think schema is ready to use launch OpenPype settings in development mode using poetry run python ./start.py settings --dev
or prepared script in ~/openpype/tools/run_settings(.sh|.ps1)
. Settings opened in development mode have the checkbox Modify defaults
available in the bottom left corner. When checked default values are modified and saved on Save
. This is a recommended approach on how default settings should be created instead of direct modification of files.