Skip to content

Commit

Permalink
Replaces get method but can not follow dict.get yet
Browse files Browse the repository at this point in the history
  • Loading branch information
Kernchen, Sophie committed Jan 5, 2024
1 parent 76a5d94 commit 631102e
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 77 deletions.
18 changes: 16 additions & 2 deletions src/hermes/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@
"""
This module provides the main entry point for the HERMES command line application.
"""
import sys
import logging
import typing as t
import pathlib
from importlib import metadata
from pydantic import ValidationError

import click

from hermes import config
from hermes.commands import workflow
from hermes.config import configure, init_logging
from hermes.settings import HermesSettings


def log_header(header, summary=None):
Expand Down Expand Up @@ -86,8 +89,19 @@ def invoke(self, ctx: click.Context) -> t.Any:

# Get the user provided working dir from the --path option or default to current working directory.
working_path = ctx.params.get('path').absolute()

configure(ctx.params.get('config').absolute(), working_path)
config_path = ctx.params.get('config').absolute()
try:
with open(config_path, 'r') as config_file:
settings = HermesSettings(config_path)
except ValidationError as e:
print(e, file=sys.stderr)
sys.exit(1)
except FileNotFoundError:
if config_path.name != 'hermes.toml':
# An explicit filename (different from default) was given, so the file should be available...
print(f"Configuration not present at {config_path}.", file=sys.stderr)
sys.exit(1)
configure(settings, working_path)
init_logging()
log_header(None)

Expand Down
2 changes: 1 addition & 1 deletion src/hermes/commands/deposit/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def map_metadata(click_ctx: click.Context, ctx: CodeMetaContext):


def publish(click_ctx: click.Context, ctx: CodeMetaContext):
file_config = config.get("deposit").get("file", {})
file_config = config.deposit.get("file", {})
output_data = ctx['deposit.file']

with open(file_config.get('filename', 'hermes.json'), 'w') as deposition_file:
Expand Down
12 changes: 6 additions & 6 deletions src/hermes/commands/deposit/invenio.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def prepare(click_ctx: click.Context, ctx: CodeMetaContext):
raise DepositionUnauthorizedError("No auth token given for deposition platform")

invenio_path = ContextPath.parse("deposit.invenio")
invenio_config = config.get("deposit").get("invenio", {})
invenio_config = config.deposit.get("invenio", {})
rec_id, rec_meta = _resolve_latest_invenio_id(ctx)

version = ctx["codemeta"].get("version")
Expand Down Expand Up @@ -115,7 +115,7 @@ def create_initial_version(click_ctx: click.Context, ctx: CodeMetaContext):

_log = logging.getLogger("cli.deposit.invenio")

invenio_config = config.get("deposit").get("invenio", {})
invenio_config = config.deposit.get("invenio", {})
site_url = invenio_config["site_url"]
depositions_api_path = invenio_config.get("api_paths", {}).get(
"depositions", _DEFAULT_DEPOSITIONS_API_PATH
Expand Down Expand Up @@ -167,7 +167,7 @@ def create_new_version(click_ctx: click.Context, ctx: CodeMetaContext):
"Authorization": f"Bearer {click_ctx.params['auth_token']}",
}

