Skip to content

Commit 35291b7

Browse files
authored
Merge pull request #80 from Ensembl/genome-counts
add genome_counts endpoint
2 parents ddeea5d + 1d6abef commit 35291b7

4 files changed

Lines changed: 93 additions & 11 deletions

File tree

app/api/models/genome.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,14 @@ class GenomeGroupsResponse(BaseModel):
207207
genome_groups: list[GenomeGroup] = Field(alias="genomeGroups")
208208

209209
class GenomesInGroupResponse(BaseModel):
210-
genomes: list[BaseGenomeDetails] = Field(alias="genomes")
210+
genomes: list[BaseGenomeDetails] = Field(alias="genomes")
211+
212+
213+
class GenomeCountItem(BaseModel):
214+
label: str
215+
count: int
216+
217+
218+
class GenomeCountsResponse(BaseModel):
219+
total: int = 0
220+
counts: list[GenomeCountItem] = Field(default_factory=list)

app/api/resources/grpc_client.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,11 @@ def get_genomes_in_group(self, group_id: str, release_label: str):
182182
"ensembl_metadata.GenomesInGroupRequest"
183183
)
184184
request = request_class(group_id=group_id, release_label=release_label)
185-
return self.stub.GetGenomesInGroup(request)
185+
return self.stub.GetGenomesInGroup(request)
186+
187+
def get_genome_counts(self, release_label: str | None):
188+
request_class = self.reflector.message_class(
189+
"ensembl_metadata.GenomeCountsRequest"
190+
)
191+
request = request_class(release_label=release_label)
192+
return self.stub.GetGenomeCounts(request)

app/api/resources/metadata.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from api.models.popular_species import PopularSpeciesGroup
2727
from api.models.karyotype import Karyotype
2828
from api.models.genome import BriefGenomeDetails, GenomeDetails, DatasetAttributes, GenomeByKeyword, Release, \
29-
GenomeGroupsResponse, GenomesInGroupResponse
29+
GenomeGroupsResponse, GenomesInGroupResponse, GenomeCountsResponse
3030
from api.models.ftplinks import FTPLinks
3131
from api.models.vep import VepFilePaths
3232

@@ -350,16 +350,16 @@ async def get_releases(
350350
return response_data
351351

352352
@router.get("/genome_groups", name="genome_groups")
353-
@redis_cache("genome_groups", arg_keys=["group_type", "release_label"])
353+
@redis_cache("genome_groups", arg_keys=["group_type", "release"])
354354
async def get_genome_groups(
355355
group_type: str = Query(..., description="Group type, e.g. 'structural_variant'"),
356-
release_label: str | None = Query(None, description="Optional release label, e.g. '2025-02'")
356+
release: str | None = Query(None, description="Optional release label, e.g. '2025-02'")
357357
):
358358
try:
359359
genome_groups_dict = MessageToDict(
360360
grpc_client.get_genome_groups_with_reference(
361361
group_type=group_type,
362-
release_label=release_label
362+
release_label=release
363363
)
364364
)
365365
logging.debug(f"genome_groups_dict: {genome_groups_dict}")
@@ -377,16 +377,16 @@ async def get_genome_groups(
377377
return response_error_handler({"status": 500})
378378

379379
@router.get("/genome_groups/{group_id}/genomes", name="genomes_in_group")
380-
@redis_cache("genomes_in_group", arg_keys=["group_id", "release_label"])
380+
@redis_cache("genomes_in_group", arg_keys=["group_id", "release"])
381381
async def get_genomes_in_group(
382382
group_id: str = Path(..., description="Group ID, e.g. 'grch38-group'"),
383-
release_label: str | None = Query(None, description="Optional release label, e.g. '2025-02'")
383+
release: str | None = Query(None, description="Optional release label, e.g. '2025-02'")
384384
):
385385
try:
386386
genomes_in_group_dict = MessageToDict(
387387
grpc_client.get_genomes_in_group(
388388
group_id=group_id,
389-
release_label=release_label
389+
release_label=release
390390
)
391391
)
392392
logging.debug(f"genomes_in_group_dict: {genomes_in_group_dict}")
@@ -402,3 +402,20 @@ async def get_genomes_in_group(
402402
except Exception as ex:
403403
logging.exception("Error in get_genomes_in_group")
404404
return response_error_handler({"status": 500})
405+
406+
407+
@router.get("/genome_counts", name="genome_counts")
408+
@redis_cache(key_prefix="genome_counts", arg_keys=["release"])
409+
async def get_genome_counts(
410+
release: str | None = Query(None, description="Optional release label to filter counts, e.g. '2025-02'")
411+
):
412+
try:
413+
genome_counts_dict = MessageToDict(
414+
grpc_client.get_genome_counts(release_label=release)
415+
)
416+
genome_counts = GenomeCountsResponse(**genome_counts_dict)
417+
response_data = responses.JSONResponse(genome_counts.model_dump(), status_code=200)
418+
except Exception as ex:
419+
logging.exception("Error in get_genome_counts")
420+
return response_error_handler({"status": 500})
421+
return response_data

docs/APISpecification.yaml

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,29 @@ paths:
235235
$ref: '#/components/schemas/PopularSpecies'
236236
'500':
237237
$ref: '#/components/responses/500InternalServerError'
238+
/api/metadata/genome_counts:
239+
get:
240+
tags:
241+
- api
242+
summary: Genome counts grouped by specific taxonomic group
243+
description: Returns aggregated genome counts optionally filtered by release label.
244+
parameters:
245+
- name: release
246+
in: query
247+
required: false
248+
description: Filter counts for genomes that belong to a specific release label.
249+
schema:
250+
type: string
251+
example: 2025-05
252+
responses:
253+
'200':
254+
description: successful operation
255+
content:
256+
application/json:
257+
schema:
258+
$ref: '#/components/schemas/GenomeCountsResponse'
259+
'500':
260+
$ref: '#/components/responses/500InternalServerError'
238261
/api/metadata/genome/{genome_id}/dataset/{dataset_type}/attributes:
239262
get:
240263
description: Returns a list of attributes of a given dataset of a genome.
@@ -392,7 +415,7 @@ paths:
392415
schema:
393416
type: string
394417
- in: query
395-
name: release_label
418+
name: release
396419
required: false
397420
schema:
398421
type: string
@@ -420,7 +443,7 @@ paths:
420443
schema:
421444
type: string
422445
- in: query
423-
name: release_label
446+
name: release
424447
required: false
425448
schema:
426449
type: string
@@ -508,6 +531,31 @@ components:
508531
- type
509532
- is_reference
510533
- latest_genome
534+
GenomeCountItem:
535+
type: object
536+
properties:
537+
label:
538+
type: string
539+
example: Animals
540+
count:
541+
type: integer
542+
example: 1207
543+
required:
544+
- label
545+
- count
546+
GenomeCountsResponse:
547+
type: object
548+
properties:
549+
total:
550+
type: integer
551+
example: 4218
552+
counts:
553+
type: array
554+
items:
555+
$ref: '#/components/schemas/GenomeCountItem'
556+
required:
557+
- total
558+
- counts
511559
GenomeStats:
512560
type: object
513561
properties:

0 commit comments

Comments
 (0)