File size: 6,914 Bytes
2c9c795
 
 
 
 
 
d9c6672
2c9c795
 
 
 
 
 
d9c6672
 
 
2c9c795
 
 
 
 
 
d9c6672
2c9c795
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d9c6672
 
2c9c795
 
 
 
 
 
 
d9c6672
 
 
 
2c9c795
d9c6672
2c9c795
d9c6672
2c9c795
 
 
 
 
d9c6672
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2c9c795
d9c6672
 
2c9c795
 
 
 
 
d9c6672
 
 
 
 
 
 
 
2c9c795
 
 
 
d9c6672
 
 
 
 
 
 
2c9c795
 
d9c6672
2c9c795
 
 
 
 
d9c6672
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2c9c795
 
 
 
 
 
 
 
 
 
 
 
d9c6672
 
2c9c795
d9c6672
 
 
 
 
 
 
 
 
 
2c9c795
 
d9c6672
 
 
 
2c9c795
 
 
 
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import gradio as gr
import sys
import subprocess
import importlib
import io
import contextlib
import traceback
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import plotly.express as px
import black

# Function to install packages dynamically
def install_package(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])

# Function to execute user code with output capturing and visualization support
def execute_code(code, libraries, timeout):
    # Install libraries
    for library in libraries.splitlines():
        if library.strip():
            install_package(library.strip())
    
    # Prepare output capturing
    output = io.StringIO()
    error_output = io.StringIO()
    
    # Execute the code
    try:
        with contextlib.redirect_stdout(output), contextlib.redirect_stderr(error_output):
            exec_globals = {
                'plt': plt,
                'np': np,
                'pd': pd,
                'sns': sns,
                'px': px,
            }
            exec(code, exec_globals)
        
        # Check if a plot was created
        if plt.get_fignums():
            plt.savefig('plot.png')
            plt.close()
            return output.getvalue(), error_output.getvalue(), 'plot.png', None
        elif 'fig' in exec_globals and isinstance(exec_globals['fig'], px.Figure):
            exec_globals['fig'].write_image('plot.png')
            return output.getvalue(), error_output.getvalue(), 'plot.png', None
        else:
            return output.getvalue(), error_output.getvalue(), None, None
    except Exception as e:
        return "", traceback.format_exc(), None, None

# Function to highlight Python code
def highlight_code(code):
    return highlight(code, PythonLexer(), HtmlFormatter(style="monokai"))

# Function to format code using Black
def format_code(code):
    try:
        formatted_code = black.format_str(code, mode=black.FileMode())
        return formatted_code, "Code formatted successfully!"
    except Exception as e:
        return code, f"Formatting error: {str(e)}"

# Function to generate sample code
def generate_sample_code(sample_type):
    samples = {
        "Basic": "print('Hello, World!')\n\nfor i in range(5):\n    print(i)",
        "Numpy": "import numpy as np\n\narr = np.array([1, 2, 3, 4, 5])\nprint(arr.mean())\nprint(arr.std())",
        "Pandas": "import pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\nprint(df.describe())",
        "Matplotlib": "import matplotlib.pyplot as plt\n\nx = [1, 2, 3, 4, 5]\ny = [2, 4, 6, 8, 10]\n\nplt.plot(x, y)\nplt.title('Simple Line Plot')\nplt.xlabel('X-axis')\nplt.ylabel('Y-axis')",
        "Seaborn": "import seaborn as sns\n\ntips = sns.load_dataset('tips')\nsns.scatterplot(x='total_bill', y='tip', data=tips)",
        "Plotly": "import plotly.express as px\n\ndf = px.data.gapminder().query('year == 2007')\nfig = px.scatter(df, x='gdpPercap', y='lifeExp', size='pop', color='continent', hover_name='country', log_x=True, size_max=60)\nfig.show()"
    }
    return samples.get(sample_type, "")

# Define the Gradio interface
with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown("# Advanced Python Code Executor and Formatter")
    
    with gr.Tabs():
        with gr.TabItem("Code Execution"):
            with gr.Row():
                with gr.Column(scale=2):
                    code_input = gr.Code(label="Python Code", language="python", lines=15)
                    with gr.Row():
                        libraries_input = gr.TextArea(label="Libraries (one per line)", placeholder="e.g.\nrequests\nscipy", lines=2)
                        timeout_input = gr.Number(label="Timeout (seconds)", value=30, minimum=1, maximum=300)
                    with gr.Row():
                        execute_button = gr.Button("Run Code", variant="primary")
                        clear_button = gr.Button("Clear", variant="secondary")
                    sample_dropdown = gr.Dropdown(choices=["Basic", "Numpy", "Pandas", "Matplotlib", "Seaborn", "Plotly"], label="Load Sample Code")
                with gr.Column(scale=1):
                    output = gr.Textbox(label="Standard Output", lines=10)
                    error_output = gr.Textbox(label="Error Output", lines=5)
                    plot_output = gr.Image(label="Plot Output")
                    file_output = gr.File(label="Generated Files")
        
        with gr.TabItem("Code Formatting"):
            code_to_format = gr.Code(label="Enter Python code to format", language="python", lines=15)
            format_button = gr.Button("Format Code")
            formatted_code = gr.Code(label="Formatted Code", language="python", lines=15)
            format_message = gr.Textbox(label="Formatting Message")
        
        with gr.TabItem("Code Highlighting"):
            code_to_highlight = gr.Code(label="Enter Python code to highlight", language="python", lines=15)
            highlight_button = gr.Button("Highlight Code")
            highlighted_code = gr.HTML(label="Highlighted Code")
    
    execute_button.click(
        fn=execute_code,
        inputs=[code_input, libraries_input, timeout_input],
        outputs=[output, error_output, plot_output, file_output]
    )
    
    clear_button.click(
        lambda: ("", "", "", None, None),
        outputs=[code_input, output, error_output, plot_output, file_output]
    )
    
    sample_dropdown.change(
        fn=generate_sample_code,
        inputs=[sample_dropdown],
        outputs=[code_input]
    )
    
    format_button.click(
        fn=format_code,
        inputs=[code_to_format],
        outputs=[formatted_code, format_message]
    )
    
    highlight_button.click(
        fn=highlight_code,
        inputs=[code_to_highlight],
        outputs=[highlighted_code]
    )

    gr.Markdown("""
    ## Features:
    - Execute Python code with custom library imports
    - Capture and display standard output and error messages separately
    - Support for data visualization with matplotlib, seaborn, and plotly
    - Code formatting using Black
    - Code highlighting for better readability
    - Sample code generator for quick starts
    - Timeout setting for code execution
    - Clear button to reset inputs and outputs
    
    ## Pre-imported Libraries:
    - `plt` for matplotlib
    - `np` for numpy
    - `pd` for pandas
    - `sns` for seaborn
    - `px` for plotly express
    
    ## Tips:
    - Use the sample code dropdown for quick examples
    - Your plot will automatically be displayed if you use plotting functions
    - Adjust the timeout if your code needs more execution time
    - Use the formatting tab to clean up your code structure
    """)

# Launch the interface
demo.launch()