-
Notifications
You must be signed in to change notification settings - Fork 190
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Engine configuration utility (#1828)
* Create the configuration utility * Gen header. * Fix types test. * Add test. * Fix test types. * Update config to take in file locations. * Ensure the ini config file is included. * Add missing docstring and formatting * Fix ambiguity with smarts and smarts.core.smarts * Update documentation * Update docs/sim/configuration.rst Co-authored-by: adai <[email protected]> * Move sim configuration to next steps. * Assign pybullet frequency to make clear. * Update docs/sim/configuration.rst Co-authored-by: Saul Field <[email protected]> --------- Co-authored-by: adai <[email protected]> Co-authored-by: Saul Field <[email protected]>
- Loading branch information
1 parent
4dae72c
commit 41ec4b7
Showing
16 changed files
with
346 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.. _todo: | ||
|
||
TODO List | ||
========= | ||
|
||
A list of current documentation TODO. | ||
|
||
.. todolist_:: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
.. _configuration: | ||
|
||
Configuration | ||
============= | ||
|
||
You can change the behavior of the underlying SMARTS engine. | ||
|
||
Configuration of the engine can come from several sources. These locations take precedence as noted: | ||
|
||
1. Individual ``SMARTS_`` prefixed environment variables (e.g. ``SMARTS_SENSOR_WORKER_COUNT``) | ||
2. Local directory engine configuration (./smarts_engine.ini ) | ||
3. Local user engine configuration, ``~/.smarts/engine.ini``, if local directory configuration is not found. | ||
4. Global engine configuration, ``/etc/smarts/engine.ini``, if local configuration is not found. | ||
5. Package default configuration, ``$PYTHON_PATH/smarts/engine.ini``, if global configuration is not found. | ||
|
||
Note that configuration files resolve all settings at the first found configuration file (they do not layer.) | ||
|
||
Options | ||
------- | ||
|
||
All settings demonstrated as environment variables are formatted to ``UPPERCASE`` and prefixed with ``SMARTS_`` (e.g. ``[core] logging`` can be configured with ``SMARTS_CORE_LOGGING``) | ||
|
||
These settings are as follows: | ||
|
||
.. todo:: | ||
|
||
List engine settings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# MIT License | ||
# | ||
# Copyright (C) 2023. Huawei Technologies Co., Ltd. All rights reserved. | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy | ||
# of this software and associated documentation files (the "Software"), to deal | ||
# in the Software without restriction, including without limitation the rights | ||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
# copies of the Software, and to permit persons to whom the Software is | ||
# furnished to do so, subject to the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be included in | ||
# all copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE | ||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
# THE SOFTWARE. | ||
import configparser | ||
import functools | ||
import os | ||
from pathlib import Path | ||
from typing import Any, Callable, Optional, Union | ||
|
||
_UNSET = object() | ||
|
||
|
||
class Config: | ||
"""A configuration utility that handles configuration from file and environment variable. | ||
Args: | ||
config_file (Union[str, Path]): The path to the configuration file. | ||
environment_prefix (str, optional): The prefix given to the environment variables. Defaults to "". | ||
Raises: | ||
FileNotFoundError: If the configuration file cannot be found at the given file location. | ||
""" | ||
|
||
def __init__( | ||
self, config_file: Union[str, Path], environment_prefix: str = "" | ||
) -> None: | ||
self._config = configparser.ConfigParser( | ||
interpolation=configparser.ExtendedInterpolation() | ||
) | ||
self._environment_prefix = environment_prefix.upper() | ||
self._environment_variable_format_string = self._environment_prefix + "_{}_{}" | ||
|
||
if isinstance(config_file, str): | ||
config_file = Path(config_file) | ||
config_file = config_file.resolve() | ||
if not config_file.is_file(): | ||
raise FileNotFoundError(f"Configuration file not found at {config_file}") | ||
|
||
self._config.read(str(config_file.absolute())) | ||
|
||
@property | ||
def environment_prefix(self): | ||
"""The prefix that environment variables configuration is provided with.""" | ||
return self._environment_prefix | ||
|
||
@functools.lru_cache(maxsize=100) | ||
def get_setting( | ||
self, | ||
section: str, | ||
option: str, | ||
default: Any = _UNSET, | ||
cast: Callable[[str], Any] = str, | ||
) -> Optional[Any]: | ||
"""Finds the given configuration checking the following in order: environment variable, | ||
configuration file, and default. | ||
Args: | ||
section (str): The grouping that the configuration option is under. | ||
option (str): The specific configuration option. | ||
default (Any, optional): The default if the requested configuration option is not found. Defaults to _UNSET. | ||
cast (Callable, optional): A function that takes a string and returns the desired type. Defaults to str. | ||
Returns: | ||
Optional[str]: The value of the configuration. | ||
Raises: | ||
KeyError: If the configuration option is not found in the configuration file and no default is provided. | ||
configparser.NoSectionError: If the section in the configuration file is not found and no default is provided. | ||
""" | ||
env_variable = self._environment_variable_format_string.format( | ||
section.upper(), option.upper() | ||
) | ||
setting = os.getenv(env_variable) | ||
if setting is not None: | ||
return cast(setting) | ||
try: | ||
value = self._config[section][option] | ||
except (configparser.NoSectionError, KeyError): | ||
if default is _UNSET: | ||
raise | ||
return default | ||
return cast(value) | ||
|
||
def __call__( | ||
self, | ||
section: str, | ||
option: str, | ||
default: Any = _UNSET, | ||
cast: Callable[[str], Any] = str, | ||
) -> Optional[Any]: | ||
return self.get_setting(section, option, default, cast) | ||
|
||
def __repr__(self) -> str: | ||
return f"Config(config_file={ {k: dict(v.items()) for k, v in self._config.items(raw=True)} }, environment_prefix={self._environment_prefix})" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.