Skip to content

Commit

Permalink
fs_storage: add possibility to define options values from env.
Browse files Browse the repository at this point in the history
  • Loading branch information
adrienpeiffer committed Nov 27, 2023
1 parent 8ef48f2 commit 79388d2
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 6 deletions.
33 changes: 32 additions & 1 deletion fs_storage/models/fs_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ def __init__(self, env, ids=(), prefetch_ids=()):
compute="_compute_json_options",
inverse="_inverse_json_options",
)

eval_options_from_env = fields.Boolean(
string="Resolve env vars",
help="Resolve options values starting with $ from environment variables"
)

directory_path = fields.Char(
help="Relative path to the directory to store the file"
)
Expand Down Expand Up @@ -302,6 +308,31 @@ def _recursive_add_odoo_storage_path(self, options: dict) -> dict:
self._recursive_add_odoo_storage_path(target_options)
return options

def _eval_options_from_env(self, options):
values = {}
for key, value in options.items():
if isinstance(value, dict):
values[key] = self._eval_options_from_env(value)
elif isinstance(value, str) and value.startswith("$"):
env_variable_name = value[1:]
env_variable_value = os.getenv(env_variable_name)
if env_variable_value is not None:
values[key] = env_variable_value
else:
values[key] = value
_logger.warning(
f"Environment variable {env_variable_name} is not set for fs_storage {self.display_name}."
)
else:
values[key] = value

Check warning on line 327 in fs_storage/models/fs_storage.py

View check run for this annotation

Codecov / codecov/patch

fs_storage/models/fs_storage.py#L327

Added line #L327 was not covered by tests
return values

def _get_fs_options(self):
options = self.json_options
if not self.eval_options_from_env:
return options
return self._eval_options_from_env(self.json_options)

def _get_filesystem(self) -> fsspec.AbstractFileSystem:
"""Get the fsspec filesystem for this backend.
Expand All @@ -311,7 +342,7 @@ def _get_filesystem(self) -> fsspec.AbstractFileSystem:
:return: fsspec.AbstractFileSystem
"""
self.ensure_one()
options = self.json_options
options = self._get_fs_options()
if self.protocol == "odoofs":
options["odoo_storage_path"] = self._odoo_storage_path
# Webdav protocol handler does need the auth to be a tuple not a list !
Expand Down
15 changes: 15 additions & 0 deletions fs_storage/tests/test_fs_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,18 @@ def test_recursive_add_odoo_storage_path_to_options(self):
.get("target_options")
.get("odoo_storage_path"),
)

def test_options_env(self):
self.backend.json_options = {"key": {"sub_key": "$KEY_VAR"}}
eval_json_options = {"key": {"sub_key": "TEST"}}
options = self.backend._get_fs_options()
self.assertDictEqual(options, self.backend.json_options)
self.backend.eval_options_from_env = True
with mock.patch.dict("os.environ", {"KEY_VAR": "TEST"}):
options = self.backend._get_fs_options()
self.assertDictEqual(options, eval_json_options)
with self.assertLogs(level='WARNING') as log:
options = self.backend._get_fs_options()
self.assertIn(f"Environment variable KEY_VAR is not set for fs_storage {self.backend.display_name}.", log.output[0])


11 changes: 6 additions & 5 deletions fs_storage/views/fs_storage_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,17 @@
</div>
<group name="config">
<group>
<field name="code" />
<field name="protocol" />
<field name="directory_path" />
<field
<field name="code" />
<field name="protocol" />
<field name="directory_path" />
<field name="eval_options_from_env" />
<field
name="options"
widget="ace"
options="{'mode': 'python'}"
placeholder="Enter you fsspec options here."
/>
</group>
</group>
<group>
<notebook colspan="2">
<page string="Protocol Descr" colspan="2">
Expand Down

0 comments on commit 79388d2

Please sign in to comment.