fmu-settings 0.5.2__py3-none-any.whl → 0.5.4__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.
Potentially problematic release.
This version of fmu-settings might be problematic. Click here for more details.
- fmu/settings/_fmu_dir.py +23 -3
- fmu/settings/_resources/cache_manager.py +149 -0
- fmu/settings/_resources/lock_manager.py +33 -17
- fmu/settings/_resources/pydantic_resource_manager.py +11 -2
- fmu/settings/_version.py +2 -2
- {fmu_settings-0.5.2.dist-info → fmu_settings-0.5.4.dist-info}/METADATA +1 -1
- {fmu_settings-0.5.2.dist-info → fmu_settings-0.5.4.dist-info}/RECORD +10 -9
- {fmu_settings-0.5.2.dist-info → fmu_settings-0.5.4.dist-info}/WHEEL +0 -0
- {fmu_settings-0.5.2.dist-info → fmu_settings-0.5.4.dist-info}/licenses/LICENSE +0 -0
- {fmu_settings-0.5.2.dist-info → fmu_settings-0.5.4.dist-info}/top_level.txt +0 -0
fmu/settings/_fmu_dir.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""Main interface for working with .fmu directory."""
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Any, Final, Self, TypeAlias, cast
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Final, Self, TypeAlias, cast
|
|
5
5
|
|
|
6
6
|
from ._logging import null_logger
|
|
7
|
+
from ._resources.cache_manager import CacheManager
|
|
7
8
|
from ._resources.config_managers import (
|
|
8
9
|
ProjectConfigManager,
|
|
9
10
|
UserConfigManager,
|
|
@@ -22,6 +23,7 @@ class FMUDirectoryBase:
|
|
|
22
23
|
|
|
23
24
|
config: FMUConfigManager
|
|
24
25
|
_lock: LockManager
|
|
26
|
+
_cache_manager: CacheManager
|
|
25
27
|
|
|
26
28
|
def __init__(self: Self, base_path: str | Path) -> None:
|
|
27
29
|
"""Initializes access to a .fmu directory.
|
|
@@ -38,6 +40,7 @@ class FMUDirectoryBase:
|
|
|
38
40
|
self.base_path = Path(base_path).resolve()
|
|
39
41
|
logger.debug(f"Initializing FMUDirectory from '{base_path}'")
|
|
40
42
|
self._lock = LockManager(self)
|
|
43
|
+
self._cache_manager = CacheManager(self, max_revisions=5)
|
|
41
44
|
|
|
42
45
|
fmu_dir = self.base_path / ".fmu"
|
|
43
46
|
if fmu_dir.exists():
|
|
@@ -57,6 +60,21 @@ class FMUDirectoryBase:
|
|
|
57
60
|
"""Returns the path to the .fmu directory."""
|
|
58
61
|
return self._path
|
|
59
62
|
|
|
63
|
+
@property
|
|
64
|
+
def cache(self: Self) -> CacheManager:
|
|
65
|
+
"""Access the cache manager."""
|
|
66
|
+
return self._cache_manager
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def cache_max_revisions(self: Self) -> int:
|
|
70
|
+
"""Current retention limit for revision snapshots."""
|
|
71
|
+
return self._cache_manager.max_revisions
|
|
72
|
+
|
|
73
|
+
@cache_max_revisions.setter
|
|
74
|
+
def cache_max_revisions(self: Self, value: int) -> None:
|
|
75
|
+
"""Update the retention limit for revision snapshots."""
|
|
76
|
+
self._cache_manager.max_revisions = value
|
|
77
|
+
|
|
60
78
|
def get_config_value(self: Self, key: str, default: Any = None) -> Any:
|
|
61
79
|
"""Gets a configuration value by key.
|
|
62
80
|
|
|
@@ -214,7 +232,8 @@ class FMUDirectoryBase:
|
|
|
214
232
|
|
|
215
233
|
|
|
216
234
|
class ProjectFMUDirectory(FMUDirectoryBase):
|
|
217
|
-
|
|
235
|
+
if TYPE_CHECKING:
|
|
236
|
+
config: ProjectConfigManager
|
|
218
237
|
|
|
219
238
|
def __init__(self, base_path: str | Path) -> None:
|
|
220
239
|
"""Initializes a project-based .fmu directory."""
|
|
@@ -287,7 +306,8 @@ class ProjectFMUDirectory(FMUDirectoryBase):
|
|
|
287
306
|
|
|
288
307
|
|
|
289
308
|
class UserFMUDirectory(FMUDirectoryBase):
|
|
290
|
-
|
|
309
|
+
if TYPE_CHECKING:
|
|
310
|
+
config: UserConfigManager
|
|
291
311
|
|
|
292
312
|
def __init__(self) -> None:
|
|
293
313
|
"""Initializes a project-based .fmu directory."""
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""Utilities for storing revision snapshots of .fmu files."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from datetime import UTC, datetime
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import TYPE_CHECKING, Final, Self
|
|
8
|
+
from uuid import uuid4
|
|
9
|
+
|
|
10
|
+
from fmu.settings._logging import null_logger
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from fmu.settings._fmu_dir import FMUDirectoryBase
|
|
14
|
+
|
|
15
|
+
logger: Final = null_logger(__name__)
|
|
16
|
+
|
|
17
|
+
_CACHEDIR_TAG_CONTENT: Final = (
|
|
18
|
+
"Signature: 8a477f597d28d172789f06886806bc55\n"
|
|
19
|
+
"# This directory contains cached FMU files.\n"
|
|
20
|
+
"# For information about cache directory tags, see:\n"
|
|
21
|
+
"# https://bford.info/cachedir/spec.html"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class CacheManager:
|
|
26
|
+
"""Stores complete file revisions under the `.fmu/cache` tree."""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self: Self,
|
|
30
|
+
fmu_dir: FMUDirectoryBase,
|
|
31
|
+
max_revisions: int = 5,
|
|
32
|
+
) -> None:
|
|
33
|
+
"""Initialize the cache manager.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
fmu_dir: The FMUDirectory instance.
|
|
37
|
+
max_revisions: Maximum number of revisions to retain. Default is 5.
|
|
38
|
+
"""
|
|
39
|
+
self._fmu_dir = fmu_dir
|
|
40
|
+
self._cache_root = Path("cache")
|
|
41
|
+
self._max_revisions = max(0, max_revisions)
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def max_revisions(self: Self) -> int:
|
|
45
|
+
"""Maximum number of revisions retained per resource."""
|
|
46
|
+
return self._max_revisions
|
|
47
|
+
|
|
48
|
+
@max_revisions.setter
|
|
49
|
+
def max_revisions(self: Self, value: int) -> None:
|
|
50
|
+
"""Update the per-resource revision retention."""
|
|
51
|
+
self._max_revisions = max(0, value)
|
|
52
|
+
|
|
53
|
+
def store_revision(
|
|
54
|
+
self: Self,
|
|
55
|
+
resource_file_path: Path | str,
|
|
56
|
+
content: str,
|
|
57
|
+
encoding: str = "utf-8",
|
|
58
|
+
) -> Path | None:
|
|
59
|
+
"""Write a full snapshot of the resource file to the cache directory.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
resource_file_path: Relative path within the ``.fmu`` directory (e.g.,
|
|
63
|
+
``config.json``) of the resource file being cached.
|
|
64
|
+
content: Serialized payload to store.
|
|
65
|
+
encoding: Encoding used when persisting the snapshot. Defaults to UTF-8.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Absolute filesystem path to the stored snapshot, or ``None`` if caching is
|
|
69
|
+
disabled (``max_revisions`` equals zero).
|
|
70
|
+
"""
|
|
71
|
+
if self.max_revisions == 0:
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
resource_file_path = Path(resource_file_path)
|
|
75
|
+
cache_dir = self._ensure_resource_cache_dir(resource_file_path)
|
|
76
|
+
snapshot_name = self._snapshot_filename(resource_file_path)
|
|
77
|
+
snapshot_path = cache_dir / snapshot_name
|
|
78
|
+
|
|
79
|
+
cache_relative = self._cache_root / resource_file_path.stem
|
|
80
|
+
self._fmu_dir.write_text_file(
|
|
81
|
+
cache_relative / snapshot_name, content, encoding=encoding
|
|
82
|
+
)
|
|
83
|
+
logger.debug("Stored revision snapshot at %s", snapshot_path)
|
|
84
|
+
|
|
85
|
+
self._trim(cache_dir)
|
|
86
|
+
return snapshot_path
|
|
87
|
+
|
|
88
|
+
def list_revisions(self: Self, resource_file_path: Path | str) -> list[Path]:
|
|
89
|
+
"""List existing snapshots for a resource file, sorted oldest to newest.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
resource_file_path: Relative path within the ``.fmu`` directory (e.g.,
|
|
93
|
+
``config.json``) whose cache entries should be listed.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
A list of absolute `Path` objects sorted oldest to newest.
|
|
97
|
+
"""
|
|
98
|
+
resource_file_path = Path(resource_file_path)
|
|
99
|
+
cache_relative = self._cache_root / resource_file_path.stem
|
|
100
|
+
if not self._fmu_dir.file_exists(cache_relative):
|
|
101
|
+
return []
|
|
102
|
+
cache_dir = self._fmu_dir.get_file_path(cache_relative)
|
|
103
|
+
|
|
104
|
+
revisions = [p for p in cache_dir.iterdir() if p.is_file()]
|
|
105
|
+
revisions.sort(key=lambda path: path.name)
|
|
106
|
+
return revisions
|
|
107
|
+
|
|
108
|
+
def _ensure_resource_cache_dir(self: Self, resource_file_path: Path) -> Path:
|
|
109
|
+
"""Create (if needed) and return the cache directory for resource file."""
|
|
110
|
+
self._cache_root_path(create=True)
|
|
111
|
+
resource_cache_dir_relative = self._cache_root / resource_file_path.stem
|
|
112
|
+
return self._fmu_dir.ensure_directory(resource_cache_dir_relative)
|
|
113
|
+
|
|
114
|
+
def _cache_root_path(self: Self, create: bool) -> Path:
|
|
115
|
+
"""Resolve the cache root, creating it and the cachedir tag if requested."""
|
|
116
|
+
if create:
|
|
117
|
+
cache_root = self._fmu_dir.ensure_directory(self._cache_root)
|
|
118
|
+
self._ensure_cachedir_tag()
|
|
119
|
+
return cache_root
|
|
120
|
+
|
|
121
|
+
return self._fmu_dir.get_file_path(self._cache_root)
|
|
122
|
+
|
|
123
|
+
def _ensure_cachedir_tag(self: Self) -> None:
|
|
124
|
+
"""Ensure the cache root complies with the Cachedir specification."""
|
|
125
|
+
tag_path_relative = self._cache_root / "CACHEDIR.TAG"
|
|
126
|
+
if self._fmu_dir.file_exists(tag_path_relative):
|
|
127
|
+
return
|
|
128
|
+
self._fmu_dir.write_text_file(tag_path_relative, _CACHEDIR_TAG_CONTENT)
|
|
129
|
+
|
|
130
|
+
def _snapshot_filename(self: Self, resource_file_path: Path) -> str:
|
|
131
|
+
"""Generate a timestamped filename for the next snapshot."""
|
|
132
|
+
timestamp = datetime.now(UTC).strftime("%Y%m%dT%H%M%S.%fZ")
|
|
133
|
+
suffix = resource_file_path.suffix or ".txt"
|
|
134
|
+
token = uuid4().hex[:8]
|
|
135
|
+
return f"{timestamp}-{token}{suffix}"
|
|
136
|
+
|
|
137
|
+
def _trim(self: Self, cache_dir: Path) -> None:
|
|
138
|
+
"""Remove the oldest snapshots until the retention limit is respected."""
|
|
139
|
+
revisions = [p for p in cache_dir.iterdir() if p.is_file()]
|
|
140
|
+
if len(revisions) <= self.max_revisions:
|
|
141
|
+
return
|
|
142
|
+
|
|
143
|
+
revisions.sort(key=lambda path: path.name)
|
|
144
|
+
excess = len(revisions) - self.max_revisions
|
|
145
|
+
for old_revision in revisions[:excess]:
|
|
146
|
+
try:
|
|
147
|
+
old_revision.unlink()
|
|
148
|
+
except FileNotFoundError:
|
|
149
|
+
continue
|
|
@@ -32,9 +32,15 @@ class LockError(Exception):
|
|
|
32
32
|
"""Raised when the lock cannot be acquired."""
|
|
33
33
|
|
|
34
34
|
|
|
35
|
+
class LockNotFoundError(FileNotFoundError):
|
|
36
|
+
"""Raised when the lock cannot be found."""
|
|
37
|
+
|
|
38
|
+
|
|
35
39
|
class LockManager(PydanticResourceManager[LockInfo]):
|
|
36
40
|
"""Manages the .lock file."""
|
|
37
41
|
|
|
42
|
+
cache_enabled: bool = False
|
|
43
|
+
|
|
38
44
|
def __init__(
|
|
39
45
|
self: Self,
|
|
40
46
|
fmu_dir: FMUDirectoryBase,
|
|
@@ -82,7 +88,7 @@ class LockManager(PydanticResourceManager[LockInfo]):
|
|
|
82
88
|
return
|
|
83
89
|
|
|
84
90
|
if not wait:
|
|
85
|
-
lock_info = self.
|
|
91
|
+
lock_info = self.safe_load()
|
|
86
92
|
if lock_info:
|
|
87
93
|
raise LockError(
|
|
88
94
|
f"Lock file is held by {lock_info.user}@{lock_info.hostname} "
|
|
@@ -152,12 +158,16 @@ class LockManager(PydanticResourceManager[LockInfo]):
|
|
|
152
158
|
with contextlib.suppress(OSError):
|
|
153
159
|
temp_path.unlink()
|
|
154
160
|
|
|
155
|
-
def is_locked(self: Self) -> bool:
|
|
161
|
+
def is_locked(self: Self, *, propagate_errors: bool = False) -> bool:
|
|
156
162
|
"""Returns whether or not the lock is locked by anyone.
|
|
157
163
|
|
|
158
164
|
This does a force load on the lock file.
|
|
159
165
|
"""
|
|
160
|
-
lock_info =
|
|
166
|
+
lock_info = (
|
|
167
|
+
self.load(force=True, store_cache=False)
|
|
168
|
+
if propagate_errors
|
|
169
|
+
else self.safe_load(force=True, store_cache=False)
|
|
170
|
+
)
|
|
161
171
|
if not lock_info:
|
|
162
172
|
return False
|
|
163
173
|
return time.time() < lock_info.expires_at
|
|
@@ -166,15 +176,16 @@ class LockManager(PydanticResourceManager[LockInfo]):
|
|
|
166
176
|
"""Returns whether or not the lock is currently acquired by this instance."""
|
|
167
177
|
if self._cache is None or self._acquired_at is None:
|
|
168
178
|
return False
|
|
169
|
-
|
|
179
|
+
|
|
180
|
+
current_lock = self.safe_load(force=True, store_cache=False)
|
|
181
|
+
if current_lock is None:
|
|
182
|
+
return False
|
|
183
|
+
|
|
184
|
+
return self._is_mine(current_lock) and not self._is_stale()
|
|
170
185
|
|
|
171
186
|
def ensure_can_write(self: Self) -> None:
|
|
172
187
|
"""Raise PermissionError if another process currently holds the lock."""
|
|
173
|
-
|
|
174
|
-
lock_info = self.load(force=True, store_cache=False)
|
|
175
|
-
except Exception:
|
|
176
|
-
lock_info = None
|
|
177
|
-
|
|
188
|
+
lock_info = self.safe_load(force=True, store_cache=False)
|
|
178
189
|
if (
|
|
179
190
|
self.exists
|
|
180
191
|
and lock_info is not None
|
|
@@ -196,9 +207,9 @@ class LockManager(PydanticResourceManager[LockInfo]):
|
|
|
196
207
|
if not self.exists:
|
|
197
208
|
if self.is_acquired():
|
|
198
209
|
self.release()
|
|
199
|
-
raise
|
|
210
|
+
raise LockNotFoundError("Cannot refresh: lock file does not exist")
|
|
200
211
|
|
|
201
|
-
lock_info = self.
|
|
212
|
+
lock_info = self.safe_load()
|
|
202
213
|
if not lock_info or not self._is_mine(lock_info):
|
|
203
214
|
raise LockError(
|
|
204
215
|
"Cannot refresh: lock file is held by another process or host."
|
|
@@ -210,7 +221,7 @@ class LockManager(PydanticResourceManager[LockInfo]):
|
|
|
210
221
|
def release(self: Self) -> None:
|
|
211
222
|
"""Release the lock."""
|
|
212
223
|
if self.exists:
|
|
213
|
-
lock_info = self.
|
|
224
|
+
lock_info = self.safe_load()
|
|
214
225
|
if lock_info and self._is_mine(lock_info):
|
|
215
226
|
with contextlib.suppress(ValueError):
|
|
216
227
|
self.path.unlink()
|
|
@@ -218,12 +229,15 @@ class LockManager(PydanticResourceManager[LockInfo]):
|
|
|
218
229
|
self._acquired_at = None
|
|
219
230
|
self._cache = None
|
|
220
231
|
|
|
221
|
-
def save(
|
|
232
|
+
def save(
|
|
233
|
+
self: Self,
|
|
234
|
+
data: LockInfo,
|
|
235
|
+
) -> None:
|
|
222
236
|
"""Save the lockfile in an NFS-atomic manner.
|
|
223
237
|
|
|
224
238
|
This overrides save() from the Pydantic resource manager.
|
|
225
239
|
"""
|
|
226
|
-
lock_info = self.
|
|
240
|
+
lock_info = self.safe_load()
|
|
227
241
|
if not lock_info or not self._is_mine(lock_info):
|
|
228
242
|
raise LockError(
|
|
229
243
|
"Failed to save lock: lock file is held by another process or host."
|
|
@@ -250,20 +264,22 @@ class LockManager(PydanticResourceManager[LockInfo]):
|
|
|
250
264
|
and lock_info.acquired_at == self._acquired_at
|
|
251
265
|
)
|
|
252
266
|
|
|
253
|
-
def
|
|
267
|
+
def safe_load(
|
|
268
|
+
self: Self, force: bool = False, store_cache: bool = False
|
|
269
|
+
) -> LockInfo | None:
|
|
254
270
|
"""Load lock info, returning None if corrupted.
|
|
255
271
|
|
|
256
272
|
Because this file does not exist in a static state, wrap around loading it.
|
|
257
273
|
"""
|
|
258
274
|
try:
|
|
259
|
-
return self.load(force=force)
|
|
275
|
+
return self.load(force=force, store_cache=store_cache)
|
|
260
276
|
except Exception:
|
|
261
277
|
return None
|
|
262
278
|
|
|
263
279
|
def _is_stale(self: Self, lock_info: LockInfo | None = None) -> bool:
|
|
264
280
|
"""Check if existing lock is stale (expired or process dead)."""
|
|
265
281
|
if lock_info is None:
|
|
266
|
-
lock_info = self.
|
|
282
|
+
lock_info = self.safe_load()
|
|
267
283
|
|
|
268
284
|
if not lock_info:
|
|
269
285
|
return True
|
|
@@ -22,6 +22,8 @@ MutablePydanticResource = TypeVar("MutablePydanticResource", bound=ResettableBas
|
|
|
22
22
|
class PydanticResourceManager(Generic[PydanticResource]):
|
|
23
23
|
"""Base class for managing resources represented by Pydantic models."""
|
|
24
24
|
|
|
25
|
+
cache_enabled: bool = True
|
|
26
|
+
|
|
25
27
|
def __init__(
|
|
26
28
|
self: Self, fmu_dir: FMUDirectoryBase, model_class: type[PydanticResource]
|
|
27
29
|
) -> None:
|
|
@@ -99,15 +101,22 @@ class PydanticResourceManager(Generic[PydanticResource]):
|
|
|
99
101
|
|
|
100
102
|
return self._cache
|
|
101
103
|
|
|
102
|
-
def save(
|
|
104
|
+
def save(
|
|
105
|
+
self: Self,
|
|
106
|
+
model: PydanticResource,
|
|
107
|
+
) -> None:
|
|
103
108
|
"""Save the Pydantic model to disk.
|
|
104
109
|
|
|
105
110
|
Args:
|
|
106
|
-
model: Validated Pydantic model instance
|
|
111
|
+
model: Validated Pydantic model instance.
|
|
107
112
|
"""
|
|
108
113
|
self.fmu_dir._lock.ensure_can_write()
|
|
109
114
|
json_data = model.model_dump_json(by_alias=True, indent=2)
|
|
110
115
|
self.fmu_dir.write_text_file(self.relative_path, json_data)
|
|
116
|
+
|
|
117
|
+
if self.cache_enabled and self.exists:
|
|
118
|
+
self.fmu_dir.cache.store_revision(self.relative_path, json_data)
|
|
119
|
+
|
|
111
120
|
self._cache = model
|
|
112
121
|
|
|
113
122
|
|
fmu/settings/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.5.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 5,
|
|
31
|
+
__version__ = version = '0.5.4'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 5, 4)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
fmu/__init__.py,sha256=htx6HlMme77I6pZ8U256-2B2cMJuELsu3JN3YM2Efh4,144
|
|
2
2
|
fmu/settings/__init__.py,sha256=CkEE7al_uBCQO1lxBKN5LzyCwzzH5Aq6kkEIR7f-zTw,336
|
|
3
|
-
fmu/settings/_fmu_dir.py,sha256=
|
|
3
|
+
fmu/settings/_fmu_dir.py,sha256=J0K6CWlkk3Z5ojyOZaUDYQadx0_FiCyKNn1ZGs79h1o,11592
|
|
4
4
|
fmu/settings/_global_config.py,sha256=C0_o99OhOc49ynz4h6ygbbHHH8OOI5lcVFr-9FCwD0c,9331
|
|
5
5
|
fmu/settings/_init.py,sha256=ucueS0BlEsM3MkX7IaRISloH4vF7-_ZKSphrORbHgJ4,4381
|
|
6
6
|
fmu/settings/_logging.py,sha256=nEdmZlNCBsB1GfDmFMKCjZmeuRp3CRlbz1EYUemc95Y,1104
|
|
7
|
-
fmu/settings/_version.py,sha256=
|
|
7
|
+
fmu/settings/_version.py,sha256=OrfVZdCDQ-QC6dUnxdROooJjwvLfeDMedTBstpAdSBU,704
|
|
8
8
|
fmu/settings/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
fmu/settings/types.py,sha256=aeXEsznBTT1YRRY_LSRqK1j2gmMmyLYYTGYl3a9fweU,513
|
|
10
10
|
fmu/settings/_resources/__init__.py,sha256=LHYR_F7lNGdv8N6R3cEwds5CJQpkOthXFqsEs24vgF8,118
|
|
11
|
+
fmu/settings/_resources/cache_manager.py,sha256=TCVefkQEZuEdrzS0yOs7K-fCMouU4fctRtEvj4Du28M,5656
|
|
11
12
|
fmu/settings/_resources/config_managers.py,sha256=QcCLlSw8KdJKrkhGax5teFJzjgQG3ym7Ljs1DykjFbc,1570
|
|
12
|
-
fmu/settings/_resources/lock_manager.py,sha256=
|
|
13
|
-
fmu/settings/_resources/pydantic_resource_manager.py,sha256=
|
|
13
|
+
fmu/settings/_resources/lock_manager.py,sha256=3h1wRhDvn1xYkKoPs4I1e-6PO8Ctu8StdS7Nh5DW5O4,10508
|
|
14
|
+
fmu/settings/_resources/pydantic_resource_manager.py,sha256=iCLO0xzTPhcYyhCoafKf7DAxjIDv8VBQIqRl-HYEDok,9472
|
|
14
15
|
fmu/settings/models/__init__.py,sha256=lRlXgl55ba2upmDzdvzx8N30JMq2Osnm8aa_xxTZn8A,112
|
|
15
16
|
fmu/settings/models/_enums.py,sha256=SQUZ-2mQcTx4F0oefPFfuQzMKsKTSFSB-wq_CH7TBRE,734
|
|
16
17
|
fmu/settings/models/_mappings.py,sha256=Z4Ex7MtmajBr6FjaNzmwDRwtJlaZZ8YKh9NDmZHRKPI,2832
|
|
17
18
|
fmu/settings/models/lock_info.py,sha256=-oHDF9v9bDLCoFvEg4S6XXYLeo19zRAZ8HynCv75VWg,711
|
|
18
19
|
fmu/settings/models/project_config.py,sha256=pxb54JmpXNMVAFUu_yJ89dNrYEk6hrPuFfFUpf84Jh0,1099
|
|
19
20
|
fmu/settings/models/user_config.py,sha256=dWFTcZY6UnEgNTuGqB-izraJ657PecsW0e0Nt9GBDhI,2666
|
|
20
|
-
fmu_settings-0.5.
|
|
21
|
-
fmu_settings-0.5.
|
|
22
|
-
fmu_settings-0.5.
|
|
23
|
-
fmu_settings-0.5.
|
|
24
|
-
fmu_settings-0.5.
|
|
21
|
+
fmu_settings-0.5.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
22
|
+
fmu_settings-0.5.4.dist-info/METADATA,sha256=kysnXaWPfT7_e-lqxRIEOgbdirMo-VvzbcdNeFztyzA,2116
|
|
23
|
+
fmu_settings-0.5.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
24
|
+
fmu_settings-0.5.4.dist-info/top_level.txt,sha256=Z-FIY3pxn0UK2Wxi9IJ7fKoLSraaxuNGi1eokiE0ShM,4
|
|
25
|
+
fmu_settings-0.5.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|