pepkit / peppy

Project metadata manager for PEPs in Python
https://pep.databio.org/peppy
BSD 2-Clause "Simplified" License
37 stars 13 forks source link

Instantiate `Project` class from in-memory dict #378

Closed nleroy917 closed 2 years ago

nleroy917 commented 2 years ago

Right now, peppy's API only lets you create a Project() from a file that is on disk. It would be nice to have the option to create an instance of Project() from a PEP that is already in memory (say, a Python dict).

Right now the __init__ function looks for a str to load the configuration file using parse_config_file. It could be nice to have another case where it looks for a dict and parses the configuration that way. Maybe something like parse_config_dict which is identical to parse_config_file, but simply starts with an already loaded dict:


    def parse_config_file(self, cfg_path, amendments=None):
        """
        Parse provided yaml config file and check required fields exist.
        :param str cfg_path: path to the config file to read and parse
        :param Iterable[str] amendments: Name of amendments to activate
        :raises KeyError: if config file lacks required section(s)
        """
        if CONFIG_KEY not in self:
            self[CONFIG_KEY] = PathExAttMap()
        if not os.path.exists(cfg_path) and not is_url(cfg_path):
            raise OSError(f"Project config file path does not exist: {cfg_path}")
        config = load_yaml(cfg_path) # <---- parse_config_dict would start here

Discussed with @Khoroshevskyi

nleroy917 commented 2 years ago

Is there a good, reliable way of comparing two instantiated Project() classes for checking if they are identical?

khoroshevskyi commented 2 years ago

Is there a good, reliable way of comparing two instantiated Project() classes for checking if they are identical?

1) Try to get all the object variables from two projects and compare them? 2) Try to call some functions from that Project?

nleroy917 commented 2 years ago

@Khoroshevskyi Let me know what you think of the new from_dict() method I wrote. I added some tests too. As of right now, I am just comparing the dictionary representations of the projects to confirm they are accurate:

    @pytest.mark.parametrize(
        "example_pep_cfg_path", EXAMPLE_TYPES, indirect=True
    )
    def test_from_dict_instatiation(self, example_pep_cfg_path):
        """
        Verify that we can accurately instantiate a project from 
        its dictionary representation.
        """
        p = Project(cfg=example_pep_cfg_path)
        p2 = Project() # empty
        p2.from_dict(p.to_dict())
        assert p.to_dict() == p2.to_dict()

Doesn't feel bulletproof, though.

khoroshevskyi commented 2 years ago

Fixed