Do not input private or sensitive data. View Qlik Privacy & Cookie Policy.
Skip to main content

Announcements
Want to see what's currently in public preview? We've pulled it all together in one place. Check it out here
cancel
Showing results for 
Search instead for 
Did you mean: 
adamlopuch
Contributor
Contributor

Python SSE: how to go through same RequestIterator multiple times

Hi Qlik SSE gurus,

The Python SSE is working like a charm, however in one call I'd like to go through the *same* request payload *twice*... is this possible?

My goal:

  1. FIRST ITERATION: go through each row and extract all parameters
  2. Parse all distinct parameter values in entire request
  3. SECOND ITERATION: go through each row AGAIN and yield result with distinct parameters

My issue:

I suspect that the (simple) approach I am using fully consumes the request iterator the first time I go through it. (Step 1).  When I go through it a second time (Step 3), there is nothing to iterate.

Example code:

# STEP 1: Go through each row and extract all parameters
all_params = []
for bundled_rows in request:
    for row in bundled_rows.rows:
        all_params.append([d.strData for d in row.duals])

# STEP 2: Get all values for parameters across entire request
distinct_params = something_with(all_params)

# STEP 3: go through each row again and use the distinct parameters
for bundled_rows in request:
    response_rows = []
    for row in bundled_rows.rows:
        duals = iter([SSE.Dual(numData=something_with(distinct_params)])
        response_rows.append(SSE.Row(duals=duals))
    yield SSE.BundledRows(rows=response_rows)

 

Labels (1)
1 Solution

Accepted Solutions
Nabeel_Asif
Employee
Employee

Hi @adamlopuch ,

Your suspicion is correct; the request is a generator object which can only be consumed once in Python. One way around it is to first store the request in a different data structure such as a list that you can step through multiple times.

# Get a list from the generator object so that it can be iterated over multiple times
request_list = [request_rows for request_rows in request]

 

In my SSE I use a function that can then take this list and convert it to a pandas dataframe which is usually a more convenient structure for Python:

def request_df(request_list, row_template, col_headers):
    """
    This function takes in a SSE request as a list together with a row template and column headers as lists of strings.
    Returns a Data Frame for the request.
    e.g. request_df(request_list, ['strData', 'numData', 'strData'], ['dim1', 'measure', 'kwargs'])
    """
    
    rows = [row for request_rows in request_list for row in request_rows.rows]
    outer = []
    
    for i in range(len(rows)):
        inner = []
        
        for j in range(len(row_template)):
            inner.append(getattr(rows[i].duals[j], row_template[j]))
        
        outer.append(inner)
    
    return pd.DataFrame(outer, columns=col_headers)

 

Finally, at the end of your function you'll need to structure the output as SSE.Duals inside SSE.Rows inside SSE.BundledRows 😂

View solution in original post

1 Reply
Nabeel_Asif
Employee
Employee

Hi @adamlopuch ,

Your suspicion is correct; the request is a generator object which can only be consumed once in Python. One way around it is to first store the request in a different data structure such as a list that you can step through multiple times.

# Get a list from the generator object so that it can be iterated over multiple times
request_list = [request_rows for request_rows in request]

 

In my SSE I use a function that can then take this list and convert it to a pandas dataframe which is usually a more convenient structure for Python:

def request_df(request_list, row_template, col_headers):
    """
    This function takes in a SSE request as a list together with a row template and column headers as lists of strings.
    Returns a Data Frame for the request.
    e.g. request_df(request_list, ['strData', 'numData', 'strData'], ['dim1', 'measure', 'kwargs'])
    """
    
    rows = [row for request_rows in request_list for row in request_rows.rows]
    outer = []
    
    for i in range(len(rows)):
        inner = []
        
        for j in range(len(row_template)):
            inner.append(getattr(rows[i].duals[j], row_template[j]))
        
        outer.append(inner)
    
    return pd.DataFrame(outer, columns=col_headers)

 

Finally, at the end of your function you'll need to structure the output as SSE.Duals inside SSE.Rows inside SSE.BundledRows 😂