invenio_config = config.get("deposit").get("invenio", {})
invenio_config = config.deposit.get("invenio", {})
site_url = invenio_config["site_url"]
depositions_api_path = invenio_config.get("api_paths", {}).get(
"depositions", _DEFAULT_DEPOSITIONS_API_PATH
Expand Down Expand Up @@ -322,7 +322,7 @@ def _resolve_latest_invenio_id(ctx: CodeMetaContext) -> t.Tuple[str, dict]:
:return: The Invenio record id and the metadata of the record
"""

invenio_config = config.get('deposit').get('invenio', {})
invenio_config = config.deposit.get('invenio', {})
site_url = invenio_config.get('site_url')
if site_url is None:
raise MisconfigurationError("deposit.invenio.site_url is not configured")
Expand Down Expand Up @@ -575,7 +575,7 @@ def _get_community_identifiers(ctx: CodeMetaContext, communities_api_url: str):
raised.
"""

communities = config.get("deposit").get("invenio", {}).get("communities")
communities = config.deposit.get("invenio", {}).get("communities")
if communities is None:
return None

Expand Down Expand Up @@ -612,7 +612,7 @@ def _get_access_modalities(license):
This function also makes sure that the given embargo date can be parsed as an ISO
8601 string representation and that the access rights are given as a string.
"""
invenio_config = config.get("deposit").get("invenio", {})
invenio_config = config.deposit.get("invenio", {})

access_right = invenio_config.get("access_right")
if access_right is None:
Expand Down
12 changes: 6 additions & 6 deletions src/hermes/commands/deposit/invenio_rdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def prepare(click_ctx: click.Context, ctx: CodeMetaContext):
raise DepositionUnauthorizedError("No auth token given for deposition platform")

invenio_path = ContextPath.parse("deposit.invenio_rdm")
invenio_config = config.get("deposit").get("invenio_rdm", {})
invenio_config = config.deposit.get("invenio_rdm", {})
rec_id, rec_meta = _resolve_latest_invenio_id(ctx)

version = ctx["codemeta"].get("version")
Expand Down Expand Up @@ -115,7 +115,7 @@ def create_initial_version(click_ctx: click.Context, ctx: CodeMetaContext):

_log = logging.getLogger("cli.deposit.invenio_rdm")

invenio_config = config.get("deposit").get("invenio_rdm", {})
invenio_config = config.deposit.get("invenio_rdm", {})
site_url = invenio_config["site_url"]
depositions_api_path = invenio_config.get("api_paths", {}).get(
"depositions", _DEFAULT_DEPOSITIONS_API_PATH
Expand Down Expand Up @@ -168,7 +168,7 @@ def create_new_version(click_ctx: click.Context, ctx: CodeMetaContext):
"Authorization": f"Bearer {click_ctx.params['auth_token']}",
}

invenio_config = config.get("deposit").get("invenio_rdm", {})
invenio_config = config.deposit.get("invenio_rdm", {})
site_url = invenio_config["site_url"]
depositions_api_path = invenio_config.get("api_paths", {}).get(
"depositions", _DEFAULT_DEPOSITIONS_API_PATH
Expand Down Expand Up @@ -323,7 +323,7 @@ def _resolve_latest_invenio_id(ctx: CodeMetaContext) -> t.Tuple[str, dict]:
:return: The Invenio record id and the metadata of the record
"""

invenio_config = config.get('deposit').get('invenio_rdm', {})
invenio_config = config.deposit.get('invenio_rdm', {})
site_url = invenio_config.get('site_url')
if site_url is None:
raise MisconfigurationError("deposit.invenio_rdm.site_url is not configured")
Expand Down Expand Up @@ -635,7 +635,7 @@ def _get_community_identifiers(ctx: CodeMetaContext, communities_api_url: str):
raised.
"""

communities = config.get("deposit").get("invenio_rdm", {}).get("communities")
communities = config.deposit.get("invenio_rdm", {}).get("communities")
if communities is None:
return None

Expand Down Expand Up @@ -672,7 +672,7 @@ def _get_access_modalities(license):
This function also makes sure that the given embargo date can be parsed as an ISO
8601 string representation and that the access rights are given as a string.
"""
invenio_config = config.get("deposit").get("invenio_rdm", {})
invenio_config = config.deposit.get("invenio_rdm", {})

access_right = invenio_config.get("access_right")
if access_right is None:
Expand Down
2 changes: 1 addition & 1 deletion src/hermes/commands/postprocess/invenio.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def config_record_id(ctx):
deposition_path = ctx.get_cache('deposit', 'deposit')
with deposition_path.open("r") as deposition_file:
deposition = json.load(deposition_file)
conf = config.get('hermes')
conf = config.hermes
try:
conf['deposit']['invenio']['record_id'] = deposition['record_id']
toml.dump(conf, open('hermes.toml', 'w'))
Expand Down
2 changes: 1 addition & 1 deletion src/hermes/commands/postprocess/invenio_rdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def config_record_id(ctx):
deposition_path = ctx.get_cache('deposit', 'deposit')
with deposition_path.open("r") as deposition_file:
deposition = json.load(deposition_file)
conf = config.get('hermes')
conf = config.hermes
try:
conf['deposit']['invenio_rdm']['record_id'] = deposition['record_id']
toml.dump(conf, open('hermes.toml', 'w'))
Expand Down
8 changes: 4 additions & 4 deletions src/hermes/commands/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def harvest(click_ctx: click.Context):
ctx.init_cache("harvest")

# Get all harvesters
harvest_config = config.get("harvest")
harvest_config = config.harvest
harvester_names = harvest_config.get('from', [ep.name for ep in metadata.entry_points(group='hermes.harvest')])

for harvester_name in harvester_names:
Expand Down Expand Up @@ -82,7 +82,7 @@ def process(click_ctx: click.Context):
click_ctx.exit(1)

# Get all harvesters
harvest_config = config.get("harvest")
harvest_config = config.harvest
harvester_names = harvest_config.get('from', [ep.name for ep in metadata.entry_points(group='hermes.harvest')])

for harvester_name in harvester_names:
Expand Down Expand Up @@ -187,7 +187,7 @@ def deposit(click_ctx: click.Context, initial, auth_token, file):
with open(codemeta_file) as codemeta_fh:
ctx.update(codemeta_path, json.load(codemeta_fh))

deposit_config = config.get("deposit")
deposit_config = config.deposit

# This is used as the default value for all entry point names for the deposit step
target_platform = deposit_config.get("target", "invenio")
Expand Down Expand Up @@ -268,7 +268,7 @@ def postprocess(click_ctx: click.Context):
click_ctx.exit(1)

# Get all postprocessors
postprocess_config = config.get("postprocess")
postprocess_config = config.postprocess
postprocess_names = postprocess_config.get('execute', [])

for postprocess_name in postprocess_names:
Expand Down
57 changes: 4 additions & 53 deletions src/hermes/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@

import logging
import pathlib
import sys

import toml
from pydantic import ValidationError

import hermes.settings
from hermes.model.context import HermesContext
from hermes.settings import HermesSettings

# This is the default logging configuration, required to see log output at all.
# - Maybe it could possibly somehow be a somewhat good idea to move this into an own module ... later perhaps
Expand Down Expand Up @@ -63,7 +59,7 @@
}


