-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* build: Update dependencies and ruff settings * feat: Add io functions for reading config files * feat: Add function for loading a config * test: Add test cases for io functions * feat: Add safe loading of config * feat Add test cases for config module * docs: Add section on config files to README * chore: Add ruff cache to .gitignore * refactor: Rename get and set function in config.py * style: Use pattern matching instead of if-statements * docs: Update package docstring * refactor: Remove file-existence check * fix: Fix pyright issues
- Loading branch information
1 parent
2c9bbcc
commit 7f24587
Showing
12 changed files
with
592 additions
and
15 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -163,4 +163,7 @@ cython_debug/ | |
#.idea/ | ||
|
||
# Test data | ||
!tests/data/.env | ||
!tests/data/.env | ||
|
||
# Ruff | ||
.ruff_cache |
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
Large diffs are not rendered by default.
Oops, something went wrong.
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 |
---|---|---|
@@ -1,17 +1,40 @@ | ||
"""Pit-viper offers configuration management capabilities. | ||
This package currently provides one main function, `auto_env`, | ||
which reads a `.env` file and sets the corresponding environment | ||
variables in the current process. This can be useful for configuring | ||
applications or scripts that rely on environment variables. | ||
This package supports accessing parameters from environment variables, | ||
and configuration files. | ||
Usage: | ||
>>> from pit import viper | ||
>>> from pathlib import Path | ||
>>> | ||
>>> viper.auto_env() | ||
>>> | ||
>>> viper.set_config_path(Path() / "config") | ||
>>> viper.set_config_name("my_config") | ||
>>> viper.set_config_type("toml") | ||
>>> viper.set("foo", "default-value") | ||
>>> | ||
>>> viper.load_config() | ||
>>> foo = viper.get("foo") | ||
For more information, see the documentation for the `auto_env` | ||
function. | ||
For more information, see the https://github.com/leoschleier/pit-viper. | ||
""" | ||
from pit.viper.config import get_conf as get | ||
from pit.viper.config import ( | ||
load_config, | ||
set_config_name, | ||
set_config_path, | ||
set_config_type, | ||
) | ||
from pit.viper.config import set_conf as set # noqa: A001 | ||
from pit.viper.env import auto_env | ||
|
||
__all__ = ["auto_env"] | ||
__all__ = [ | ||
"auto_env", | ||
"get", | ||
"load_config", | ||
"set", | ||
"set_config_name", | ||
"set_config_path", | ||
"set_config_type", | ||
] |
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,94 @@ | ||
"""Internal IO functions for viper.""" | ||
import json | ||
import tomllib | ||
from pathlib import Path | ||
from typing import Any | ||
|
||
import yaml | ||
|
||
|
||
def read_config(path: Path) -> dict[str, Any]: | ||
"""Read a config file. | ||
This function supports configs from JSON, TOML, and YAML files. | ||
Parameters | ||
---------- | ||
path : Path | ||
Path to the config file. | ||
Returns | ||
------- | ||
dict[str, Any] | ||
Config | ||
Raises | ||
------ | ||
ValueError | ||
Raised if the config file extension is not supported. | ||
""" | ||
file_extension = path.suffix if path.suffix else path.name | ||
|
||
match file_extension: | ||
case ".json": | ||
return _read_json(path) | ||
case ".toml": | ||
return _read_toml(path) | ||
case ".yml" | ".yaml": | ||
return _read_yaml(path) | ||
case _: | ||
msg = f"Config file extension {file_extension} not supported." | ||
raise ValueError(msg) | ||
|
||
|
||
|
||
|
||
def _read_json(path: Path) -> dict[str, Any]: | ||
"""Read a JSON file. | ||
Parameters | ||
---------- | ||
path : Path | ||
Path to the JSON file. | ||
Returns | ||
------- | ||
dict[str, Any] | ||
JSON file contents. | ||
""" | ||
with path.open("rb") as stream: | ||
return json.load(stream) | ||
|
||
|
||
def _read_toml(path: Path) -> dict[str, Any]: | ||
"""Read a TOML file. | ||
Parameters | ||
---------- | ||
path : Path | ||
Path to the TOML file. | ||
Returns | ||
------- | ||
dict[str, Any] | ||
TOML file contents. | ||
""" | ||
with path.open("rb") as stream: | ||
return tomllib.load(stream) | ||
|
||
|
||
def _read_yaml(path: Path) -> dict[str, Any]: | ||
"""Read a YAML file. | ||
Parameters | ||
---------- | ||
path : Path | ||
Path to the YAML file. | ||
Returns | ||
------- | ||
dict[str, Any] | ||
YAML file contents. | ||
""" | ||
with path.open("rb") as stream: | ||
return yaml.safe_load(stream) |
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,135 @@ | ||
"""Load config from file.""" | ||
from pathlib import Path | ||
from typing import Any | ||
|
||
from pit.viper import _io | ||
|
||
_config_path: Path | None = None | ||
_config_name: str = "" | ||
_config_type: str = "" | ||
_config: dict[str, Any] = {} | ||
|
||
|
||
def set_config_name(name: str) -> None: | ||
"""Set the config name. | ||
Parameters | ||
---------- | ||
name : str | ||
Name of the config file. | ||
""" | ||
global _config_name # noqa: PLW0603 | ||
_config_name = name | ||
|
||
|
||
def set_config_path(path: Path) -> None: | ||
"""Set the config path. | ||
Parameters | ||
---------- | ||
path : Path | ||
Path to the config file or the directory containing the config | ||
file. | ||
""" | ||
global _config_path # noqa: PLW0603 | ||
_config_path = path | ||
|
||
|
||
def set_config_type(type_: str) -> None: | ||
"""Set the config type. | ||
Supported config formats: json, toml, yaml, yml. | ||
Parameters | ||
---------- | ||
type_ : str | ||
Config format. | ||
""" | ||
global _config_type # noqa: PLW0603 | ||
_config_type = type_.lower() | ||
|
||
|
||
def get_conf(key: str, default: Any = None) -> Any: | ||
"""Get a value from the config. | ||
Parameters | ||
---------- | ||
key : str | ||
Key to get the value for. | ||
default : Any, optional | ||
Default value to return if the key is not found, by default None | ||
Returns | ||
------- | ||
Any | ||
Value for the key. | ||
""" | ||
keys = key.split(".") | ||
value = _config | ||
|
||
for k in keys: | ||
if isinstance(value, dict): | ||
value = value.get(k, default) | ||
|
||
return value | ||
|
||
|
||
def set_conf(key: str, value: Any) -> None: | ||
"""Set a value in the config. | ||
Parameters | ||
---------- | ||
key : str | ||
Key to set the value for. | ||
value : Any | ||
Value to set. | ||
""" | ||
keys = key.split(".") | ||
config = _config | ||
|
||
for k in keys[:-1]: | ||
if isinstance(config, dict): | ||
config = config.setdefault(k, {}) | ||
|
||
config[keys[-1]] = value | ||
|
||
|
||
def load_config() -> None: | ||
"""Load the config from the config file. | ||
Raises | ||
------ | ||
FileNotFoundError | ||
Raised if the config path is not set or the path does not exist. | ||
""" | ||
if not _config_path: | ||
msg = "Config path not set." | ||
raise FileNotFoundError(msg) | ||
|
||
config_file = ( | ||
f"{_config_name}.{_config_type}" if _config_type else _config_name | ||
) | ||
config_path = _config_path / config_file | ||
|
||
config = _io.read_config(config_path) | ||
for key, value in config.items(): | ||
_safe_set(key, value) | ||
|
||
|
||
def _safe_set(key: str, value: Any) -> None: | ||
"""Set a value in the config without overwriting nested defaults. | ||
Parameters | ||
---------- | ||
key : str | ||
Key to set the value for. | ||
value : Any | ||
Value to set. | ||
""" | ||
if isinstance(value, dict): | ||
for k, v in value.items(): # pyright: ignore [reportUnknownVariableType] | ||
_safe_set(f"{key}.{k}", v) | ||
else: | ||
set_conf(key, value) | ||
|
||
|
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,11 @@ | ||
{ | ||
"foo": "bar", | ||
"test": { | ||
"nested": { | ||
"a": 0, | ||
"b": 1.1, | ||
"c": true, | ||
"d": "test-string" | ||
} | ||
} | ||
} |
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 @@ | ||
foo = "bar" | ||
|
||
[test] | ||
[test.nested] | ||
a = 0 | ||
b = 1.1 | ||
c = true | ||
d = "test-string" |
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 @@ | ||
foo: bar | ||
|
||
test: | ||
nested: | ||
a: 0 | ||
b: 1.1 | ||
c: true | ||
d: test-string |
Oops, something went wrong.