From b587252bb54d905c9539c84d9907fd9da847a286 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Tue, 1 Mar 2022 16:31:07 +0100 Subject: [PATCH] feat(api): request changes --- api/chalicelib/core/sessions.py | 49 ++++++++++++++++++++++----------- api/schemas.py | 36 ++++++++++++------------ 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/api/chalicelib/core/sessions.py b/api/chalicelib/core/sessions.py index 74b7f7cfa..3c766b74c 100644 --- a/api/chalicelib/core/sessions.py +++ b/api/chalicelib/core/sessions.py @@ -567,7 +567,6 @@ def search_query_parts(data, error_status, errors_only, favorite_only, issue, pr value_key=f_k)) # --------------------------------------------------------------------------- if len(data.events) > 0: - # ss_constraints = [s.decode('UTF-8') for s in ss_constraints] events_query_from = [] event_index = 0 or_events = data.events_order == schemas.SearchEventOrder._or @@ -578,13 +577,15 @@ def search_query_parts(data, error_status, errors_only, favorite_only, issue, pr is_any = _isAny_opreator(event.operator) if not isinstance(event.value, list): event.value = [event.value] - if not is_any and len(event.value) == 0 \ + if not is_any and len(event.value) == 0 and event_type not in [schemas.EventType.request_details] \ or event_type in [schemas.PerformanceEventType.location_dom_complete, schemas.PerformanceEventType.location_largest_contentful_paint_time, schemas.PerformanceEventType.location_ttfb, schemas.PerformanceEventType.location_avg_cpu_load, schemas.PerformanceEventType.location_avg_memory_usage - ] and (event.source is None or len(event.source) == 0): + ] and (event.source is None or len(event.source) == 0) \ + or event_type in [schemas.EventType.request_details] and ( + event.filters is None or len(event.filters) == 0): continue op = __get_sql_operator(event.operator) is_not = False @@ -803,20 +804,36 @@ def search_query_parts(data, error_status, errors_only, favorite_only, issue, pr _multiple_conditions(f"main2.timestamp - main.timestamp {event.sourceOperator} %({e_k})s", event.source, value_key=e_k)) - elif event_type==schemas.EventType.request_details: + elif event_type == schemas.EventType.request_details: event_from = event_from % f"{events.event_type.REQUEST.table} AS main " - if len(event.value[0].url_value)>0 and not _isAny_opreator(event.value[0].url_operator): - event_where.append(_multiple_conditions(f"main.{events.event_type.REQUEST.column} {op} %({e_k})s", event.value[0].url_value,value_key=e_k)) - if len(event.value[0].status_code_value)>0 and not _isAny_opreator(event.value[0].status_code_operator): - event_where.append(_multiple_conditions(f"main.{events.event_type.REQUEST.column} {op} %({e_k})s", event.value[0].status_code_value,value_key=e_k)) - if len(event.value[0].method_value)>0 and not _isAny_opreator(event.value[0].method_operator): - event_where.append(_multiple_conditions(f"main.method {op} %({e_k})s", event.value[0].method_value,value_key=e_k)) - if len(event.value[0].duration_value)>0 and not _isAny_opreator(event.value[0].duration_operator): - event_where.append(_multiple_conditions(f"main.{events.event_type.REQUEST.column} {op} %({e_k})s", event.value[0].duration_value,value_key=e_k)) - if len(event.value[0].request_value)>0 and not _isAny_opreator(event.value[0].request_operator): - event_where.append(_multiple_conditions(f"main.{events.event_type.REQUEST.column} {op} %({e_k})s", event.value[0].request_value,value_key=e_k)) - if len(event.value[0].response_value)>0 and not _isAny_opreator(event.value[0].response_operator): - event_where.append(_multiple_conditions(f"main.{events.event_type.REQUEST.column} {op} %({e_k})s", event.value[0].response_value,value_key=e_k)) + for j, f in enumerate(event.filters): + is_any = _isAny_opreator(f.operator) + if is_any or len(f.value) == 0: + continue + op = __get_sql_operator(f.operator) + e_k_f = e_k + f"_fetch{j}" + full_args = {**full_args, **_multiple_values(f.value, value_key=e_k_f)} + if f.type == schemas.FetchFilterType._url: + event_where.append( + _multiple_conditions(f"main.{events.event_type.REQUEST.column} {op} %({e_k_f})s", f.value, + value_key=e_k_f)) + elif f.type == schemas.FetchFilterType._status_code: + event_where.append( + _multiple_conditions(f"main.status_code {op} %({e_k_f})s", f.value, value_key=e_k_f)) + elif f.type == schemas.FetchFilterType._method: + event_where.append( + _multiple_conditions(f"main.method {op} %({e_k_f})s", f.value, value_key=e_k_f)) + elif f.type == schemas.FetchFilterType._duration: + event_where.append( + _multiple_conditions(f"main.duration {op} %({e_k_f})s", f.value, value_key=e_k_f)) + elif f.type == schemas.FetchFilterType._request_body: + event_where.append( + _multiple_conditions(f"main.request_body {op} %({e_k_f})s", f.value, value_key=e_k_f)) + elif f.type == schemas.FetchFilterType._response_body: + event_where.append( + _multiple_conditions(f"main.response_body {op} %({e_k_f})s", f.value, value_key=e_k_f)) + else: + print(f"undefined fetch filter: {f.type}") else: continue if event_index == 0 or or_events: diff --git a/api/schemas.py b/api/schemas.py index f35125ae5..6e59bdafd 100644 --- a/api/schemas.py +++ b/api/schemas.py @@ -384,7 +384,7 @@ class EventType(str, Enum): location = "LOCATION" custom = "CUSTOM" request = "REQUEST" - request_details = "REQUEST_DETAILS" + request_details = "FETCH" graphql = "GRAPHQL" state_action = "STATEACTION" error = "ERROR" @@ -503,22 +503,19 @@ class HttpMethod(str, Enum): _patch = 'PATCH' -class RequestDetailsSchema(BaseModel): - url_value: List[str] = Field([]) - url_operator: SearchEventOperator = Field(SearchEventOperator._is_any) - status_code_value: List[int] = Field(None) - status_code_operator: MathOperator = Field(None) - method_value: List[HttpMethod] = Field([]) - method_operator: SearchEventOperator = Field(None) - duration_value: List[int] = Field(None) - duration_operator: MathOperator = Field(None) - request_value: List[str] = Field([]) - request_operator: SearchEventOperator = Field(None) - response_value: List[str] = Field([]) - response_operator: SearchEventOperator = Field(None) +class FetchFilterType(str, Enum): + _url = "FETCH_URL" + _status_code = "FETCH_STATUS_CODE" + _method = "FETCH_METHOD" + _duration = "FETCH_DURATION" + _request_body = "FETCH_REQUEST_BODY" + _response_body = "FETCH_RESPONSE_BODY" - class Config: - alias_generator = attribute_to_camel_case + +class RequestFilterSchema(BaseModel): + type: FetchFilterType = Field(...) + value: List[Union[int, str]] = Field(...) + operator: Union[SearchEventOperator, MathOperator] = Field(...) class _SessionSearchEventRaw(__MixedSearchFilter): @@ -528,6 +525,7 @@ class _SessionSearchEventRaw(__MixedSearchFilter): operator: SearchEventOperator = Field(...) source: Optional[List[Union[ErrorSource, int, str]]] = Field(None) sourceOperator: Optional[MathOperator] = Field(None) + filters: Optional[List[RequestFilterSchema]] = Field(None) @root_validator def event_validator(cls, values): @@ -553,14 +551,14 @@ class _SessionSearchEventRaw(__MixedSearchFilter): elif values.get("type") == EventType.error and values.get("source") is None: values["source"] = [ErrorSource.js_exception] elif values.get("type") == EventType.request_details: - assert len(values.get("value", [])) == 1 and isinstance(values["value"][0], RequestDetailsSchema), \ - f"event should be of type RequestDetailsSchema for {EventType.request_details}" + assert isinstance(values.get("filters"), List) and len(values.get("filters", [])) > 0, \ + f"filters should be defined for {EventType.request_details}" return values class _SessionSearchEventSchema(_SessionSearchEventRaw): - value: Union[List[Union[RequestDetailsSchema, _SessionSearchEventRaw, str]], str] = Field(...) + value: Union[List[Union[_SessionSearchEventRaw, str]], str] = Field(...) class _SessionSearchFilterSchema(__MixedSearchFilter):