How to pass dynamic data to a Gradio Blocks on each FastAPI request?

I have a FASTAPI server that serves different requests and on call of /chatbot I want to render the Gradio block with some message that is passed dynamically to the app.

@app.get("/chatbot") 
def render_chatbot(request: Request):
    username = request.query_params.get('username', 'admin')
    gradio_blocks = GradioApp(username)
    return HTMLResponse(gradio_blocks)

I have implemented the GradioApp function, but how can I pass the variable based on request to GradioApp?

def GradioApp(username: str):
    with gr.Blocks(title="ChatBot", css=style_css) as demo:
    ...
    return demo

Any ideas are welcome. Thank you very much!

1 Like

Hmm… auth_dependency?

Lets take an example what I am trying to achieve.
I am authenticate the users and getting call back to /callback endpoint with username and other details stored in cookies.

@router.get("/callback")
def callback(request: Request):
    response = RedirectResponse(url="/chatbot")
    username = request.cookies.get("username")

    return response

Which is redirecting the request to the /chatbot endpoint.
I have mounted the /chatbot some like this for gradio blocks:

app = gr.mount_gradio_app(app, launch_chatbot(""), path="/chatbot")

I have launch_chatbot function some like:

def launch_chatbot(username=""):
    logger.info(f"Access Token: {username}")
    with gr.Blocks(title="Naviga-ChatBot", css=style_css, head=f"<script src=\"{script_js}\"></script>") as demo:

    # UI implementation and other logic

    return demo

Now I am looking for a way to pass this username variable to this gradio UI.
I have tried different ways but failed to achieve this.

As per my observation, I might be wrong this gr.mount_gradio_app loads the code at the start of the program it does not re-render the code when /chatbot is called.

Please let me know if I am missing something. Thanks.

1 Like

It’s a bit rough, but how about embedding it in the response?

@app.get("/callback")
async def callback(request: Request):
    response = RedirectResponse(url="/chatbot")
    username = request.cookies.get("username")
    response.url = f"{response.url}?username={username}"
    return response
@app.get("/chatbot")
async def render_chatbot(request: Request):
    username = request.query_params.get('username', 'guest')
    
    with gr.Blocks() as demo:
        gr.Markdown(f"Welcome, {username}!")
        # Add other dynamic components based on the username
        
    return HTMLResponse(demo)
1 Like

Thanks for the suggestion; however, if we go with this approach, there is no problem passing values to /chatbot, but return HTMLResponse(demo) doesn’t work.

As per my observation, we can not return gr.Block() using:

from fastapi.responses import HTMLResponse

It gives the below error:
AttributeError: ‘Blocks’ object has no attribute ‘encode’

1 Like

It seems that this can be avoided by encoding it in advance, but I was unable to find any examples of HTMLResponse. There were examples of Response.

1 Like