gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
30.37k stars 2.26k forks source link

UI not displaying properly because path to theme.css is not using the provided root_path #7934

Closed PaulClas closed 2 months ago

PaulClas commented 2 months ago

I have tried all the solutions listed in this issue as well as #3798, #3662, #3482, #3472 and https://stackoverflow.com/questions/61641514/css-not-recognized-when-served-with-fastapi.

Solutions that I have tried include:

My issue is the same as stated in the issue title of #3472. When running behind a proxy and load balancer, the gradio app requests the theme.css at the root of the url and not after the url+prefix. I have tried providing the root_path at the app.mount_gradio_app(root_path=) level and at the app=FastAPI(rooth_path=) level.

The gradio app runs at the provided root_path but the theme.css file is requested at the url without the root_path:

Screenshot 2024-04-04 at 3 29 04 PM

I have tried a few different releases from gradio and the gradio python client and have the problem persisting.

This is a sample version of the two solutions I have tried in my code that don't provide the right url to get the theme.css. Both ways work to have the gradio app running with the prefix at https//:abc.com/app/gradio but the theme is requested at https//:abc.com/gradio and fails.

Try 1:

import gradio as gr
import uvicorn

app = FastAPI(root_path="/app")

@app.get('/')
def hello():
    return {"message":"hello"}

g_app = gr.Interface(
    lambda x: f"Hello {x}",
    "textbox",
    "textbox",
)

app = gr.mount_gradio_app(app, g_app, path="/gradio")

uvicorn.run(app,host="0.0.0.0",port=8080)

Try 2:

from fastapi import FastAPI
import gradio as gr
import uvicorn

app = FastAPI()

@app.get('/')
def hello():
    return {"message":"hello"}

g_app = gr.Interface(
    lambda x: f"Hello {x}",
    "textbox",
    "textbox",
)

app = gr.mount_gradio_app(app, g_app, path="/gradio",root_path="/app")

uvicorn.run(app,host="0.0.0.0",port=8080)

Thx for the help.

Originally posted by @PaulClas in https://github.com/gradio-app/gradio/issues/3472#issuecomment-2038081429

abidlabs commented 2 months ago

Hmm I thought this was fixed. Let me look into this

PaulClas commented 2 months ago

Requirements I am using @abidlabs

Screenshot 2024-04-04 at 4 10 31 PM
abidlabs commented 2 months ago

the gradio app requests the theme.css at the root of the url and not after the url+prefix

Can you specify what the root of the url is here, and what the url+prefix is? If the url is sensitive, you can use a placeholder, but I need to understand what the format of the correct and incorrect urls are

PaulClas commented 2 months ago

the gradio app requests the theme.css at the root of the url and not after the url+prefix

Can you specify what the root of the url is here, and what the url+prefix is? If the url is sensitive, you can use a placeholder, but I need to understand what the format of the correct and incorrect urls are

The root url is : https://example.com/api/sql-agent

The path that I want to mount the gradio interface to is https://example.com/api/sql-agent/gradio

So the root_path (prefix) is: root_path="/api/sql-agent"

PS: I want to add that this issue is only observed when deployed behing a proxy (cloud run + load balancer). I do not see this issue when running locally and with docker.

abidlabs commented 2 months ago

Can you please go to https://example.com/api/sql-agent/gradio/config and tell me what the value of the "root" key is in that json? Again you can use placeholders

PaulClas commented 2 months ago

"root":"https://example.com/api/sql-agent/gradio"

abidlabs commented 2 months ago

Ok so the root looks correct, but for some reason its not being used in the request for theme.css, hmm

pngwn commented 2 months ago

It looks like it being loaded from the correct location from the screenshot of the request in the original issue. It just doesn't seem to exist.

image

PaulClas commented 2 months ago

The theme loads from the url without the root_path @pngwn

The theme is actually loading from https//:example.com/gradio/theme.css and not https//:example.com/api/sql-agent/gradio/theme.css

pngwn commented 2 months ago

Why is that url showing in the request pane?

abidlabs commented 2 months ago

