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 _initialize_service(self, source: str, targets: Dict[str, str], **source_config) -> Any: # Resolver data could be accessed from a directory, a web service, or a Store. # Initialize the access to the resolver data according to the source type. # POLICY Should not use 'self'. This is not a function only for the specialization to work. origin = source_config.pop("origin") if origin == "directory": dirpath = Path(source) return self._service_from_directory(dirpath, targets) elif origin == "web_service": return self._service_from_web_service(source, targets) elif origin == "store": store = import_class(source, "stores") return self._service_from_store(store, targets, **source_config) else: raise ConfigurationError( f"unrecognized Resolver origin '{origin}'")
def _initialize_service(self, source: str, **source_config) -> Any: # Model data could be loaded from a directory, an URL, or a Store. # Initialize the access to the model data according to the source type. # POLICY Should not use 'self'. This is not a function only for the specialization to work. origin = source_config.pop("origin") context_config = source_config.pop("context", {}) context_iri = context_config.get("iri", None) if origin == "directory": dirpath = Path(source) return self._service_from_directory(dirpath, context_iri) elif origin == "url": return self._service_from_url(source, context_iri) elif origin == "store": store = import_class(source, "stores") return self._service_from_store(store, context_config, **source_config) else: raise ConfigurationError(f"unrecognized Model origin '{origin}'")
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)