Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reintroduce Swagger API docs #4054

Closed
1 task done
zolrath opened this issue May 3, 2023 · 16 comments
Closed
1 task done

Reintroduce Swagger API docs #4054

zolrath opened this issue May 3, 2023 · 16 comments

Comments

@zolrath
Copy link

zolrath commented May 3, 2023

  • I have searched to see if a similar issue already exists.

Is your feature request related to a problem? Please describe.
Recently the /docs endpoint which exposed swagger API docs was removed in favor of the sidebar docs available at ?view=api.

These docs simply show a list of gradio_client functions that can be called, limiting its usefulness to only users of gradio_client. There is no way to do discover how to do a simple HTTP POST to the API with the current docs.

The previous /docs endpoint was generally applicable and allowed anyone to integrate a gradio project into another project, regardless of language.

Describe the solution you'd like
I would love to see the Swagger API docs reintroduced at /docs to allow users to integrate via API more easily.

@vladmandic
Copy link

+1 as a highly desired feature

note that gradio allows for defining of additional apis that don't have just gradio controls tied to them. and those were also automatically covered by swagger.
but gradio_client is not a universal client, its ok to work with if endpoint is gradio control and nothing else.
and its ok on some platforms only - it cannot be used everywhere where simple http requests can be made.

if you wanted to have both docs, that would be perfectly fine - introduce new interface for gradio_client, but why remove previous interface which serves different audience?

@1lint
Copy link
Contributor

1lint commented May 4, 2023

If your in a hurry and want to restore the api docs in the latest gradio version, you can modify it manually by running

from gradio.routes import App
from inspect import getfile
import subprocess
# replace "code" with your text editor, i.e. "nano"
subprocess.run(["code", getfile(App)])

Then change line 115 to where you want to put the swagger/redoc api docs
super().__init__(**kwargs, docs_url=None, redoc_url=None)

If I remember correctly, the old default paths were (you can also just delete the doc params)
super().__init__(**kwargs, docs_url="/docs", redoc_url="/redoc")

@vladmandic
Copy link

@1lint if you're talking about modifying gradio src, that's not an option - my repo has ~35k clones in the last 2 weeks. i cannot distibute a modified gradio package. and situation with original repo is even worse - its ~0.5M clones in the last 2 weeks.

and community using docs to use those repos via api or write their scripts or extensions to repos is extremely active.

so whats the impact of this change? beyond massive.

@abidlabs
Copy link
Member

abidlabs commented May 4, 2023

Hi @vladmandic @zolrath can you elaborate a little more on the use case for the Swagger API docs?

The default Swagger API docs have some drawbacks: (1) They include lots of extraneous routes that are not useful to developers (2) They don't provide any specific information on what the payloads should be for these routes. E.g. the new API docs will tell you that /api/predict should take in two parameters, a string and an int, for example. Whereas the old Swagger docs only told you that /api/predict is a HTTP POST endpoint, which is information you can infer from the current API docs. So I guess my question is, what value does the Swagger API docs actually provide?

@vladmandic
Copy link

what value? swagger docs are actually usable by anyone famillar with HTTP REST concept.
new docs are usable only by gradio_client.

not to mention that old docs they provide far more functionality in forms of actually doing validation tests and http requests.

and what about when not even talking about built-in gradio routes, how about additional routes that application may define using add_api_route? swagger was not perfect, but it was usable. new docs are not slightly inferior, they are unusable.

@abidlabs
Copy link
Member

abidlabs commented May 4, 2023

You mention that the new docs are unusuable, but I'm not following why. How are you using the API docs? If you could please explain, it will help us figure out the best path forward

@vladmandic
Copy link

vladmandic commented May 4, 2023

if you trigger new docs, you ONLY see examples for gradio_client.
and first thing new docs say is $ pip install gradio_client

gradio_client may be Gradio's preferred method of performing HTTPRest requests, but it only one of thousands such tools.
swagger docs were actual HTTPRest docs and as such are applicable to ANY client tool (even using simple curl).
For example, if I'm building a browser app, I'll be sending requests from the browser which means I'm going to use built-in fetch method in browser's JavaScript engine, how does gradio_client even apply???

by documenting ONLY gradio_client, you've basically changed something that was based on open and well established standard (HTTPRest) that can be truly used cross-platform to Python-only and gradio-client-only.

@abidlabs
Copy link
Member

abidlabs commented May 4, 2023

For example, if I'm building a browser app, I'll be sending requests from the browser which means I'm going to use built-in fetch method in browser's JavaScript engine, how does gradio_client even apply???

It's helpful to hear your use case. So long story short, we don't encourage the use of the HTTP API endpoints directly. They have several issues, such as timeouts for long predictions and the fact that they don't work well with the queue if queuing is enabled. We are working on releasing clients for the most popular use cases, which don't have these drawbacks. We will release a client for JS (both node and browser) in the next few days, so that this use case should be covered.

@vladmandic
Copy link

we don't encourage the use of the HTTP API endpoints directly. They have several issues, such as timeouts for long predictions and the fact that they don't work well with the queue if queuing is enabled

Those are internal issues with routes.
For example:

  • Yes, I understand that /api/predict may timeout.
  • So instead of that, I create my own route using well-defined add_api_route method which just submits a job and doesn't wait for completion.
  • Additionally, I implement my own route which checks for progress

Basically, you made from an open-model tool that Gradio was, you're going in a direction "you can do what we allow and nothing else"

