From 25beec8cb38cb2a3849cad02b210b18d0d68e19b Mon Sep 17 00:00:00 2001 From: Charles Tapley Hoyt Date: Thu, 16 Mar 2023 17:45:16 +0100 Subject: [PATCH] Implement URI mapping service (#773) Closes #686 This adds the URI mapping service implemented in https://github.com/cthoyt/curies/pull/41. It will allow for SPARQL queries to be written that call the Bioregistry as a service for generating URI mappings (e.g., between OBO PURLs, Identifiers.org URIs, and first-party URIs whose URI prefixes are stored in the Bioregistry). Here's a simplified example that doesn't require any triple store, and can be directly executed with RDFLib: ```sparql SELECT DISTINCT ?s ?o WHERE { VALUES ?s { } SERVICE { ?s owl:sameAs ?o } } ``` returns the following (some not shown, you should get the idea): | subject | object | |---------------------------------------|------------------------------------------------- | | http://purl.obolibrary.org/obo/CHEBI_24867 | http://purl.obolibrary.org/obo/CHEBI_24867 | | http://purl.obolibrary.org/obo/CHEBI_24867 | http://identifiers.org/chebi/24867 | | http://purl.obolibrary.org/obo/CHEBI_24867 | https://www.ebi.ac.uk/chebi/searchId.do?chebiId=24867 | | ... | ... | This is built on top of the [`curies.Converter.expand_pair_all`](https://curies.readthedocs.io/en/latest/api/curies.Converter.html#curies.Converter.expand_pair_all), which itself is populated by all of the URI format strings available in the Bioregistry. To see examples of the possible ChEBI URIs, see https://bioregistry.io/registry/chebi. --- setup.cfg | 2 +- src/bioregistry/app/impl.py | 4 ++++ src/bioregistry/resolve.py | 3 +-- src/bioregistry/resource_manager.py | 9 +++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index 20f33762b..0fbad6a85 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,7 +51,7 @@ install_requires = click more_click>=0.1.2 pydantic - curies + curies>=0.5.0 zip_safe = false include_package_data = True diff --git a/src/bioregistry/app/impl.py b/src/bioregistry/app/impl.py index cf6d49af0..9cfb6d19e 100644 --- a/src/bioregistry/app/impl.py +++ b/src/bioregistry/app/impl.py @@ -5,6 +5,7 @@ from textwrap import dedent from typing import TYPE_CHECKING, Any, Mapping, Optional, Union +from curies.mapping_service import get_flask_mapping_blueprint from flasgger import Swagger from flask import Flask from flask_bootstrap import Bootstrap4 @@ -169,6 +170,9 @@ def get_app( app.register_blueprint(api_blueprint) app.register_blueprint(ui_blueprint) + sparql_blueprint = get_flask_mapping_blueprint(app.manager.converter) + app.register_blueprint(sparql_blueprint) + # Make manager available in all jinja templates app.jinja_env.globals.update(manager=app.manager, curie_to_str=curie_to_str) return app diff --git a/src/bioregistry/resolve.py b/src/bioregistry/resolve.py index bc6550984..d407a3105 100644 --- a/src/bioregistry/resolve.py +++ b/src/bioregistry/resolve.py @@ -982,7 +982,6 @@ def get_converter(**kwargs) -> curies.Converter: return manager.get_converter(**kwargs) -@lru_cache(1) def get_default_converter() -> curies.Converter: """Get a converter from this manager.""" - return manager.get_converter() + return manager.converter diff --git a/src/bioregistry/resource_manager.py b/src/bioregistry/resource_manager.py index 05cc7fb9a..e18443508 100644 --- a/src/bioregistry/resource_manager.py +++ b/src/bioregistry/resource_manager.py @@ -159,6 +159,15 @@ def __init__( self.provided_by = dict(provided_by) self.has_parts = dict(has_parts) + self._converter = None + + @property + def converter(self) -> curies.Converter: + """Get the default converter.""" + if self._converter is None: + self._converter = curies.Converter(records=self.get_curies_records()) + return self._converter + def write_registry(self): """Write the registry.""" write_registry(self.registry)