Skip to content

Commit

Permalink
Merge pull request #158 from Ensembl/server_reflection
Browse files Browse the repository at this point in the history
added gRPC reflection to Thoas client
  • Loading branch information
darefalola authored Nov 20, 2024
2 parents ca43caf + 14db968 commit 5b42a6e
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 29 deletions.
21 changes: 19 additions & 2 deletions common/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
import pymongo
import mongomock
import grpc
from ensembl.production.metadata.grpc import ensembl_metadata_pb2_grpc

from yagrc import reflector as yagrc_reflector

from common.utils import process_release_version

Expand Down Expand Up @@ -117,8 +118,24 @@ def __init__(self, config):
"{}:{}".format(host, port), options=(("grpc.enable_http_proxy", 0),)
)

# create reflector for querying server using reflection
self.reflector = yagrc_reflector.GrpcReflectionClient()

# use reflection to load service definitions and message types
self.reflector.load_protocols(
self.channel, symbols=["ensembl_metadata.EnsemblMetadata"]
)

# dynamically retrieve the client stub class for service
stub_class = self.reflector.service_stub_class(
"ensembl_metadata.EnsemblMetadata"
)

# bind the client and the server
self.stub = ensembl_metadata_pb2_grpc.EnsemblMetadataStub(self.channel)
self.stub = stub_class(self.channel)

def get_grpc_stub(self):
return self.stub

def get_grpc_reflector(self):
return self.reflector
1 change: 0 additions & 1 deletion common/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,5 @@ def format(self, context):
)
return {
"execution_time_in_seconds": exec_time_in_secs,
"metadata_api_version": utils.get_ensembl_metadata_api_version(),
}
return None
15 changes: 0 additions & 15 deletions common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,6 @@ def process_release_version(grpc_response):
return "release_" + release_version


def get_ensembl_metadata_api_version():
"""
Get the Metadata API tag from requirement.txt file
"""
version = "unknown" # default version
with open("requirements.txt", "r", encoding="UTF-8") as file:
lines = file.readlines()
for line in lines:
if "ensembl-metadata-api" in line:
# Extract the tag part from the line
version = line.strip().split("@")[-1]
break
return version


def check_requested_fields(info: GraphQLResolveInfo, fields: List[str]) -> List[bool]:
"""
Check if specific fields are requested in the GraphQL query.
Expand Down
3 changes: 1 addition & 2 deletions graphql_service/resolver/gene_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from typing import Dict, Optional, List, Any, Mapping

from ariadne import QueryType, ObjectType
from ensembl.production.metadata.api.models import Genome
from graphql import GraphQLResolveInfo, GraphQLError
from pymongo.database import Database, Collection

Expand Down Expand Up @@ -868,7 +867,7 @@ def resolve_genome(_, info: GraphQLResolveInfo, by_genome_uuid: Dict[str, str])


def create_genome_response(
genome: Genome,
genome,
dataset_data: Optional[List] = None,
assembly_data: Optional[Mapping[Any, Any]] = None,
) -> Dict:
Expand Down
3 changes: 2 additions & 1 deletion graphql_service/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@

GRPC_SERVER = db.GRPCServiceClient(os.environ)
GRPC_STUB = GRPC_SERVER.get_grpc_stub()
GRPC_MODEL = grpc_model.GRPC_MODEL(GRPC_STUB)
GRPC_REFLECTOR = GRPC_SERVER.get_grpc_reflector()
GRPC_MODEL = grpc_model.GRPC_MODEL(GRPC_STUB, GRPC_REFLECTOR)

EXECUTABLE_SCHEMA = prepare_executable_schema()

Expand Down
29 changes: 22 additions & 7 deletions grpc_service/grpc_model.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import logging

from ensembl.production.metadata.grpc import ensembl_metadata_pb2

logger = logging.getLogger(__name__)


class GRPC_MODEL: # pylint: disable=invalid-name
def __init__(self, grpc_stub):
def __init__(self, grpc_stub, grpc_reflector):
self.grpc_stub = grpc_stub
self.reflector = grpc_reflector

def get_genome_by_genome_uuid(self, genome_uuid, release_version=None):
logger.debug(
"Received RPC for GetGenomeByUUID with genome_uuid: '%s', release: %s",
genome_uuid,
release_version,
)
request = ensembl_metadata_pb2.GenomeUUIDRequest(
request_class = self.reflector.message_class(
"ensembl_metadata.GenomeUUIDRequest"
)

request = request_class(
genome_uuid=genome_uuid, release_version=release_version
)
response = self.grpc_stub.GetGenomeByUUID(request)

return response

def get_genome_by_specific_keyword(
Expand Down Expand Up @@ -47,7 +51,12 @@ def get_genome_by_specific_keyword(
species_taxonomy_id,
release_version,
)
request = ensembl_metadata_pb2.GenomeBySpecificKeywordRequest(

request_class = self.reflector.message_class(
"ensembl_metadata.GenomeBySpecificKeywordRequest"
)

request = request_class(
tolid=tolid,
assembly_accession_id=assembly_accession_id,
assembly_name=assembly_name,
Expand All @@ -67,13 +76,19 @@ def get_datasets_list_by_uuid(self, genome_uuid, release_version=None):
genome_uuid,
release_version,
)
request = ensembl_metadata_pb2.DatasetsRequest(
request_class = self.reflector.message_class("ensembl_metadata.DatasetsRequest")

request = request_class(
genome_uuid=genome_uuid, release_version=release_version
)
response = self.grpc_stub.GetDatasetsListByUUID(request)
return response

def get_release_by_genome_uuid(self, genome_uuid):
request = ensembl_metadata_pb2.ReleaseVersionRequest(genome_uuid=genome_uuid)
request_class = self.reflector.message_class(
"ensembl_metadata.ReleaseVersionRequest"
)

request = request_class(genome_uuid=genome_uuid)
response = self.grpc_stub.GetReleaseVersionByUUID(request)
return response
2 changes: 2 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ ignore_missing_imports = True
[mypy-ensembl.production.metadata.*]
ignore_missing_imports = True

[mypy-yagrc.*]
ignore_missing_imports = True
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ aiodataloader==0.4.0
ariadne==0.23
python-dotenv==1.0.1
uvicorn==0.18.1
ensembl-metadata-api@git+https://github.com/Ensembl/[email protected]
grpcio==1.66.1
grpcio-tools==1.66.1
ensembl-utils==0.4.4
ensembl-py==2.1.3
yagrc==1.1.2

0 comments on commit 5b42a6e

Please sign in to comment.