From 3961d9e17ec17041b643bce6fb1af22e171d1096 Mon Sep 17 00:00:00 2001 From: mikedarcy Date: Fri, 21 Jul 2023 14:16:09 -0700 Subject: [PATCH] Fix erroneous implementation in `validate_bag_profile` and allow for passing a local profile per PR: https://github.com/fair-research/bdbag/pull/54 --- bdbag/__init__.py | 3 +-- bdbag/bdbag_api.py | 22 ++++++++++++++-------- test/test_api.py | 22 ++++++++++++++++++++-- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/bdbag/__init__.py b/bdbag/__init__.py index c113b2a..c65fedd 100644 --- a/bdbag/__init__.py +++ b/bdbag/__init__.py @@ -21,13 +21,12 @@ import mimetypes import shutil from datetime import datetime -from requests.utils import requote_uri from distutils.util import strtobool from importlib_metadata import distribution, PackageNotFoundError logger = logging.getLogger(__name__) -__version__ = "1.7.0dev3" +__version__ = "1.7.0dev4" __bagit_version__ = "1.8.1" __bagit_profile_version__ = "1.3.1" diff --git a/bdbag/bdbag_api.py b/bdbag/bdbag_api.py index cb4e97c..8e6e2fb 100644 --- a/bdbag/bdbag_api.py +++ b/bdbag/bdbag_api.py @@ -439,18 +439,24 @@ def validate_bag_structure(bag_path, skip_remote=True): def validate_bag_profile(bag_path, profile_path=None): - - logger.info("Validating bag profile: %s" % bag_path) + logger.info("Validating bag profile: %s", bag_path) bag = bdbagit.BDBag(bag_path) # Instantiate a profile, supplying its URI. - if not profile_path: - profile_path = bag.info.get(BAG_PROFILE_TAG, None) - if not profile_path: - raise bdbp.ProfileValidationError("Bag does not contain a BagIt-Profile-Identifier") + profile_url = bag.info.get(BAG_PROFILE_TAG, None) + if not profile_url: + raise bdbp.ProfileValidationError("Bag does not contain a BagIt-Profile-Identifier") + logger.info("Loading profile: %s" % profile_path if profile_path else profile_url) + + profile = None + if profile_path: + try: + with open(profile_path, encoding="UTF-8") as profile_file: + profile = json.loads(profile_file.read()) + except (OSError, IOError, json.JSONDecodeError) as exc: + raise bdbp.ProfileValidationError("Profile %s could not be read: %s" % (profile_path, exc)) - logger.info("Retrieving profile: %s" % profile_path) - profile = bdbp.BDBProfile(profile_path) + profile = bdbp.BDBProfile(profile_url, profile) # Validate the profile. if profile.validate(bag): diff --git a/test/test_api.py b/test/test_api.py index b9a3b0d..a988e89 100644 --- a/test/test_api.py +++ b/test/test_api.py @@ -25,8 +25,8 @@ from os.path import join as ospj from os.path import exists as ospe from os.path import isfile as ospif -from bdbag import bdbag_api as bdb, bdbag_config as bdbcfg, bdbag_ro as bdbro, bdbagit as bdbagit, filter_dict, \ - get_typed_exception, DEFAULT_CONFIG_PATH +from bdbag import bdbag_api as bdb, bdbag_config as bdbcfg, bdbag_ro as bdbro, bdbagit as bdbagit, bdbagit_profile, \ + filter_dict, get_typed_exception, DEFAULT_CONFIG_PATH from bdbag.fetch.auth import keychain from test.test_common import BaseTest @@ -893,6 +893,24 @@ def test_validate_invalid_bag_state_fetch_filesize(self): except Exception as e: self.fail(get_typed_exception(e)) + def test_validate_profile_with_local_profile(self): + logger.info(self.getTestHeader('validate local profile')) + try: + profile = bdb.validate_bag_profile(self.test_bag_profile_dir, "./profiles/bdbag-profile.json") + self.assertIsInstance(profile, bdbagit_profile.Profile) + except Exception as e: + self.fail(get_typed_exception(e)) + + def test_validate_profile_with_local_bad_path_profile(self): + logger.info(self.getTestHeader('validate bad path local profile')) + try: + self.assertRaises(bdbagit_profile.ProfileValidationError, + bdb.validate_bag_profile, + self.test_bag_profile_dir, + "./profiles/missing-bdbag-profile.json") + except Exception as e: + self.fail(get_typed_exception(e)) + def test_filter_dict(self): logger.info(self.getTestHeader('test filter function'))