shiwake / app.py
Renecto's picture
Update app.py
f8682d2 verified
import gradio as gr
import os
import importlib
import re
import ast
import inspect
#UIを__doc__から生成する
def get_io_types(func):
doc = func.__doc__
input_pattern = r"input\d* \((\w+)\): (.+)?" #inputから始まる行は、型とサンプル
input_matches = re.finditer(input_pattern, doc)
inputs = []
# 関数の引数名を取得
sig = inspect.signature(func)
param_names = list(sig.parameters.keys())
for match, param_name in zip(input_matches, param_names):
typ = match.group(1)
sample = match.group(2).strip() if match.group(2) else "" # サンプルがない場合は
inputs.append((param_name, typ, sample))
output_pattern = r"output\d* \((\w+)\): ([^\n]+)" # outputから始まる行は、型とUIに表示する説明
output_matches = re.findall(output_pattern, doc)
outputs = [(typ, name.strip()) for typ, name in output_matches]
return inputs, outputs
def create_component(type,name,sample=None):
# 出力タイプに対応するGradioコンポーネント生成関数の辞書を定義
component_factory = {
"image": lambda: gr.Image(label=name, type='pil'),
"image_filepath": lambda: gr.Image(label=name, type='filepath'),
"text": lambda: gr.Textbox(label=name, value=sample),
"dataframe": lambda: gr.DataFrame(label=name, value=sample),
}
# 出力タイプに対応するコンポーネント生成関数を辞書から取得し、関数を実行して新しいコンポーネントを生成
return component_factory.get(type, lambda: gr.Textbox(label="Output(unknown)"))()
def load_apis():
api_dir = 'apis'
apis = {}
for file in os.listdir(api_dir):
if file.endswith('.py') and not file.startswith('__'):
module_name = file[:-3]
module = importlib.import_module(f"apis.{module_name}")
func = getattr(module, module_name, None)
input_types, output_types = get_io_types(func)
apis[module_name] = (func, input_types, output_types)
print(apis)
return apis
def create_app(apis):
with gr.Blocks() as app:
with gr.Tabs():
buttons = {}
for api_name, (api_func,input_types, output_types) in apis.items():
with gr.Tab(api_name):
with gr.Column():
print("Constructing: ", api_name, input_types, output_types)
with gr.Row():
inputs = []
for param_name, input_type, sample in input_types:
with gr.Column():
input_component = create_component(input_type, param_name, sample)
inputs.append(input_component)
with gr.Row():
buttons[api_name] = gr.Button("↓Run↓")
with gr.Row():
outputs = []
for output_type, name in output_types:
with gr.Column():
output_component = create_component(output_type, name)
outputs.append(output_component)
buttons[api_name].click(api_func, inputs=inputs, outputs=outputs)
return app
apis = load_apis()
app = create_app(apis)
app.launch(debug=True)