File size: 4,066 Bytes
e0d6c83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ccb4b5f
e0d6c83
 
 
ccb4b5f
e0d6c83
 
 
 
 
 
 
 
 
 
9bdb607
e0d6c83
 
 
 
 
 
 
9bdb607
e0d6c83
 
9bdb607
ccb4b5f
 
 
 
 
 
 
 
 
 
 
 
 
e0d6c83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2026013
e0d6c83
 
 
 
 
 
 
72cbf19
 
 
 
 
 
 
 
 
 
9bdb607
e0d6c83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import logging
import random
import time

import gradio as gr
from gradio_logsview import LogsView


def random_values(failing: bool = False):
    for i in range(10):
        logging.log(
            random.choice(
                [  # Random levels
                    logging.INFO,
                    logging.DEBUG,
                    logging.WARNING,
                    logging.ERROR,
                    logging.CRITICAL,
                ]
            ),
            f"Value {i+1}",  # Random values
        )
        time.sleep(random.uniform(0, 1))
        if failing and i == 5:
            raise ValueError("Failing!!")


def fn_process_success():
    yield from LogsView.run_process(["python", "-u", "script.py"])


def fn_process_failing():
    yield from LogsView.run_process(["python", "-u", "script.py", "--failing"])


def fn_thread_success():
    yield from LogsView.run_thread(random_values, log_level=logging.INFO, failing=False)


def fn_thread_failing():
    yield from LogsView.run_thread(random_values, log_level=logging.INFO, failing=True)


markdown_top = """
# LogsView Demo

This demo shows how to use the `LogsView` component to display logs from a process or a thread in real-time.

Click on any button to launch a process or a thread and see the logs displayed in real-time.
In the thread example, logs are generated randomly with different log levels.
In the process example, logs are generated by a Python script but any command can be executed.
"""


markdown_bottom = """
## Installation

```
pip install https://huggingface.co/spaces/Wauplin/gradio_logsview/resolve/main/gradio_logsview-0.0.1-py3-none-any.whl
```

or add this line to your `requirements.txt`:

```
gradio_logsview@https://huggingface.co/spaces/Wauplin/gradio_logsview/resolve/main/gradio_logsview-0.0.1-py3-none-any.whl
```


## How to run in a thread?

With `LogsView.run_thread`, you can run a function in a separate thread and capture logs in real-time.
You can configure which logs to capture (log level and logger name).

```py
from gradio_logsview import LogsView

def fn_thread():
    # Run `my_function` in a separate thread
    # All logs above `INFO` level will be captured and displayed in real-time.
    yield from LogsView.run_thread(my_function, log_level=logging.INFO, arg1="value1")

with gr.Blocks() as demo:
    logs = LogsView()
    btn = gr.Button("Run thread")
    btn.click(fn_thread, outputs=logs)
```

## How to run in a process?

With `LogsView.run_process`, you can run a command in a separate process and capture logs from the process in real-time.
    
```py
from gradio_logsview import LogsView

def fn_process():
    # Run a process and capture all logs from the process
    yield from LogsView.run_process(
        [mergekit-yaml", "config.yaml", "merge", "--copy-", "--cuda", "--low-cpu-memory"]
    )

with gr.Blocks() as demo:
    logs = LogsView()
    btn = gr.Button("Run process")
    btn.click(fn_process, outputs=logs)
```

## TODO

- [ ] display logs with colors (front-end)
- [ ] format logs client-side (front-end)
- [ ] scrollable logs if more than N lines (front-end)
- [ ] format each log only once (front-end)
- [ ] stop process if `run_process` gets cancelled (back-end)
- [ ] correctly pass error stacktrace in `run_thread` (back-end)
- [ ] disable interactivity + remove all code editing logic (both?)
"""

with gr.Blocks() as demo:
    gr.Markdown(markdown_top)

    with gr.Row():
        btn_thread_success = gr.Button("Run thread (success)")
        btn_thread_failing = gr.Button("Run thread (failing)")
    with gr.Row():
        btn_process_success = gr.Button("Run process (success)")
        btn_process_failing = gr.Button("Run process (failing)")
    logs = LogsView()

    gr.Markdown(markdown_bottom)

    btn_thread_failing.click(fn_thread_failing, outputs=logs)
    btn_thread_success.click(fn_thread_success, outputs=logs)
    btn_process_failing.click(fn_process_failing, outputs=logs)
    btn_process_success.click(fn_process_success, outputs=logs)


if __name__ == "__main__":
    demo.launch()