configaroo 0.4.0__py3-none-any.whl → 0.4.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
configaroo/__init__.py CHANGED
@@ -1,6 +1,10 @@
1
1
  """Bouncy configuration handling."""
2
2
 
3
- from configaroo.configuration import Configuration, print_configuration
3
+ from configaroo.configuration import (
4
+ Configuration,
5
+ find_pyproject_toml,
6
+ print_configuration,
7
+ )
4
8
  from configaroo.exceptions import (
5
9
  ConfigarooError,
6
10
  MissingEnvironmentVariableError,
@@ -12,7 +16,8 @@ __all__ = [
12
16
  "Configuration",
13
17
  "MissingEnvironmentVariableError",
14
18
  "UnsupportedLoaderError",
19
+ "find_pyproject_toml",
15
20
  "print_configuration",
16
21
  ]
17
22
 
18
- __version__ = "0.4.0"
23
+ __version__ = "0.4.2"
@@ -6,6 +6,7 @@ import re
6
6
  from collections import UserDict
7
7
  from collections.abc import Callable
8
8
  from pathlib import Path
9
+ from types import UnionType
9
10
  from typing import Any, Self, TypeVar
10
11
 
11
12
  from pydantic import BaseModel
@@ -99,30 +100,6 @@ class Configuration(UserDict[str, Any]):
99
100
  cls = type(self)
100
101
  return self | {prefix: cls(self.setdefault(prefix, {})).add(rest, value)}
101
102
 
102
- def add_envs(self, envs: dict[str, str] | None = None, prefix: str = "") -> Self:
103
- """Add environment variables to configuration.
104
-
105
- If you don't specify which environment variables to read, you'll
106
- automatically add any that matches a top-level value of the
107
- configuration.
108
- """
109
- if envs is None:
110
- # Automatically add top-level configuration items
111
- envs = {
112
- re.sub(r"\W", "_", key).upper(): key
113
- for key, value in self.data.items()
114
- if isinstance(value, str | int | float)
115
- }
116
-
117
- # Read environment variables
118
- for env, key in envs.items():
119
- env_key = f"{prefix}{env}"
120
- if env_value := os.getenv(env_key):
121
- self = self.add(key, env_value) # noqa: PLW0642
122
- elif key not in self:
123
- raise MissingEnvironmentVariableError(env_key)
124
- return self
125
-
126
103
  def parse_dynamic(
127
104
  self, extra: dict[str, Any] | None = None, *, _include_self: bool = True
128
105
  ) -> Self:
@@ -150,6 +127,60 @@ class Configuration(UserDict[str, Any]):
150
127
  # Continue parsing until no more replacements are made.
151
128
  return parsed.parse_dynamic(extra=extra, _include_self=_include_self)
152
129
 
130
+ def add_envs(self, envs: dict[str, str] | None = None, prefix: str = "") -> Self:
131
+ """Add environment variables to configuration.
132
+
133
+ If you don't specify which environment variables to read, you'll
134
+ automatically add any that matches a simple top-level value of the
135
+ configuration.
136
+ """
137
+ if envs is None:
138
+ # Automatically add top-level configuration items
139
+ envs = {
140
+ re.sub(r"\W", "_", key).upper(): key
141
+ for key, value in self.data.items()
142
+ if isinstance(value, str | int | float)
143
+ }
144
+
145
+ # Read environment variables
146
+ for env, key in envs.items():
147
+ env_key = f"{prefix}{env}"
148
+ if env_value := os.getenv(env_key):
149
+ self = self.add(key, env_value) # noqa: PLW0642
150
+ elif key not in self:
151
+ raise MissingEnvironmentVariableError(env_key)
152
+ return self
153
+
154
+ def add_envs_from_model(
155
+ self,
156
+ model: type[BaseModel],
157
+ prefix: str = "",
158
+ types: type | UnionType = str | bool | int | float,
159
+ ) -> Self:
160
+ """Add environment variables to configuration based on the given model.
161
+
162
+ Top level string, bool, integer, and float fields from the model are
163
+ looked for among environment variables.
164
+ """
165
+
166
+ def _get_class_from_annotation(annotation: type) -> type:
167
+ """Unpack generic annotations and return the underlying class."""
168
+ return (
169
+ _get_class_from_annotation(annotation.__origin__)
170
+ if hasattr(annotation, "__origin__")
171
+ else annotation
172
+ )
173
+
174
+ envs = {
175
+ re.sub(r"\W", "_", key).upper(): key
176
+ for key, field in model.model_fields.items()
177
+ if (
178
+ field.annotation is not None
179
+ and issubclass(_get_class_from_annotation(field.annotation), types)
180
+ )
181
+ }
182
+ return self.add_envs(envs, prefix=prefix)
183
+
153
184
  def validate_model(self, model: type[BaseModel]) -> Self:
154
185
  """Validate the configuration against the given model."""
155
186
  model.model_validate(self.data)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: configaroo
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Bouncy handling of configuration files
5
5
  Author-email: Geir Arne Hjelle <geirarne@gmail.com>
6
6
  Maintainer-email: Geir Arne Hjelle <geirarne@gmail.com>
@@ -1,12 +1,12 @@
1
- configaroo/__init__.py,sha256=zlCtdtE7UWy7SWKYq_NfGX0uUvO8l5-xRj1mB1Bn3Ac,412
2
- configaroo/configuration.py,sha256=hMo9INlvD3OwjYeK0PJpun8T8x6wfAl8t1ZM2_EaqvY,9823
1
+ configaroo/__init__.py,sha256=rzq0iqqBuc--QB3yBM4dA6LYLAdLuviKwqeUzfcjCs0,477
2
+ configaroo/configuration.py,sha256=1tGBLkyz703txcaGx49kWHMiVYgjTcERnikVQ69Pusc,10928
3
3
  configaroo/exceptions.py,sha256=GfLf3CLfHStiQjvdS7ZAtrKF9gmGL_8biFLayue6J0M,772
4
4
  configaroo/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  configaroo/loaders/__init__.py,sha256=XQrFwCMWzQ71ykaZFPmYysDz12y_elPqxWhUMQCsq3s,1076
6
6
  configaroo/loaders/json.py,sha256=fT2Lg4hPM2BuwqrDsP7bcJlepAdmEh2iKU-YVK4KmIA,306
7
7
  configaroo/loaders/toml.py,sha256=jw9U78Lf-GMA8QmGIM8xMBqOhPaa8ITSMAhhN1ZNyng,256
8
- configaroo-0.4.0.dist-info/licenses/LICENSE,sha256=rdeT6Y5bm0MUaERso7HRWpPj37Y1RD5li2lIQaMNJjc,1090
9
- configaroo-0.4.0.dist-info/METADATA,sha256=6527XCdJ8w6eo3v693VifE-AzR1ZUw4tCGeSEXAomUs,2672
10
- configaroo-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
- configaroo-0.4.0.dist-info/top_level.txt,sha256=JVYICl1cWSjvSOZuZMYm976z9lnZaWtHVRSt373QCxg,11
12
- configaroo-0.4.0.dist-info/RECORD,,
8
+ configaroo-0.4.2.dist-info/licenses/LICENSE,sha256=rdeT6Y5bm0MUaERso7HRWpPj37Y1RD5li2lIQaMNJjc,1090
9
+ configaroo-0.4.2.dist-info/METADATA,sha256=i3TOmbmkG6e85-OGWqNK_sKC6CCBmjhlj8vtbreGVL8,2672
10
+ configaroo-0.4.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
+ configaroo-0.4.2.dist-info/top_level.txt,sha256=JVYICl1cWSjvSOZuZMYm976z9lnZaWtHVRSt373QCxg,11
12
+ configaroo-0.4.2.dist-info/RECORD,,