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

New schema field - secondary contact list #1388

Merged
merged 13 commits into from
Feb 14, 2025
1 change: 1 addition & 0 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ not be abused to represent any non-individual.
In addition to the primary responsible contact person, the Bioregistry has
structured fields for additional contact methods, such as:

- `contact_extras` for annotating secondary contact people
- `contact_page` for annotating the URL of a web page that has contact
information, e.g., containing a contact form. Only curate this field if a
direct email is not available, as this is the least transparent option for
Expand Down
5 changes: 5 additions & 0 deletions src/bioregistry/app/templates/resource.html
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,11 @@ <h5 style="margin: 0"><a href="{{ url_for("metaregistry_ui.resources") }}">Regis
<span class="badge badge-pill badge-warning">Missing Contact</span>
{% endif %}
</dd>
{%- for secondary_contact in resource.contact_extras or [] %}
<dd>
{{ utils.render_author(secondary_contact, link=none) }}
</dd>
{%- endfor %}
{% if resource.owners %}
<dt>Identifier Space Owner{% if resource.owners | length > 1 %}s{% endif %}</dt>
{% for owner in resource.owners %}
Expand Down
26 changes: 20 additions & 6 deletions src/bioregistry/data/bioregistry.json
Original file line number Diff line number Diff line change
Expand Up @@ -117062,9 +117062,10 @@
"prefix": "UNIPARC"
},
"contact": {
"email": "[email protected]",
"name": "Rolf Apweiler",
"orcid": "0000-0001-7078-200X"
"email": "[email protected]",
"github": "bateman-research",
"name": "Alex Bateman",
"orcid": "0000-0002-6982-4660"
},
"edam": {
"description": "Accession number of a UniParc (protein sequence) database entry.",
Expand Down Expand Up @@ -117230,10 +117231,23 @@
"uri_format": "https://www.uniprot.org/uniprotkb/$1/entry"
},
"contact": {
"email": "[email protected]",
"name": "Rolf Apweiler",
"orcid": "0000-0001-7078-200X"
"email": "[email protected]",
"github": "bateman-research",
"name": "Alex Bateman",
"orcid": "0000-0002-6982-4660"
},
"contact_extras": [
{
"email": "[email protected]",
"name": "Alan Bridge",
"orcid": "0000-0003-2148-9135"
},
{
"email": "[email protected]",
"name": "Cathy Wu",
"orcid": "0000-0001-6379-8601"
}
],
"contact_page": "https://www.uniprot.org/contact",
"contributor_extras": [
{
Expand Down
16 changes: 16 additions & 0 deletions src/bioregistry/schema/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,22 @@
"default": null,
"description": "The contact email address for the resource. This must correspond to a specific person and not be a listserve nor a shared email account."
},
"contact_extras": {
"anyOf": [
{
"items": {
"$ref": "#/$defs/Attributable"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"description": "Secondary contacts. It's required to have a primary contact to have this field.",
"title": "Contact Extras"
},
"contact_page": {
"anyOf": [
{
Expand Down
4 changes: 4 additions & 0 deletions src/bioregistry/schema/struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,10 @@ class Resource(BaseModel):
"person and not be a listserve nor a shared email account."
),
)
contact_extras: list[Attributable] | None = Field(
default=None,
description="Secondary contacts. It's required to have a primary contact to have this field.",
)
contact_page: str | None = Field(
default=None,
description="A URL for a web page that has contact information, e.g., containing a contact form. "
Expand Down
6 changes: 6 additions & 0 deletions src/bioregistry/schema_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,12 @@ def read_prefix_contacts(registry: Mapping[str, Resource]) -> Mapping[str, set[s
contact_orcid = resource.get_contact_orcid()
if contact_orcid:
rv[contact_orcid].add(prefix)

# Add all secondary contacts' ORCIDs
for secondary_contact in resource.contact_extras or []:
if secondary_contact.orcid:
rv[secondary_contact.orcid].add(prefix)

return dict(rv)


Expand Down
16 changes: 16 additions & 0 deletions tests/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,9 @@ def test_reviewers(self):
def test_contacts(self):
"""Check contacts have minimal metadata."""
for prefix, resource in self.registry.items():
with self.subTest(prefix=prefix):
if resource.contact_extras:
self.assertIsNotNone(resource.contact)
if not resource.contact:
continue
with self.subTest(prefix=prefix):
Expand All @@ -839,6 +842,19 @@ def test_contacts(self):
)
self.assert_contact_metadata(resource.contact)

def test_secondary_contacts(self) -> None:
"""Check secondary contacts."""
for prefix, resource in self.registry.items():
if not resource.contact_extras:
continue
with self.subTest(prefix=prefix):
self.assertIsNotNone(resource.contact)
for contact in resource.contact_extras:
self.assert_contact_metadata(contact)
self.assertNotEqual(
resource.contact.orcid, contact.orcid, msg="duplicate secondary contact"
)

def test_contact_page(self) -> None:
"""Test curation of contact page."""
for prefix, resource in self.registry.items():
Expand Down