Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interactive console in solara web interface. #2683

Open
Sahil-Chhoker opened this issue Feb 12, 2025 · 2 comments
Open

Interactive console in solara web interface. #2683

Sahil-Chhoker opened this issue Feb 12, 2025 · 2 comments

Comments

@Sahil-Chhoker
Copy link
Contributor

This feature idea originates from discussions on PR #2674 and PR #2176. After setting up an environment for Python code execution in the Solara GUI (PR #2674), the idea of turning it into a more console-like experience was proposed. I decided to take a step back and create a minimal prototype to explore its potential. My plan is to refine the backend for code execution once the Solara GUI is fully developed. However, due to my limited knowledge of the Solara web framework, I’m opening this issue to gather ideas and collaborate on making this feature possible.

Current Implementation:

import solara
import sys
import code
import io


# Backend console stuff
class Interpreter(code.InteractiveInterpreter):
    def __init__(self):
        super().__init__()
        self.output_buffer = io.StringIO()

    def run_code(self, command):
        sys.stdout = self.output_buffer
        sys.stderr = self.output_buffer
        try:
            self.runsource(command)
            output = self.output_buffer.getvalue()
            return output if output else "Command executed successfully."
        except SyntaxError as e:
            return f"SyntaxError: {str(e).split(')')[-1].strip()}"
        except Exception as e:
            return f"{type(e).__name__}: {str(e)}"
        finally:
            sys.stdout = sys.__stdout__
            sys.stderr = sys.__stderr__
            self.output_buffer.truncate(0)
            self.output_buffer.seek(0)


interpreter = Interpreter()

# history list to replicate the console
history = []


def execute_code(input_text, set_input_text):
    if input_text.strip():
        output = interpreter.run_code(input_text)
        # error cleanup
        if isinstance(output, str) and "Traceback" in output:
            error_lines = output.strip().splitlines()
            for line in reversed(error_lines):
                if ": " in line:
                    output = line.strip()
                    break
        history.append((f">>> {input_text}", output))
        set_input_text("")


def clear_console():
    history.clear()


@solara.component
def Page():
    input_text, set_input_text = solara.use_state("")

    solara.Markdown(
        """
    # Python Console
    """
    )

    for cmd, result in history:
        solara.Markdown( # random styling + looks ugly 
            f"""
        <pre style="background-color: #f9f9f9; border: 1px solid #ddd; padding: 10px; border-radius: 1px; margin: 1px 0; font-family: 'Courier New', monospace; font-size: 14px;">
        ```python
        {cmd}
        ```
        {result}
        </pre>
        """
        )

    solara.InputText(
        value=input_text,
        label=">>>",
        continuous_update=True,
        on_value=set_input_text,
    )

    # For styling the input text
    solara.Style("""
    .v-text-field__slot {
        font-family: monospace !important;
    }
    """)

    solara.Button("Run", on_click=lambda: execute_code(input_text, set_input_text))
    solara.Button("Clear", on_click=clear_console)


Page()

Some features I am struggling to implement:

  1. Keyboard Enter -> Enter on app.
  2. Ctrl + L -> Console cleanup.
  3. Make the GUI look like a proper python console.

Features I am hoping to implement:

  1. Using _SecureCodeValidator from Feat: Added command center #2674 for validation of code executed in the console(if it gets a pass).
  2. Adding a variable explorer as suggested in this comment.

These features are open for discussion and feedback. I would greatly appreciate any new ideas or suggestions you may have!

@quaquel
Copy link
Member

quaquel commented Feb 12, 2025

Thanks a lot for this. I hope to be able to dig into this a bit more over the weekend.

@tpike3
Copy link
Member

tpike3 commented Feb 12, 2025

This is awesome @Sahil-Chhoker!

I have no immediate thoughts beyond what has already been discussed, but do have strategic goals to keep in mind. Just to emphasize, these are my ideas and @EwoutH and @quaquel can absolutely disagree.

The hard problem in ABMs is the solution space is so large and the details matter, so related to an interactive console would be interactive blocks that allow for rapidly assembling models, with the capability to interact with the blocks to make customizations. Partially articulated here https://github.com/projectmesa/mesa/wiki/Google-Summer-of-Code-2025#mesa-blocks

My thought for posting this here is that as you make these initial decisions you may make different choice for how to interact (initial conditions and long term dependencies).

To my concisely state, I think the long term goal is interactive blocks that can be reassembled rapidly, and not necessarily interacting with the entire model all at once. However, there are many paths to the end state, and getting an interactive console maybe the best 1st step.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants