Skip to content

Feature/ega2 catalog - #106

Merged
SeanBerrieHRI merged 9 commits into
mainfrom
feature/EGA2Catalog
Aug 31, 2026
Merged

Feature/ega2 catalog#106
SeanBerrieHRI merged 9 commits into
mainfrom
feature/EGA2Catalog

Conversation

@SeanBerrieHRI

@SeanBerrieHRI SeanBerrieHRI commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Description:

Summary

  • Adds a new ega CLI input that fetches dataset metadata from the EGA (European Genome-phenome Archive) metadata API by accession ID
  • Adds map-ega-hriv2 to map EGA dataset metadata into the Health-RI DCAT dataset model, with dataset-level config (theme, publisher, contact point, access rights, applicable legislation) supplied via the img2catalog config file
  • Wires the new input/mapping into the existing rdf and fdp output commands, and adds an example config (examples/ega/example_config.toml)

Test plan

  • tests/img2catalog/inputs/test_ega.py — EGA API fetch input tests
  • tests/img2catalog/mapping/test_ega.py — EGA → Health-RI DCAT mapping tests
  • Manually verified against a local FAIR Data Point: img2catalog -c examples/ega/example_config.toml ega -a <accession_id> map-ega-hriv2 fdp --fdp <url> --username <user> --password <pass> --catalog <catalog_uri>

Summary by Sourcery

Integrate EGA dataset metadata ingestion and Health-RI catalog export into img2catalog.

New Features:

  • Add an EGA CLI input for fetching dataset metadata by accession ID.
  • Map EGA metadata into the Health-RI DCAT dataset model using configurable dataset, publisher, and contact metadata.
  • Support exporting mapped EGA datasets through the existing RDF and FAIR Data Point outputs.

Enhancements:

  • Handle failed EGA dataset requests without preventing successful datasets from being processed.

Build:

  • Add the requests dependency and an example EGA configuration.

Tests:

  • Add coverage for EGA API retrieval and EGA-to-Health-RI mapping.

@sourcery-ai

sourcery-ai Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Introduces an EGA accession-based CLI ingestion path, maps EGA metadata plus node-supplied configuration into Health-RI DCAT, and connects the result to RDF and FAIR Data Point outputs with tests and an example configuration.

Sequence diagram for EGA metadata ingestion and catalog output

sequenceDiagram
    participant User
    participant CLI
    participant EGAAPI
    participant Mapping
    participant RDF
    participant FDP

    User->>CLI: ega -a dataset_id
    CLI->>EGAAPI: fetch_ega_datasets(dataset_ids, api_url)
    EGAAPI-->>CLI: Dataset metadata
    User->>CLI: map-ega-hriv2
    CLI->>Mapping: map_ega_to_healthri_dcat_dataset(ega_dataset, config)
    Mapping-->>CLI: HRIDataset
    User->>CLI: rdf or fdp
    CLI->>RDF: Serialize mapped dataset
    CLI->>FDP: Publish mapped dataset
Loading

File-Level Changes

Change Details Files
Adds EGA metadata ingestion with configurable API access and batch accession handling.
  • Introduces ega CLI input with repeatable accession IDs and API URL configuration.
  • Fetches each dataset from the EGA metadata API with a 30-second timeout.
  • Continues processing when individual requests fail, logging skipped datasets.
src/img2catalog/inputs/ega.py
src/img2catalog/cli_app.py
src/img2catalog/const.py
pyproject.toml
tests/img2catalog/inputs/test_ega.py
Maps EGA dataset responses into the Health-RI DCAT model using local dataset configuration for non-EGA metadata.
  • Maps identifiers, title, description, sample count, release date, and technologies.
  • Combines EGA technologies with configured keywords and constructs publisher, creator, contact point, theme, legislation, and access-rights fields from configuration.
  • Uses an internal dataset URI when wiring mapped objects to RDF and FDP outputs.
src/img2catalog/mappings/ega.py
src/img2catalog/cli_app.py
examples/ega/example_config.toml
tests/img2catalog/mapping/test_ega.py
Integrates the EGA pipeline into existing output commands and adds automated coverage.
  • Registers map-ega-hriv2 beneath the EGA input and exposes RDF and FDP outputs.
  • Adds shared EGA fixtures and tests for API success/failure behavior and mapping behavior.
  • Adds an example configuration showing required dataset, publisher, and contact-point settings.
src/img2catalog/cli_app.py
tests/conftest.py
tests/img2catalog/ega_fixtures.py
tests/img2catalog/inputs/test_ega.py
tests/img2catalog/mapping/test_ega.py
examples/ega/example_config.toml
.idea/.gitignore

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 4 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="pyproject.toml" line_range="37" />
<code_context>
   "sparqlwrapper~=2.0",
   "fairclient >= 1.0.0",
   "pandas >= 2.0.0",
+  "requests >= 2.34.2",
 ]

