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.56k stars 2.27k forks source link

Issue with Mounting Multiple Gradio Interfaces using gr.mount_gradio_app #8428

Closed yjtan0819 closed 3 weeks ago

yjtan0819 commented 3 weeks ago

Describe the bug

I am currently facing an issue when trying to mount two Gradio interfaces using the gr.mount_gradio_app function.

Here's what I am experiencing:

Have you searched existing issues? ๐Ÿ”Ž

Reproduction

import gradio as gr
from fastapi import FastAPI
import uvicorn

app = FastAPI()

def check_login_state(is_logged_in):
    if is_logged_in:
        return "Login", "Logout"
    else:
        return "Logout", "Login"

io = gr.TabbedInterface([
    gr.Interface(fn=lambda x: x, inputs="text", outputs="text"),
    gr.Interface(fn=lambda x: x, inputs="text", outputs="text")
])

app = gr.mount_gradio_app(app, io, path='/gradio')

app = gr.mount_gradio_app(app, io, path='/', auth_dependency = check_login_state)

if __name__ == "__main__":
    uvicorn.run(app)

Screenshot

image

Logs

No response

System Info

Gradio Environment Information:
------------------------------
Operating System: Linux
gradio version: 4.32.1
gradio_client version: 0.17.0

------------------------------------------------

Severity

I can work around it

freddyaboulton commented 3 weeks ago

I have not looked into it but I think this makes sense. When you mount gradio at the root /, the request to /gradio will be sent to the gradio app at the root, which does not have a way to fulfill that request.

Does this problem happen if the first app is not mounted at /? Or if you switch the order of the mounting (first mount at /gradio then /)?

yjtan0819 commented 3 weeks ago

The problem does not happen if the first app is not mounted at /, but it still happens if I switch the order of the mounting.

freddyaboulton commented 3 weeks ago

This is the intended behavior of FastAPI so I will close.

from fastapi import FastAPI

parent = FastAPI()

root = FastAPI()
child = FastAPI()

@root.get("/")
def hello():
    return "Hello"

@child.get("/hi")
def hi():
    return "hi"

parent.mount("/", root)
parent.mount("/child", child)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(parent, port=7860)

I suggest you don't place either app at the root and redirect visitors of the home page to whichever child app you want.

from fastapi import FastAPI
from fastapi.responses import RedirectResponse

parent = FastAPI()

root = FastAPI()
child = FastAPI()

@parent.get("/")
def go_to_root():
    return RedirectResponse("/root")

@root.get("/")
def hello():
    return "Hello"

@child.get("/")
def hi():
    return "hi"

parent.mount("/root", root)
parent.mount("/child", child)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(parent, port=7860)
pievalentin commented 3 weeks ago

Thank you, @freddyaboulton very helpful !