Skip to content

Commit

Permalink
gene apis enhanced to support sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
vikasguptaebi committed Nov 14, 2024
1 parent 4234e0f commit 30e4de1
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 53 deletions.
50 changes: 41 additions & 9 deletions dataportal_api/dataportal/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,20 @@ async def gene_autocomplete_suggestions(
# API Endpoint to search genes by query string
@gene_router.get("/search", response=GenePaginationSchema)
async def search_genes_by_string(
request, query: str, page: int = 1, per_page: int = 10
request,
query: str,
page: int = 1,
per_page: int = 10,
sort_field: Optional[str] = None,
sort_order: Optional[str] = "asc",
):
try:
paginated_results = await gene_service.search_genes(
query=query, page=page, per_page=per_page
query=query,
page=page,
per_page=per_page,
sort_field=sort_field,
sort_order=sort_order,
)
return paginated_results
except Exception as e:
Expand All @@ -176,17 +185,30 @@ async def get_gene_by_id(request, gene_id: int):

# API Endpoint to retrieve all genes
@gene_router.get("/", response=GenePaginationSchema)
async def get_all_genes(request, page: int = 1, per_page: int = 10):
return await gene_service.get_all_genes(page, per_page)
async def get_all_genes(
request,
page: int = 1,
per_page: int = 10,
sort_field: Optional[str] = None,
sort_order: Optional[str] = "asc",
):
return await gene_service.get_all_genes(page, per_page, sort_field, sort_order)


# API Endpoint to retrieve genes filtered by a single genome ID
@genome_router.get("/{genome_id}/genes", response=GenePaginationSchema)
async def get_genes_by_genome(
request, genome_id: int, page: int = 1, per_page: int = 10
request,
genome_id: int,
page: int = 1,
per_page: int = 10,
sort_field: Optional[str] = None,
sort_order: Optional[str] = "asc",
):
try:
return await gene_service.get_genes_by_genome(genome_id, page, per_page)
return await gene_service.get_genes_by_genome(
genome_id, page, per_page, sort_field, sort_order
)
except Exception as e:
logger.error(f"Error in get_genes_by_genome: {e}")
raise HttpError(500, f"Internal Server Error: {str(e)}")
Expand All @@ -195,10 +217,18 @@ async def get_genes_by_genome(
# API Endpoint to search genes by genome ID and gene string
@genome_router.get("/{genome_id}/genes/search", response=GenePaginationSchema)
async def search_genes_by_genome_and_string(
request, genome_id: int, query: str, page: int = 1, per_page: int = 10
request,
genome_id: int,
query: str,
page: int = 1,
per_page: int = 10,
sort_field: Optional[str] = None,
sort_order: Optional[str] = "asc",
):
try:
return await gene_service.search_genes(query, genome_id, page, per_page)
return await gene_service.search_genes(
query, genome_id, page, per_page, sort_field, sort_order
)
except Exception as e:
logger.error(f"Error in search_genes_by_genome_and_string: {e}")
raise HttpError(500, f"Internal Server Error: {str(e)}")
Expand All @@ -213,10 +243,12 @@ async def search_genes_by_multiple_genomes_and_species_and_string(
query: str = "",
page: int = 1,
per_page: int = 10,
sort_field: Optional[str] = None,
sort_order: Optional[str] = "asc",
):
try:
return await gene_service.get_genes_by_multiple_genomes_and_string(
genome_ids, species_id, query, page, per_page
genome_ids, species_id, query, page, per_page, sort_field, sort_order
)
except HttpError as e:
raise e
Expand Down
81 changes: 39 additions & 42 deletions dataportal_api/dataportal/services/gene_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,19 @@ async def get_gene_by_id(self, gene_id: int) -> GeneResponseSchema:
raise HttpError(500, "Internal Server Error")

async def get_all_genes(
self, page: int = 1, per_page: int = 10
self,
page: int = 1,
per_page: int = 10,
sort_field: Optional[str] = None,
sort_order: Optional[str] = "asc",
) -> GenePaginationSchema:
try:
genes, total_results = await self._fetch_paginated_genes(
Q(), page, per_page
Q(), page, per_page, sort_field, sort_order
)
serialized_genes = [self._serialize_gene(gene) for gene in genes]

return GenePaginationSchema(
results=serialized_genes,
page_number=page,
num_pages=(total_results + per_page - 1) // per_page,
has_previous=page > 1,
has_next=(page * per_page) < total_results,
total_results=total_results,
return self._create_pagination_schema(
serialized_genes, page, per_page, total_results
)
except Exception as e:
logger.error(f"Error fetching all genes: {e}")
Expand All @@ -87,7 +85,9 @@ async def search_genes(
genome_id: Optional[int] = None,
page: int = 1,
per_page: int = 10,
):
sort_field: Optional[str] = None,
sort_order: Optional[str] = "asc",
) -> GenePaginationSchema:
try:
filters = Q()
if query:
Expand All @@ -98,38 +98,31 @@ async def search_genes(
filters &= Q(strain_id=genome_id)

genes, total_results = await self._fetch_paginated_genes(
filters, page, per_page
filters, page, per_page, sort_field, sort_order
)
serialized_genes = [self._serialize_gene(gene) for gene in genes]

return GenePaginationSchema(
results=serialized_genes,
page_number=page,
num_pages=(total_results + per_page - 1) // per_page,
has_previous=page > 1,
has_next=(page * per_page) < total_results,
total_results=total_results,
return self._create_pagination_schema(
serialized_genes, page, per_page, total_results
)
except Exception as e:
logger.error(f"Error searching genes: {e}")
raise HttpError(500, "Internal Server Error")

async def get_genes_by_genome(
self, genome_id: int, page: int = 1, per_page: int = 10
):
self,
genome_id: int,
page: int = 1,
per_page: int = 10,
sort_field: Optional[str] = None,
sort_order: Optional[str] = "asc",
) -> GenePaginationSchema:
try:
genes, total_results = await self._fetch_paginated_genes(
Q(strain_id=genome_id), page, per_page
Q(strain_id=genome_id), page, per_page, sort_field, sort_order
)
serialized_genes = [self._serialize_gene(gene) for gene in genes]

return GenePaginationSchema(
results=serialized_genes,
page_number=page,
num_pages=(total_results + per_page - 1) // per_page,
has_previous=page > 1,
has_next=(page * per_page) < total_results,
total_results=total_results,
return self._create_pagination_schema(
serialized_genes, page, per_page, total_results
)
except Exception as e:
logger.error(f"Error fetching genes for genome ID {genome_id}: {e}")
Expand Down Expand Up @@ -158,6 +151,8 @@ async def get_genes_by_multiple_genomes_and_string(
query: str = None,
page: int = 1,
per_page: int = 10,
sort_field: Optional[str] = None,
sort_order: Optional[str] = "asc",
) -> GenePaginationSchema:
try:
genome_id_list = (
Expand All @@ -175,17 +170,11 @@ async def get_genes_by_multiple_genomes_and_string(
filters &= Q(gene_name__icontains=query.strip())

genes, total_results = await self._fetch_paginated_genes(
filters, page, per_page
filters, page, per_page, sort_field, sort_order
)
serialized_genes = [self._serialize_gene(gene) for gene in genes]

return GenePaginationSchema(
results=serialized_genes,
page_number=page,
num_pages=(total_results + per_page - 1) // per_page,
has_previous=page > 1,
has_next=(page * per_page) < total_results,
total_results=total_results,
return self._create_pagination_schema(
serialized_genes, page, per_page, total_results
)
except ValueError:
logger.error("Invalid genome ID provided")
Expand Down Expand Up @@ -278,14 +267,22 @@ def _create_pagination_schema(
)

async def _fetch_paginated_genes(
self, filter_criteria: Q, page: int, per_page: int
self,
filter_criteria: Q,
page: int,
per_page: int,
sort_field: Optional[str] = None,
sort_order: Optional[str] = "asc",
) -> Tuple[List[Gene], int]:
start = (page - 1) * per_page
order_prefix = "-" if sort_order == "desc" else ""
sort_by = f"{order_prefix}{sort_field}" if sort_field else "gene_name"

genes = await sync_to_async(
lambda: list(
Gene.objects.select_related("strain")
.filter(filter_criteria)
.order_by("gene_name")[start : start + per_page]
.order_by(sort_by)[start : start + per_page]
)
)()
total_results = await sync_to_async(
Expand Down
2 changes: 1 addition & 1 deletion k8s-hl/dev/mett-dataportal-api-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ spec:
runAsUser: 7123
runAsGroup: 1347
containers:
- image: quay.io/microbiome-informatics/mett-dataportal-api:v0.0.27
- image: quay.io/microbiome-informatics/mett-dataportal-api:v0.0.29
imagePullPolicy: Always
name: mett-dataportal-api-dev
env:
Expand Down
2 changes: 1 addition & 1 deletion k8s-hl/dev/mett-dataportal-app-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ spec:
app: mett-dataportal-react-app-dev
spec:
containers:
- image: quay.io/microbiome-informatics/mett-dataportal-react-app:v0.0.27
- image: quay.io/microbiome-informatics/mett-dataportal-react-app:v0.0.29
imagePullPolicy: Always
name: mett-dataportal-react-app-dev
env:
Expand Down

0 comments on commit 30e4de1

Please sign in to comment.