userconfig
Handle reading and parsing, writing and saving of all user configurations.
This module handles the reading and writing of the pyRevit configuration files. It's been used extensively by pyRevit sub-modules. user_config is set up automatically in the global scope by this module and can be imported into scripts and other modules to access the default configurations.
All other modules use this module to query user config.
Examples:
from pyrevit.userconfig import user_config
user_config.add_section('newsection')
user_config.newsection.property = value
user_config.newsection.get_option('property', default_value)
user_config.save_changes()
The user_config object is also the destination for reading and writing
configuration by pyRevit scripts through pyrevit.script.get_config.
Examples:
from pyrevit import script
cfg = script.get_config()
cfg.property = value
cfg.get_option('property', default_value)
script.save_config()
Typed section access is the canonical way to reach the built-in settings.
The core, routes, and telemetry properties expose the strongly-typed
sections backed by the shared configuration service, so a setting is read and
written by its section and its C# property name:
Examples:
The flat snake_case accessors (e.g. user_config.rocket_mode) are aliases
over these sections. They are frozen, not deprecated: they keep working
for reads and writes indefinitely, none is scheduled for removal, and no new
one may be added. That is a decision, not an oversight - see
docs/config-api.md for the naming contract, the full alias inventory, and
the reasoning.
Important: a typed section falls back to a raw option for any name the C#
schema does not declare, on read and on write alike. So
user_config.core.rocket_mode = True stores a raw key named rocket_mode in a
section whose real key is rocketmode; it does not raise, and it leaves
RocketMode untouched. Use the PascalCase property name, or set_option for a
key the schema has no property for.
Examples:
user_config.core.set_option("my_key", value) # explicit: raw option
user_config.core.my_key # reads it back
add_section/get_section and the per-section get_option/set_option are
the escape hatch for anything outside the typed schema, and
pyrevit.coreutils.configparser.open_config_file covers a tool's own ini.
Attributes
DEFAULT_CSV_SEPARATOR = ','
module-attribute
mlogger = logger.get_logger(__name__)
module-attribute
CONSTS = PyRevit.PyRevitConsts
module-attribute
Re-exported for extensions that do from pyrevit.userconfig import CONSTS.
user_config = _build_user_config()
module-attribute
Classes
PyRevitConfig(config_service)
Bases: object
Provide read/write access to pyRevit configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config_service
|
IConfigurationService
|
configuration service to start from. Access resolves against the shared service the store hands out, falling back to this one while the store is unreachable. |
required |
Examples:
cfg = PyRevitConfig(config_service)
cfg.add_section('sectionname')
cfg.sectionname.property = value
cfg.sectionname.get_option('property', default_value)
cfg.save_changes()
Store an accessor for config_service, not the service itself.
Sections handed to scripts hold a bound method, so they follow a later reload instead of continuing to read a replaced service whose edits are never flushed.
Source code in pyrevitlib/pyrevit/userconfig.py
Attributes
config_sections = ConfigSections(self._current_config_service)
instance-attribute
config_service
property
IConfigurationService: shared service backing this configuration.
config_file
property
Path of the config file backing this configuration.
This is the file the service resolved on load, which may be a read-only all-users config.
environment
property
Environment section.
core
property
Core section (supports .get_option/.set_option for extension compat).
routes
property
Routes section (supports .get_option/.set_option for extension compat).
telemetry
property
Telemetry section (supports .get_option/.set_option for extension compat).
bin_cache
property
writable
Whether to use the cache for extensions.
check_updates
property
writable
Whether to check for updates.
auto_update
property
writable
Whether to automatically update pyRevit.
rocket_mode
property
writable
Whether to enable rocket mode.
log_level
property
writable
Logging level.
file_logging
property
writable
Whether to enable file logging.
startuplog_timeout
property
writable
Timeout for the startup log.
required_host_build
property
writable
Host build required to run the commands.
min_host_drivefreespace
property
writable
Minimum free space for running the commands.
load_beta
property
writable
Whether to load commands in beta.
read_script_metadata
property
writable
Whether to read script metadata (title, author, etc) from Python scripts.
When False, pyRevit will skip reading metadata from .py script files and will only use values from bundle.yaml. This improves startup performance but may affect commands that rely on script-level metadata.
output_close_others
property
writable
Whether to close other output windows.
output_close_mode_enum
property
writable
Output window closing mode as enum (CurrentCommand | CloseAll).
cpython_engine_version
property
writable
CPython engine version to use.
user_locale
property
writable
User locale.
output_stylesheet
property
writable
Stylesheet used for output.
routes_host
property
writable
Routes API host.
routes_port
property
writable
API routes port.
load_core_api
property
writable
Whether to load pyRevit core api.
telemetry_utc_timestamp
property
writable
Whether to use UTC timestamps in telemetry.
telemetry_status
property
writable
Telemetry status.
telemetry_file_dir
property
writable
Telemetry file directory.
telemetry_server_url
property
writable
Telemetry server URL.
telemetry_include_hooks
property
writable
Whether to include hooks in telemetry.
apptelemetry_status
property
writable
App telemetry status.
apptelemetry_server_url
property
writable
App telemetry server URL.
apptelemetry_event_flags
property
writable
App telemetry event flags.
user_can_update
property
writable
Whether the user can update pyRevit repos.
user_can_extend
property
writable
Whether the user can manage pyRevit Extensions.
user_can_config
property
writable
Whether the user can access the configuration.
colorize_docs
property
writable
Whether to enable the document colorizer.
tooltip_debug_info
property
writable
Whether to append debug info on tooltips.
routes_server
property
writable
Whether the server routes are enabled.
agent_enabled
property
writable
Whether the agent host (MCP) starts on the next pyRevit load.
The agent host is independent of the routes server: it listens on a current-user named pipe, never on the network.
Note
The setters write the config file immediately, through the same
accessors the agent host and the pyrevit CLI use.
agent_policy
property
writable
What agent runs may do.
readonly allows queries and dry runs only, ask needs approval in
Revit for every change, and auto commits changes without the prompt.
agent_engine
property
writable
Script engine for agent runs that don't name one: ironpython or cpython.
agent_user_skills_enabled
property
writable
Whether the MCP server loads user-authored skills for this user.
User skills are trusted-account guidance. They cannot replace shipped skills or relax host policy.
is_readonly
property
bool: whether the config is read only.
config_type
property
str: "Admin" for a read-only admin config, "User" otherwise.
Methods:
get_thirdparty_ext_root_dirs(include_default=True)
Return a list of external extension directories set by the user.
Ordering is deterministic: the default path first, then config-file order, with duplicates removed. User paths are resolved through the shared C# core so the loader and CLI agree on normalization and existence.
Returns:
| Type | Description |
|---|---|
list[str]
|
External user extension directories. |
Source code in pyrevitlib/pyrevit/userconfig.py
get_ext_root_dirs()
Return a list of all extension directories.
Returns:
| Type | Description |
|---|---|
list[str]
|
user extension directories. |
Source code in pyrevitlib/pyrevit/userconfig.py
get_ext_sources()
set_thirdparty_ext_root_dirs(path_list)
Updates list of external extension directories in config file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path_list
|
list[str]
|
list of external extension paths |
required |
Source code in pyrevitlib/pyrevit/userconfig.py
get_current_attachment(cached=True)
Return current pyRevit attachment.
The shared C# attachment cache lets all script engines reuse a single disk lookup. Cleared on reload and on Attach/Detach/clone changes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cached
|
bool
|
set False to bypass the session cache when the attachment may have changed out of process. |
True
|
Source code in pyrevitlib/pyrevit/userconfig.py
get_active_cpython_engine()
Return the user's configured CPython engine, or the latest available.
Falls back to a temp clone at HOME_DIR when there's no attachment, and to the highest-versioned engine when the configured version isn't among the clone's available engines.
Source code in pyrevitlib/pyrevit/userconfig.py
set_active_cpython_engine(pyrevit_engine)
Set the active CPython engine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pyrevit_engine
|
PyRevitEngine
|
python engine to set as active |
required |
save_changes()
Flush the in-memory config to disk.
Typed and dynamic section edits are already written through to the in-memory store as they happen; this just flushes the whole default config to disk once. A failed write is logged rather than raised: settings are not worth aborting a session load or a settings dialog over. The error is logged against the path from _get_default_config() directly, since the config_file property falls back to a path helper that creates files on disk, which must not run from an error handler.
Source code in pyrevitlib/pyrevit/userconfig.py
reload()
Reload configuration from disk, discarding unsaved in-memory edits.
Drops the cached shared service so the next access re-reads from disk across every consumer, not just this object.
Source code in pyrevitlib/pyrevit/userconfig.py
get_list_separator()
staticmethod
Get list separator defined in user os regional settings.
Source code in pyrevitlib/pyrevit/userconfig.py
has_section(section_name)
Check if the config contains the given section.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
section_name
|
str
|
name of the section |
required |
Returns:
| Type | Description |
|---|---|
bool
|
whether the section exists |
Source code in pyrevitlib/pyrevit/userconfig.py
add_section(section_name)
Add a new section to the config.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
section_name
|
str
|
name of the section |
required |
Returns:
| Type | Description |
|---|---|
ConfigSection
|
the added section |
Source code in pyrevitlib/pyrevit/userconfig.py
get_section(section_name)
Get the named config section.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
section_name
|
str
|
name of the section |
required |
Returns:
| Type | Description |
|---|---|
ConfigSection
|
the requested section |
Raises:
| Type | Description |
|---|---|
AttributeError
|
if the section does not exist |
Source code in pyrevitlib/pyrevit/userconfig.py
remove_section(section_name)
Remove the named section, and its subsections, from the config.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
section_name
|
str
|
name of the section |
required |