</code_context>
<issue_to_address>
**issue (bug_risk):** Package installation fails because the dependency requires `requests >= 2.34.2`, a version that is not available in the Requests release line, so the project dependency resolver cannot satisfy the requirement.

**Triggers:** When installing the project from a clean environment.

**Suggested fix:** Use an available Requests version constraint, such as the intended released version or a compatible lower bound.

```suggestion
  "requests >= 2.32.0",
```
</issue_to_address>

### Comment 2
<location path="src/img2catalog/mappings/ega.py" line_range="38" />
<code_context>
+def fetch_ega_datasets(dataset_ids: List[str], api_url: str) -> List[Dict]:
+    datasets = []
+    for dataset_id in dataset_ids:
+        try:
+            datasets.append(fetch_ega_dataset(dataset_id, api_url))
+        except requests.RequestException as e:
</code_context>
<issue_to_address>
**issue (bug_risk):** `get_release_date` returns the unparseable string despite its `Optional[datetime]` contract, so `map_ega_to_healthri_dcat_dataset` passes that string to `HRIDataset` and model validation raises instead of producing a dataset for an API response with an invalid release date.

**Triggers:** When an EGA dataset contains a non-ISO `released_date`.

**Suggested fix:** Return `None` after logging the parse failure, or raise a deliberate mapping error before constructing `HRIDataset`; do not return a string from a datetime-typed helper.

```suggestion
        return None
```
</issue_to_address>

### Comment 3
<location path="src/img2catalog/inputs/ega.py" line_range="18-22" />
<code_context>
+def fetch_ega_datasets(dataset_ids: List[str], api_url: str) -> List[Dict]:
+    datasets = []
+    for dataset_id in dataset_ids:
+        try:
+            datasets.append(fetch_ega_dataset(dataset_id, api_url))
+        except requests.RequestException as e:
+            logger.warning("Error fetching EGA dataset %s: %s", dataset_id, e)
+
+    return datasets
\ No newline at end of file
</code_context>
<issue_to_address>
**issue (bug_risk):** Request failures are logged and discarded, so the CLI exits successfully with an incomplete or empty dataset list even though one or more explicitly requested accession IDs were not imported.

**Triggers:** When any requested EGA accession returns an HTTP error, times out, or otherwise raises `requests.RequestException`.

**Suggested fix:** Propagate an aggregate error or make the CLI exit nonzero when a requested accession cannot be fetched; if partial results are intentional, report the failed IDs prominently and distinguish the run from a successful import.
</issue_to_address>

### Comment 4
<location path="examples/ega/example_config.toml" line_range="8" />
<code_context>
+theme = ["http://publications.europa.eu/resource/authority/data-theme/HEAL"]
+keyword = ["list", "of", "key", "words"]
+access_rights = "http://publications.europa.eu/resource/authority/access-right/PUBLIC"
+applicable_legislation = ["http://publications.europa.eu/resource/authority/access-right/NON_PUBLIC"]
+
+[dataset.publisher]
</code_context>
<issue_to_address>
**issue:** The example config declares the access-right vocabulary URI `.../access-right/NON_PUBLIC` as applicable legislation, so every generated EGA dataset contains an invalid legislation value rather than a legal-act URI.

**Triggers:** When the documented example configuration is used for the manual EGA-to-RDF or EGA-to-FDP command.

**Suggested fix:** Replace the value with the applicable legal instrument URI intended for the node's datasets.

```suggestion
applicable_legislation = ["http://data.europa.eu/eli/reg/2025/327/oj"]
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread pyproject.toml
Comment thread src/img2catalog/mappings/ega.py
Comment on lines +18 to +22
try:
datasets.append(fetch_ega_dataset(dataset_id, api_url))
except requests.RequestException as e:
logger.warning("Error fetching EGA dataset %s: %s", dataset_id, e)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Request failures are logged and discarded, so the CLI exits successfully with an incomplete or empty dataset list even though one or more explicitly requested accession IDs were not imported.

Triggers: When any requested EGA accession returns an HTTP error, times out, or otherwise raises requests.RequestException.

Suggested fix: Propagate an aggregate error or make the CLI exit nonzero when a requested accession cannot be fetched; if partial results are intentional, report the failed IDs prominently and distinguish the run from a successful import.

Comment thread examples/ega/example_config.toml
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
71.6% Coverage on New Code (required ≥ 80%)
B Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@ishtiaqahmad ishtiaqahmad left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While pushing data to Fair Data Point (FDP), the EGA client defaults to port 80, which is incorrect. This should be fixed, but let's treat it as out of scope for this PR.

@SeanBerrieHRI
SeanBerrieHRI merged commit 3a2297d into main Aug 31, 2026
19 of 20 checks passed
@SeanBerrieHRI
SeanBerrieHRI deleted the feature/EGA2Catalog branch August 31, 2026 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants