Commit 0104afc1 authored by fabian serin's avatar fabian serin
Browse files

work in progress

parent 0933cca7
Pipeline #58663 passed with stages
in 6 minutes and 34 seconds
......@@ -18,15 +18,17 @@ from odes_search.models import Point, CursorQueryResponse
from app.utils import Context
from .search_v3 import (
SearchQuery,
SearchQueryRequest,
query_request,
query_type,
basic_query_request,
added_relationships_query,
query_request_with_specific_attribute,
OSDU_WELLBORE_KIND,
OSDU_WELLLOG_KIND,
OSDU_WELLBOREMARKERSET_KIND,
WELLBORE_RELATIONSHIP,
REQUIRED_ROLES_READ
REQUIRED_ROLES_READ,
DEFAULT_QUERYREQUEST
)
router = APIRouter()
......@@ -41,8 +43,8 @@ def get_ctx() -> Context:
description=f"""Get all Wellbores IDs object. <p>The wellbore kind is
{OSDU_WELLBORE_KIND} returns all records IDs IDs directly based on existing schemas</p>{REQUIRED_ROLES_READ}""",
response_model=CursorQueryResponse)
async def fastquery_wellbores(body: SearchQuery = None, ctx: Context = Depends(get_ctx)):
return await basic_query_request(query_type, OSDU_WELLBORE_KIND, ctx, body.query)
async def fastquery_wellbores(body: SearchQueryRequest = DEFAULT_QUERYREQUEST, ctx: Context = Depends(get_ctx)):
return await query_request(query_type, OSDU_WELLBORE_KIND, ctx, body)
@router.post('/fastquery/wellbores/{wellbore_id}/welllogs',
summary='Query with cursor, search WellLogs IDs by wellbore ID',
......@@ -50,10 +52,10 @@ async def fastquery_wellbores(body: SearchQuery = None, ctx: Context = Depends(g
specific ID will be returned</p>
<p>The LogSet kind is {OSDU_WELLLOG_KIND} returns all records IDs directly based on existing schemas</p>{REQUIRED_ROLES_READ}""",
response_model=CursorQueryResponse)
async def fastquery_welllogs_bywellbore(wellbore_id: str, body: SearchQuery = None,
ctx: Context = Depends(get_ctx)):
query = added_relationships_query(wellbore_id, WELLBORE_RELATIONSHIP, body.query)
return await basic_query_request(query_type, OSDU_WELLLOG_KIND, ctx, query)
async def fastquery_welllogs_bywellbore(wellbore_id: str, body: SearchQueryRequest = DEFAULT_QUERYREQUEST,
ctx: Context = Depends(get_ctx)):
body.query = added_relationships_query(wellbore_id, WELLBORE_RELATIONSHIP, body.query)
return await query_request(query_type, OSDU_WELLLOG_KIND, ctx, body)
@router.post('/fastquery/wellbore/{wellbore_attribute}/welllogs',
......@@ -75,7 +77,7 @@ async def fastquery_welllogs_bywellboreattribute(wellbore_attribute: str, body:
specific ID will be returned</p>
<p>The Marker kind is {OSDU_WELLBOREMARKERSET_KIND} returns all records IDs directly based on existing schemas</p>{REQUIRED_ROLES_READ}""",
response_model=CursorQueryResponse)
async def fastquery_markers_bywellbore(wellbore_id: str, body: SearchQuery = None,
async def fastquery_markers_bywellbore(wellbore_id: str, body: SearchQueryRequest = DEFAULT_QUERYREQUEST,
ctx: Context = Depends(get_ctx)):
query = added_relationships_query(wellbore_id, WELLBORE_RELATIONSHIP, body.query)
return await basic_query_request(query_type, OSDU_WELLBOREMARKERSET_KIND, ctx, query)
body.query = added_relationships_query(wellbore_id, WELLBORE_RELATIONSHIP, body.query)
return await query_request(query_type, OSDU_WELLBOREMARKERSET_KIND, ctx, body)
......@@ -15,12 +15,17 @@
from fastapi import APIRouter, Depends
from odes_search.models import (
QueryRequest,
CursorQueryResponse)
CursorQueryResponse,
CursorQueryRequest,
BaseModel,
Field,
Optional)
from app.clients.search_service_client import get_search_service
from ..common_parameters import REQUIRED_ROLES_READ
from app.utils import Context
import app.routers.search.search_wrapper as search_wrapper
from .search import (
LIMIT,
query_type,
SearchQuery,
get_ctx,
......@@ -37,6 +42,39 @@ OSDU_WELLBOREMARKERSET_KIND = '*:wks:work-product-component--WellboreMarkerSet:*
WELLBORE_RELATIONSHIP = "WellboreID"
class SearchQueryRequest(BaseModel):
# Used by as input, w/o kind, etc...
limit: "Optional[int]" = Field(None, alias="limit")
query: "Optional[str]" = Field(None, alias="query")
cursor: "Optional[str]" = Field(None, alias="cursor")
offset: "Optional[int]" = Field(None, alias="offset")
SearchQueryRequest.update_forward_refs()
DEFAULT_SEARCHQUERYREQUEST = SearchQueryRequest(limit=None, query=None, cursor=None, offset=None)
class SimpleCursorQueryRequest(BaseModel):
# Used by as input, w/o kind, etc...
limit: "Optional[int]" = Field(None, alias="limit")
query: "Optional[str]" = Field(None, alias="query")
cursor: "Optional[str]" = Field(None, alias="cursor")
SimpleCursorQueryRequest.update_forward_refs()
DEFAULT_CURSORQUERYREQUEST = SimpleCursorQueryRequest(limit=None, query=None, cursor=None)
class SimpleOffsetQueryRequest(BaseModel):
limit: "Optional[int]" = Field(None, alias="limit")
query: "Optional[str]" = Field(None, alias="query")
offset: "Optional[int]" = Field(None, alias="offset")
SimpleOffsetQueryRequest.update_forward_refs()
DEFAULT_QUERYREQUEST = SimpleOffsetQueryRequest(limit=None, query=None, offset=None)
def create_relationships_id_str(data_type: str, id: str):
return f'data.{data_type}:\"{id}\"'
......@@ -87,12 +125,69 @@ async def query_request_with_specific_attribute(query_type: str, attribute: str,
query_request=query_request)
def update_query_with_names_based_search(names: str = None, user_query: str = None) -> str:
generated_query = f"data.FacilityName:{names}"
return added_query(generated_query, user_query)
def escape_forbidden_characters_for_search(input_str: str) -> str:
# Reserved character are listed here https://community.opengroup.org/osdu/documentation/-/blob/master/platform/tutorials/core-services/SearchService.md
# ? and * are allowed for wildcard search
reserved_char_list = ['+', '-', '=', '>', '<', '!', '(', ')', '{', '}', '[', ']', '^', '"', '~',
':', '\\', '/']
def escape_char(input_char: str, reserved_char_list: [str]) -> str:
return input_char if input_char not in reserved_char_list else f"\\{input_char}"
result_str = ''.join([escape_char(char, reserved_char_list) for char in input_str])
return result_str
async def query_request_with_cursor(query_type: str, kind: str, ctx: Context, query: SimpleCursorQueryRequest = None):
returned_fields = query_type_returned_fields(query_type)
query_request = CursorQueryRequest(kind=kind,
limit=query.limit or LIMIT,
query=query.query,
returnedFields=[returned_fields],
cursor=query.cursor)
client = await get_search_service(ctx)
return await client.query_with_cursor(
data_partition_id=ctx.partition_id,
cursor_query_request=query_request)
async def query_request_with_offset(query_type: str, kind: str, ctx: Context, query: SimpleOffsetQueryRequest = None):
returned_fields = query_type_returned_fields(query_type)
query_request = QueryRequest(kind=kind,
limit=query.limit or LIMIT,
query=query.query,
returnedFields=[returned_fields],
offset=query.offset)
client = await get_search_service(ctx)
return await client.query(
data_partition_id=ctx.partition_id,
query_request=query_request)
async def query_request(query_type: str, kind: str, ctx: Context, query: SearchQueryRequest = None):
# use offset if not not none else use cursor
query_as_dict = query.dict(exclude_none=True, exclude_unset=True)
if query.offset is not None:
cursor_query = SimpleOffsetQueryRequest(**query_as_dict)
return await query_request_with_offset(query_type, kind, ctx, cursor_query)
cursor_query = SimpleCursorQueryRequest(**query_as_dict)
return await query_request_with_cursor(query_type, kind, ctx, cursor_query)
@router.post('/query/wellbores', summary='Query with cursor, get wellbores',
description=f"""Get all Wellbores object. <p>The wellbore kind is {OSDU_WELLBORE_KIND}
returns all records directly based on existing schemas</p>{REQUIRED_ROLES_READ}""",
response_model=CursorQueryResponse)
async def query_wellbores(body: SearchQuery = None, ctx: Context = Depends(get_ctx)):
return await basic_query_request_with_cursor(query_type, OSDU_WELLBORE_KIND, ctx, body.query)
async def query_wellbores(body: SearchQueryRequest = DEFAULT_QUERYREQUEST, ctx: Context = Depends(get_ctx)):
return await query_request(query_type, OSDU_WELLBORE_KIND, ctx, body)
@router.post('/query/wellbores/{wellboreId}/welllogs', summary='Query with cursor, search WellLogs by wellbore ID',
......@@ -100,10 +195,10 @@ async def query_wellbores(body: SearchQuery = None, ctx: Context = Depends(get_c
specific ID will be returned</p>
<p>The WellLogs kind is {OSDU_WELLLOG_KIND} returns all records directly based on existing schemas</p>{REQUIRED_ROLES_READ}""",
response_model=CursorQueryResponse)
async def query_welllogs_bywellbore(wellboreId: str, body: SearchQuery = None,
async def query_welllogs_bywellbore(wellboreId: str, body: SearchQueryRequest = DEFAULT_QUERYREQUEST,
ctx: Context = Depends(get_ctx)):
query = added_relationships_query(wellboreId, WELLBORE_RELATIONSHIP, body.query)
return await basic_query_request(query_type, OSDU_WELLLOG_KIND, ctx, query)
body.query = added_relationships_query(wellboreId, WELLBORE_RELATIONSHIP, body.query)
return await query_request(query_type, OSDU_WELLLOG_KIND, ctx, body)
@router.post('/query/wellbore/{wellboreAttribute}/welllogs',
......@@ -126,7 +221,7 @@ async def query_welllogs_bywellboreattribute(wellboreAttribute: str, body: Searc
specific ID will be returned</p>
<p>The Wellbore Markerset kind is {OSDU_WELLBOREMARKERSET_KIND} returns all records directly based on existing schemas</p>{REQUIRED_ROLES_READ}""",
response_model=CursorQueryResponse)
async def query_markers_bywellbore(wellboreId: str, body: SearchQuery = None,
async def query_markers_bywellbore(wellboreId: str, body: SearchQueryRequest = DEFAULT_QUERYREQUEST,
ctx: Context = Depends(get_ctx)):
query = added_relationships_query(wellboreId, WELLBORE_RELATIONSHIP, body.query)
return await basic_query_request(query_type, OSDU_WELLBOREMARKERSET_KIND, ctx, query)
body.query = added_relationships_query(wellboreId, WELLBORE_RELATIONSHIP, body.query)
return await query_request(query_type, OSDU_WELLBOREMARKERSET_KIND, ctx, body)
......@@ -13,21 +13,16 @@
# limitations under the License.
from fastapi import APIRouter, Depends
from odes_search.models import (
QueryRequest,
CursorQueryResponse,
CursorQueryRequest,
BaseModel,
Field,
Optional)
from odes_search.models import CursorQueryResponse
from app.clients.search_service_client import get_search_service
from app.utils import Context
from .search_v3 import (
added_query,
create_relationships_id_str,
query_type_returned_fields,
SearchQueryRequest,
DEFAULT_QUERYREQUEST,
OSDU_WELLBORE_KIND,
escape_forbidden_characters_for_search,
update_query_with_names_based_search,
query_request,
get_ctx,
query_type)
from ..common_parameters import REQUIRED_ROLES_READ
......@@ -35,100 +30,6 @@ from ..common_parameters import REQUIRED_ROLES_READ
router = APIRouter()
def update_query_with_names_based_search(names: str = None, user_query: str = None) -> str:
generated_query = f"data.FacilityName:{names}"
return added_query(generated_query, user_query)
def escape_forbidden_characters_for_search(input_str: str) -> str:
# Reserved character are listed here https://community.opengroup.org/osdu/documentation/-/blob/master/platform/tutorials/core-services/SearchService.md
# ? and * are allowed for wildcard search
reserved_char_list = ['+', '-', '=', '>', '<', '!', '(', ')', '{', '}', '[', ']', '^', '"', '~',
':', '\\', '/']
def escape_char(input_char: str, reserved_char_list: [str]) -> str:
return input_char if input_char not in reserved_char_list else f"\\{input_char}"
result_str = ''.join([escape_char(char, reserved_char_list) for char in input_str])
return result_str
def added_relationships_query(id: str, data_type: str, query: str = None):
relationships_id = create_relationships_id_str(data_type, id)
return added_query(relationships_id, query)
class SearchQueryRequest(BaseModel):
# Used by as input, w/o kind, etc...
limit: "Optional[int]" = Field(None, alias="limit")
query: "Optional[str]" = Field(None, alias="query")
cursor: "Optional[str]" = Field(None, alias="cursor")
offset: "Optional[int]" = Field(None, alias="offset")
SearchQueryRequest.update_forward_refs()
DEFAULT_SEARCHQUERYREQUEST = SearchQueryRequest(limit=None, query=None, cursor=None, offset=None)
class SimpleCursorQueryRequest(BaseModel):
# Used by as input, w/o kind, etc...
limit: "Optional[int]" = Field(None, alias="limit")
query: "Optional[str]" = Field(None, alias="query")
cursor: "Optional[str]" = Field(None, alias="cursor")
SimpleCursorQueryRequest.update_forward_refs()
DEFAULT_CURSORQUERYREQUEST = SimpleCursorQueryRequest(limit=None, query=None, cursor=None)
class SimpleOffsetQueryRequest(BaseModel):
limit: "Optional[int]" = Field(None, alias="limit")
query: "Optional[str]" = Field(None, alias="query")
offset: "Optional[int]" = Field(None, alias="offset")
SimpleOffsetQueryRequest.update_forward_refs()
DEFAULT_QUERYREQUEST = SimpleOffsetQueryRequest(limit=None, query=None, offset=None)
async def query_request_with_cursor(query_type: str, kind: str, ctx: Context, query: SimpleCursorQueryRequest = None):
returned_fields = query_type_returned_fields(query_type)
query_request = CursorQueryRequest(kind=kind,
limit=query.limit or 1000,
query=query.query,
returnedFields=[returned_fields],
cursor=query.cursor)
client = await get_search_service(ctx)
return await client.query_with_cursor(
data_partition_id=ctx.partition_id,
cursor_query_request=query_request)
async def query_request_with_offset(query_type: str, kind: str, ctx: Context, query: SimpleOffsetQueryRequest = None):
returned_fields = query_type_returned_fields(query_type)
query_request = QueryRequest(kind=kind,
limit=query.limit or 1000,
query=query.query,
returnedFields=[returned_fields],
offset=query.offset)
client = await get_search_service(ctx)
return await client.query(
data_partition_id=ctx.partition_id,
query_request=query_request)
async def query_request(query_type: str, kind: str, ctx: Context, query: SearchQueryRequest = None):
# use offset if not not none else use cursor
query_as_dict = query.dict(exclude_none=True, exclude_unset=True)
if query.offset is not None:
cursor_query = SimpleOffsetQueryRequest(**query_as_dict)
return await query_request_with_offset(query_type, kind, ctx, cursor_query)
cursor_query = SimpleCursorQueryRequest(**query_as_dict)
return await query_request_with_cursor(query_type, kind, ctx, cursor_query)
@router.post('/query/wellbores/byname', summary='Query with cursor or offset, get wellbores',
description=f"""Get Wellbores object by name. <p>The wellbore kind is {OSDU_WELLBORE_KIND}
returns all records directly based on existing schemas. The query is done on data.FacilityName field</p>{REQUIRED_ROLES_READ}""",
......
......@@ -15751,7 +15751,13 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchQuery"
"allOf": [
{
"$ref": "#/components/schemas/SearchQueryRequest"
}
],
"default": {},
"title": "Body"
}
}
}
......@@ -15820,7 +15826,13 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchQuery"
"allOf": [
{
"$ref": "#/components/schemas/SearchQueryRequest"
}
],
"default": {},
"title": "Body"
}
}
}
......@@ -15889,7 +15901,13 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchQuery"
"allOf": [
{
"$ref": "#/components/schemas/SearchQueryRequest"
}
],
"default": {},
"title": "Body"
}
}
}
......@@ -16018,7 +16036,13 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchQuery"
"allOf": [
{
"$ref": "#/components/schemas/SearchQueryRequest"
}
],
"default": {},
"title": "Body"
}
}
}
......@@ -16087,7 +16111,13 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchQuery"
"allOf": [
{
"$ref": "#/components/schemas/SearchQueryRequest"
}
],
"default": {},
"title": "Body"
}
}
}
......@@ -16156,7 +16186,13 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SearchQuery"
"allOf": [
{
"$ref": "#/components/schemas/SearchQueryRequest"
}
],
"default": {},
"title": "Body"
}
}
}
......
import pytest
import app.routers.search.search_v3_wellbore as search_v3_wellbore
import app.routers.search.search_v3 as search_v3
ADDED_QUERY_PARAMS = [
......@@ -43,7 +42,7 @@ NAMES_QUERY_PARAMS = [
@pytest.mark.parametrize("names, user_query, expected_query", NAMES_QUERY_PARAMS)
def test_update_query_with_names_based_search(names, user_query, expected_query):
assert search_v3_wellbore.update_query_with_names_based_search(names, user_query) == expected_query
assert search_v3.update_query_with_names_based_search(names, user_query) == expected_query
ESCAPE_CHAR_PARAMS = [
......@@ -56,4 +55,4 @@ ESCAPE_CHAR_PARAMS = [
@pytest.mark.parametrize("input_str, expected_str", ESCAPE_CHAR_PARAMS)
def test_escape_forbidden_characters_for_search(input_str, expected_str):
assert search_v3_wellbore.escape_forbidden_characters_for_search(input_str) == expected_str
assert search_v3.escape_forbidden_characters_for_search(input_str) == expected_str
Supports Markdown
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