Oh yeah good point @pngwn the URL from your screenshot @PaulClas is https//:example.com/api/sql-agent/gradio/theme.css so it does look like its loading from the right place

Are we missing something @PaulClas?

PaulClas commented 2 months ago

I am mounting the gradio interface as such:

app = gr.mount_gradio_app(app,demo,path="/gradio",root_path="/api/sql-agent")

The theme.css is not using the root_path with the code above and also when trying to use app=FastAPI(root_path="/api/sql-agent")

abidlabs commented 2 months ago

But according to your screenshot @PaulClas, as @pngwn pointed, the request is being made to https//:example.com/api/sql-agent/gradio/theme.css, which does include the prefix, right?

PaulClas commented 2 months ago

But according to your screenshot @PaulClas, as @pngwn pointed, the request is being made to https//:example.com/api/sql-agent/gradio/theme.css, which does include the prefix, right?

@pngwn and @abidlabs you are correct. I was forcing the theme.css file as a redirect. This is the screenshot with the correct link that returns a 404

Screenshot 2024-04-04 at 5 15 53 PM

And the root in the config is just: https://example.com/gradio

abidlabs commented 2 months ago

Can you clarify? -- How were you forcing the redirect? How did the root in the config change? Is this a different Gradio app?

PaulClas commented 2 months ago

@abidlabs as a solution attempt: I was intercepting the call and changing the path in the header for the correct one.

pngwn commented 2 months ago

We need to see the request url in the right sidebar. The files list always just shows the file name.

It would be helpful if you could give the exact code you are using, the config (without components, dependencies, layout), and the request info for theme.css (and it also looks like the info route is failing too).

Your original post had several snippets, so I'm not sure what I should be looking at.

pngwn commented 2 months ago

It's very hard for us to debug this without a reproduction. I've checked and the theme.css does use the config.root value, so I'm guessing the problem is either in the js client or the backend.

PaulClas commented 2 months ago

I understand @pngwn. Here are some clarifications:

This is a screenshot where you can see the full request as well as the request for the theme.css failing:

Screenshot 2024-04-07 at 6 43 30 PM

as for the code :

app = FastAPI()

@app.get("/")
def read_main():
    return {"message": "The app Tac-o-Tac is ready v1.0.0"}

with gr.Blocks(title="Tac-o-tac v1.0.0") as demo:
# More code here for the interface

app = gr.mount_gradio_app(app, demo,path="/gradio", root_path="/api/sql-agent")

And looking at the config: "root":"https:/urlhere.ca/gradio"}

abidlabs commented 2 months ago

Agree with @pngwn this behavior is unusual and may be specific to your proxy / load_balancer set up. Basically, it seems to me that the proxy or load balancer isn't forwarding the headers as needed by Gradio to reconstruct the full URL: https://www.gradio.app/guides/running-gradio-on-your-web-server-with-nginx

One workaround you could try is to pass in the full url as your root path, so instead of just the prefix, do something like:

app = FastAPI()

@app.get("/")
def read_main():
    return {"message": "The app Tac-o-Tac is ready v1.0.0"}

with gr.Blocks(title="Tac-o-tac v1.0.0") as demo:
# More code here for the interface

app = gr.mount_gradio_app(app, demo,path="/gradio", root_path="https//:example.com/api/sql-agent")
PaulClas commented 2 months ago

