Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow provider specific examples #1429

Merged
merged 17 commits into from
Mar 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/bioregistry/app/templates/resource.html
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,8 @@ <h5 style="margin: 0">Providers</h5>
{% if providers %}
<p>
The local unique identifier <code>{{ example }}</code> is used to demonstrate the providers
available for {{ name_pack.value }}. A guide for curating additional providers can be found
available for {{ name_pack.value }}. Some providers may use a different example, which is displayed in the table below.
A guide for curating additional providers can be found
<a href="https://biopragmatics.github.io/bioregistry/curation/providers">here</a>.
</p>
{% else %}
Expand Down Expand Up @@ -651,7 +652,8 @@ <h5 class="card-header">Extra Providers</h5>
<tr>
<td><code>{{ provider.code }}</code></td>
<td>{{ provider.name }}</td>
{% set url = provider.resolve(example) %}
{% set example_id = provider.example if provider.example else example %}
{% set url = provider.resolve(example_id) %}
<td><a href="{{ url }}">{{ url }}</a></td>
</tr>
{% endfor %}
Expand Down
2 changes: 1 addition & 1 deletion src/bioregistry/app/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def resource(prefix: str) -> str | flask.Response:

example = _resource.get_example()
example_curie = _resource.get_example_curie(use_preferred=True)
example_extras = _resource.example_extras or []
example_extras = _resource.get_example_extras()
example_curie_extras = [
_resource.get_curie(example_extra, use_preferred=True) for example_extra in example_extras
]
Expand Down
2 changes: 1 addition & 1 deletion src/bioregistry/benchmarks/uri_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def iter_uris() -> Iterable[tuple[str, str, str, str]]:
for metaprefix, url in manager.get_providers_list(prefix, example):
if url.endswith(example): # skip funny formats
yield prefix, example, metaprefix, url
for extra_example in resource.example_extras or []:
for extra_example in resource.get_example_extras():
for metaprefix, url in manager.get_providers_list(prefix, extra_example):
if url.endswith(extra_example):
yield prefix, extra_example, metaprefix, url
Expand Down
2 changes: 1 addition & 1 deletion src/bioregistry/curation/add_ontology_regexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
example = resource.get_example()
if example:
rv.append(example)
rv.extend(resource.example_extras or [])
rv.extend(resource.get_example_extras())

Check warning on line 16 in src/bioregistry/curation/add_ontology_regexes.py

View check run for this annotation

Codecov / codecov/patch

src/bioregistry/curation/add_ontology_regexes.py#L16

Added line #L16 was not covered by tests
return rv


Expand Down
1 change: 1 addition & 0 deletions src/bioregistry/data/bioregistry.json
Original file line number Diff line number Diff line change
Expand Up @@ -89050,6 +89050,7 @@
{
"code": "furna",
"description": "FURNA (Functions of RNAs) is a database of ligand-RNA interactions and Gene Ontology annotations for RNAs in the Protein Data Bank (PDB).",
"example": "157d",
"homepage": "https://seq2fun.dcmb.med.umich.edu/furna/",
"name": "furna",
"publications": [
Expand Down
2 changes: 1 addition & 1 deletion src/bioregistry/resource_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,7 @@ def rasterized_resource(self, resource: Resource) -> Resource:
download_rdf=resource.get_download_rdf(),
# Registry properties
example=resource.get_example(),
example_extras=resource.example_extras,
example_extras=resource.get_example_extras(),
example_decoys=resource.example_decoys,
uri_format=resource.get_uri_format(),
rdf_uri_format=resource.get_rdf_uri_format(),
Expand Down
13 changes: 13 additions & 0 deletions src/bioregistry/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,19 @@
"default": null,
"description": "A list of publications about the provider. See the `indra` provider for `hgnc` for an example.",
"title": "Publications"
},
"example": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"description": "An example local identifier, specific to the provider. Providing this value is only necessary if the example associated with the prefix for which this is a provider is not resolvable by the provider. The example identifier should exclude any redundant usage of the prefix. For example, a GO identifier should only look like ``1234567`` and not like ``GO:1234567``",
"title": "Example"
}
},
"required": [
Expand Down
19 changes: 18 additions & 1 deletion src/bioregistry/schema/struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,14 @@
default=None,
description="A list of publications about the provider. See the `indra` provider for `hgnc` for an example.",
)
example: str | None = Field(
default=None,
description="An example local identifier, specific to the provider. Providing this value is "
"only necessary if the example associated with the prefix for which this is a provider "
"is not resolvable by the provider. The example identifier should exclude any redundant "
"usage of the prefix. For example, a GO identifier should only "
"look like ``1234567`` and not like ``GO:1234567``",
)

def resolve(self, identifier: str) -> str:
"""Resolve the identifier into a URI.
Expand Down Expand Up @@ -1355,9 +1363,18 @@
example = self.get_example()
if example:
rv.append(example)
rv.extend(self.example_extras or [])
rv.extend(self.get_example_extras())

Check warning on line 1366 in src/bioregistry/schema/struct.py

View check run for this annotation

Codecov / codecov/patch

src/bioregistry/schema/struct.py#L1366

Added line #L1366 was not covered by tests
return rv

def get_example_extras(self) -> list[str]:
"""Aggregate manually curated examples with provider-specific examples."""
rv = set(self.example_extras or [])
if self.providers:
for provider in self.providers:
if provider.example:
rv.add(provider.example)
return sorted(rv)

def get_example_curie(self, use_preferred: bool = False) -> str | None:
"""Get an example CURIE, if an example identifier is available.

Expand Down
9 changes: 5 additions & 4 deletions tests/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,15 +421,16 @@ def assert_is_valid_identifier(self, prefix: str, example: str) -> None:
def test_extra_examples(self):
"""Test extra examples."""
for prefix, entry in self.registry.items():
if not entry.example_extras:
example_extras = entry.get_example_extras()
if not example_extras:
continue
primary_example = entry.get_example()
with self.subTest(prefix=prefix):
self.assertIsNotNone(
primary_example, msg="entry has extra examples but not primary example"
)

for example in entry.example_extras:
for example in example_extras:
with self.subTest(prefix=prefix, identifier=example):
self.assertEqual(entry.standardize_identifier(example), example)
self.assertNotEqual(
Expand All @@ -438,8 +439,8 @@ def test_extra_examples(self):
self.assert_is_valid_identifier(prefix, example)

self.assertEqual(
len(entry.example_extras),
len(set(entry.example_extras)),
len(example_extras),
len(set(example_extras)),
msg="duplicate extra examples",
)

Expand Down