def test_same_given_given(self, original, other):
     # Same Store name. Given endpoint. Given token.
     # => Use original endpoint and original token.
     original["k2"] = "v2b"
     with_defaults(original, other, "k2", "k2", ["k3", "k4"])
     assert original["k3"] == "v3a"
     assert original["k4"] == "v4a"
示例#2
0
def prepare_resolver(config: Dict, store_config: Dict) -> Tuple[str, Resolver]:
    if config["origin"] == "store":
        with_defaults(config, store_config, "source", "name",
                      ["endpoint", "token", "bucket", "model_context"])
    resolver_name = config.pop("resolver")
    resolver = import_class(resolver_name, "resolvers")
    return resolver.__name__, resolver(**config)
 def test_same_given_missing(self, original, other):
     # Same Store name. Given endpoint. Missing token.
     # => Use original endpoint and other token.
     original["k2"] = "v2b"
     del original["k4"]
     with_defaults(original, other, "k2", "k2", ["k3", "k4"])
     assert original["k3"] == "v3a"
     assert original["k4"] == "v4b"
示例#4
0
    def __init__(self, configuration: Union[str, Dict], **kwargs) -> None:

        # Required minimal configuration: name for Model and Store, origin and source for Model.
        # Keyword arguments could be used to override the configuration provided for the Store.
        #
        # The configuration could be provided either as:
        #
        #   - A path to a YAML file with the following structure.
        #     Class name could be provided in three formats:
        #       * 'SomeClass',
        #       * 'SomeClass from package.module',
        #       * 'SomeClass from package.module.file'.
        #     When the class is from this package, the first is used. Otherwise, the two others.
        #     Values using braces with something inside should be quoted with double quotes.
        #     See demo-forge.yml in kgforge/examples/configurations/ for an example.
        #
        # Model:
        #   name: <a class name of a Model>
        #   origin: <'directory', 'url', or 'store'>
        #   source: <a directory path, an URL, or the class name of a Store>
        #   bucket: <when 'origin' is 'store', a Store bucket>
        #   endpoint: <when 'origin' is 'store', a Store endpoint, default to Store:endpoint>
        #   token: <when 'origin' is 'store', a Store token, default to Store:token>
        #   context:
        #     iri: <an IRI>
        #     bucket: <when 'origin' is 'store', a Store bucket, default to Model:bucket>
        #     endpoint: <when 'origin' is 'store', a Store endpoint, default to Model:endpoint>
        #     token: <when 'origin' is 'store', a Store token, default to Model:token>
        #
        # Store:
        #   name: <a class name of a Store>
        #   endpoint: <an URL>
        #   bucket: <a bucket as a string>
        #   token: <a token as a string>
        #   searchendpoints:
        #     <querytype>: <a query paradigm supported by configured store (e.g. sparql)>
        #       endpoint: <an IRI of a query endpoint>
        #   versioned_id_template: <a string template using 'x' to access resource fields>
        #   file_resource_mapping: <an Hjson string, a file path, or an URL>
        #
        # Resolvers:
        #   <scope>:
        #     - resolver: <a class name of a Resolver>
        #       origin: <'directory', 'web_service', or 'store'>
        #       source: <a directory path, a web service endpoint, or the class name of a Store>
        #       targets:
        #         - identifier: <a name, or an IRI>
        #           bucket: <a file name, an URL path, or a Store bucket>
        #       result_resource_mapping: <an Hjson string, a file path, or an URL>
        #       endpoint: <when 'origin' is 'store', a Store endpoint, default to Store:endpoint>
        #       token: <when 'origin' is 'store', a Store token, default to Store:token>
        #
        # Formatters:
        #   <identifier>: <a string template with replacement fields delimited by braces, i.e. '{}'>
        #
        #   - A Python dictionary with the following structure.
        #
        # {
        #     "Model": {
        #         "name": <str>,
        #         "origin": <str>,
        #         "source": <str>,
        #         "bucket": <str>,
        #         "endpoint": <str>,
        #         "token": <str>,
        #         "context": {
        #               "iri": <str>,
        #               "bucket": <str>,
        #               "endpoint": <str>,
        #               "token": <str>,
        #         }
        #     },
        #     "Store": {
        #         "name": <str>,
        #         "endpoint": <str>,
        #         "bucket": <str>,
        #         "token": <str>,
        #         "searchendpoints": {
        #           "<querytype>": {
        #               "endpoint": <str>
        #           }
        #         }
        #         "versioned_id_template": <str>,
        #         "file_resource_mapping": <str>,
        #     },
        #     "Resolvers": {
        #         "<scope>": [
        #             {
        #                 "resolver": <str>,
        #                 "origin": <str>,
        #                 "source": <str>,
        #                 "targets": [
        #                     {
        #                         "identifier": <str>,
        #                         "bucket": <str>,
        #                     },
        #                     ...,
        #                 ],
        #                 "result_resource_mapping": <str>,
        #                 "endpoint": <str>,
        #                 "token": <str>,
        #             },
        #             ...,
        #         ],
        #     },
        #     "Formatters": {
        #         "<name>": <str>,
        #         ...,
        #     },
        # }
        if isinstance(configuration, str):
            config_data = load_file_as_byte(configuration)
            config_data = config_data.decode("utf-8")
            config = yaml.safe_load(config_data)
        else:
            config = deepcopy(configuration)

        # Debugging.

        self._debug = kwargs.pop("debug", False)

        # Store.

        store_config = config.pop("Store")
        store_config.update(kwargs)

        # Model.

        model_config = config.pop("Model")
        if model_config["origin"] == "store":
            with_defaults(model_config, store_config, "source", "name", ["endpoint", "token", "bucket"])
        model_name = model_config.pop("name")
        model = import_class(model_name, "models")
        self._model: Model = model(**model_config)

        # Store.

        store_config.update(model_context=self._model.context())
        store_name = store_config.pop("name")
        store = import_class(store_name, "stores")
        self._store: Store = store(**store_config)
        store_config.update(name=store_name)

        # Resolvers.

        resolvers_config = config.pop("Resolvers", None)
        # Format: Optional[Dict[scope_name, Dict[resolver_name, Resolver]]].
        self._resolvers: Optional[Dict[str, Dict[str, Resolver]]] = prepare_resolvers(
            resolvers_config, store_config) if resolvers_config else None

        # Formatters.

        self._formatters: Optional[Dict[str, str]] = config.pop("Formatters", None)
 def test_different_name(self, original, other):
     # Different Store name. Do nothing
     original_copy = copy(original)
     with_defaults(original, other, "k2", "k2", ["k3", "k4"])
     assert original == original_copy