We will release a client for JS (both node and browser) in the next few days, so that this use case should be covered.

One thing is to release a client, another is to force its usage.
For example, Google has a fully documented JS client library. Do I have to use it? No. They also have a well defined HTTPRest end-points. Same about pretty much anyone that publishes a JS library.
Its about choice. You're removing choice by forcing usage of gradio_client

@abidlabs
Copy link
Member

abidlabs commented May 4, 2023

I totally understand what you're saying. But we want to provide a good experience to all developers, not just that know how to add additional routes. That's why we're not disabling the HTTP APIs, but just not officially documenting them -- because we can't guarantee reliable results from them. Even this is not a hard decision, we could decide to bring that back. One thing I'd like to understand -- when you say that

So instead of that, I create my own route using well-defined add_api_route method which just submits a job and doesn't wait for completion.

  1. Where do you add this route? Do you modify the gradio codebase? Or do you mount gradio within a FastAPI app? I haven't tested it, but I think mounting Gradio within a FastAPI app should give you access to the Swagger docs again
  2. How do you get the result of a job that you've submitted?

@vladmandic
Copy link

vladmandic commented May 4, 2023

But we want to provide a good experience to all developers, not just that know how to add additional routes

Ok. So allow such developers to enable swagger docs without modifying Gradio source code.

Where do you add this route? Do you modify the gradio codebase? Or do you mount gradio within a FastAPI app

Neither. I just add routes to gradio's fastapi instance.
Something like this (oversimplified, just for example)

import fastapi
import gradio as gr
app = gr.Blocks.launch() # this is basically fastapi instance
app.include_router(fastapi.APIRouter())
app.add_api_route("/api/v1/progress", api_progress, methods=["GET"], response_model=ProgressResponse)

class ProgressResponse(BaseModel): # inherits from base Pydantic response:
    progress: float = Field(title="Progress", description="The progress with a range of 0 to 1")

def api_progress():
    return {"progress": 0}

and since request/response can be defined with pydantic, swagger picks it up perfectly - every field becomes automatically documented and validated.

@1lint
Copy link
Contributor

1lint commented May 4, 2023

If you don't want to change source you can just modify the class definition at runtime. In your case its easier to do it at the fastapi level

import gradio as gr
from fastapi import FastAPI

def greet(name):
    return "Hello " + name + "!"

with gr.Blocks() as demo:
    name = gr.Textbox(label="Name")
    output = gr.Textbox(label="Output Box")
    greet_btn = gr.Button("Greet")
    greet_btn.click(fn=greet, inputs=name, outputs=output, api_name="greet")

# monkeypatch in url for api docs
def my_setup(self):
    self.docs_url = "/docs"
    self.redoc_url = "/redoc"
    self.orig_setup()

FastAPI.orig_setup = FastAPI.setup
setattr(FastAPI, "setup", my_setup)

# swagger docs should be at http://127.0.0.1:7860/docs
demo.launch()

# reverse monkey patch
FastAPI.setup = FastAPI.orig_setup

@vladmandic
Copy link

money patch works - thanks!

feature request is still valid - why not implement exactly that behind a flag in launch() method - all other flags are there.

@aetherwu
Copy link

But we want to provide a good experience to all developers, not just that know how to add additional routes

Ok. So allow such developers to enable swagger docs without modifying Gradio source code.

Where do you add this route? Do you modify the gradio codebase? Or do you mount gradio within a FastAPI app

Neither. I just add routes to gradio's fastapi instance. Something like this (oversimplified, just for example)

import fastapi
import gradio as gr
app = gr.Blocks.launch() # this is basically fastapi instance
app.include_router(fastapi.APIRouter())
app.add_api_route("/api/v1/progress", api_progress, methods=["GET"], response_model=ProgressResponse)

class ProgressResponse(BaseModel): # inherits from base Pydantic response:
    progress: float = Field(title="Progress", description="The progress with a range of 0 to 1")

def api_progress():
    return {"progress": 0}

and since request/response can be defined with pydantic, swagger picks it up perfectly - every field becomes automatically documented and validated.

I'm astonished you're here, vladmandic, as a champion for developers representing countless peers like us. It's been tough utilizing their offering since their recent launch.
Per Gradio's newest release, I noted the Gradio team consistently overlooking developers. Might you contemplate devising an alternative to Gradio? I'm aware that numerous individuals would appreciate this news.

I ought to propose this idea in your official repository.

@dewzor
Copy link

dewzor commented May 17, 2023

Im trying to query this API from C# and yeah, the current API docs arent very helpful to say the least.. No idea where to apply the monkeypatch.

If anyone could explain how i can get the swagger UI working and HTTP requests, that would be great.

@abidlabs
Copy link
Member

Ok so we have a good compromise thanks to a recent PR by @akx (#4282). If you'd like to reintroduce the FastAPI docs, you can do so by passing in app_kwargs={"docs_url": "/docs"} to the launch() method of your Gradio app. Basically, the app_kwargs method allows you to pass in any FastAPI app parameters, in this case the path to the docs page.

Just to recap the discussion above, we do not endorse the built-in FastAPI API endpoints, because:
(1) They do not respect the queueing mechanism built into Gradio
(2) They might time out if your machine learning model takes >60 seconds to return a prediction

Instead, we have released Python and JS clients that allow you to use any Gradio app as an API properly. We will consider creating a more general solution. In the meantime, if you know what you're doing and you'd like to use the FastAPI docs, you can enable them using the suggestion above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants