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

Integrating gradio demo #6034

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions extra-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ docarray>=0.16.4: core
jina-hubble-sdk>=0.30.4: core
jcloud>=0.0.35: core
opentelemetry-api>=1.12.0: core
gradio: core
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if it is good to add this dependency as a core dependency. How big and how many extra dependencies does gradio bring?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, makes sense. Do you want me to add it some other type or remove it all together (and ask users to install it separately) ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now lets ask users to install it, let think about it later then

opentelemetry-instrumentation-grpc>=0.35b0: core
uvloop: perf,standard,devel
prometheus_client>=0.12.0: perf,standard,devel
Expand Down
70 changes: 70 additions & 0 deletions jina/serve/runtimes/worker/http_fastapi_app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import inspect
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Union
import gradio as gr
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would imply thay impprting gradio should be protected, and the feature should be activated via an argument for Deployment or Flow

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it, I will move it inside the function call or if block

from pydantic import BaseModel

from jina import DocumentArray, Document
from jina._docarray import docarray_v2
Expand Down Expand Up @@ -189,6 +191,15 @@ async def streaming_get(request: Request):
output_doc_list_model=output_doc_model,
)

def _executor_caller(*args):
return args

print(input_doc_model, output_doc_model)
inputs = generate_gradio_interface(input_doc_model)
outputs = generate_gradio_interface(output_doc_model)
interface = gr.Interface(_executor_caller, inputs, outputs)
app = gr.mount_gradio_app(app, interface, path="/_jina_gradio_demo")

from jina.serve.runtimes.gateway.health_model import JinaHealthModel

@app.get(
Expand Down Expand Up @@ -222,3 +233,62 @@ def _doc_to_event(doc):
return {'event': 'update', 'data': doc.to_dict()}
else:
return {'event': 'update', 'data': doc.dict()}

def generate_gradio_interface(model: BaseModel):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these have to be more ambitious and also cover docarray built-in types.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read that docarray is compatible with pydantic. Any thing that is different and you want me to pay special attention to?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some special prebuilt types such as TextDoc, ImageDoc, etc ...

"""helper function to convert pydantic model to gradio interface"""
inputs = []

# Process each attribute in the model
for attr, field in model.__annotations__.items():
input_type = field.__name__
input_label = attr.replace("_", " ").capitalize()

# Generate appropriate input component based on the field type
if input_type == "str":
# Additional options for string type
field_info = model.__annotations__[attr]
default = field_info.default if hasattr(field_info, "default") else None
choices = field_info.choices if hasattr(field_info, "choices") else None

input_component = gr.Textbox(
label=input_label,
)
elif input_type == "int":
# Additional options for integer type
field_info = model.__annotations__[attr]
ge = field_info.ge if hasattr(field_info, "ge") else None
le = field_info.le if hasattr(field_info, "le") else None

input_component = gr.Number(
label=input_label,
minimum=ge,
maximum=le,
step=1,
)
elif input_type == "float":
# Additional options for float type
field_info = model.__annotations__[attr]
ge = field_info.ge if hasattr(field_info, "ge") else None
le = field_info.le if hasattr(field_info, "le") else None

input_component = gr.Number(
label=input_label,
minimum=ge,
maximum=le,
step=0.01,
)
elif input_type == "bool":
# Additional options for boolean type
field_info = model.__annotations__[attr]
input_component = gr.Checkbox(label=input_label)
elif input_type == "File":
input_component = gr.File(label=input_label)
elif input_type == "Path":
input_component = gr.Textbox(label=input_label)
else:
# For unsupported types, skip the attribute
continue

# Add the input component to the inputs list
inputs.append(input_component)
return inputs