File size: 3,472 Bytes
f8682d2
43b7be6
f8682d2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43b7be6
f8682d2
 
 
 
 
 
 
 
 
 
 
43b7be6
f8682d2
 
43b7be6
f8682d2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43b7be6
f8682d2
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
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)