vortex-nwp 2.0.0__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.
- vortex/__init__.py +159 -0
- vortex/algo/__init__.py +13 -0
- vortex/algo/components.py +2462 -0
- vortex/algo/mpitools.py +1953 -0
- vortex/algo/mpitools_templates/__init__.py +1 -0
- vortex/algo/mpitools_templates/envelope_wrapper_default.tpl +27 -0
- vortex/algo/mpitools_templates/envelope_wrapper_mpiauto.tpl +29 -0
- vortex/algo/mpitools_templates/wrapstd_wrapper_default.tpl +18 -0
- vortex/algo/serversynctools.py +171 -0
- vortex/config.py +112 -0
- vortex/data/__init__.py +19 -0
- vortex/data/abstractstores.py +1510 -0
- vortex/data/containers.py +835 -0
- vortex/data/contents.py +622 -0
- vortex/data/executables.py +275 -0
- vortex/data/flow.py +119 -0
- vortex/data/geometries.ini +2689 -0
- vortex/data/geometries.py +799 -0
- vortex/data/handlers.py +1230 -0
- vortex/data/outflow.py +67 -0
- vortex/data/providers.py +487 -0
- vortex/data/resources.py +207 -0
- vortex/data/stores.py +1390 -0
- vortex/data/sync_templates/__init__.py +0 -0
- vortex/gloves.py +309 -0
- vortex/layout/__init__.py +20 -0
- vortex/layout/contexts.py +577 -0
- vortex/layout/dataflow.py +1220 -0
- vortex/layout/monitor.py +969 -0
- vortex/nwp/__init__.py +14 -0
- vortex/nwp/algo/__init__.py +21 -0
- vortex/nwp/algo/assim.py +537 -0
- vortex/nwp/algo/clim.py +1086 -0
- vortex/nwp/algo/coupling.py +831 -0
- vortex/nwp/algo/eda.py +840 -0
- vortex/nwp/algo/eps.py +785 -0
- vortex/nwp/algo/forecasts.py +886 -0
- vortex/nwp/algo/fpserver.py +1303 -0
- vortex/nwp/algo/ifsnaming.py +463 -0
- vortex/nwp/algo/ifsroot.py +404 -0
- vortex/nwp/algo/monitoring.py +263 -0
- vortex/nwp/algo/mpitools.py +694 -0
- vortex/nwp/algo/odbtools.py +1258 -0
- vortex/nwp/algo/oopsroot.py +916 -0
- vortex/nwp/algo/oopstests.py +220 -0
- vortex/nwp/algo/request.py +660 -0
- vortex/nwp/algo/stdpost.py +1641 -0
- vortex/nwp/data/__init__.py +30 -0
- vortex/nwp/data/assim.py +380 -0
- vortex/nwp/data/boundaries.py +314 -0
- vortex/nwp/data/climfiles.py +521 -0
- vortex/nwp/data/configfiles.py +153 -0
- vortex/nwp/data/consts.py +954 -0
- vortex/nwp/data/ctpini.py +149 -0
- vortex/nwp/data/diagnostics.py +209 -0
- vortex/nwp/data/eda.py +147 -0
- vortex/nwp/data/eps.py +432 -0
- vortex/nwp/data/executables.py +1045 -0
- vortex/nwp/data/fields.py +111 -0
- vortex/nwp/data/gridfiles.py +380 -0
- vortex/nwp/data/logs.py +584 -0
- vortex/nwp/data/modelstates.py +363 -0
- vortex/nwp/data/monitoring.py +193 -0
- vortex/nwp/data/namelists.py +696 -0
- vortex/nwp/data/obs.py +840 -0
- vortex/nwp/data/oopsexec.py +74 -0
- vortex/nwp/data/providers.py +207 -0
- vortex/nwp/data/query.py +206 -0
- vortex/nwp/data/stores.py +160 -0
- vortex/nwp/data/surfex.py +337 -0
- vortex/nwp/syntax/__init__.py +9 -0
- vortex/nwp/syntax/stdattrs.py +437 -0
- vortex/nwp/tools/__init__.py +10 -0
- vortex/nwp/tools/addons.py +40 -0
- vortex/nwp/tools/agt.py +67 -0
- vortex/nwp/tools/bdap.py +59 -0
- vortex/nwp/tools/bdcp.py +41 -0
- vortex/nwp/tools/bdm.py +24 -0
- vortex/nwp/tools/bdmp.py +54 -0
- vortex/nwp/tools/conftools.py +1661 -0
- vortex/nwp/tools/drhook.py +66 -0
- vortex/nwp/tools/grib.py +294 -0
- vortex/nwp/tools/gribdiff.py +104 -0
- vortex/nwp/tools/ifstools.py +203 -0
- vortex/nwp/tools/igastuff.py +273 -0
- vortex/nwp/tools/mars.py +68 -0
- vortex/nwp/tools/odb.py +657 -0
- vortex/nwp/tools/partitioning.py +258 -0
- vortex/nwp/tools/satrad.py +71 -0
- vortex/nwp/util/__init__.py +6 -0
- vortex/nwp/util/async.py +212 -0
- vortex/nwp/util/beacon.py +40 -0
- vortex/nwp/util/diffpygram.py +447 -0
- vortex/nwp/util/ens.py +279 -0
- vortex/nwp/util/hooks.py +139 -0
- vortex/nwp/util/taskdeco.py +85 -0
- vortex/nwp/util/usepygram.py +697 -0
- vortex/nwp/util/usetnt.py +101 -0
- vortex/proxy.py +6 -0
- vortex/sessions.py +374 -0
- vortex/syntax/__init__.py +9 -0
- vortex/syntax/stdattrs.py +867 -0
- vortex/syntax/stddeco.py +185 -0
- vortex/toolbox.py +1117 -0
- vortex/tools/__init__.py +20 -0
- vortex/tools/actions.py +523 -0
- vortex/tools/addons.py +316 -0
- vortex/tools/arm.py +96 -0
- vortex/tools/compression.py +325 -0
- vortex/tools/date.py +27 -0
- vortex/tools/ddhpack.py +10 -0
- vortex/tools/delayedactions.py +782 -0
- vortex/tools/env.py +541 -0
- vortex/tools/folder.py +834 -0
- vortex/tools/grib.py +738 -0
- vortex/tools/lfi.py +953 -0
- vortex/tools/listings.py +423 -0
- vortex/tools/names.py +637 -0
- vortex/tools/net.py +2124 -0
- vortex/tools/odb.py +10 -0
- vortex/tools/parallelism.py +368 -0
- vortex/tools/prestaging.py +210 -0
- vortex/tools/rawfiles.py +10 -0
- vortex/tools/schedulers.py +480 -0
- vortex/tools/services.py +940 -0
- vortex/tools/storage.py +996 -0
- vortex/tools/surfex.py +61 -0
- vortex/tools/systems.py +3976 -0
- vortex/tools/targets.py +440 -0
- vortex/util/__init__.py +9 -0
- vortex/util/config.py +1122 -0
- vortex/util/empty.py +24 -0
- vortex/util/helpers.py +216 -0
- vortex/util/introspection.py +69 -0
- vortex/util/iosponge.py +80 -0
- vortex/util/roles.py +49 -0
- vortex/util/storefunctions.py +129 -0
- vortex/util/structs.py +26 -0
- vortex/util/worker.py +162 -0
- vortex_nwp-2.0.0.dist-info/METADATA +67 -0
- vortex_nwp-2.0.0.dist-info/RECORD +144 -0
- vortex_nwp-2.0.0.dist-info/WHEEL +5 -0
- vortex_nwp-2.0.0.dist-info/licenses/LICENSE +517 -0
- vortex_nwp-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Empty init file
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!${python}
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
sys.path.append('${sitepath}')
|
|
7
|
+
rank = os.environ['${mpirankvariable}']
|
|
8
|
+
|
|
9
|
+
todolist = {
|
|
10
|
+
${todolist}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
bindinglist = {
|
|
14
|
+
${bindinglist}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if bindinglist:
|
|
18
|
+
from bronx.system.cpus import set_affinity
|
|
19
|
+
set_affinity(bindinglist[int(rank)])
|
|
20
|
+
# Also bind threads
|
|
21
|
+
os.environ['OMP_PROC_BIND'] = 'true'
|
|
22
|
+
|
|
23
|
+
me = todolist[int(rank)]
|
|
24
|
+
if me[2]:
|
|
25
|
+
os.environ['OMP_NUM_THREADS'] = str(me[2])
|
|
26
|
+
|
|
27
|
+
os.execl(me[0], me[0], *me[1])
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!${python}
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
sys.path.append('${sitepath}')
|
|
7
|
+
|
|
8
|
+
actual_mpirankvariable = os.environ['${mpirankvariable}']
|
|
9
|
+
rank = os.environ[actual_mpirankvariable]
|
|
10
|
+
|
|
11
|
+
todolist = {
|
|
12
|
+
${todolist}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
bindinglist = {
|
|
16
|
+
${bindinglist}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if bindinglist:
|
|
20
|
+
from bronx.system.cpus import set_affinity
|
|
21
|
+
set_affinity(bindinglist[int(rank)])
|
|
22
|
+
# Also bind threads
|
|
23
|
+
os.environ['OMP_PROC_BIND'] = 'true'
|
|
24
|
+
|
|
25
|
+
me = todolist[int(rank)]
|
|
26
|
+
if me[2]:
|
|
27
|
+
os.environ['OMP_NUM_THREADS'] = str(me[2])
|
|
28
|
+
|
|
29
|
+
os.execl(me[0], me[0], *me[1])
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!${python}
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
rank = os.environ['${mpirankvariable}']
|
|
7
|
+
|
|
8
|
+
# Redirect stdout and stderr in a very very crude manner
|
|
9
|
+
if int(rank) > 0:
|
|
10
|
+
stdout_fno = sys.stdout.fileno()
|
|
11
|
+
stderr_fno = sys.stderr.fileno()
|
|
12
|
+
red_outputs = os.open('vwrap_stdeo.{:06d}'.format(int(rank)),
|
|
13
|
+
os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o644)
|
|
14
|
+
os.dup2(red_outputs, stdout_fno)
|
|
15
|
+
os.dup2(red_outputs, stderr_fno)
|
|
16
|
+
os.close(red_outputs)
|
|
17
|
+
|
|
18
|
+
os.execl(sys.argv[1], *sys.argv[1:])
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utility classes to interact with long running binaries.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import socket
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
import footprints
|
|
9
|
+
from bronx.fancies import loggers
|
|
10
|
+
from vortex import sessions
|
|
11
|
+
from vortex.util import config
|
|
12
|
+
|
|
13
|
+
# : No automatic export
|
|
14
|
+
__all__ = []
|
|
15
|
+
|
|
16
|
+
logger = loggers.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ServerSyncTool(footprints.FootprintBase):
|
|
20
|
+
"""
|
|
21
|
+
:class:`ServerSyncTool` classes are in charge of interactions between the
|
|
22
|
+
main process and the server.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
_abstract = True
|
|
26
|
+
_collector = ("serversynctool",)
|
|
27
|
+
_footprint = dict(
|
|
28
|
+
info="Abstract Server Synchronisation Tool",
|
|
29
|
+
attr=dict(
|
|
30
|
+
method=dict(),
|
|
31
|
+
medium=dict(
|
|
32
|
+
optional=True,
|
|
33
|
+
),
|
|
34
|
+
raiseonexit=dict(type=bool, optional=True, default=True),
|
|
35
|
+
checkinterval=dict(
|
|
36
|
+
type=int,
|
|
37
|
+
optional=True,
|
|
38
|
+
default=10,
|
|
39
|
+
),
|
|
40
|
+
),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
def __init__(self, *args, **kw):
|
|
44
|
+
logger.debug("Server Synchronisation Tool init %s", self.__class__)
|
|
45
|
+
self._check_callback = lambda: True
|
|
46
|
+
super().__init__(*args, **kw)
|
|
47
|
+
|
|
48
|
+
def set_servercheck_callback(self, cb):
|
|
49
|
+
"""Set a callback method that will be called to check the server state."""
|
|
50
|
+
self._check_callback = cb
|
|
51
|
+
|
|
52
|
+
def trigger_wait(self):
|
|
53
|
+
"""Ask the SyncTool to wait for a request."""
|
|
54
|
+
raise NotImplementedError
|
|
55
|
+
|
|
56
|
+
def trigger_run(self):
|
|
57
|
+
"""Indicate that the main process is ready for the server to run the next step.
|
|
58
|
+
|
|
59
|
+
It then wait for the server to complete this step.
|
|
60
|
+
"""
|
|
61
|
+
raise NotImplementedError
|
|
62
|
+
|
|
63
|
+
def trigger_stop(self):
|
|
64
|
+
"""Ask the server to stop (gently)."""
|
|
65
|
+
raise NotImplementedError
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class ServerSyncSimpleSocket(ServerSyncTool):
|
|
69
|
+
"""Practical implementation of a ServerSyncTool that relies on sockets.
|
|
70
|
+
|
|
71
|
+
A script is created (its name is defined by the *medium* attribute): it
|
|
72
|
+
will be called by the server process before starting any computations. This
|
|
73
|
+
script and the main process communicate using standard UNIX sockets (through
|
|
74
|
+
the socket package).
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
_footprint = dict(
|
|
78
|
+
info="Server Synchronisation Tool that uses a Socket",
|
|
79
|
+
attr=dict(
|
|
80
|
+
method=dict(
|
|
81
|
+
values=["simple_socket"],
|
|
82
|
+
),
|
|
83
|
+
medium=dict(
|
|
84
|
+
optional=False,
|
|
85
|
+
),
|
|
86
|
+
tplname=dict(
|
|
87
|
+
optional=True,
|
|
88
|
+
default="@servsync-simplesocket.tpl",
|
|
89
|
+
),
|
|
90
|
+
),
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
def __init__(self, *args, **kw):
|
|
94
|
+
super().__init__(*args, **kw)
|
|
95
|
+
# Create the socket
|
|
96
|
+
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
97
|
+
try:
|
|
98
|
+
self._socket.bind((socket.getfqdn(), 0))
|
|
99
|
+
except OSError:
|
|
100
|
+
self._socket.bind(("localhost", 0))
|
|
101
|
+
self._socket.settimeout(self.checkinterval)
|
|
102
|
+
self._socket.listen(1)
|
|
103
|
+
# Current connection
|
|
104
|
+
self._socket_conn = None
|
|
105
|
+
# Create the script that will be called by the server
|
|
106
|
+
t = sessions.current()
|
|
107
|
+
tpl = config.load_template(t, self.tplname)
|
|
108
|
+
with open(self.medium, "w") as fd:
|
|
109
|
+
fd.write(
|
|
110
|
+
tpl.substitute(
|
|
111
|
+
python=sys.executable,
|
|
112
|
+
address=self._socket.getsockname(),
|
|
113
|
+
)
|
|
114
|
+
)
|
|
115
|
+
t.sh.chmod(self.medium, 0o555)
|
|
116
|
+
|
|
117
|
+
def __del__(self):
|
|
118
|
+
self._socket.close()
|
|
119
|
+
if self._socket_conn is not None:
|
|
120
|
+
logger.warning("The socket is still up... that's odd.")
|
|
121
|
+
t = sessions.current()
|
|
122
|
+
if t.sh.path.exists(self.medium):
|
|
123
|
+
t.sh.remove(self.medium)
|
|
124
|
+
|
|
125
|
+
def _command(self, mess):
|
|
126
|
+
"""Send a command (a string) to the server and wait for a response."""
|
|
127
|
+
if self._socket_conn is not None:
|
|
128
|
+
logger.info('Sending "%s" to the server.', mess)
|
|
129
|
+
# NB: For send/recv, the settimeout also applies...
|
|
130
|
+
self._socket_conn.send(mess.encode(encoding="utf-8"))
|
|
131
|
+
repl = self._socket_conn.recv(255).decode(encoding="utf-8")
|
|
132
|
+
logger.info('Server replied "%s" to %s.', repl, mess)
|
|
133
|
+
self._socket_conn.close()
|
|
134
|
+
self._socket_conn = None
|
|
135
|
+
if repl != "OK":
|
|
136
|
+
raise ValueError(mess + " failed")
|
|
137
|
+
return True
|
|
138
|
+
else:
|
|
139
|
+
# This should not happen ! If we are sitting here, it's most likely
|
|
140
|
+
# that the main process received a signal like SIGTERM...
|
|
141
|
+
return False
|
|
142
|
+
|
|
143
|
+
def trigger_wait(self):
|
|
144
|
+
logger.info("Waiting for the server to complete")
|
|
145
|
+
while self._socket_conn is None and self._check_callback():
|
|
146
|
+
try:
|
|
147
|
+
self._socket_conn, addr = (
|
|
148
|
+
self._socket.accept()
|
|
149
|
+
) # @UnusedVariable
|
|
150
|
+
except socket.timeout:
|
|
151
|
+
logger.debug(
|
|
152
|
+
"Socket accept timed-out: checking for the server..."
|
|
153
|
+
)
|
|
154
|
+
self._socket_conn = None
|
|
155
|
+
if self._socket_conn is None:
|
|
156
|
+
if self.raiseonexit:
|
|
157
|
+
raise OSError("Apparently the server died.")
|
|
158
|
+
else:
|
|
159
|
+
logger.info("The server stopped.")
|
|
160
|
+
else:
|
|
161
|
+
self._socket_conn.settimeout(self.checkinterval)
|
|
162
|
+
logger.info("The server is now waiting")
|
|
163
|
+
|
|
164
|
+
def trigger_run(self):
|
|
165
|
+
# Tell the server that everything is ready
|
|
166
|
+
self._command("STEP")
|
|
167
|
+
# Wait for the server to complete its work
|
|
168
|
+
self.trigger_wait()
|
|
169
|
+
|
|
170
|
+
def trigger_stop(self):
|
|
171
|
+
return self._command("STOP")
|
vortex/config.py
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""This module provides getter and setter functions to set and get
|
|
2
|
+
the value of configuration options, respectively.
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import tomli
|
|
7
|
+
|
|
8
|
+
from bronx.fancies import loggers
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"load_config",
|
|
12
|
+
"print_config",
|
|
13
|
+
"from_config",
|
|
14
|
+
"set_config",
|
|
15
|
+
"is_defined",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
VORTEX_CONFIG = {}
|
|
19
|
+
|
|
20
|
+
logger = loggers.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ConfigurationError(Exception):
|
|
24
|
+
"""Something is wrong with the provided configuration"""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def load_config(configpath="vortex.toml"):
|
|
28
|
+
"""Load configuration from a TOML configuration file
|
|
29
|
+
|
|
30
|
+
Existing configuration values are overriden. The configuration
|
|
31
|
+
is expected to have valid TOML syntax, e.g.
|
|
32
|
+
|
|
33
|
+
.. code:: toml
|
|
34
|
+
|
|
35
|
+
[data-tree]
|
|
36
|
+
op_rootdir = "/chaine/mxpt001"
|
|
37
|
+
|
|
38
|
+
[storage]
|
|
39
|
+
address = "hendrix.meteo.fr"
|
|
40
|
+
protocol = "ftp"
|
|
41
|
+
# ...
|
|
42
|
+
"""
|
|
43
|
+
global VORTEX_CONFIG
|
|
44
|
+
try:
|
|
45
|
+
with open(configpath, "rb") as f:
|
|
46
|
+
VORTEX_CONFIG = tomli.load(f)
|
|
47
|
+
print(f"Successfully read configuration file {configpath}")
|
|
48
|
+
except FileNotFoundError:
|
|
49
|
+
print(f"Could not read configuration file {configpath} (not found).")
|
|
50
|
+
print("Use load_config(/path/to/config) to update the configuration")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def print_config():
|
|
54
|
+
"""Print configuration (key, value) pairs"""
|
|
55
|
+
if VORTEX_CONFIG:
|
|
56
|
+
for k, v in VORTEX_CONFIG:
|
|
57
|
+
print(k.upper(), v)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def from_config(section, key=None):
|
|
61
|
+
"""Retrieve a configuration key value for a given section.
|
|
62
|
+
|
|
63
|
+
If key is ``None``, the whole section is returned as a dictionary.
|
|
64
|
+
|
|
65
|
+
"""
|
|
66
|
+
try:
|
|
67
|
+
subconfig = VORTEX_CONFIG[section]
|
|
68
|
+
except KeyError:
|
|
69
|
+
raise ConfigurationError(
|
|
70
|
+
f"Missing configuration section {section}",
|
|
71
|
+
)
|
|
72
|
+
if not key:
|
|
73
|
+
return subconfig
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
value = subconfig[key]
|
|
77
|
+
except KeyError:
|
|
78
|
+
raise ConfigurationError(
|
|
79
|
+
f"Missing configuration key {key} in section {section}",
|
|
80
|
+
)
|
|
81
|
+
return value
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def set_config(section, key, value):
|
|
85
|
+
"""Set a configuration key to a value"""
|
|
86
|
+
global VORTEX_CONFIG
|
|
87
|
+
if section not in VORTEX_CONFIG.keys():
|
|
88
|
+
VORTEX_CONFIG[section] = {}
|
|
89
|
+
if key in VORTEX_CONFIG[section]:
|
|
90
|
+
logger.warning(f"Updating existing configuration {section}:{key}")
|
|
91
|
+
VORTEX_CONFIG[section][key] = value
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def is_defined(section, key=None):
|
|
95
|
+
"""Return whether or not the key is defined for the section.
|
|
96
|
+
|
|
97
|
+
If ``key`` is ``None``, return whether or not the section exists
|
|
98
|
+
in the current configuration.
|
|
99
|
+
|
|
100
|
+
"""
|
|
101
|
+
if section not in VORTEX_CONFIG.keys():
|
|
102
|
+
return False
|
|
103
|
+
if key:
|
|
104
|
+
return key in VORTEX_CONFIG[section].keys()
|
|
105
|
+
return True
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def get_from_config_w_default(section, key, default):
|
|
109
|
+
try:
|
|
110
|
+
return from_config(section, key)
|
|
111
|
+
except ConfigurationError:
|
|
112
|
+
return default
|
vortex/data/__init__.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Abstract classes involved in data management within VORTEX.
|
|
3
|
+
|
|
4
|
+
Actual resources and custom providers should be defined in dedicated packages.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from . import handlers as handlers
|
|
8
|
+
from . import resources as resources
|
|
9
|
+
from . import containers as containers
|
|
10
|
+
from . import contents as contents
|
|
11
|
+
from . import providers as providers
|
|
12
|
+
from . import executables as executables
|
|
13
|
+
from . import stores as stores
|
|
14
|
+
from . import geometries as geometries
|
|
15
|
+
|
|
16
|
+
#: No automatic export
|
|
17
|
+
__all__ = []
|
|
18
|
+
|
|
19
|
+
__tocinfoline__ = "Abstract classes involved in data management within VORTEX"
|