From 54b4bfdad6c66c976d26cf3146639c9c7e96314e Mon Sep 17 00:00:00 2001 From: Bilal El Houdaigui Date: Tue, 14 Oct 2025 09:23:20 +0100 Subject: [PATCH 1/5] initial working code (too code much duplication) --- .../metadata/grpc/ensembl_metadata.proto | 20 ++++ .../metadata/grpc/ensembl_metadata_pb2.py | 98 ++++++++++--------- .../grpc/ensembl_metadata_pb2_grpc.py | 44 +++++++++ .../metadata/grpc/protobuf_msg_factory.py | 27 +++++ .../production/metadata/grpc/servicer.py | 6 ++ src/ensembl/production/metadata/grpc/utils.py | 18 ++++ 6 files changed, 166 insertions(+), 47 deletions(-) diff --git a/protos/ensembl/production/metadata/grpc/ensembl_metadata.proto b/protos/ensembl/production/metadata/grpc/ensembl_metadata.proto index fb02c017..939c67ce 100644 --- a/protos/ensembl/production/metadata/grpc/ensembl_metadata.proto +++ b/protos/ensembl/production/metadata/grpc/ensembl_metadata.proto @@ -104,6 +104,9 @@ service EnsemblMetadata { // Get release version for a given genome_uuid rpc GetReleaseVersionByUUID(ReleaseVersionRequest) returns (ReleaseVersion) {} + // Get release label for a given genome_uuid + rpc GetReleaseLabelByUUID(ReleaseInfoRequest) returns (ReleaseLabel) {} + // Get attributes by genome UUID rpc GetAttributesValuesByUUID(DatasetAttributesValuesRequest) returns (DatasetAttributesValues) {} @@ -372,6 +375,10 @@ message ReleaseVersion { double release_version = 1; } +message ReleaseLabel { + string release_label = 1; +} + message DatasetAttributeValue { string attribute_name = 1; string attribute_value = 2; @@ -552,6 +559,10 @@ message FTPLinksRequest { /* Release version request +TODO: before removing this request message + we need to update the code in: + 1. Thoas: https://github.com/Ensembl/ensembl-thoas/blob/876dc846f7e7e61771c13aea152e1e3623881e39/grpc_service/grpc_model.py#L106 and + 2. Compara: https://github.com/Ensembl/ensembl-naxos/blob/b6430373ba59ce8aed7a50d9749d5ecc2d3ebaea/src/ensembl/io/naxos/metadata/grpc/client.py#L403 */ message ReleaseVersionRequest { string genome_uuid = 1; // Mandatory @@ -559,6 +570,15 @@ message ReleaseVersionRequest { double release_version = 3; // Optional } +/* +Release info request + */ +message ReleaseInfoRequest { + string genome_uuid = 1; // Mandatory + string dataset_type = 2; // Optional + double release_version = 3; // Optional +} + /* Dataset attribute request */ diff --git a/src/ensembl/production/metadata/grpc/ensembl_metadata_pb2.py b/src/ensembl/production/metadata/grpc/ensembl_metadata_pb2.py index 88e232e1..88b49be1 100755 --- a/src/ensembl/production/metadata/grpc/ensembl_metadata_pb2.py +++ b/src/ensembl/production/metadata/grpc/ensembl_metadata_pb2.py @@ -24,7 +24,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n7ensembl/production/metadata/grpc/ensembl_metadata.proto\x12\x10\x65nsembl_metadata\"\xbb\x02\n\x06Genome\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12,\n\x08\x61ssembly\x18\x02 \x01(\x0b\x32\x1a.ensembl_metadata.Assembly\x12&\n\x05taxon\x18\x03 \x01(\x0b\x32\x17.ensembl_metadata.Taxon\x12\x0f\n\x07\x63reated\x18\x04 \x01(\t\x12,\n\x08organism\x18\x05 \x01(\x0b\x32\x1a.ensembl_metadata.Organism\x12\x39\n\x0f\x61ttributes_info\x18\x06 \x01(\x0b\x32 .ensembl_metadata.AttributesInfo\x12 \n\x18related_assemblies_count\x18\x07 \x01(\x05\x12*\n\x07release\x18\x08 \x01(\x0b\x32\x19.ensembl_metadata.Release\"\xbe\x02\n\x12\x42riefGenomeDetails\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12,\n\x08\x61ssembly\x18\x02 \x01(\x0b\x32\x1a.ensembl_metadata.Assembly\x12&\n\x05taxon\x18\x03 \x01(\x0b\x32\x17.ensembl_metadata.Taxon\x12\x0f\n\x07\x63reated\x18\x04 \x01(\t\x12,\n\x08organism\x18\x05 \x01(\x0b\x32\x1a.ensembl_metadata.Organism\x12*\n\x07release\x18\x06 \x01(\x0b\x32\x19.ensembl_metadata.Release\x12@\n\rlatest_genome\x18\x07 \x01(\x0b\x32$.ensembl_metadata.BriefGenomeDetailsH\x00\x88\x01\x01\x42\x10\n\x0e_latest_genome\"h\n\x16\x41ttributesInfoByGenome\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x39\n\x0f\x61ttributes_info\x18\x02 \x01(\x0b\x32 .ensembl_metadata.AttributesInfo\"\x99\x01\n\x07Species\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x10\n\x08taxon_id\x18\x02 \x01(\r\x12\x17\n\x0fscientific_name\x18\x03 \x01(\t\x12 \n\x18scientific_parlance_name\x18\x04 \x01(\t\x12\x1b\n\x13genbank_common_name\x18\x05 \x01(\t\x12\x0f\n\x07synonym\x18\x06 \x03(\t\"\xb6\x01\n\x0c\x41ssemblyInfo\x12\x15\n\rassembly_uuid\x18\x01 \x01(\t\x12\x11\n\taccession\x18\x02 \x01(\t\x12\r\n\x05level\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x13\n\x0b\x63hromosomal\x18\x05 \x01(\r\x12\x0e\n\x06length\x18\x06 \x01(\x04\x12\x19\n\x11sequence_location\x18\x07 \x01(\t\x12\x0b\n\x03md5\x18\x08 \x01(\t\x12\x12\n\nsha512t24u\x18\t \x01(\t\"O\n\nSubSpecies\x12\x15\n\rorganism_uuid\x18\x01 \x01(\t\x12\x14\n\x0cspecies_type\x18\x02 \x03(\t\x12\x14\n\x0cspecies_name\x18\x03 \x03(\t\"c\n\x13\x41ttributeStatistics\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x16\n\x0estatistic_type\x18\x03 \x01(\t\x12\x17\n\x0fstatistic_value\x18\x04 \x01(\t\"j\n\x18TopLevelStatisticsByUUID\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x39\n\nstatistics\x18\x02 \x03(\x0b\x32%.ensembl_metadata.AttributeStatistics\"u\n\x12TopLevelStatistics\x12\x15\n\rorganism_uuid\x18\x01 \x01(\t\x12H\n\x14stats_by_genome_uuid\x18\x02 \x03(\x0b\x32*.ensembl_metadata.TopLevelStatisticsByUUID\"\xb2\x01\n\x08\x41ssembly\x12\x11\n\taccession\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x11\n\tucsc_name\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\t\x12\x14\n\x0c\x65nsembl_name\x18\x05 \x01(\t\x12\x15\n\rassembly_uuid\x18\x06 \x01(\t\x12\x14\n\x0cis_reference\x18\x07 \x01(\x08\x12\x10\n\x08url_name\x18\x08 \x01(\t\x12\x0e\n\x06tol_id\x18\t \x01(\t\"`\n\x05Taxon\x12\x13\n\x0btaxonomy_id\x18\x01 \x01(\r\x12\x17\n\x0fscientific_name\x18\x02 \x01(\t\x12\x0e\n\x06strain\x18\x03 \x01(\t\x12\x19\n\x11\x61lternative_names\x18\x04 \x03(\t\"\xb2\x01\n\x07Release\x12\x17\n\x0frelease_version\x18\x01 \x01(\x01\x12\x14\n\x0crelease_date\x18\x02 \x01(\t\x12\x15\n\rrelease_label\x18\x03 \x01(\t\x12\x14\n\x0crelease_type\x18\x04 \x01(\t\x12\x12\n\nis_current\x18\x05 \x01(\x08\x12\x11\n\tsite_name\x18\x06 \x01(\t\x12\x12\n\nsite_label\x18\x07 \x01(\t\x12\x10\n\x08site_uri\x18\x08 \x01(\t\"\xde\x01\n\x08Organism\x12\x13\n\x0b\x63ommon_name\x18\x01 \x01(\t\x12\x0e\n\x06strain\x18\x02 \x01(\t\x12\x17\n\x0fscientific_name\x18\x03 \x01(\t\x12\x14\n\x0c\x65nsembl_name\x18\x04 \x01(\t\x12 \n\x18scientific_parlance_name\x18\x05 \x01(\t\x12\x15\n\rorganism_uuid\x18\x06 \x01(\t\x12\x13\n\x0bstrain_type\x18\x07 \x01(\t\x12\x13\n\x0btaxonomy_id\x18\x08 \x01(\x05\x12\x1b\n\x13species_taxonomy_id\x18\t \x01(\x05\"K\n\tAttribute\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x0c\n\x04type\x18\x04 \x01(\t\"\xaa\x03\n\x0e\x41ttributesInfo\x12\x18\n\x10genebuild_method\x18\x01 \x01(\t\x12 \n\x18genebuild_method_display\x18\x02 \x01(\t\x12%\n\x1dgenebuild_last_geneset_update\x18\x03 \x01(\t\x12\"\n\x1agenebuild_provider_version\x18\x04 \x01(\t\x12\x1f\n\x17genebuild_provider_name\x18\x05 \x01(\t\x12\x1e\n\x16genebuild_provider_url\x18\x06 \x01(\t\x12\x1d\n\x15genebuild_sample_gene\x18\x07 \x01(\t\x12!\n\x19genebuild_sample_location\x18\x08 \x01(\t\x12\x16\n\x0e\x61ssembly_level\x18\t \x01(\t\x12\x15\n\rassembly_date\x18\n \x01(\t\x12\x1e\n\x16\x61ssembly_provider_name\x18\x0b \x01(\t\x12\x1d\n\x15\x61ssembly_provider_url\x18\x0c \x01(\t\x12 \n\x18variation_sample_variant\x18\r \x01(\t\"q\n\x0eGenomeSequence\x12\x11\n\taccession\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x19\n\x11sequence_location\x18\x03 \x01(\t\x12\x0e\n\x06length\x18\x04 \x01(\x04\x12\x13\n\x0b\x63hromosomal\x18\x05 \x01(\x08\"r\n\x0e\x41ssemblyRegion\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04rank\x18\x02 \x01(\x05\x12\x0b\n\x03md5\x18\x03 \x01(\t\x12\x0e\n\x06length\x18\x04 \x01(\x04\x12\x12\n\nsha512t24u\x18\x05 \x01(\t\x12\x13\n\x0b\x63hromosomal\x18\x06 \x01(\x08\"r\n\x1cGenomeAssemblySequenceRegion\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03md5\x18\x02 \x01(\t\x12\x0e\n\x06length\x18\x03 \x01(\x04\x12\x12\n\nsha512t24u\x18\x04 \x01(\t\x12\x13\n\x0b\x63hromosomal\x18\x05 \x01(\x08\"\xcb\x02\n\x0b\x44\x61tasetInfo\x12\x14\n\x0c\x64\x61taset_uuid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x61taset_name\x18\x02 \x01(\t\x12\x16\n\x0e\x61ttribute_name\x18\x03 \x01(\t\x12\x16\n\x0e\x61ttribute_type\x18\x04 \x01(\t\x12\x17\n\x0f\x64\x61taset_version\x18\x05 \x01(\t\x12\x15\n\rdataset_label\x18\x06 \x01(\t\x12\x17\n\x0frelease_version\x18\x07 \x01(\x01\x12\x17\n\x0f\x61ttribute_value\x18\x08 \x01(\t\x12\x1a\n\x12\x64\x61taset_type_topic\x18\t \x01(\t\x12\x1b\n\x13\x64\x61taset_source_type\x18\n \x01(\t\x12\x19\n\x11\x64\x61taset_type_name\x18\x0b \x01(\t\x12\x14\n\x0crelease_date\x18\x0c \x01(\t\x12\x14\n\x0crelease_type\x18\r \x01(\t\"P\n\x08\x44\x61tasets\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12/\n\x08\x64\x61tasets\x18\x02 \x03(\x0b\x32\x1d.ensembl_metadata.DatasetInfo\":\n\x0cVepFilePaths\x12\x14\n\x0c\x66\x61\x61_location\x18\x01 \x01(\t\x12\x14\n\x0cgff_location\x18\x02 \x01(\t\"!\n\nGenomeUUID\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\"y\n\x0eOrganismsGroup\x12\x1b\n\x13species_taxonomy_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63ommon_name\x18\x02 \x01(\t\x12\x17\n\x0fscientific_name\x18\x03 \x01(\t\x12\r\n\x05order\x18\x04 \x01(\r\x12\r\n\x05\x63ount\x18\x05 \x01(\r\"m\n\x13OrganismsGroupCount\x12?\n\x15organisms_group_count\x18\x01 \x03(\x0b\x32 .ensembl_metadata.OrganismsGroup\x12\x15\n\rrelease_label\x18\x02 \x01(\x01\"-\n\x07\x46TPLink\x12\x14\n\x0c\x64\x61taset_type\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\t\"4\n\x08\x46TPLinks\x12(\n\x05Links\x18\x01 \x03(\x0b\x32\x19.ensembl_metadata.FTPLink\")\n\x0eReleaseVersion\x12\x17\n\x0frelease_version\x18\x01 \x01(\x01\"\x8d\x01\n\x15\x44\x61tasetAttributeValue\x12\x16\n\x0e\x61ttribute_name\x18\x01 \x01(\t\x12\x17\n\x0f\x61ttribute_value\x18\x02 \x01(\t\x12\x17\n\x0f\x64\x61taset_version\x18\x03 \x01(\t\x12\x14\n\x0c\x64\x61taset_uuid\x18\x04 \x01(\t\x12\x14\n\x0c\x64\x61taset_type\x18\x05 \x01(\t\"o\n\x17\x44\x61tasetAttributesValues\x12;\n\nattributes\x18\x01 \x03(\x0b\x32\'.ensembl_metadata.DatasetAttributeValue\x12\x17\n\x0frelease_version\x18\x02 \x01(\x01\"A\n\x11GenomeUUIDRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x17\n\x0frelease_version\x18\x02 \x01(\x01\",\n\x15GenomeUUIDOnlyRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\"\x81\x02\n\x1eGenomeBySpecificKeywordRequest\x12\r\n\x05tolid\x18\x01 \x01(\t\x12\x1d\n\x15\x61ssembly_accession_id\x18\x02 \x01(\t\x12\x15\n\rassembly_name\x18\x03 \x01(\t\x12\x14\n\x0c\x65nsembl_name\x18\x04 \x01(\t\x12\x13\n\x0b\x63ommon_name\x18\x05 \x01(\t\x12\x17\n\x0fscientific_name\x18\x06 \x01(\t\x12 \n\x18scientific_parlance_name\x18\x07 \x01(\t\x12\x1b\n\x13species_taxonomy_id\x18\x08 \x01(\t\x12\x17\n\x0frelease_version\x18\t \x01(\x01\"8\n\x1dGenomeByReleaseVersionRequest\x12\x17\n\x0frelease_version\x18\x01 \x01(\x01\"U\n\x11GenomeNameRequest\x12\x14\n\x0c\x65nsembl_name\x18\x01 \x01(\t\x12\x11\n\tsite_name\x18\x02 \x01(\t\x12\x17\n\x0frelease_version\x18\x03 \x01(\x01\"C\n\x11\x41ssemblyIDRequest\x12\x15\n\rassembly_uuid\x18\x01 \x01(\t\x12\x17\n\x0frelease_version\x18\x02 \x01(\x01\"Q\n\x1a\x41ssemblyAccessionIDRequest\x12\x1a\n\x12\x61ssembly_accession\x18\x01 \x01(\t\x12\x17\n\x0frelease_version\x18\x02 \x01(\x01\"9\n\x11OrganismIDRequest\x12\x15\n\rorganism_uuid\x18\x01 \x01(\t\x12\r\n\x05group\x18\x02 \x01(\t\"P\n\x0eReleaseRequest\x12\x11\n\tsite_name\x18\x01 \x03(\t\x12\x15\n\rrelease_label\x18\x02 \x03(\t\x12\x14\n\x0c\x63urrent_only\x18\x03 \x01(\x08\"F\n\x15GenomeSequenceRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x18\n\x10\x63hromosomal_only\x18\x02 \x01(\x08\"F\n\x15\x41ssemblyRegionRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x18\n\x10\x63hromosomal_only\x18\x02 \x01(\x08\"X\n#GenomeAssemblySequenceRegionRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x1c\n\x14sequence_region_name\x18\x02 \x01(\t\"?\n\x0f\x44\x61tasetsRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x17\n\x0frelease_version\x18\x02 \x01(\x01\"B\n\x15GenomeDatatypeRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x61taset_type\x18\x02 \x01(\t\"\x89\x01\n\x11GenomeInfoRequest\x12\x17\n\x0fproduction_name\x18\x01 \x01(\t\x12\x15\n\rassembly_name\x18\x02 \x01(\t\x12\x16\n\x0egenebuild_date\x18\x03 \x01(\t\x12\x17\n\x0frelease_version\x18\x04 \x01(\x01\x12\x13\n\x0buse_default\x18\x05 \x01(\x08\".\n\x15OrganismsGroupRequest\x12\x15\n\rrelease_label\x18\x01 \x01(\x01\"&\n\x10GenomeTagRequest\x12\x12\n\ngenome_tag\x18\x01 \x01(\t\"U\n\x0f\x46TPLinksRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x61taset_type\x18\x02 \x01(\t\x12\x17\n\x0frelease_version\x18\x03 \x01(\t\"[\n\x15ReleaseVersionRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x61taset_type\x18\x02 \x01(\t\x12\x17\n\x0frelease_version\x18\x03 \x01(\x01\"\x91\x01\n\x1e\x44\x61tasetAttributesValuesRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x61taset_type\x18\x02 \x01(\t\x12\x16\n\x0e\x61ttribute_name\x18\x03 \x03(\t\x12\x17\n\x0frelease_version\x18\x04 \x01(\x01\x12\x13\n\x0blatest_only\x18\x05 \x01(\x08\x32\xc9\x14\n\x0f\x45nsemblMetadata\x12R\n\x0fGetGenomeByUUID\x12#.ensembl_metadata.GenomeUUIDRequest\x1a\x18.ensembl_metadata.Genome\"\x00\x12l\n\x19GetAttributesByGenomeUUID\x12#.ensembl_metadata.GenomeUUIDRequest\x1a(.ensembl_metadata.AttributesInfoByGenome\"\x00\x12j\n\x1bGetBriefGenomeDetailsByUUID\x12#.ensembl_metadata.GenomeUUIDRequest\x1a$.ensembl_metadata.BriefGenomeDetails\"\x00\x12T\n\rGetGenomeUUID\x12#.ensembl_metadata.GenomeInfoRequest\x1a\x1c.ensembl_metadata.GenomeUUID\"\x00\x12m\n\x1bGetGenomesBySpecificKeyword\x12\x30.ensembl_metadata.GenomeBySpecificKeywordRequest\x1a\x18.ensembl_metadata.Genome\"\x00\x30\x01\x12w\n\x1aGetGenomesByReleaseVersion\x12/.ensembl_metadata.GenomeByReleaseVersionRequest\x1a$.ensembl_metadata.BriefGenomeDetails\"\x00\x30\x01\x12m\n\x1fGetGenomesByAssemblyAccessionID\x12,.ensembl_metadata.AssemblyAccessionIDRequest\x1a\x18.ensembl_metadata.Genome\"\x00\x30\x01\x12Y\n\x15GetSpeciesInformation\x12#.ensembl_metadata.GenomeUUIDRequest\x1a\x19.ensembl_metadata.Species\"\x00\x12_\n\x16GetAssemblyInformation\x12#.ensembl_metadata.AssemblyIDRequest\x1a\x1e.ensembl_metadata.AssemblyInfo\"\x00\x12_\n\x18GetSubSpeciesInformation\x12#.ensembl_metadata.OrganismIDRequest\x1a\x1c.ensembl_metadata.SubSpecies\"\x00\x12\x64\n\x15GetTopLevelStatistics\x12#.ensembl_metadata.OrganismIDRequest\x1a$.ensembl_metadata.TopLevelStatistics\"\x00\x12p\n\x1bGetTopLevelStatisticsByUUID\x12#.ensembl_metadata.GenomeUUIDRequest\x1a*.ensembl_metadata.TopLevelStatisticsByUUID\"\x00\x12R\n\x0fGetGenomeByName\x12#.ensembl_metadata.GenomeNameRequest\x1a\x18.ensembl_metadata.Genome\"\x00\x12M\n\nGetRelease\x12 .ensembl_metadata.ReleaseRequest\x1a\x19.ensembl_metadata.Release\"\x00\x30\x01\x12V\n\x10GetReleaseByUUID\x12#.ensembl_metadata.GenomeUUIDRequest\x1a\x19.ensembl_metadata.Release\"\x00\x30\x01\x12\x62\n\x11GetGenomeSequence\x12\'.ensembl_metadata.GenomeSequenceRequest\x1a .ensembl_metadata.GenomeSequence\"\x00\x30\x01\x12\x62\n\x11GetAssemblyRegion\x12\'.ensembl_metadata.AssemblyRegionRequest\x1a .ensembl_metadata.AssemblyRegion\"\x00\x30\x01\x12\x8a\x01\n\x1fGetGenomeAssemblySequenceRegion\x12\x35.ensembl_metadata.GenomeAssemblySequenceRegionRequest\x1a..ensembl_metadata.GenomeAssemblySequenceRegion\"\x00\x12X\n\x15GetDatasetsListByUUID\x12!.ensembl_metadata.DatasetsRequest\x1a\x1a.ensembl_metadata.Datasets\"\x00\x12^\n\x15GetDatasetInformation\x12\'.ensembl_metadata.GenomeDatatypeRequest\x1a\x1a.ensembl_metadata.Datasets\"\x00\x12j\n\x16GetOrganismsGroupCount\x12\'.ensembl_metadata.OrganismsGroupRequest\x1a%.ensembl_metadata.OrganismsGroupCount\"\x00\x12X\n\x12GetGenomeUUIDByTag\x12\".ensembl_metadata.GenomeTagRequest\x1a\x1c.ensembl_metadata.GenomeUUID\"\x00\x12N\n\x0bGetFTPLinks\x12!.ensembl_metadata.FTPLinksRequest\x1a\x1a.ensembl_metadata.FTPLinks\"\x00\x12\x66\n\x17GetReleaseVersionByUUID\x12\'.ensembl_metadata.ReleaseVersionRequest\x1a .ensembl_metadata.ReleaseVersion\"\x00\x12z\n\x19GetAttributesValuesByUUID\x12\x30.ensembl_metadata.DatasetAttributesValuesRequest\x1a).ensembl_metadata.DatasetAttributesValues\"\x00\x12\x62\n\x15GetVepFilePathsByUUID\x12\'.ensembl_metadata.GenomeUUIDOnlyRequest\x1a\x1e.ensembl_metadata.VepFilePaths\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n7ensembl/production/metadata/grpc/ensembl_metadata.proto\x12\x10\x65nsembl_metadata\"\xbb\x02\n\x06Genome\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12,\n\x08\x61ssembly\x18\x02 \x01(\x0b\x32\x1a.ensembl_metadata.Assembly\x12&\n\x05taxon\x18\x03 \x01(\x0b\x32\x17.ensembl_metadata.Taxon\x12\x0f\n\x07\x63reated\x18\x04 \x01(\t\x12,\n\x08organism\x18\x05 \x01(\x0b\x32\x1a.ensembl_metadata.Organism\x12\x39\n\x0f\x61ttributes_info\x18\x06 \x01(\x0b\x32 .ensembl_metadata.AttributesInfo\x12 \n\x18related_assemblies_count\x18\x07 \x01(\x05\x12*\n\x07release\x18\x08 \x01(\x0b\x32\x19.ensembl_metadata.Release\"\xbe\x02\n\x12\x42riefGenomeDetails\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12,\n\x08\x61ssembly\x18\x02 \x01(\x0b\x32\x1a.ensembl_metadata.Assembly\x12&\n\x05taxon\x18\x03 \x01(\x0b\x32\x17.ensembl_metadata.Taxon\x12\x0f\n\x07\x63reated\x18\x04 \x01(\t\x12,\n\x08organism\x18\x05 \x01(\x0b\x32\x1a.ensembl_metadata.Organism\x12*\n\x07release\x18\x06 \x01(\x0b\x32\x19.ensembl_metadata.Release\x12@\n\rlatest_genome\x18\x07 \x01(\x0b\x32$.ensembl_metadata.BriefGenomeDetailsH\x00\x88\x01\x01\x42\x10\n\x0e_latest_genome\"h\n\x16\x41ttributesInfoByGenome\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x39\n\x0f\x61ttributes_info\x18\x02 \x01(\x0b\x32 .ensembl_metadata.AttributesInfo\"\x99\x01\n\x07Species\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x10\n\x08taxon_id\x18\x02 \x01(\r\x12\x17\n\x0fscientific_name\x18\x03 \x01(\t\x12 \n\x18scientific_parlance_name\x18\x04 \x01(\t\x12\x1b\n\x13genbank_common_name\x18\x05 \x01(\t\x12\x0f\n\x07synonym\x18\x06 \x03(\t\"\xb6\x01\n\x0c\x41ssemblyInfo\x12\x15\n\rassembly_uuid\x18\x01 \x01(\t\x12\x11\n\taccession\x18\x02 \x01(\t\x12\r\n\x05level\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x13\n\x0b\x63hromosomal\x18\x05 \x01(\r\x12\x0e\n\x06length\x18\x06 \x01(\x04\x12\x19\n\x11sequence_location\x18\x07 \x01(\t\x12\x0b\n\x03md5\x18\x08 \x01(\t\x12\x12\n\nsha512t24u\x18\t \x01(\t\"O\n\nSubSpecies\x12\x15\n\rorganism_uuid\x18\x01 \x01(\t\x12\x14\n\x0cspecies_type\x18\x02 \x03(\t\x12\x14\n\x0cspecies_name\x18\x03 \x03(\t\"c\n\x13\x41ttributeStatistics\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x16\n\x0estatistic_type\x18\x03 \x01(\t\x12\x17\n\x0fstatistic_value\x18\x04 \x01(\t\"j\n\x18TopLevelStatisticsByUUID\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x39\n\nstatistics\x18\x02 \x03(\x0b\x32%.ensembl_metadata.AttributeStatistics\"u\n\x12TopLevelStatistics\x12\x15\n\rorganism_uuid\x18\x01 \x01(\t\x12H\n\x14stats_by_genome_uuid\x18\x02 \x03(\x0b\x32*.ensembl_metadata.TopLevelStatisticsByUUID\"\xb2\x01\n\x08\x41ssembly\x12\x11\n\taccession\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x11\n\tucsc_name\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\t\x12\x14\n\x0c\x65nsembl_name\x18\x05 \x01(\t\x12\x15\n\rassembly_uuid\x18\x06 \x01(\t\x12\x14\n\x0cis_reference\x18\x07 \x01(\x08\x12\x10\n\x08url_name\x18\x08 \x01(\t\x12\x0e\n\x06tol_id\x18\t \x01(\t\"`\n\x05Taxon\x12\x13\n\x0btaxonomy_id\x18\x01 \x01(\r\x12\x17\n\x0fscientific_name\x18\x02 \x01(\t\x12\x0e\n\x06strain\x18\x03 \x01(\t\x12\x19\n\x11\x61lternative_names\x18\x04 \x03(\t\"\xb2\x01\n\x07Release\x12\x17\n\x0frelease_version\x18\x01 \x01(\x01\x12\x14\n\x0crelease_date\x18\x02 \x01(\t\x12\x15\n\rrelease_label\x18\x03 \x01(\t\x12\x14\n\x0crelease_type\x18\x04 \x01(\t\x12\x12\n\nis_current\x18\x05 \x01(\x08\x12\x11\n\tsite_name\x18\x06 \x01(\t\x12\x12\n\nsite_label\x18\x07 \x01(\t\x12\x10\n\x08site_uri\x18\x08 \x01(\t\"\xde\x01\n\x08Organism\x12\x13\n\x0b\x63ommon_name\x18\x01 \x01(\t\x12\x0e\n\x06strain\x18\x02 \x01(\t\x12\x17\n\x0fscientific_name\x18\x03 \x01(\t\x12\x14\n\x0c\x65nsembl_name\x18\x04 \x01(\t\x12 \n\x18scientific_parlance_name\x18\x05 \x01(\t\x12\x15\n\rorganism_uuid\x18\x06 \x01(\t\x12\x13\n\x0bstrain_type\x18\x07 \x01(\t\x12\x13\n\x0btaxonomy_id\x18\x08 \x01(\x05\x12\x1b\n\x13species_taxonomy_id\x18\t \x01(\x05\"K\n\tAttribute\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05label\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x0c\n\x04type\x18\x04 \x01(\t\"\xaa\x03\n\x0e\x41ttributesInfo\x12\x18\n\x10genebuild_method\x18\x01 \x01(\t\x12 \n\x18genebuild_method_display\x18\x02 \x01(\t\x12%\n\x1dgenebuild_last_geneset_update\x18\x03 \x01(\t\x12\"\n\x1agenebuild_provider_version\x18\x04 \x01(\t\x12\x1f\n\x17genebuild_provider_name\x18\x05 \x01(\t\x12\x1e\n\x16genebuild_provider_url\x18\x06 \x01(\t\x12\x1d\n\x15genebuild_sample_gene\x18\x07 \x01(\t\x12!\n\x19genebuild_sample_location\x18\x08 \x01(\t\x12\x16\n\x0e\x61ssembly_level\x18\t \x01(\t\x12\x15\n\rassembly_date\x18\n \x01(\t\x12\x1e\n\x16\x61ssembly_provider_name\x18\x0b \x01(\t\x12\x1d\n\x15\x61ssembly_provider_url\x18\x0c \x01(\t\x12 \n\x18variation_sample_variant\x18\r \x01(\t\"q\n\x0eGenomeSequence\x12\x11\n\taccession\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x19\n\x11sequence_location\x18\x03 \x01(\t\x12\x0e\n\x06length\x18\x04 \x01(\x04\x12\x13\n\x0b\x63hromosomal\x18\x05 \x01(\x08\"r\n\x0e\x41ssemblyRegion\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04rank\x18\x02 \x01(\x05\x12\x0b\n\x03md5\x18\x03 \x01(\t\x12\x0e\n\x06length\x18\x04 \x01(\x04\x12\x12\n\nsha512t24u\x18\x05 \x01(\t\x12\x13\n\x0b\x63hromosomal\x18\x06 \x01(\x08\"r\n\x1cGenomeAssemblySequenceRegion\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03md5\x18\x02 \x01(\t\x12\x0e\n\x06length\x18\x03 \x01(\x04\x12\x12\n\nsha512t24u\x18\x04 \x01(\t\x12\x13\n\x0b\x63hromosomal\x18\x05 \x01(\x08\"\xcb\x02\n\x0b\x44\x61tasetInfo\x12\x14\n\x0c\x64\x61taset_uuid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x61taset_name\x18\x02 \x01(\t\x12\x16\n\x0e\x61ttribute_name\x18\x03 \x01(\t\x12\x16\n\x0e\x61ttribute_type\x18\x04 \x01(\t\x12\x17\n\x0f\x64\x61taset_version\x18\x05 \x01(\t\x12\x15\n\rdataset_label\x18\x06 \x01(\t\x12\x17\n\x0frelease_version\x18\x07 \x01(\x01\x12\x17\n\x0f\x61ttribute_value\x18\x08 \x01(\t\x12\x1a\n\x12\x64\x61taset_type_topic\x18\t \x01(\t\x12\x1b\n\x13\x64\x61taset_source_type\x18\n \x01(\t\x12\x19\n\x11\x64\x61taset_type_name\x18\x0b \x01(\t\x12\x14\n\x0crelease_date\x18\x0c \x01(\t\x12\x14\n\x0crelease_type\x18\r \x01(\t\"P\n\x08\x44\x61tasets\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12/\n\x08\x64\x61tasets\x18\x02 \x03(\x0b\x32\x1d.ensembl_metadata.DatasetInfo\":\n\x0cVepFilePaths\x12\x14\n\x0c\x66\x61\x61_location\x18\x01 \x01(\t\x12\x14\n\x0cgff_location\x18\x02 \x01(\t\"!\n\nGenomeUUID\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\"y\n\x0eOrganismsGroup\x12\x1b\n\x13species_taxonomy_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63ommon_name\x18\x02 \x01(\t\x12\x17\n\x0fscientific_name\x18\x03 \x01(\t\x12\r\n\x05order\x18\x04 \x01(\r\x12\r\n\x05\x63ount\x18\x05 \x01(\r\"m\n\x13OrganismsGroupCount\x12?\n\x15organisms_group_count\x18\x01 \x03(\x0b\x32 .ensembl_metadata.OrganismsGroup\x12\x15\n\rrelease_label\x18\x02 \x01(\t\"-\n\x07\x46TPLink\x12\x14\n\x0c\x64\x61taset_type\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\t\"4\n\x08\x46TPLinks\x12(\n\x05Links\x18\x01 \x03(\x0b\x32\x19.ensembl_metadata.FTPLink\")\n\x0eReleaseVersion\x12\x17\n\x0frelease_version\x18\x01 \x01(\x01\"%\n\x0cReleaseLabel\x12\x15\n\rrelease_label\x18\x01 \x01(\t\"\x8d\x01\n\x15\x44\x61tasetAttributeValue\x12\x16\n\x0e\x61ttribute_name\x18\x01 \x01(\t\x12\x17\n\x0f\x61ttribute_value\x18\x02 \x01(\t\x12\x17\n\x0f\x64\x61taset_version\x18\x03 \x01(\t\x12\x14\n\x0c\x64\x61taset_uuid\x18\x04 \x01(\t\x12\x14\n\x0c\x64\x61taset_type\x18\x05 \x01(\t\"o\n\x17\x44\x61tasetAttributesValues\x12;\n\nattributes\x18\x01 \x03(\x0b\x32\'.ensembl_metadata.DatasetAttributeValue\x12\x17\n\x0frelease_version\x18\x02 \x01(\x01\"A\n\x11GenomeUUIDRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x17\n\x0frelease_version\x18\x02 \x01(\x01\",\n\x15GenomeUUIDOnlyRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\"\x81\x02\n\x1eGenomeBySpecificKeywordRequest\x12\r\n\x05tolid\x18\x01 \x01(\t\x12\x1d\n\x15\x61ssembly_accession_id\x18\x02 \x01(\t\x12\x15\n\rassembly_name\x18\x03 \x01(\t\x12\x14\n\x0c\x65nsembl_name\x18\x04 \x01(\t\x12\x13\n\x0b\x63ommon_name\x18\x05 \x01(\t\x12\x17\n\x0fscientific_name\x18\x06 \x01(\t\x12 \n\x18scientific_parlance_name\x18\x07 \x01(\t\x12\x1b\n\x13species_taxonomy_id\x18\x08 \x01(\t\x12\x17\n\x0frelease_version\x18\t \x01(\x01\"8\n\x1dGenomeByReleaseVersionRequest\x12\x17\n\x0frelease_version\x18\x01 \x01(\x01\"U\n\x11GenomeNameRequest\x12\x14\n\x0c\x65nsembl_name\x18\x01 \x01(\t\x12\x11\n\tsite_name\x18\x02 \x01(\t\x12\x17\n\x0frelease_version\x18\x03 \x01(\x01\"C\n\x11\x41ssemblyIDRequest\x12\x15\n\rassembly_uuid\x18\x01 \x01(\t\x12\x17\n\x0frelease_version\x18\x02 \x01(\x01\"Q\n\x1a\x41ssemblyAccessionIDRequest\x12\x1a\n\x12\x61ssembly_accession\x18\x01 \x01(\t\x12\x17\n\x0frelease_version\x18\x02 \x01(\x01\"9\n\x11OrganismIDRequest\x12\x15\n\rorganism_uuid\x18\x01 \x01(\t\x12\r\n\x05group\x18\x02 \x01(\t\"P\n\x0eReleaseRequest\x12\x11\n\tsite_name\x18\x01 \x03(\t\x12\x15\n\rrelease_label\x18\x02 \x03(\t\x12\x14\n\x0c\x63urrent_only\x18\x03 \x01(\x08\"F\n\x15GenomeSequenceRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x18\n\x10\x63hromosomal_only\x18\x02 \x01(\x08\"F\n\x15\x41ssemblyRegionRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x18\n\x10\x63hromosomal_only\x18\x02 \x01(\x08\"X\n#GenomeAssemblySequenceRegionRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x1c\n\x14sequence_region_name\x18\x02 \x01(\t\"?\n\x0f\x44\x61tasetsRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x17\n\x0frelease_version\x18\x02 \x01(\x01\"B\n\x15GenomeDatatypeRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x61taset_type\x18\x02 \x01(\t\"\x89\x01\n\x11GenomeInfoRequest\x12\x17\n\x0fproduction_name\x18\x01 \x01(\t\x12\x15\n\rassembly_name\x18\x02 \x01(\t\x12\x16\n\x0egenebuild_date\x18\x03 \x01(\t\x12\x17\n\x0frelease_version\x18\x04 \x01(\x01\x12\x13\n\x0buse_default\x18\x05 \x01(\x08\".\n\x15OrganismsGroupRequest\x12\x15\n\rrelease_label\x18\x01 \x01(\x01\"&\n\x10GenomeTagRequest\x12\x12\n\ngenome_tag\x18\x01 \x01(\t\"U\n\x0f\x46TPLinksRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x61taset_type\x18\x02 \x01(\t\x12\x17\n\x0frelease_version\x18\x03 \x01(\t\"[\n\x15ReleaseVersionRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x61taset_type\x18\x02 \x01(\t\x12\x17\n\x0frelease_version\x18\x03 \x01(\x01\"X\n\x12ReleaseInfoRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x61taset_type\x18\x02 \x01(\t\x12\x17\n\x0frelease_version\x18\x03 \x01(\x01\"\x91\x01\n\x1e\x44\x61tasetAttributesValuesRequest\x12\x13\n\x0bgenome_uuid\x18\x01 \x01(\t\x12\x14\n\x0c\x64\x61taset_type\x18\x02 \x01(\t\x12\x16\n\x0e\x61ttribute_name\x18\x03 \x03(\t\x12\x17\n\x0frelease_version\x18\x04 \x01(\x01\x12\x13\n\x0blatest_only\x18\x05 \x01(\x08\x32\xaa\x15\n\x0f\x45nsemblMetadata\x12R\n\x0fGetGenomeByUUID\x12#.ensembl_metadata.GenomeUUIDRequest\x1a\x18.ensembl_metadata.Genome\"\x00\x12l\n\x19GetAttributesByGenomeUUID\x12#.ensembl_metadata.GenomeUUIDRequest\x1a(.ensembl_metadata.AttributesInfoByGenome\"\x00\x12j\n\x1bGetBriefGenomeDetailsByUUID\x12#.ensembl_metadata.GenomeUUIDRequest\x1a$.ensembl_metadata.BriefGenomeDetails\"\x00\x12T\n\rGetGenomeUUID\x12#.ensembl_metadata.GenomeInfoRequest\x1a\x1c.ensembl_metadata.GenomeUUID\"\x00\x12m\n\x1bGetGenomesBySpecificKeyword\x12\x30.ensembl_metadata.GenomeBySpecificKeywordRequest\x1a\x18.ensembl_metadata.Genome\"\x00\x30\x01\x12w\n\x1aGetGenomesByReleaseVersion\x12/.ensembl_metadata.GenomeByReleaseVersionRequest\x1a$.ensembl_metadata.BriefGenomeDetails\"\x00\x30\x01\x12m\n\x1fGetGenomesByAssemblyAccessionID\x12,.ensembl_metadata.AssemblyAccessionIDRequest\x1a\x18.ensembl_metadata.Genome\"\x00\x30\x01\x12Y\n\x15GetSpeciesInformation\x12#.ensembl_metadata.GenomeUUIDRequest\x1a\x19.ensembl_metadata.Species\"\x00\x12_\n\x16GetAssemblyInformation\x12#.ensembl_metadata.AssemblyIDRequest\x1a\x1e.ensembl_metadata.AssemblyInfo\"\x00\x12_\n\x18GetSubSpeciesInformation\x12#.ensembl_metadata.OrganismIDRequest\x1a\x1c.ensembl_metadata.SubSpecies\"\x00\x12\x64\n\x15GetTopLevelStatistics\x12#.ensembl_metadata.OrganismIDRequest\x1a$.ensembl_metadata.TopLevelStatistics\"\x00\x12p\n\x1bGetTopLevelStatisticsByUUID\x12#.ensembl_metadata.GenomeUUIDRequest\x1a*.ensembl_metadata.TopLevelStatisticsByUUID\"\x00\x12R\n\x0fGetGenomeByName\x12#.ensembl_metadata.GenomeNameRequest\x1a\x18.ensembl_metadata.Genome\"\x00\x12M\n\nGetRelease\x12 .ensembl_metadata.ReleaseRequest\x1a\x19.ensembl_metadata.Release\"\x00\x30\x01\x12V\n\x10GetReleaseByUUID\x12#.ensembl_metadata.GenomeUUIDRequest\x1a\x19.ensembl_metadata.Release\"\x00\x30\x01\x12\x62\n\x11GetGenomeSequence\x12\'.ensembl_metadata.GenomeSequenceRequest\x1a .ensembl_metadata.GenomeSequence\"\x00\x30\x01\x12\x62\n\x11GetAssemblyRegion\x12\'.ensembl_metadata.AssemblyRegionRequest\x1a .ensembl_metadata.AssemblyRegion\"\x00\x30\x01\x12\x8a\x01\n\x1fGetGenomeAssemblySequenceRegion\x12\x35.ensembl_metadata.GenomeAssemblySequenceRegionRequest\x1a..ensembl_metadata.GenomeAssemblySequenceRegion\"\x00\x12X\n\x15GetDatasetsListByUUID\x12!.ensembl_metadata.DatasetsRequest\x1a\x1a.ensembl_metadata.Datasets\"\x00\x12^\n\x15GetDatasetInformation\x12\'.ensembl_metadata.GenomeDatatypeRequest\x1a\x1a.ensembl_metadata.Datasets\"\x00\x12j\n\x16GetOrganismsGroupCount\x12\'.ensembl_metadata.OrganismsGroupRequest\x1a%.ensembl_metadata.OrganismsGroupCount\"\x00\x12X\n\x12GetGenomeUUIDByTag\x12\".ensembl_metadata.GenomeTagRequest\x1a\x1c.ensembl_metadata.GenomeUUID\"\x00\x12N\n\x0bGetFTPLinks\x12!.ensembl_metadata.FTPLinksRequest\x1a\x1a.ensembl_metadata.FTPLinks\"\x00\x12\x66\n\x17GetReleaseVersionByUUID\x12\'.ensembl_metadata.ReleaseVersionRequest\x1a .ensembl_metadata.ReleaseVersion\"\x00\x12_\n\x15GetReleaseLabelByUUID\x12$.ensembl_metadata.ReleaseInfoRequest\x1a\x1e.ensembl_metadata.ReleaseLabel\"\x00\x12z\n\x19GetAttributesValuesByUUID\x12\x30.ensembl_metadata.DatasetAttributesValuesRequest\x1a).ensembl_metadata.DatasetAttributesValues\"\x00\x12\x62\n\x15GetVepFilePathsByUUID\x12\'.ensembl_metadata.GenomeUUIDOnlyRequest\x1a\x1e.ensembl_metadata.VepFilePaths\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -85,50 +85,54 @@ _globals['_FTPLINKS']._serialized_end=3954 _globals['_RELEASEVERSION']._serialized_start=3956 _globals['_RELEASEVERSION']._serialized_end=3997 - _globals['_DATASETATTRIBUTEVALUE']._serialized_start=4000 - _globals['_DATASETATTRIBUTEVALUE']._serialized_end=4141 - _globals['_DATASETATTRIBUTESVALUES']._serialized_start=4143 - _globals['_DATASETATTRIBUTESVALUES']._serialized_end=4254 - _globals['_GENOMEUUIDREQUEST']._serialized_start=4256 - _globals['_GENOMEUUIDREQUEST']._serialized_end=4321 - _globals['_GENOMEUUIDONLYREQUEST']._serialized_start=4323 - _globals['_GENOMEUUIDONLYREQUEST']._serialized_end=4367 - _globals['_GENOMEBYSPECIFICKEYWORDREQUEST']._serialized_start=4370 - _globals['_GENOMEBYSPECIFICKEYWORDREQUEST']._serialized_end=4627 - _globals['_GENOMEBYRELEASEVERSIONREQUEST']._serialized_start=4629 - _globals['_GENOMEBYRELEASEVERSIONREQUEST']._serialized_end=4685 - _globals['_GENOMENAMEREQUEST']._serialized_start=4687 - _globals['_GENOMENAMEREQUEST']._serialized_end=4772 - _globals['_ASSEMBLYIDREQUEST']._serialized_start=4774 - _globals['_ASSEMBLYIDREQUEST']._serialized_end=4841 - _globals['_ASSEMBLYACCESSIONIDREQUEST']._serialized_start=4843 - _globals['_ASSEMBLYACCESSIONIDREQUEST']._serialized_end=4924 - _globals['_ORGANISMIDREQUEST']._serialized_start=4926 - _globals['_ORGANISMIDREQUEST']._serialized_end=4983 - _globals['_RELEASEREQUEST']._serialized_start=4985 - _globals['_RELEASEREQUEST']._serialized_end=5065 - _globals['_GENOMESEQUENCEREQUEST']._serialized_start=5067 - _globals['_GENOMESEQUENCEREQUEST']._serialized_end=5137 - _globals['_ASSEMBLYREGIONREQUEST']._serialized_start=5139 - _globals['_ASSEMBLYREGIONREQUEST']._serialized_end=5209 - _globals['_GENOMEASSEMBLYSEQUENCEREGIONREQUEST']._serialized_start=5211 - _globals['_GENOMEASSEMBLYSEQUENCEREGIONREQUEST']._serialized_end=5299 - _globals['_DATASETSREQUEST']._serialized_start=5301 - _globals['_DATASETSREQUEST']._serialized_end=5364 - _globals['_GENOMEDATATYPEREQUEST']._serialized_start=5366 - _globals['_GENOMEDATATYPEREQUEST']._serialized_end=5432 - _globals['_GENOMEINFOREQUEST']._serialized_start=5435 - _globals['_GENOMEINFOREQUEST']._serialized_end=5572 - _globals['_ORGANISMSGROUPREQUEST']._serialized_start=5574 - _globals['_ORGANISMSGROUPREQUEST']._serialized_end=5620 - _globals['_GENOMETAGREQUEST']._serialized_start=5622 - _globals['_GENOMETAGREQUEST']._serialized_end=5660 - _globals['_FTPLINKSREQUEST']._serialized_start=5662 - _globals['_FTPLINKSREQUEST']._serialized_end=5747 - _globals['_RELEASEVERSIONREQUEST']._serialized_start=5749 - _globals['_RELEASEVERSIONREQUEST']._serialized_end=5840 - _globals['_DATASETATTRIBUTESVALUESREQUEST']._serialized_start=5843 - _globals['_DATASETATTRIBUTESVALUESREQUEST']._serialized_end=5988 - _globals['_ENSEMBLMETADATA']._serialized_start=5991 - _globals['_ENSEMBLMETADATA']._serialized_end=8624 + _globals['_RELEASELABEL']._serialized_start=3999 + _globals['_RELEASELABEL']._serialized_end=4036 + _globals['_DATASETATTRIBUTEVALUE']._serialized_start=4039 + _globals['_DATASETATTRIBUTEVALUE']._serialized_end=4180 + _globals['_DATASETATTRIBUTESVALUES']._serialized_start=4182 + _globals['_DATASETATTRIBUTESVALUES']._serialized_end=4293 + _globals['_GENOMEUUIDREQUEST']._serialized_start=4295 + _globals['_GENOMEUUIDREQUEST']._serialized_end=4360 + _globals['_GENOMEUUIDONLYREQUEST']._serialized_start=4362 + _globals['_GENOMEUUIDONLYREQUEST']._serialized_end=4406 + _globals['_GENOMEBYSPECIFICKEYWORDREQUEST']._serialized_start=4409 + _globals['_GENOMEBYSPECIFICKEYWORDREQUEST']._serialized_end=4666 + _globals['_GENOMEBYRELEASEVERSIONREQUEST']._serialized_start=4668 + _globals['_GENOMEBYRELEASEVERSIONREQUEST']._serialized_end=4724 + _globals['_GENOMENAMEREQUEST']._serialized_start=4726 + _globals['_GENOMENAMEREQUEST']._serialized_end=4811 + _globals['_ASSEMBLYIDREQUEST']._serialized_start=4813 + _globals['_ASSEMBLYIDREQUEST']._serialized_end=4880 + _globals['_ASSEMBLYACCESSIONIDREQUEST']._serialized_start=4882 + _globals['_ASSEMBLYACCESSIONIDREQUEST']._serialized_end=4963 + _globals['_ORGANISMIDREQUEST']._serialized_start=4965 + _globals['_ORGANISMIDREQUEST']._serialized_end=5022 + _globals['_RELEASEREQUEST']._serialized_start=5024 + _globals['_RELEASEREQUEST']._serialized_end=5104 + _globals['_GENOMESEQUENCEREQUEST']._serialized_start=5106 + _globals['_GENOMESEQUENCEREQUEST']._serialized_end=5176 + _globals['_ASSEMBLYREGIONREQUEST']._serialized_start=5178 + _globals['_ASSEMBLYREGIONREQUEST']._serialized_end=5248 + _globals['_GENOMEASSEMBLYSEQUENCEREGIONREQUEST']._serialized_start=5250 + _globals['_GENOMEASSEMBLYSEQUENCEREGIONREQUEST']._serialized_end=5338 + _globals['_DATASETSREQUEST']._serialized_start=5340 + _globals['_DATASETSREQUEST']._serialized_end=5403 + _globals['_GENOMEDATATYPEREQUEST']._serialized_start=5405 + _globals['_GENOMEDATATYPEREQUEST']._serialized_end=5471 + _globals['_GENOMEINFOREQUEST']._serialized_start=5474 + _globals['_GENOMEINFOREQUEST']._serialized_end=5611 + _globals['_ORGANISMSGROUPREQUEST']._serialized_start=5613 + _globals['_ORGANISMSGROUPREQUEST']._serialized_end=5659 + _globals['_GENOMETAGREQUEST']._serialized_start=5661 + _globals['_GENOMETAGREQUEST']._serialized_end=5699 + _globals['_FTPLINKSREQUEST']._serialized_start=5701 + _globals['_FTPLINKSREQUEST']._serialized_end=5786 + _globals['_RELEASEVERSIONREQUEST']._serialized_start=5788 + _globals['_RELEASEVERSIONREQUEST']._serialized_end=5879 + _globals['_RELEASEINFOREQUEST']._serialized_start=5881 + _globals['_RELEASEINFOREQUEST']._serialized_end=5969 + _globals['_DATASETATTRIBUTESVALUESREQUEST']._serialized_start=5972 + _globals['_DATASETATTRIBUTESVALUESREQUEST']._serialized_end=6117 + _globals['_ENSEMBLMETADATA']._serialized_start=6120 + _globals['_ENSEMBLMETADATA']._serialized_end=8850 # @@protoc_insertion_point(module_scope) diff --git a/src/ensembl/production/metadata/grpc/ensembl_metadata_pb2_grpc.py b/src/ensembl/production/metadata/grpc/ensembl_metadata_pb2_grpc.py index 848aae7f..8d3cb2d5 100755 --- a/src/ensembl/production/metadata/grpc/ensembl_metadata_pb2_grpc.py +++ b/src/ensembl/production/metadata/grpc/ensembl_metadata_pb2_grpc.py @@ -158,6 +158,11 @@ def __init__(self, channel): request_serializer=ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.ReleaseVersionRequest.SerializeToString, response_deserializer=ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.ReleaseVersion.FromString, _registered_method=True) + self.GetReleaseLabelByUUID = channel.unary_unary( + '/ensembl_metadata.EnsemblMetadata/GetReleaseLabelByUUID', + request_serializer=ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.ReleaseInfoRequest.SerializeToString, + response_deserializer=ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.ReleaseLabel.FromString, + _registered_method=True) self.GetAttributesValuesByUUID = channel.unary_unary( '/ensembl_metadata.EnsemblMetadata/GetAttributesValuesByUUID', request_serializer=ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.DatasetAttributesValuesRequest.SerializeToString, @@ -346,6 +351,13 @@ def GetReleaseVersionByUUID(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def GetReleaseLabelByUUID(self, request, context): + """Get release label for a given genome_uuid + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def GetAttributesValuesByUUID(self, request, context): """Get attributes by genome UUID """ @@ -483,6 +495,11 @@ def add_EnsemblMetadataServicer_to_server(servicer, server): request_deserializer=ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.ReleaseVersionRequest.FromString, response_serializer=ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.ReleaseVersion.SerializeToString, ), + 'GetReleaseLabelByUUID': grpc.unary_unary_rpc_method_handler( + servicer.GetReleaseLabelByUUID, + request_deserializer=ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.ReleaseInfoRequest.FromString, + response_serializer=ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.ReleaseLabel.SerializeToString, + ), 'GetAttributesValuesByUUID': grpc.unary_unary_rpc_method_handler( servicer.GetAttributesValuesByUUID, request_deserializer=ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.DatasetAttributesValuesRequest.FromString, @@ -1156,6 +1173,33 @@ def GetReleaseVersionByUUID(request, metadata, _registered_method=True) + @staticmethod + def GetReleaseLabelByUUID(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/ensembl_metadata.EnsemblMetadata/GetReleaseLabelByUUID', + ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.ReleaseInfoRequest.SerializeToString, + ensembl_dot_production_dot_metadata_dot_grpc_dot_ensembl__metadata__pb2.ReleaseLabel.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + @staticmethod def GetAttributesValuesByUUID(request, target, diff --git a/src/ensembl/production/metadata/grpc/protobuf_msg_factory.py b/src/ensembl/production/metadata/grpc/protobuf_msg_factory.py index 8531c5a6..a806c157 100644 --- a/src/ensembl/production/metadata/grpc/protobuf_msg_factory.py +++ b/src/ensembl/production/metadata/grpc/protobuf_msg_factory.py @@ -384,6 +384,33 @@ def create_release_version(data=None): ) return release +def create_label_version(data=None): + """ + This function will be used by Thoas to determine the MongoDB instance containing + the data for a specified genome_uuid. It either constructs a ReleaseLabel + instance with the release version obtained from the provided data or returns + a default ReleaseLabel instance when data is None or lacks the necessary attributes. + + Args: + data (Optional[sqlalchemy.engine.row.Row]): The input data from which the release + version is extracted. It's expected to have an attribute 'EnsemblRelease' + with a nested attribute 'version'. If None or the 'EnsemblRelease' attribute + is absent, a default ReleaseLabel instance is returned. + + Returns: + ensembl_metadata_pb2.ReleaseLabel: An instance of the ReleaseLabel message. + It contains the release label extracted from the input data if the relevant + attributes are present; otherwise, it's a default instance of ReleaseLabel. + """ + if data is None: + return ensembl_metadata_pb2.ReleaseLabel() + logger.debug(f"Release data {data}") + print(f"\n####### Release data {data}") + release = ensembl_metadata_pb2.ReleaseLabel( + release_label=data.release.label if hasattr(data, 'release') else None, + ) + return release + def create_datasets(data=None): if data is None: diff --git a/src/ensembl/production/metadata/grpc/servicer.py b/src/ensembl/production/metadata/grpc/servicer.py index d8775066..521d5022 100644 --- a/src/ensembl/production/metadata/grpc/servicer.py +++ b/src/ensembl/production/metadata/grpc/servicer.py @@ -165,6 +165,12 @@ def GetReleaseVersionByUUID(self, request, context): self.genome_adaptor, request.genome_uuid, request.dataset_type, request.release_version ) + def GetReleaseLabelByUUID(self, request, context): + logger.debug(f"Received RPC for GetReleaseLabelByUUID with request: {request}") + return utils.get_release_label_by_uuid( + self.genome_adaptor, request.genome_uuid, request.dataset_type, request.release_version + ) + def GetAttributesValuesByUUID(self, request, context): logger.debug(f"Received RPC for GetAttributesByUUID with request: {request}") attribute_names = list(request.attribute_name) if request.attribute_name else None diff --git a/src/ensembl/production/metadata/grpc/utils.py b/src/ensembl/production/metadata/grpc/utils.py index f4893de1..8156d3a0 100644 --- a/src/ensembl/production/metadata/grpc/utils.py +++ b/src/ensembl/production/metadata/grpc/utils.py @@ -637,6 +637,24 @@ def get_release_version_by_uuid(db_conn, genome_uuid, dataset_type, release_vers return response_data return msg_factory.create_release_version() +def get_release_label_by_uuid(db_conn, genome_uuid, dataset_type, release_version): + if not genome_uuid: + logger.warning("Missing or Empty Genome UUID field.") + return msg_factory.create_label_version() + + release_version_result = db_conn.fetch_genome_datasets(genome_uuid=genome_uuid, + dataset_type_name=dataset_type, + release_version=release_version) + + if len(release_version_result) == 0: + logger.error(f"No result found for {genome_uuid}/{dataset_type}/{release_version}") + else: + if len(release_version_result) > 1: + logger.warning(f"Multiple results returned. {release_version_result}") + response_data = msg_factory.create_label_version(release_version_result[0]) + return response_data + return msg_factory.create_label_version() + def get_attributes_values_by_uuid(db_conn, genome_uuid, dataset_type, release_version, attribute_names, latest_only): """ From e5652b5b159dca5796225d832731663b8f61d8ce Mon Sep 17 00:00:00 2001 From: Bilal El Houdaigui Date: Tue, 20 Jan 2026 13:51:33 +0000 Subject: [PATCH 2/5] :test_tube: add examples --- .../metadata/grpc/client_examples.py | 35 +++++++++++++++++++ .../metadata/grpc/protobuf_msg_factory.py | 1 - 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/ensembl/production/metadata/grpc/client_examples.py b/src/ensembl/production/metadata/grpc/client_examples.py index 82ca505f..60d00d8c 100755 --- a/src/ensembl/production/metadata/grpc/client_examples.py +++ b/src/ensembl/production/metadata/grpc/client_examples.py @@ -37,6 +37,7 @@ GroupTypeRequest, GenomesInGroupRequest, GenomeCountsRequest, + ReleaseInfoRequest, ) @@ -545,6 +546,38 @@ def get_genome_counts(stub): print("**** Genome Counts (Mock) ****") print(genome_counts) +def get_release_label_by_genome_uuid(stub): + request1 = ReleaseInfoRequest( + genome_uuid="a73351f7-93e7-11ec-a39d-005056b38ce3" + ) + release_label1 = stub.GetReleaseLabelByUUID(request1) + + request2 = ReleaseInfoRequest( + genome_uuid="a73351f7-93e7-11ec-a39d-005056b38ce3", + dataset_type="genebuild" + ) + release_label2 = stub.GetReleaseLabelByUUID(request2) + + request3 = ReleaseInfoRequest( + dataset_type="genebuild" + ) + release_label3 = stub.GetReleaseLabelByUUID(request3) + + request4 = ReleaseInfoRequest( + genome_uuid="a73351f7-93e7-11ec-a39d-005056b38ce3", + dataset_type="blabla" + ) + release_label4 = stub.GetReleaseLabelByUUID(request4) + + print("**** Get release label: By genome_uuid (Ecoli)****") + print(release_label1) + print("**** Get release label: By genome_uuid and dataset_type = genebuild (Ecoli)****") + print(release_label2) + print("**** Get release label: No genome_uuid provided and dataset_type = genebuild (Ecoli) No results****") + print(release_label3) + print("**** Get release label: By genome_uuid and dataset_type = blabla (Ecoli) No results****") + print(release_label4) + def run(): with grpc.insecure_channel("localhost:50051") as channel: @@ -605,6 +638,8 @@ def run(): get_genomes_in_groups(stub) print("-------------- Get Genome Counts --------------") get_genome_counts(stub) + print("-------------- Get Release Label By Genome UUID --------------") + get_release_label_by_genome_uuid(stub) if __name__ == "__main__": diff --git a/src/ensembl/production/metadata/grpc/protobuf_msg_factory.py b/src/ensembl/production/metadata/grpc/protobuf_msg_factory.py index a660c514..4e975066 100644 --- a/src/ensembl/production/metadata/grpc/protobuf_msg_factory.py +++ b/src/ensembl/production/metadata/grpc/protobuf_msg_factory.py @@ -410,7 +410,6 @@ def create_label_version(data=None): if data is None: return ensembl_metadata_pb2.ReleaseLabel() logger.debug(f"Release data {data}") - print(f"\n####### Release data {data}") release = ensembl_metadata_pb2.ReleaseLabel( release_label=data.release.label if hasattr(data, 'release') else None, ) From 97b66b5519f89abd0a6a0f247208a886e0b14ea2 Mon Sep 17 00:00:00 2001 From: Bilal El Houdaigui Date: Tue, 3 Feb 2026 15:15:47 +0000 Subject: [PATCH 3/5] :hammer: refactore and improve get_release_label_by_uuid function --- src/ensembl/production/metadata/grpc/utils.py | 56 +++++++++++++++---- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/src/ensembl/production/metadata/grpc/utils.py b/src/ensembl/production/metadata/grpc/utils.py index 4f46c792..5e914570 100644 --- a/src/ensembl/production/metadata/grpc/utils.py +++ b/src/ensembl/production/metadata/grpc/utils.py @@ -665,22 +665,57 @@ def get_release_version_by_uuid(db_conn, genome_uuid, dataset_type, release_vers return msg_factory.create_release_version() def get_release_label_by_uuid(db_conn, genome_uuid, dataset_type, release_version): + """ + Retrieve the release label for a genome dataset, prioritizing partial releases. + + This function looks up release labels for a given genome UUID, dataset type, + and release version. When multiple release labels are available, **partial + releases are preferred over integrated releases**. + + Rationale: + - Genomes are always released first as partial releases before being + included in integrated releases. + - Integrated releases only reference genes that were previously loaded + via partial releases. + - THOAS uses the release label to locate the correct MongoDB database; + all MongoDB databases follow the naming pattern: ``release-YYYY-MM-DD``. + + As a result, only partial release labels are considered. If multiple partial + releases are found, the most recent one (by release date) is selected. + """ if not genome_uuid: logger.warning("Missing or Empty Genome UUID field.") return msg_factory.create_label_version() - release_version_result = db_conn.fetch_genome_datasets(genome_uuid=genome_uuid, - dataset_type_name=dataset_type, - release_version=release_version) + results = db_conn.fetch_genome_datasets( + genome_uuid=genome_uuid, + dataset_type_name=dataset_type, + release_version=release_version, + ) - if len(release_version_result) == 0: + if not results: logger.error(f"No result found for {genome_uuid}/{dataset_type}/{release_version}") - else: - if len(release_version_result) > 1: - logger.warning(f"Multiple results returned. {release_version_result}") - response_data = msg_factory.create_label_version(release_version_result[0]) - return response_data - return msg_factory.create_label_version() + return msg_factory.create_label_version() + + # When looking up release labels, prioritize partial releases over integrated releases. + partials = [ + item for item in results + if getattr(getattr(item, "release", None), "release_type", None) == "partial" + ] + + if not partials: + logger.error( + f"No partial release found for {genome_uuid}/{dataset_type}/{release_version}" + ) + return msg_factory.create_label_version() + + if len(partials) > 1: + logger.warning(f"Multiple partial results returned. {partials}") + + # Pick the latest partial by release_date (works for 1 item too). + latest = max(partials, key=lambda item: item.release.release_date) + + return msg_factory.create_label_version(latest) def get_attributes_values_by_uuid(db_conn, genome_uuid, dataset_type, release_version, attribute_names, latest_only): @@ -1303,4 +1338,3 @@ def get_genome_counts(db_conn: Any, release_label: str | None): "(release_label=%r)",release_label ) return msg_factory.create_genome_counts([]) - From f3b5a4cb576d87d4161d0764594a437fc22e3498 Mon Sep 17 00:00:00 2001 From: Bilal El Houdaigui Date: Tue, 3 Feb 2026 15:52:50 +0000 Subject: [PATCH 4/5] :pencil: fix minor typo --- src/ensembl/production/metadata/grpc/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ensembl/production/metadata/grpc/utils.py b/src/ensembl/production/metadata/grpc/utils.py index 5e914570..fd09fcb8 100644 --- a/src/ensembl/production/metadata/grpc/utils.py +++ b/src/ensembl/production/metadata/grpc/utils.py @@ -677,7 +677,7 @@ def get_release_label_by_uuid(db_conn, genome_uuid, dataset_type, release_versio included in integrated releases. - Integrated releases only reference genes that were previously loaded via partial releases. - - THOAS uses the release label to locate the correct MongoDB database; + - Thoas uses the release label to locate the correct MongoDB database; all MongoDB databases follow the naming pattern: ``release-YYYY-MM-DD``. As a result, only partial release labels are considered. If multiple partial From ec1dd5e254a540719716a97613ce7256675b33e4 Mon Sep 17 00:00:00 2001 From: Bilal El Houdaigui Date: Tue, 9 Jun 2026 11:47:05 +0100 Subject: [PATCH 5/5] :bug: Fix release date sorting for latest partial release --- src/ensembl/production/metadata/grpc/utils.py | 36 +++++++++++++++++-- src/tests/test_utils.py | 32 +++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/ensembl/production/metadata/grpc/utils.py b/src/ensembl/production/metadata/grpc/utils.py index fcb9a637..de7eff00 100644 --- a/src/ensembl/production/metadata/grpc/utils.py +++ b/src/ensembl/production/metadata/grpc/utils.py @@ -13,7 +13,7 @@ import logging import uuid from typing import Type, Any -from datetime import datetime +from datetime import date, datetime import ensembl.production.metadata.grpc.protobuf_msg_factory as msg_factory from ensembl.production.metadata.api.adaptors import GenomeAdaptor, BaseAdaptor @@ -24,6 +24,38 @@ logger = logging.getLogger(__name__) +def _release_date_sort_key(release_date): + """Return a comparable date value for release-date sorting. + + Release dates usually come from the ORM as ``datetime.date`` values, but + some gRPC/protobuf paths serialize them as strings. This helper normalizes + both representations so callers can reliably select the latest release. + + Args: + release_date: A release date as ``datetime.date``, ``datetime.datetime``, + or a string in ``YYYY-MM-DD`` or ``MM/DD/YYYY`` format. + + Returns: + datetime.date: The parsed date. Invalid or missing values return + ``date.min`` so they sort before valid release dates. + """ + if isinstance(release_date, datetime): + return release_date.date() + if isinstance(release_date, date): + return release_date + if isinstance(release_date, str): + # Support both the ORM/factory ISO format and the protobuf display format. + for date_format in ("%Y-%m-%d", "%m/%d/%Y"): + try: + return datetime.strptime(release_date, date_format).date() + except ValueError: + pass + + # Keep malformed dates from being selected as the latest release. + logger.warning(f"Invalid release date for sorting: {release_date}") + return date.min + + def connect_to_db(adaptor_class: Type[BaseAdaptor], **kwargs): """ Connect to the database using the specified adaptor class. @@ -713,7 +745,7 @@ def get_release_label_by_uuid(db_conn, genome_uuid, dataset_type, release_versio logger.warning(f"Multiple partial results returned. {partials}") # Pick the latest partial by release_date (works for 1 item too). - latest = max(partials, key=lambda item: item.release.release_date) + latest = max(partials, key=lambda item: _release_date_sort_key(item.release.release_date)) return msg_factory.create_label_version(latest) diff --git a/src/tests/test_utils.py b/src/tests/test_utils.py index 4f13effd..c3ec9d30 100644 --- a/src/tests/test_utils.py +++ b/src/tests/test_utils.py @@ -15,6 +15,7 @@ import json import logging from pathlib import Path +from types import SimpleNamespace from typing import List import pytest @@ -765,6 +766,37 @@ def test_get_release_version_by_uuid(self, genome_conn, genome_uuid, dataset_typ )) assert json.loads(output) == expected_output + def test_get_release_label_by_uuid_picks_latest_partial_by_date(self): + db_conn = SimpleNamespace( + fetch_genome_datasets=lambda **kwargs: [ + SimpleNamespace( + release=SimpleNamespace( + release_type="partial", + release_date="12/31/2024", + label="2024-12-31" + ) + ), + SimpleNamespace( + release=SimpleNamespace( + release_type="partial", + release_date="02/27/2025", + label="2025-02-27" + ) + ), + ] + ) + + output = json_format.MessageToJson( + utils.get_release_label_by_uuid( + db_conn=db_conn, + genome_uuid="a73351f7-93e7-11ec-a39d-005056b38ce3", + dataset_type="genebuild", + release_version=111.1 + ) + ) + + assert json.loads(output) == {"releaseLabel": "2025-02-27"} + @pytest.mark.parametrize( "genome_uuid, expected_output", [