flood-adapt 0.3.9__py3-none-any.whl → 0.3.10__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.
- flood_adapt/__init__.py +26 -22
- flood_adapt/adapter/__init__.py +9 -9
- flood_adapt/adapter/fiat_adapter.py +1541 -1541
- flood_adapt/adapter/interface/hazard_adapter.py +70 -70
- flood_adapt/adapter/interface/impact_adapter.py +36 -36
- flood_adapt/adapter/interface/model_adapter.py +89 -89
- flood_adapt/adapter/interface/offshore.py +19 -19
- flood_adapt/adapter/sfincs_adapter.py +1848 -1848
- flood_adapt/adapter/sfincs_offshore.py +193 -193
- flood_adapt/config/config.py +248 -248
- flood_adapt/config/fiat.py +219 -219
- flood_adapt/config/gui.py +331 -331
- flood_adapt/config/sfincs.py +481 -336
- flood_adapt/config/site.py +129 -129
- flood_adapt/database_builder/database_builder.py +2210 -2210
- flood_adapt/database_builder/templates/default_units/imperial.toml +9 -9
- flood_adapt/database_builder/templates/default_units/metric.toml +9 -9
- flood_adapt/database_builder/templates/green_infra_table/green_infra_lookup_table.csv +10 -10
- flood_adapt/database_builder/templates/infographics/OSM/config_charts.toml +90 -90
- flood_adapt/database_builder/templates/infographics/OSM/config_people.toml +57 -57
- flood_adapt/database_builder/templates/infographics/OSM/config_risk_charts.toml +121 -121
- flood_adapt/database_builder/templates/infographics/OSM/config_roads.toml +65 -65
- flood_adapt/database_builder/templates/infographics/OSM/styles.css +45 -45
- flood_adapt/database_builder/templates/infographics/US_NSI/config_charts.toml +126 -126
- flood_adapt/database_builder/templates/infographics/US_NSI/config_people.toml +60 -60
- flood_adapt/database_builder/templates/infographics/US_NSI/config_risk_charts.toml +121 -121
- flood_adapt/database_builder/templates/infographics/US_NSI/config_roads.toml +65 -65
- flood_adapt/database_builder/templates/infographics/US_NSI/styles.css +45 -45
- flood_adapt/database_builder/templates/infometrics/OSM/metrics_additional_risk_configs.toml +4 -4
- flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config.toml +143 -143
- flood_adapt/database_builder/templates/infometrics/OSM/with_SVI/infographic_metrics_config_risk.toml +153 -153
- flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config.toml +127 -127
- flood_adapt/database_builder/templates/infometrics/OSM/without_SVI/infographic_metrics_config_risk.toml +57 -57
- flood_adapt/database_builder/templates/infometrics/US_NSI/metrics_additional_risk_configs.toml +4 -4
- flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config.toml +191 -191
- flood_adapt/database_builder/templates/infometrics/US_NSI/with_SVI/infographic_metrics_config_risk.toml +153 -153
- flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config.toml +178 -178
- flood_adapt/database_builder/templates/infometrics/US_NSI/without_SVI/infographic_metrics_config_risk.toml +57 -57
- flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config.toml +9 -9
- flood_adapt/database_builder/templates/infometrics/mandatory_metrics_config_risk.toml +65 -65
- flood_adapt/database_builder/templates/output_layers/bin_colors.toml +5 -5
- flood_adapt/database_builder.py +16 -16
- flood_adapt/dbs_classes/__init__.py +21 -21
- flood_adapt/dbs_classes/database.py +495 -684
- flood_adapt/dbs_classes/dbs_benefit.py +77 -76
- flood_adapt/dbs_classes/dbs_event.py +61 -59
- flood_adapt/dbs_classes/dbs_measure.py +112 -111
- flood_adapt/dbs_classes/dbs_projection.py +34 -34
- flood_adapt/dbs_classes/dbs_scenario.py +137 -137
- flood_adapt/dbs_classes/dbs_static.py +274 -273
- flood_adapt/dbs_classes/dbs_strategy.py +130 -129
- flood_adapt/dbs_classes/dbs_template.py +279 -278
- flood_adapt/dbs_classes/interface/database.py +107 -139
- flood_adapt/dbs_classes/interface/element.py +121 -121
- flood_adapt/dbs_classes/interface/static.py +47 -47
- flood_adapt/flood_adapt.py +1207 -1178
- flood_adapt/misc/database_user.py +16 -16
- flood_adapt/misc/exceptions.py +22 -0
- flood_adapt/misc/log.py +183 -183
- flood_adapt/misc/path_builder.py +54 -54
- flood_adapt/misc/utils.py +185 -185
- flood_adapt/objects/__init__.py +82 -82
- flood_adapt/objects/benefits/benefits.py +61 -61
- flood_adapt/objects/events/event_factory.py +135 -135
- flood_adapt/objects/events/event_set.py +88 -84
- flood_adapt/objects/events/events.py +234 -234
- flood_adapt/objects/events/historical.py +58 -58
- flood_adapt/objects/events/hurricane.py +68 -67
- flood_adapt/objects/events/synthetic.py +46 -50
- flood_adapt/objects/forcing/__init__.py +92 -92
- flood_adapt/objects/forcing/csv.py +68 -68
- flood_adapt/objects/forcing/discharge.py +66 -66
- flood_adapt/objects/forcing/forcing.py +150 -150
- flood_adapt/objects/forcing/forcing_factory.py +182 -182
- flood_adapt/objects/forcing/meteo_handler.py +93 -93
- flood_adapt/objects/forcing/netcdf.py +40 -40
- flood_adapt/objects/forcing/plotting.py +453 -429
- flood_adapt/objects/forcing/rainfall.py +98 -98
- flood_adapt/objects/forcing/tide_gauge.py +191 -191
- flood_adapt/objects/forcing/time_frame.py +90 -90
- flood_adapt/objects/forcing/timeseries.py +564 -564
- flood_adapt/objects/forcing/unit_system.py +580 -580
- flood_adapt/objects/forcing/waterlevels.py +108 -108
- flood_adapt/objects/forcing/wind.py +124 -124
- flood_adapt/objects/measures/measure_factory.py +92 -92
- flood_adapt/objects/measures/measures.py +529 -529
- flood_adapt/objects/object_model.py +74 -68
- flood_adapt/objects/projections/projections.py +103 -103
- flood_adapt/objects/scenarios/scenarios.py +22 -22
- flood_adapt/objects/strategies/strategies.py +89 -89
- flood_adapt/workflows/benefit_runner.py +579 -554
- flood_adapt/workflows/floodmap.py +85 -85
- flood_adapt/workflows/impacts_integrator.py +85 -85
- flood_adapt/workflows/scenario_runner.py +70 -70
- {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/LICENSE +674 -674
- {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/METADATA +866 -865
- flood_adapt-0.3.10.dist-info/RECORD +140 -0
- flood_adapt-0.3.9.dist-info/RECORD +0 -139
- {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/WHEEL +0 -0
- {flood_adapt-0.3.9.dist-info → flood_adapt-0.3.10.dist-info}/top_level.txt +0 -0
flood_adapt/misc/utils.py
CHANGED
|
@@ -1,185 +1,185 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import shutil
|
|
3
|
-
from contextlib import contextmanager
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import Union
|
|
6
|
-
|
|
7
|
-
from pydantic import BeforeValidator
|
|
8
|
-
|
|
9
|
-
from flood_adapt.misc.path_builder import (
|
|
10
|
-
ObjectDir,
|
|
11
|
-
db_path,
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@contextmanager
|
|
16
|
-
def modified_environ(*remove, **update):
|
|
17
|
-
"""
|
|
18
|
-
Temporarily updates the ``os.environ`` dictionary in-place.
|
|
19
|
-
|
|
20
|
-
From https://github.com/laurent-laporte-pro/stackoverflow-q2059482/blob/master/demo/environ_ctx.py
|
|
21
|
-
|
|
22
|
-
The ``os.environ`` dictionary is updated in-place so that the modification
|
|
23
|
-
is sure to work in all situations.
|
|
24
|
-
|
|
25
|
-
:param remove: Environment variables to remove.
|
|
26
|
-
:param update: Dictionary of environment variables and values to add/update.
|
|
27
|
-
"""
|
|
28
|
-
env = os.environ
|
|
29
|
-
update = update or {}
|
|
30
|
-
remove = remove or []
|
|
31
|
-
|
|
32
|
-
# List of environment variables being updated or removed.
|
|
33
|
-
stomped = (set(update.keys()) | set(remove)) & set(env.keys())
|
|
34
|
-
# Environment variables and values to restore on exit.
|
|
35
|
-
update_after = {k: env[k] for k in stomped}
|
|
36
|
-
# Environment variables and values to remove on exit.
|
|
37
|
-
remove_after = frozenset(k for k in update if k not in env)
|
|
38
|
-
|
|
39
|
-
try:
|
|
40
|
-
env.update(update)
|
|
41
|
-
[env.pop(k, None) for k in remove]
|
|
42
|
-
yield
|
|
43
|
-
finally:
|
|
44
|
-
env.update(update_after)
|
|
45
|
-
[env.pop(k) for k in remove_after]
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@contextmanager
|
|
49
|
-
def cd(newdir: Path):
|
|
50
|
-
prevdir = Path().cwd()
|
|
51
|
-
os.chdir(newdir)
|
|
52
|
-
try:
|
|
53
|
-
yield
|
|
54
|
-
finally:
|
|
55
|
-
os.chdir(prevdir)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def write_finished_file(path: Path):
|
|
59
|
-
if not path.exists():
|
|
60
|
-
path.mkdir(parents=True)
|
|
61
|
-
with open(Path(path) / "finished.txt", "w") as f:
|
|
62
|
-
f.write("run finished")
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def finished_file_exists(path: Path):
|
|
66
|
-
return (Path(path) / "finished.txt").exists()
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
def resolve_filepath(
|
|
70
|
-
object_dir: ObjectDir, obj_name: str, path: Path | str | os.PathLike
|
|
71
|
-
) -> Path:
|
|
72
|
-
"""
|
|
73
|
-
Determine whether a given path is an external file or a file in the database.
|
|
74
|
-
|
|
75
|
-
Users can set the path to a file in the database directly, meaning it will be an absolute path.
|
|
76
|
-
Users can also read the path from loading a toml file, meaning it will be a filename relative to the toml file.
|
|
77
|
-
|
|
78
|
-
Parameters
|
|
79
|
-
----------
|
|
80
|
-
object_dir : ObjectDir
|
|
81
|
-
The directory name of the object in the database.
|
|
82
|
-
obj_name : str
|
|
83
|
-
The name of the object.
|
|
84
|
-
path : Union[Path, str, os.PathLike]
|
|
85
|
-
The path to the file, which can be an absolute path or a relative path.
|
|
86
|
-
|
|
87
|
-
Returns
|
|
88
|
-
-------
|
|
89
|
-
Path
|
|
90
|
-
The resolved path to the file.
|
|
91
|
-
|
|
92
|
-
Raises
|
|
93
|
-
------
|
|
94
|
-
FileNotFoundError
|
|
95
|
-
If the file does not exist in either the provided path or the database path.
|
|
96
|
-
"""
|
|
97
|
-
_path = Path(path)
|
|
98
|
-
if str(_path) == _path.name:
|
|
99
|
-
# this is a filename, so it is in the database
|
|
100
|
-
src_path = db_path(object_dir=object_dir, obj_name=obj_name) / path
|
|
101
|
-
else:
|
|
102
|
-
# this is a path, so it is an external file
|
|
103
|
-
src_path = Path(path)
|
|
104
|
-
return src_path
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def save_file_to_database(
|
|
108
|
-
src_file: Path | str | os.PathLike, dst_dir: Path | str | os.PathLike
|
|
109
|
-
) -> Path:
|
|
110
|
-
"""Save a file to the database.
|
|
111
|
-
|
|
112
|
-
Parameters
|
|
113
|
-
----------
|
|
114
|
-
src_file : Path | str | os.PathLike
|
|
115
|
-
Path to the file to be copied.
|
|
116
|
-
dst_dir : Path | str | os.PathLike
|
|
117
|
-
Path to the destination directory.
|
|
118
|
-
|
|
119
|
-
Returns
|
|
120
|
-
-------
|
|
121
|
-
Path
|
|
122
|
-
Path to the copied file
|
|
123
|
-
|
|
124
|
-
Raises
|
|
125
|
-
------
|
|
126
|
-
FileNotFoundError
|
|
127
|
-
If the src_file does not exist at the given path
|
|
128
|
-
"""
|
|
129
|
-
src_file = Path(src_file).resolve()
|
|
130
|
-
dst_file = Path(dst_dir).resolve() / src_file.name
|
|
131
|
-
|
|
132
|
-
if not src_file.exists():
|
|
133
|
-
raise FileNotFoundError(
|
|
134
|
-
f"Failed to find {src_file} when saving external file to the database as it does not exist."
|
|
135
|
-
)
|
|
136
|
-
if src_file == dst_file:
|
|
137
|
-
return dst_file
|
|
138
|
-
elif dst_file.exists():
|
|
139
|
-
if dst_file.suffix == ".shp":
|
|
140
|
-
for file in list(dst_file.parent.glob(f"{dst_file.stem}.*")):
|
|
141
|
-
os.remove(file)
|
|
142
|
-
else:
|
|
143
|
-
os.remove(dst_file)
|
|
144
|
-
|
|
145
|
-
dst_file.parent.mkdir(parents=True, exist_ok=True)
|
|
146
|
-
if src_file.suffix == ".shp":
|
|
147
|
-
for file in list(src_file.parent.glob(f"{src_file.stem}.*")):
|
|
148
|
-
shutil.copy2(file, dst_file.parent.joinpath(file.name))
|
|
149
|
-
else:
|
|
150
|
-
shutil.copy2(src_file, dst_file)
|
|
151
|
-
|
|
152
|
-
return dst_file
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
def copy_file_to_output_dir(file_path: Path, output_dir: Path) -> Path:
|
|
156
|
-
output_dir = output_dir.resolve()
|
|
157
|
-
if file_path == output_dir / file_path.name:
|
|
158
|
-
return file_path
|
|
159
|
-
output_dir.mkdir(parents=True, exist_ok=True)
|
|
160
|
-
shutil.copy2(file_path, output_dir)
|
|
161
|
-
return output_dir / file_path.name
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
def validate_file_extension(allowed_extensions: list[str]):
|
|
165
|
-
"""Validate the extension of the given path has one of the given suffixes.
|
|
166
|
-
|
|
167
|
-
Examples
|
|
168
|
-
--------
|
|
169
|
-
>>> from pydantic import BaseModel
|
|
170
|
-
>>> from pathlib import Path
|
|
171
|
-
>>> from typing import Annotated
|
|
172
|
-
|
|
173
|
-
>>> class MyClass(BaseModel):
|
|
174
|
-
>>> csv_path: Annotated[Path, validate_file_extension([".csv"])]
|
|
175
|
-
"""
|
|
176
|
-
|
|
177
|
-
def _validator(value: Union[Path, str, os.PathLike]) -> Path:
|
|
178
|
-
value = Path(value)
|
|
179
|
-
if value.suffix not in allowed_extensions:
|
|
180
|
-
raise ValueError(
|
|
181
|
-
f"Invalid file extension: {value}. Allowed extensions are {', '.join(allowed_extensions)}."
|
|
182
|
-
)
|
|
183
|
-
return value
|
|
184
|
-
|
|
185
|
-
return BeforeValidator(_validator)
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
from contextlib import contextmanager
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Union
|
|
6
|
+
|
|
7
|
+
from pydantic import BeforeValidator
|
|
8
|
+
|
|
9
|
+
from flood_adapt.misc.path_builder import (
|
|
10
|
+
ObjectDir,
|
|
11
|
+
db_path,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@contextmanager
|
|
16
|
+
def modified_environ(*remove, **update):
|
|
17
|
+
"""
|
|
18
|
+
Temporarily updates the ``os.environ`` dictionary in-place.
|
|
19
|
+
|
|
20
|
+
From https://github.com/laurent-laporte-pro/stackoverflow-q2059482/blob/master/demo/environ_ctx.py
|
|
21
|
+
|
|
22
|
+
The ``os.environ`` dictionary is updated in-place so that the modification
|
|
23
|
+
is sure to work in all situations.
|
|
24
|
+
|
|
25
|
+
:param remove: Environment variables to remove.
|
|
26
|
+
:param update: Dictionary of environment variables and values to add/update.
|
|
27
|
+
"""
|
|
28
|
+
env = os.environ
|
|
29
|
+
update = update or {}
|
|
30
|
+
remove = remove or []
|
|
31
|
+
|
|
32
|
+
# List of environment variables being updated or removed.
|
|
33
|
+
stomped = (set(update.keys()) | set(remove)) & set(env.keys())
|
|
34
|
+
# Environment variables and values to restore on exit.
|
|
35
|
+
update_after = {k: env[k] for k in stomped}
|
|
36
|
+
# Environment variables and values to remove on exit.
|
|
37
|
+
remove_after = frozenset(k for k in update if k not in env)
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
env.update(update)
|
|
41
|
+
[env.pop(k, None) for k in remove]
|
|
42
|
+
yield
|
|
43
|
+
finally:
|
|
44
|
+
env.update(update_after)
|
|
45
|
+
[env.pop(k) for k in remove_after]
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@contextmanager
|
|
49
|
+
def cd(newdir: Path):
|
|
50
|
+
prevdir = Path().cwd()
|
|
51
|
+
os.chdir(newdir)
|
|
52
|
+
try:
|
|
53
|
+
yield
|
|
54
|
+
finally:
|
|
55
|
+
os.chdir(prevdir)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def write_finished_file(path: Path):
|
|
59
|
+
if not path.exists():
|
|
60
|
+
path.mkdir(parents=True)
|
|
61
|
+
with open(Path(path) / "finished.txt", "w") as f:
|
|
62
|
+
f.write("run finished")
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def finished_file_exists(path: Path):
|
|
66
|
+
return (Path(path) / "finished.txt").exists()
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def resolve_filepath(
|
|
70
|
+
object_dir: ObjectDir, obj_name: str, path: Path | str | os.PathLike
|
|
71
|
+
) -> Path:
|
|
72
|
+
"""
|
|
73
|
+
Determine whether a given path is an external file or a file in the database.
|
|
74
|
+
|
|
75
|
+
Users can set the path to a file in the database directly, meaning it will be an absolute path.
|
|
76
|
+
Users can also read the path from loading a toml file, meaning it will be a filename relative to the toml file.
|
|
77
|
+
|
|
78
|
+
Parameters
|
|
79
|
+
----------
|
|
80
|
+
object_dir : ObjectDir
|
|
81
|
+
The directory name of the object in the database.
|
|
82
|
+
obj_name : str
|
|
83
|
+
The name of the object.
|
|
84
|
+
path : Union[Path, str, os.PathLike]
|
|
85
|
+
The path to the file, which can be an absolute path or a relative path.
|
|
86
|
+
|
|
87
|
+
Returns
|
|
88
|
+
-------
|
|
89
|
+
Path
|
|
90
|
+
The resolved path to the file.
|
|
91
|
+
|
|
92
|
+
Raises
|
|
93
|
+
------
|
|
94
|
+
FileNotFoundError
|
|
95
|
+
If the file does not exist in either the provided path or the database path.
|
|
96
|
+
"""
|
|
97
|
+
_path = Path(path)
|
|
98
|
+
if str(_path) == _path.name:
|
|
99
|
+
# this is a filename, so it is in the database
|
|
100
|
+
src_path = db_path(object_dir=object_dir, obj_name=obj_name) / path
|
|
101
|
+
else:
|
|
102
|
+
# this is a path, so it is an external file
|
|
103
|
+
src_path = Path(path)
|
|
104
|
+
return src_path
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def save_file_to_database(
|
|
108
|
+
src_file: Path | str | os.PathLike, dst_dir: Path | str | os.PathLike
|
|
109
|
+
) -> Path:
|
|
110
|
+
"""Save a file to the database.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
src_file : Path | str | os.PathLike
|
|
115
|
+
Path to the file to be copied.
|
|
116
|
+
dst_dir : Path | str | os.PathLike
|
|
117
|
+
Path to the destination directory.
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
Path
|
|
122
|
+
Path to the copied file
|
|
123
|
+
|
|
124
|
+
Raises
|
|
125
|
+
------
|
|
126
|
+
FileNotFoundError
|
|
127
|
+
If the src_file does not exist at the given path
|
|
128
|
+
"""
|
|
129
|
+
src_file = Path(src_file).resolve()
|
|
130
|
+
dst_file = Path(dst_dir).resolve() / src_file.name
|
|
131
|
+
|
|
132
|
+
if not src_file.exists():
|
|
133
|
+
raise FileNotFoundError(
|
|
134
|
+
f"Failed to find {src_file} when saving external file to the database as it does not exist."
|
|
135
|
+
)
|
|
136
|
+
if src_file == dst_file:
|
|
137
|
+
return dst_file
|
|
138
|
+
elif dst_file.exists():
|
|
139
|
+
if dst_file.suffix == ".shp":
|
|
140
|
+
for file in list(dst_file.parent.glob(f"{dst_file.stem}.*")):
|
|
141
|
+
os.remove(file)
|
|
142
|
+
else:
|
|
143
|
+
os.remove(dst_file)
|
|
144
|
+
|
|
145
|
+
dst_file.parent.mkdir(parents=True, exist_ok=True)
|
|
146
|
+
if src_file.suffix == ".shp":
|
|
147
|
+
for file in list(src_file.parent.glob(f"{src_file.stem}.*")):
|
|
148
|
+
shutil.copy2(file, dst_file.parent.joinpath(file.name))
|
|
149
|
+
else:
|
|
150
|
+
shutil.copy2(src_file, dst_file)
|
|
151
|
+
|
|
152
|
+
return dst_file
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def copy_file_to_output_dir(file_path: Path, output_dir: Path) -> Path:
|
|
156
|
+
output_dir = output_dir.resolve()
|
|
157
|
+
if file_path == output_dir / file_path.name:
|
|
158
|
+
return file_path
|
|
159
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
160
|
+
shutil.copy2(file_path, output_dir)
|
|
161
|
+
return output_dir / file_path.name
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def validate_file_extension(allowed_extensions: list[str]):
|
|
165
|
+
"""Validate the extension of the given path has one of the given suffixes.
|
|
166
|
+
|
|
167
|
+
Examples
|
|
168
|
+
--------
|
|
169
|
+
>>> from pydantic import BaseModel
|
|
170
|
+
>>> from pathlib import Path
|
|
171
|
+
>>> from typing import Annotated
|
|
172
|
+
|
|
173
|
+
>>> class MyClass(BaseModel):
|
|
174
|
+
>>> csv_path: Annotated[Path, validate_file_extension([".csv"])]
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
def _validator(value: Union[Path, str, os.PathLike]) -> Path:
|
|
178
|
+
value = Path(value)
|
|
179
|
+
if value.suffix not in allowed_extensions:
|
|
180
|
+
raise ValueError(
|
|
181
|
+
f"Invalid file extension: {value}. Allowed extensions are {', '.join(allowed_extensions)}."
|
|
182
|
+
)
|
|
183
|
+
return value
|
|
184
|
+
|
|
185
|
+
return BeforeValidator(_validator)
|
flood_adapt/objects/__init__.py
CHANGED
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
from flood_adapt.objects.benefits.benefits import Benefit, CurrentSituationModel
|
|
2
|
-
from flood_adapt.objects.events.event_factory import EventFactory
|
|
3
|
-
from flood_adapt.objects.events.event_set import EventSet, SubEventModel
|
|
4
|
-
from flood_adapt.objects.events.events import (
|
|
5
|
-
Event,
|
|
6
|
-
Mode,
|
|
7
|
-
Template,
|
|
8
|
-
TimeFrame,
|
|
9
|
-
)
|
|
10
|
-
from flood_adapt.objects.events.historical import HistoricalEvent
|
|
11
|
-
from flood_adapt.objects.events.hurricane import HurricaneEvent
|
|
12
|
-
from flood_adapt.objects.events.synthetic import SyntheticEvent
|
|
13
|
-
from flood_adapt.objects.forcing.forcing import (
|
|
14
|
-
ForcingSource,
|
|
15
|
-
ForcingType,
|
|
16
|
-
IForcing,
|
|
17
|
-
)
|
|
18
|
-
from flood_adapt.objects.forcing.forcing_factory import ForcingFactory
|
|
19
|
-
from flood_adapt.objects.measures.measure_factory import MeasureFactory
|
|
20
|
-
from flood_adapt.objects.measures.measures import (
|
|
21
|
-
Buyout,
|
|
22
|
-
Elevate,
|
|
23
|
-
FloodProof,
|
|
24
|
-
FloodWall,
|
|
25
|
-
GreenInfrastructure,
|
|
26
|
-
Measure,
|
|
27
|
-
MeasureType,
|
|
28
|
-
Pump,
|
|
29
|
-
SelectionType,
|
|
30
|
-
)
|
|
31
|
-
from flood_adapt.objects.object_model import Object
|
|
32
|
-
from flood_adapt.objects.projections.projections import (
|
|
33
|
-
PhysicalProjection,
|
|
34
|
-
Projection,
|
|
35
|
-
SocioEconomicChange,
|
|
36
|
-
)
|
|
37
|
-
from flood_adapt.objects.scenarios.scenarios import Scenario
|
|
38
|
-
from flood_adapt.objects.strategies.strategies import Strategy
|
|
39
|
-
|
|
40
|
-
__all__ = [
|
|
41
|
-
# Object
|
|
42
|
-
"Object",
|
|
43
|
-
# Measures
|
|
44
|
-
"MeasureFactory",
|
|
45
|
-
"Measure",
|
|
46
|
-
"MeasureType",
|
|
47
|
-
"SelectionType",
|
|
48
|
-
"Buyout",
|
|
49
|
-
"Elevate",
|
|
50
|
-
"FloodProof",
|
|
51
|
-
"FloodWall",
|
|
52
|
-
"GreenInfrastructure",
|
|
53
|
-
"Pump",
|
|
54
|
-
# Events
|
|
55
|
-
"Event",
|
|
56
|
-
"EventFactory",
|
|
57
|
-
"SyntheticEvent",
|
|
58
|
-
"HistoricalEvent",
|
|
59
|
-
"HurricaneEvent",
|
|
60
|
-
"TimeFrame",
|
|
61
|
-
"Mode",
|
|
62
|
-
"Template",
|
|
63
|
-
# EventSet
|
|
64
|
-
"EventSet",
|
|
65
|
-
"SubEventModel",
|
|
66
|
-
# Forcing
|
|
67
|
-
"ForcingFactory",
|
|
68
|
-
"IForcing",
|
|
69
|
-
"ForcingType",
|
|
70
|
-
"ForcingSource",
|
|
71
|
-
# Projections
|
|
72
|
-
"Projection",
|
|
73
|
-
"PhysicalProjection",
|
|
74
|
-
"SocioEconomicChange",
|
|
75
|
-
# Strategies
|
|
76
|
-
"Strategy",
|
|
77
|
-
# Scenarios
|
|
78
|
-
"Scenario",
|
|
79
|
-
# Benefits
|
|
80
|
-
"Benefit",
|
|
81
|
-
"CurrentSituationModel",
|
|
82
|
-
]
|
|
1
|
+
from flood_adapt.objects.benefits.benefits import Benefit, CurrentSituationModel
|
|
2
|
+
from flood_adapt.objects.events.event_factory import EventFactory
|
|
3
|
+
from flood_adapt.objects.events.event_set import EventSet, SubEventModel
|
|
4
|
+
from flood_adapt.objects.events.events import (
|
|
5
|
+
Event,
|
|
6
|
+
Mode,
|
|
7
|
+
Template,
|
|
8
|
+
TimeFrame,
|
|
9
|
+
)
|
|
10
|
+
from flood_adapt.objects.events.historical import HistoricalEvent
|
|
11
|
+
from flood_adapt.objects.events.hurricane import HurricaneEvent
|
|
12
|
+
from flood_adapt.objects.events.synthetic import SyntheticEvent
|
|
13
|
+
from flood_adapt.objects.forcing.forcing import (
|
|
14
|
+
ForcingSource,
|
|
15
|
+
ForcingType,
|
|
16
|
+
IForcing,
|
|
17
|
+
)
|
|
18
|
+
from flood_adapt.objects.forcing.forcing_factory import ForcingFactory
|
|
19
|
+
from flood_adapt.objects.measures.measure_factory import MeasureFactory
|
|
20
|
+
from flood_adapt.objects.measures.measures import (
|
|
21
|
+
Buyout,
|
|
22
|
+
Elevate,
|
|
23
|
+
FloodProof,
|
|
24
|
+
FloodWall,
|
|
25
|
+
GreenInfrastructure,
|
|
26
|
+
Measure,
|
|
27
|
+
MeasureType,
|
|
28
|
+
Pump,
|
|
29
|
+
SelectionType,
|
|
30
|
+
)
|
|
31
|
+
from flood_adapt.objects.object_model import Object
|
|
32
|
+
from flood_adapt.objects.projections.projections import (
|
|
33
|
+
PhysicalProjection,
|
|
34
|
+
Projection,
|
|
35
|
+
SocioEconomicChange,
|
|
36
|
+
)
|
|
37
|
+
from flood_adapt.objects.scenarios.scenarios import Scenario
|
|
38
|
+
from flood_adapt.objects.strategies.strategies import Strategy
|
|
39
|
+
|
|
40
|
+
__all__ = [
|
|
41
|
+
# Object
|
|
42
|
+
"Object",
|
|
43
|
+
# Measures
|
|
44
|
+
"MeasureFactory",
|
|
45
|
+
"Measure",
|
|
46
|
+
"MeasureType",
|
|
47
|
+
"SelectionType",
|
|
48
|
+
"Buyout",
|
|
49
|
+
"Elevate",
|
|
50
|
+
"FloodProof",
|
|
51
|
+
"FloodWall",
|
|
52
|
+
"GreenInfrastructure",
|
|
53
|
+
"Pump",
|
|
54
|
+
# Events
|
|
55
|
+
"Event",
|
|
56
|
+
"EventFactory",
|
|
57
|
+
"SyntheticEvent",
|
|
58
|
+
"HistoricalEvent",
|
|
59
|
+
"HurricaneEvent",
|
|
60
|
+
"TimeFrame",
|
|
61
|
+
"Mode",
|
|
62
|
+
"Template",
|
|
63
|
+
# EventSet
|
|
64
|
+
"EventSet",
|
|
65
|
+
"SubEventModel",
|
|
66
|
+
# Forcing
|
|
67
|
+
"ForcingFactory",
|
|
68
|
+
"IForcing",
|
|
69
|
+
"ForcingType",
|
|
70
|
+
"ForcingSource",
|
|
71
|
+
# Projections
|
|
72
|
+
"Projection",
|
|
73
|
+
"PhysicalProjection",
|
|
74
|
+
"SocioEconomicChange",
|
|
75
|
+
# Strategies
|
|
76
|
+
"Strategy",
|
|
77
|
+
# Scenarios
|
|
78
|
+
"Scenario",
|
|
79
|
+
# Benefits
|
|
80
|
+
"Benefit",
|
|
81
|
+
"CurrentSituationModel",
|
|
82
|
+
]
|
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
|
-
from pydantic import BaseModel
|
|
4
|
-
|
|
5
|
-
from flood_adapt.objects.object_model import Object
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class CurrentSituationModel(BaseModel):
|
|
9
|
-
"""
|
|
10
|
-
The accepted input for a current situation in FloodAdapt.
|
|
11
|
-
|
|
12
|
-
Attributes
|
|
13
|
-
----------
|
|
14
|
-
projection : str
|
|
15
|
-
The name of the projection. Should be a projection saved in the database.
|
|
16
|
-
year : int
|
|
17
|
-
The year of the current situation.
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
projection: str
|
|
21
|
-
year: int
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class Benefit(Object):
|
|
25
|
-
"""BaseModel describing the expected variables and data types of a Benefit analysis object.
|
|
26
|
-
|
|
27
|
-
Attributes
|
|
28
|
-
----------
|
|
29
|
-
name: str
|
|
30
|
-
The name of the benefit analysis.
|
|
31
|
-
description: str
|
|
32
|
-
The description of the benefit analysis. Defaults to "".
|
|
33
|
-
strategy : str
|
|
34
|
-
The name of the strategy. Should be a strategy saved in the database.
|
|
35
|
-
event_set : str
|
|
36
|
-
The name of the event set. Should be an event set saved in the database.
|
|
37
|
-
projection : str
|
|
38
|
-
The name of the projection. Should be a projection saved in the database.
|
|
39
|
-
future_year : int
|
|
40
|
-
The future year for the analysis.
|
|
41
|
-
current_situation : CurrentSituationModel
|
|
42
|
-
The current situation model.
|
|
43
|
-
baseline_strategy : str
|
|
44
|
-
The name of the baseline strategy.
|
|
45
|
-
discount_rate : float
|
|
46
|
-
The discount rate for the analysis.
|
|
47
|
-
implementation_cost : Optional[float]
|
|
48
|
-
The implementation cost of the strategy. Defaults to None.
|
|
49
|
-
annual_maint_cost : Optional[float]
|
|
50
|
-
The annual maintenance cost of the strategy. Defaults to None.
|
|
51
|
-
"""
|
|
52
|
-
|
|
53
|
-
strategy: str
|
|
54
|
-
event_set: str
|
|
55
|
-
projection: str
|
|
56
|
-
future_year: int
|
|
57
|
-
current_situation: CurrentSituationModel
|
|
58
|
-
baseline_strategy: str
|
|
59
|
-
discount_rate: float
|
|
60
|
-
implementation_cost: Optional[float] = None
|
|
61
|
-
annual_maint_cost: Optional[float] = None
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
|
|
5
|
+
from flood_adapt.objects.object_model import Object
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CurrentSituationModel(BaseModel):
|
|
9
|
+
"""
|
|
10
|
+
The accepted input for a current situation in FloodAdapt.
|
|
11
|
+
|
|
12
|
+
Attributes
|
|
13
|
+
----------
|
|
14
|
+
projection : str
|
|
15
|
+
The name of the projection. Should be a projection saved in the database.
|
|
16
|
+
year : int
|
|
17
|
+
The year of the current situation.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
projection: str
|
|
21
|
+
year: int
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Benefit(Object):
|
|
25
|
+
"""BaseModel describing the expected variables and data types of a Benefit analysis object.
|
|
26
|
+
|
|
27
|
+
Attributes
|
|
28
|
+
----------
|
|
29
|
+
name: str
|
|
30
|
+
The name of the benefit analysis.
|
|
31
|
+
description: str
|
|
32
|
+
The description of the benefit analysis. Defaults to "".
|
|
33
|
+
strategy : str
|
|
34
|
+
The name of the strategy. Should be a strategy saved in the database.
|
|
35
|
+
event_set : str
|
|
36
|
+
The name of the event set. Should be an event set saved in the database.
|
|
37
|
+
projection : str
|
|
38
|
+
The name of the projection. Should be a projection saved in the database.
|
|
39
|
+
future_year : int
|
|
40
|
+
The future year for the analysis.
|
|
41
|
+
current_situation : CurrentSituationModel
|
|
42
|
+
The current situation model.
|
|
43
|
+
baseline_strategy : str
|
|
44
|
+
The name of the baseline strategy.
|
|
45
|
+
discount_rate : float
|
|
46
|
+
The discount rate for the analysis.
|
|
47
|
+
implementation_cost : Optional[float]
|
|
48
|
+
The implementation cost of the strategy. Defaults to None.
|
|
49
|
+
annual_maint_cost : Optional[float]
|
|
50
|
+
The annual maintenance cost of the strategy. Defaults to None.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
strategy: str
|
|
54
|
+
event_set: str
|
|
55
|
+
projection: str
|
|
56
|
+
future_year: int
|
|
57
|
+
current_situation: CurrentSituationModel
|
|
58
|
+
baseline_strategy: str
|
|
59
|
+
discount_rate: float
|
|
60
|
+
implementation_cost: Optional[float] = None
|
|
61
|
+
annual_maint_cost: Optional[float] = None
|