Why would all other files for the frontend be passed with the correct url in the header and the theme.css file as well as assets/index-a889f790.css and info use the url without the prefix ? I have found four other issues that recall the same issue with gradio (https://github.com/gradio-app/gradio/issues/3798, https://github.com/gradio-app/gradio/issues/3662, https://github.com/gradio-app/gradio/pull/3482, https://github.com/gradio-app/gradio/issues/3472)

That's why it makes me believe this is a gradio issue with handling proxies.

pngwn commented 2 months ago

Because the theme is handled slightly differently to other static assets. The issue here is that even if the theme worked, I think there would probably be other issues too if the config.root isn't correct.

PaulClas commented 2 months ago

@abidlabs Trying with the full url as root_path fails. The endpoint is not found.

abidlabs commented 2 months ago

The endpoint is not found

So the exact same error?

And what is config.root in this case?

PaulClas commented 2 months ago

The config file is not accessible. I just get a 404 not found at the endpoint when using root_path="url"

abidlabs commented 2 months ago

@PaulClas can you try installing from this PR and see if solves the issue? Installation instructions will show up shortly on the PR: https://github.com/gradio-app/gradio/pull/7938 -- this is the only thing I can think of, and we can't do much else without more step-by-step repro details

PaulClas commented 2 months ago

Will do @abidlabs Thank you each of you @pngwn for your help.

PaulClas commented 2 months ago

Will do @abidlabs

What is the difference between providing app=FastAPI(root_path) and then mounting with FastAPI versus using app.mount_gradio_app(root_path) ?

abidlabs commented 2 months ago

@PaulClas there's no difference, the root path provided in app.mount_gradio_app(root_path) gets set as the FastAPI root path:

https://github.com/gradio-app/gradio/blob/6a4bf7abe29059dbdc6a342e0366fdaa2e4120ee/gradio/routes.py#L187

Just FYI https://github.com/gradio-app/gradio/pull/7938 has been merged into main and we'll include in the upcoming release. But we'll probably need to close this issue in the absence of a repro

abidlabs commented 2 months ago

Will go ahead and close this for now since we can't repro. Happy to reopen if we get a step-by-step repro.

PaulClas commented 2 months ago

@PaulClas there's no difference, the root path provided in app.mount_gradio_app(root_path) gets set as the FastAPI root path:

https://github.com/gradio-app/gradio/blob/6a4bf7abe29059dbdc6a342e0366fdaa2e4120ee/gradio/routes.py#L187

Just FYI #7938 has been merged into main and we'll include in the upcoming release. But we'll probably need to close this issue in the absence of a repro

I added the pip install command to my dockerfile for deployment but it didn't solve the issue. I havec looked into our nginx settings and I still can't pinpoint why the root-path is not passed to theme.css and other files.

@abidlabs is there a way you know off to pass the theme.css as a static file that can be linked to the frontend when loaded by the DOM ?

abidlabs commented 2 months ago

That's very strange, can't think of what the issue might be --

@abidlabs is there a way you know off to pass the theme.css as a static file that can be linked to the frontend when loaded by the DOM ?

We don't support that with a public api,you'd need to edit the gradio source files to do this.

PaulClas commented 2 months ago

It's a shame. I have at least 4 gradio interfaces we wanted to deploy using cloud run. This issue means I'll need to migrate to another ML app service.

abidlabs commented 2 months ago

If you can provide a step-by-step repro including how you are deploying the Gradio app that will allow reproduce the issue you're describing, we're still happy to take a look and can reopen the issue

jrowen commented 2 months ago

I'm seeing the same missing theme.css behavior with v4.25.0. Rolling back to v4.20.0 seems to provide a temporary fix.

abidlabs commented 2 months ago

@jrowen can you provide more details on your Gradio app and how it is deployed?

jrowen commented 2 months ago

I'm also using FastAPI and mount_gradio_app, only setting the path. There's a nginx reverse proxy in front of the app.

I also see this path value is missing for theme.css.

PaulClas commented 2 months ago

@abidlabs I have deployed my front-end app as a separate cloud run using demo.launch(server_name,server_port,root_path) with the same reverse proxy, load_balancer and nginx settings as before. The theme.css is passed properly when using this way. This really seems like an issue specifically related to the mount_gradio_app() method and the root_path=XXX having bugs.

jrowen commented 2 months ago

One more quick update, I'm still seeing a 404 for one css file, but this doesn't seem to impact the usability of my app.

image

luvwinnie commented 2 months ago

is this already fix?

abidlabs commented 2 months ago

Nope as we don't have a repro. @luvwinnie if you can provide a minimal code example that we can use to reproduce the issue above, we can reopen this issue. See: https://stackoverflow.com/help/minimal-reproducible-example

duynguyen-0203 commented 2 months ago

I had the same problem with version 4.26.0, and going back to version 4.20.0 helped me solve the problem. But I hope this problem can be completely resolved in the next versions.