Commit 20a0b23f authored by Kamal Dodiya's avatar Kamal Dodiya
Browse files

Iniital commit

parents
"""
.. See the NOTICE file distributed with this work for additional information
regarding copyright ownership.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import os
PAGE = os.getenv("PAGE", 1)
PER_PAGE = os.getenv("PAGE", 100)
SOLR_SERVER = os.getenv("SOLR_SERVER","ensembl-solr-svc:8983")
SOLR_COLLECTION = os.getenv("SOLR_COLLECTION", "genome_search_v1")
\ No newline at end of file
"""
.. See the NOTICE file distributed with this work for additional information
regarding copyright ownership.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
async def transform_request_for_solr(query_input):
"""
Transform client request parameter to the parameter expected by the SOLR
"""
solr_query_params = {}
wt = "json"
q = query_input.query
rows = query_input.per_page
start = (query_input.page - 1) * rows
genome_ids = query_input.genome_ids
fq = None
if genome_ids:
fq = " OR ".join(query_input.genome_ids)
solr_query_params["q"] = q
solr_query_params["start"] = start
solr_query_params["rows"] = rows
solr_query_params["wt"] = wt
if fq:
solr_query_params["fq"] = f"genome_id:({fq})"
return solr_query_params
async def collate_slice(search_doc):
"""
Create Slice Object from the raw solr result document
"""
collated_slice = {"location": {}, "region": {}, "strand": {}}
collated_slice["location"]["start"] = search_doc["slice.location.start"]
collated_slice["location"]["end"] = search_doc["slice.location.end"]
collated_slice["region"]["name"] = search_doc["slice.region.name"]
collated_slice["strand"]["code"] = search_doc["slice.strand.code"]
return collated_slice
async def transform_search_result(search_result):
"""
Transform search result returned from SOLR in to the format expected by the client
"""
transformed_search_result_docs = []
for search_result_doc in search_result["response"]["docs"]:
collated_slice = await collate_slice(search_result_doc)
search_result_doc["slice"] = collated_slice
# Remove unwanted fields
del search_result_doc["slice.region.name"]
del search_result_doc["slice.location.start"]
del search_result_doc["slice.location.end"]
del search_result_doc["slice.strand.code"]
del search_result_doc["id"]
del search_result_doc["_version_"]
transformed_search_result_docs.append(search_result_doc)
return transformed_search_result_docs
\ No newline at end of file
"""
.. See the NOTICE file distributed with this work for additional information
regarding copyright ownership.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from fastapi import FastAPI, Query
from core.config import PAGE, PER_PAGE, SOLR_SERVER, SOLR_COLLECTION
from core.utils import *
from ensembl_search_hub.resources.models import SearchQuery, SearchResult
from ensembl_search_hub.resources.solr_client import SOLRClient
solr = SOLRClient(SOLR_SERVER, SOLR_COLLECTION)
app = FastAPI()
@app.get("/search", response_model=SearchResult)
async def get_search_results(search_query: SearchQuery):
"""
Query SOLR with the search string and additional parameter and transform result
as expected by the client
"""
solr_query_input = await transform_request_for_solr(search_query)
search_result = await solr.get_search_results(solr_query_input)
meta = {
"total_hits": search_result["response"]["numFound"],
"page": search_query.page,
"per_page": search_query.per_page,
}
transformed_search_result_docs = await transform_search_result(search_result)
response = SearchResult(meta=meta, matches=transformed_search_result_docs)
return response
from typing import Optional, List
from pydantic import BaseModel
class SearchQuery(BaseModel):
query: str
genome_ids: List[str] # = Query(..., min_length=1)
page: Optional[int] = 1
per_page: Optional[int] = 100
class SearchResultMeta(BaseModel):
total_hits: int
page: int
per_page: int
class Location(BaseModel):
start: int
end: int
class Region(BaseModel):
name: str
class Strand(BaseModel):
code: str
class Slice(BaseModel):
location: Location
region: Region
strand: Strand
class SearchResultDoc(BaseModel):
type: str
stable_id: str
unversioned_stable_id: str
biotype: str
symbol: str
so_term: str
name: str
genome_id: str
transcript_count: int
slice: Slice
class SearchResult(BaseModel):
meta: SearchResultMeta
matches: List[SearchResultDoc] = []
\ No newline at end of file
"""
.. See the NOTICE file distributed with this work for additional information
regarding copyright ownership.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import asyncio, aiohttp
import json
class SOLRClient:
def __init__(self, server_url, collection):
self.server = server_url
self.collection = collection
self.search_url = f'{self.server}/{self.collection}/select?'
def _prepare_search_request(self, solr_query_input):
query_params = "&".join(f'{k}={v}' for k,v in solr_query_input.items())
request_string = f'{self.search_url}{query_params}'
print (f'>>> {request_string}')
return request_string
async def get_search_results(self, solr_query_input):
solr_request = self._prepare_search_request(solr_query_input)
headers = {'Accept': 'application/json'}
async with aiohttp.ClientSession() as session:
async with session.get(solr_request, headers=headers) as response:
if response.status == 200:
search_results = await response.json(content_type=None)
return search_results
async def main():
solr_url = 'http://hx-rke-wp-webadmin-14-worker-1.caas.ebi.ac.uk:31118/solr'
collection = 'genome_search_v1'
e2020_solr = SOLRClient(solr_url, collection)
search_q="MSH2"
resp1 = await e2020_solr.get_search_results(search_q)
print (resp1['response']['numFound'])
resp2 = await e2020_solr.get_search_results(search_q, ["homo_sapiens_GCA_000001405_28"])
print (resp2['response']['numFound'])
resp3 = await e2020_solr.get_search_results(search_q, ["homo_sapiens_GCA_000001405_28", "homo_sapiens_GCA_000001405_14"])
print (resp3['response']['numFound'])
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
\ No newline at end of file
This diff is collapsed.
[tool.poetry]
name = "ensembl_search_hub"
version = "0.1.0"
description = ""
authors = ["Ensembl Webteam <ensembl-webteam@ebi.ac.uk>"]
[tool.poetry.dependencies]
python = "^3.7"
fastapi = "^0.65.2"
uvicorn = "^0.14.0"
aiohttp = "^3.7.4"
[tool.poetry.dev-dependencies]
pytest = "^5.2"
black = "^21.6b0"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
# -*- coding: utf-8 -*-
# @Author: kamal
# @Date: 2021-06-29 15:23:59
# @Last Modified by: kamal
# @Last Modified time: 2021-06-29 22:56:48
from ensembl_search_hub import __version__
def test_version():
assert __version__ == '0.1.0'
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment