Spaces:
Running
Running
| import logging | |
| import random | |
| import time | |
| import gradio as gr | |
| from tqdm import tqdm | |
| from gradio_logsview import LogsView, LogsViewRunner | |
| logger = logging.getLogger("custom.foo") | |
| def random_values(failing: bool = False): | |
| for i in tqdm(range(10)): | |
| logger.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_command_success(): | |
| runner = LogsViewRunner() | |
| yield from runner.run_command(["python", "-u", "script.py"]) | |
| yield runner.log(f"Runner: {runner}") | |
| def fn_command_failing(): | |
| runner = LogsViewRunner() | |
| yield from runner.run_command(["python", "-u", "script.py", "--failing"]) | |
| yield runner.log(f"Runner: {runner}") | |
| def fn_python_success(): | |
| runner = LogsViewRunner() | |
| yield from runner.run_python(random_values, log_level=logging.INFO, logger_name="custom.foo", failing=False) | |
| yield runner.log(f"Runner: {runner}") | |
| def fn_python_failing(): | |
| runner = LogsViewRunner() | |
| yield from runner.run_python(random_values, log_level=logging.INFO, logger_name="custom.foo", failing=True) | |
| yield runner.log(f"Runner: {runner}") | |
| markdown_top = """ | |
| # LogsView Demo | |
| This demo shows how to use the `LogsView` component to run some Python code or execute a command and display logs in real-time. | |
| Click on any button to launch a process and see the logs displayed in real-time. | |
| In the Python examples, code is executed in a process. You can see the logs (generated randomly with different log levels). | |
| In the command examples, the command line is executed on the system directly. Any command can be executed. | |
| """ | |
| markdown_bottom = """ | |
| ## Installation | |
| ``` | |
| pip install https://huggingface.co/spaces/Wauplin/gradio_logsview/resolve/main/gradio_logsview-0.0.5-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.5-py3-none-any.whl | |
| ``` | |
| ## How to run Python code? | |
| With `LogsView.run_python`, you can run Python code in a separate process 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_python(): | |
| # Run `my_function` in a separate process | |
| # All logs above `INFO` level will be captured and displayed in real-time. | |
| runner = LogsViewRunner() # Initialize the runner | |
| yield from runner.run_python(my_function, log_level=logging.INFO, arg1="value1") | |
| yield runner.log(f"Runner: {runner}") # Log any message | |
| if runner.exit_code != 0: | |
| # Handle error | |
| ... | |
| with gr.Blocks() as demo: | |
| logs = LogsView() | |
| btn = gr.Button("Run Python code") | |
| btn.click(fn_python, outputs=logs) | |
| ``` | |
| ## How to run a command? | |
| With `LogsView.run_command`, you can run a command on the system and capture logs from the process in real-time. | |
| ```py | |
| from gradio_logsview import LogsView | |
| def fn_command(): | |
| # Run a command and capture all logs from the subprocess | |
| runner = LogsViewRunner() # Initialize the runner | |
| yield from runner.run_command( | |
| cmd=["mergekit-yaml", "config.yaml", "merge", "--copy-", "--cuda", "--low-cpu-memory"] | |
| ) | |
| yield runner.log(f"Runner: {runner}") # Log any message | |
| if runner.exit_code != 0: | |
| # Handle error | |
| ... | |
| with gr.Blocks() as demo: | |
| logs = LogsView() | |
| btn = gr.Button("Run command") | |
| btn.click(fn_command, 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) | |
| - [x] stop process if `run_command` gets cancelled (back-end) | |
| - [x] correctly pass error stacktrace in `run_python` (back-end) | |
| - [x] correctly catch print statements in `run_python` (back-end) | |
| - [ ] disable interactivity + remove all code editing logic (both?) | |
| - [x] how to handle progress bars? (i.e when logs are overwritten in terminal) | |
| - [ ] Have 3 tabs in UI for stdout, stderr and logging (front-end + back-end) | |
| - [ ] Write logger name in the logs (back-end) | |
| """ | |
| with gr.Blocks() as demo: | |
| gr.Markdown(markdown_top) | |
| with gr.Row(): | |
| btn_python_success = gr.Button("Run Python code (success)") | |
| btn_python_failing = gr.Button("Run Python code (failing)") | |
| with gr.Row(): | |
| btn_command_success = gr.Button("Run command (success)") | |
| btn_command_failing = gr.Button("Run command (failing)") | |
| logs = LogsView() | |
| gr.Markdown(markdown_bottom) | |
| btn_python_failing.click(fn_python_failing, outputs=logs) | |
| btn_python_success.click(fn_python_success, outputs=logs) | |
| btn_command_failing.click(fn_command_failing, outputs=logs) | |
| btn_command_success.click(fn_command_success, outputs=logs) | |
| if __name__ == "__main__": | |
| demo.launch() | |