def configure(config_path: pathlib.Path, working_path: pathlib.Path):
def configure(settings: hermes.settings.HermesSettings, working_path: pathlib.Path):
"""
Load the configuration from the given path as global hermes configuration.
Expand All @@ -78,53 +74,8 @@ def configure(config_path: pathlib.Path, working_path: pathlib.Path):
_config['logging']['handlers']['auditfile']['filename'] = \
working_path / HermesContext.hermes_cache_name / "audit.log"

# Load configuration if not present
try:
with open(config_path, 'r') as config_file:
settings = HermesSettings(config_path)

_config['hermes'] = settings
_config['logging'] = settings.get('logging', _config['logging'])
except ValidationError as e:
print(e, file=sys.stderr)
sys.exit(1)
except FileNotFoundError:
if config_path.name != 'hermes.toml':
# An explicit filename (different from default) was given, so the file should be available...
print(f"Configuration not present at {config_path}.", file=sys.stderr)
sys.exit(1)


def get(name: str) -> dict:
"""
Retrieve the configuration dict for a certain sub-system (i.e., a section from the config file).
The returned dict comes directly from the cache.
I.e., it is possible to do the following *stunt* to inject default values:
.. code: python
my_config = config.get('my-config')
my_config.update({ 'default': 'values' })
:param name: The section to retrieve.
:return: The loaded configuration data or an empty dictionary.
"""

if name not in _config:
# If configuration is not present, create it.
if 'hermes' not in _config:
_config['hermes'] = {}
if name not in _config['hermes']:
_config['hermes'][name] = {}
_config[name] = _config['hermes'][name]

elif name != 'hermes' and _config['hermes'][name] is not _config[name]:
# If a configuration was loaded, after the defaults were set, update it.
_config[name].update(_config['hermes'].get('name', {}))

return _config.get(name)

_config['hermes'] = settings
_config['logging'] = settings.get('logging', _config['logging']) # TODO: 'dict' object is not callable

# Might be a good idea to move somewhere else (see comment for _logging_config)?
_loggers = {}
Expand Down
18 changes: 15 additions & 3 deletions src/hermes/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,23 @@ def settings_customise_sources(
env_settings,
file_secret_settings,
)
def __call__(self) -> Dict[str, Any]:
d: Dict[str, Any] = {}
for field_name, field in self.settings_cls.model_fields.items():
field_value, field_key, value_is_complex = self.get_field_value(
field, field_name
)
field_value = self.prepare_field_value(
field_name, field, field_value, value_is_complex
)
if field_value is not None:
d[field_key] = field_value

def __getattr__(self, item):
return d
def __getattr__(self, item, *args):
self.__pydantic_extra__ = {item: {}}
return item

print(args)
return {}

class TomlConfigSettingsSource(PydanticBaseSettingsSource):
"""
Expand Down

0 comments on commit 631102e

Please sign in to comment.