Refresh UI post change in URL parameters

I have a gradio app where I wish to hide certain text boxes in normal model and only display them when in debug mode. For this, I’m capturing query params from the url (url:/?debug=true) and setting visibility of these boxes basis that. However, the app once instantiated remains in the same state - UI doesn’t change while switching between the urls.

Here’s my code:

get_window_url_params = """
function() {
    const params = new URLSearchParams(window.location.search);
    const url_params = Object.fromEntries(params);
    console.log(url_params);  // Debugging line

    return [url_params];
}
"""

def init_ui_components(url_params):
    print(url_params)
    debug_mode = url_params.get('debug', 'false') == 'True'
    print("Debug Mode:", debug_mode)
    visibility = debug_mode  # True means boxes will be visible, False means they will be hidden
    contextbox = gr.Textbox(label='Context', visible=visibility)
    qeroutputbox = gr.Textbox(label='QER String', visible=visibility)
    intentoutputbox = gr.Textbox(label='Intent', visible=visibility)
    return contextbox, qeroutputbox, intentoutputbox

with gr.Blocks(css='style.css') as demo:
  ### Other components defined 

  url_params = gr.JSON({}, visible=False, label="URL Params")
  
  
  # Read the URL parameters when the Gradio app starts
  init_values = demo.load(fn=lambda x: x, inputs=url_params, outputs=url_params, _js=get_window_url_params)
  print("init values", init_values)
  # Check the structure of the outputs
  outputs = init_values.get('outputs', [])
  if outputs and isinstance(outputs[0], dict):
      extracted_url_params = outputs[0]
  else:
      extracted_url_params = {}
  print("extracted_url_params", extracted_url_params)
  # Use the debug value from the extracted url_params to initialize our UI components
  contextbox, qeroutputbox, intentoutputbox = init_ui_components(extracted_url_params)

### rest of the code ####
demo.queue(max_size=20).launch(share=False, server_name="10.10.76.98", server_port=7861)

The init_values gets printed only once - how can I force a UI reload/refresh upon change in url params?

Hi, this example doesn’t work. Not sure why it worked before…

The extracted_url_params is an empty {}

This is the output I get:

init values {'targets': [(None, 'load')], 'inputs': [1], 'outputs': [1], 'backend_fn': True, 'js': '\n function() {\n const params = new URLSearchParams(window.location.search);\n const url_params = Object.fromEntries(params);\n console.log(url_params); // Debugging line\n\n return [url_params];\n }\n ', 'queue': None, 'api_name': None, 'scroll_to_output': False, 'show_progress': 'full', 'every': None, 'batch': False, 'max_batch_size': 4, 'cancels': [], 'types': {'continuous': False, 'generator': False}, 'collects_event_data': False, 'trigger_after': None, 'trigger_only_on_success': False} OUTPUTS: [1] 1 extracted_url_params {}

I have inspected the codebase and it appears that the output is the Dependency. I am using 3.45.2 version of gradio & 0.5.3 gradio client. What version of Gradio are you using?

Any tips? Suggestions?

Thank you!

Since few weeks ago you can get the url param from gr.Request, here is an example

import gradio as gr

def echo(text, request: gr.Request):
    if request:
        print("Request headers dictionary:", request.headers)
        print("IP address:", request.client.host)
        print("Query parameters:", dict(request.query_params))
    return text

io = gr.Interface(echo, "textbox", "textbox").launch()

more here

1 Like

Thank you for responding @radames but this does not return the query parameters to be used as a variable but returns to the text to the Component. Did that make sense?

hi @blackmarkt,

You can have it on a gr.State and load it on load

import gradio as gr

def echo(params):
    print(params)
    return params

def get_params(request: gr.Request):
  params = request.query_params
  ip = request.client.host
  return {"params": params, 
          "ip": ip}

  
with gr.Blocks() as demo:
  url_params = gr.State()
  text_in = gr.Textbox()
  text_out = gr.JSON()
  btn = gr.Button()
  btn.click(echo, inputs=[url_params], outputs=[text_out])
  demo.load(get_params, None, url_params)

demo.queue()
demo.launch()
#demo.launch(debug=True, share=True)
1 Like

@radames Hmmm this didn’t work either. When I print out the url_params it shows state and is of type <class 'gradio.components.state.State'> which is consistent with the codebase. Also the btn.click(echo, inputs=[url_params], outputs=[text_out]) doesn’t output the params so I am again not able to capture the actual URL parameters and store them in global variables.

Not sure why if you’re seeing something else. Suggestions?

Thanks @radames but this again didn’t work for me. I can see the printed params but can’t access them. When I print the url_params I get state and type <class 'gradio.components.state.State'>.

I can see the URL parameters outputted in the gr.JSON but can’t store the actual parameters as global variables.

Did that make sense? I feel like there is a not understanding of what I am trying to achieve as every suggested solution doesn’t actually output the URL parameter(s).

Any suggestions? Feedback?

Thank you

what’s your Gradio version?

1 Like

My gradio version is 3.45.2

sorry but code snippet above works for me

https://huggingface.co/spaces/radames/gradio-url-params-request?test=hello

1 Like

@radames I think there is a miscommunication/misunderstanding here. I want to use the URL parameters in my code as global variables not in a gradio UI component. This code displays the params but are not returned in the python code so I can use in another function (i.e. to access a database).

Did that make sense?

@radames Oh hey BTW I am also in Berkeley :bear:

1 Like

Sorry, yes, I’m not sure if I understand your need. With Gradio, you need the app context, i.e. with gr.Blocks() as block or gr.Interface to be able to read URL parameters from gr.Request. You also need gr.State since every user session is different; every URL parameter will be different for each user request, so a global state here won’t work.

@radames sorry the sentences were a bit confusing to understand but correct me if I am wrong but what you are saying is that I need to use gradio context to request the URL parameters? Is there a component that returns the params so I can use in my python code?

Thank you

yes, that’s correct, under the hood Gradio use Fast API Query Parameters - FastAPI

1 Like

Thank you @radames

Do you know of another solution using Python I can use to query the parameters when the embedded iFrame loads?

I appreciate you rubber ducking this with me

@radames Thanks for the help!

I see you’re working demo on Hugging Face, but that exact code locally (Gradio==4.0.2) just shows these hash and function variables.

Ever seen anything like this?

1 Like

hi @derek-pyne , thanks for reporting, I think it’s bug on the newer version Gradio==4.0.2 the workaround for now is to disable the queue app.py · radames/gradio-url-params-request at main I created an issue here

2 Likes

Ahhhhhh, got it. Disabling the queue works. Thanks for the fast reply!

1 Like

Thanks @radames for the solution and @derek-pyne for reporting. Hopefully an updated version doesn’t re-trigger this issue again.