Run Python in Browser with Cyberpunk Terminal (Streamlit + PyQt6) | No VS Code Needed π₯
Demo :
Click Video πππ
Code :
web_runner.py
import streamlit as st
import sys
import os
import subprocess
import tempfile
# -----------------------------------------------------------------------------
# PAGE CONFIGURATION (Cyberpunk Title & Layout)
# -----------------------------------------------------------------------------
st.set_page_config(
page_title="FUZZUTECH TERMINAL",
page_icon="⚡",
layout="wide",
initial_sidebar_state="collapsed"
)
# -----------------------------------------------------------------------------
# CUSTOM CSS styling (The "Matrix/Cyberpunk" Look)
# -----------------------------------------------------------------------------
st.markdown("""
<style>
/* Main Background */
.stApp {
background-color: #0d0d0d;
color: #e0e0e0;
font-family: 'Consolas', 'Courier New', monospace;
}
/* Hide Streamlit Header/Footer */
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
/* Custom Header */
.cyber-header {
text-align: center;
padding: 20px;
background: rgba(0, 255, 65, 0.05);
border-bottom: 2px solid #00ff41;
margin-bottom: 20px;
}
.cyber-header h1 {
color: #00ff41; /* CRT Green */
font-family: 'Consolas', monospace;
letter-spacing: 4px;
text-transform: uppercase;
text-shadow: 0 0 10px rgba(0, 255, 65, 0.5);
font-size: 40px;
margin: 0;
}
.cyber-header p {
color: #00f3ff;
font-size: 14px;
letter-spacing: 2px;
margin-top: 5px;
}
/* Text Area (Code Input) */
.stTextArea textarea {
background-color: #1a1a1a !important;
color: #00ff41 !important;
border: 1px solid #333 !important;
font-family: 'Consolas', monospace !important;
font-size: 16px !important;
}
.stTextArea textarea:focus {
border-color: #00f3ff !important;
box-shadow: 0 0 10px rgba(0, 243, 255, 0.2) !important;
}
/* Buttons */
.stButton button {
background-color: transparent !important;
color: #00f3ff !important;
border: 2px solid #00f3ff !important;
border-radius: 5px !important;
padding: 10px 24px !important;
font-weight: bold !important;
font-family: 'Consolas', monospace !important;
transition: all 0.3s ease !important;
}
.stButton button:hover {
background-color: #00f3ff !important;
color: #000 !important;
box-shadow: 0 0 15px #00f3ff !important;
transform: scale(1.02);
}
.stButton button:active {
background-color: #0099aa !important;
border-color: #0099aa !important;
}
/* Output Container */
.output-container {
background-color: #000;
border: 1px solid #00f3ff;
border-radius: 5px;
padding: 20px;
min-height: 400px;
font-family: 'Consolas', monospace;
position: relative;
}
.output-label {
color: #888;
font-size: 12px;
border-bottom: 1px solid #333;
padding-bottom: 5px;
margin-bottom: 10px;
}
.console-text {
color: #00ff41;
white-space: pre-wrap;
font-size: 14px;
}
.error-text {
color: #ff5555;
white-space: pre-wrap;
font-size: 14px;
}
/* Blinking Cursor animation */
.cursor {
display: inline-block;
width: 10px;
height: 18px;
background-color: #00ff41;
animation: blink 1s infinite;
vertical-align: text-bottom;
}
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
</style>
""", unsafe_allow_html=True)
# -----------------------------------------------------------------------------
# APP LAYOUT
# -----------------------------------------------------------------------------
# Header
st.markdown("""
<div class="cyber-header">
<h1>⚡ FUZZUTECH TERMINAL ⚡</h1>
<p>// PYTHON BROWSER RUNNER v2026 //</p>
</div>
""", unsafe_allow_html=True)
# Main Splits
col1, col2 = st.columns([1, 1])
# -----------------------------------------------------------------------------
# LEFT COLUMN: Code Editor
# -----------------------------------------------------------------------------
with col1:
st.markdown("### INPUT_SOURCE // CODE.PY")
default_code = """# Write your Python code here...
import time
print("Initializing System...")
for i in range(3):
print(f"Loading Module {i+1}...")
# time.sleep(0.5)
print("System Ready.")
print("Hello FuzzuTech!")
"""
# Text Editor
code_input = st.text_area(
label="Code Editor",
value=default_code,
height=400,
label_visibility="collapsed",
key="editor"
)
# Run Button
if st.button("EXECUTE SEQUENCE [RUN]"):
run_triggered = True
else:
run_triggered = False
# -----------------------------------------------------------------------------
# RIGHT COLUMN: Browser Output
# -----------------------------------------------------------------------------
with col2:
st.markdown("### OUTPUT_STREAM // BROWSER_VIEW")
# Container for output
output_html = ""
if run_triggered:
# EXECUTION LOGIC
try:
# Create temp file
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False, encoding='utf-8') as tmp_file:
tmp_file.write(code_input)
tmp_filename = tmp_file.name
# Run with subprocess
process = subprocess.Popen(
[sys.executable, tmp_filename],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
encoding='utf-8',
cwd=os.path.dirname(tmp_filename),
creationflags=subprocess.CREATE_NO_WINDOW if sys.platform == "win32" else 0
)
# Wait for result
stdout, stderr = process.communicate(timeout=5)
# Cleanup
try:
os.unlink(tmp_filename)
except:
pass
# Prepare Output HTML
if stderr:
# Show Error
output_content = ""
if stdout:
output_content += f"{stdout}\n"
output_content += f"{stderr}"
output_html = f"""
<div class="output-container" style="border-color: #ff5555;">
<div class="output-label">root@fuzzutech:~$ ./run_script.py (EXIT CODE 1)</div>
<div class="error-text">{output_content}</div>
<span class="cursor" style="background-color: #ff5555;"></span>
</div>
"""
else:
# Show Success
output_html = f"""
<div class="output-container">
<div class="output-label">root@fuzzutech:~$ ./run_script.py (SUCCESS)</div>
<div class="console-text">{stdout}</div>
<span class="cursor"></span>
</div>
"""
except Exception as e:
output_html = f"""
<div class="output-container" style="border-color: #ff5555;">
<div class="output-label">SYSTEM_ERROR</div>
<div class="error-text">{str(e)}</div>
</div>
"""
else:
# IDLE STATE
output_html = """
<div class="output-container">
<div class="output-label">root@fuzzutech:~$ _</div>
<div class="console-text" style="color: #444;">[Waiting for execution sequence...]</div>
<span class="cursor"></span>
</div>
"""
# Render Output
st.markdown(output_html, unsafe_allow_html=True)
main.py
import sys
import os
import subprocess
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QHBoxLayout, QPlainTextEdit, QPushButton, QSplitter,
QLabel, QFrame, QStatusBar, QFileDialog, QMessageBox)
from PyQt6.QtCore import Qt, QSize, QPropertyAnimation, QEasingCurve, QTimer
from PyQt6.QtGui import QFont, QColor, QSyntaxHighlighter, QTextCharFormat, QIcon
from PyQt6.QtWebEngineWidgets import QWebEngineView
# -----------------------------------------------------------------------------
# Syntax Highlighter for Python (Basic)
# -----------------------------------------------------------------------------
class PythonHighlighter(QSyntaxHighlighter):
def __init__(self, document):
super().__init__(document)
self.rules = []
# Keywords
keyword_format = QTextCharFormat()
keyword_format.setForeground(QColor("#ff79c6")) # Pinkish
keyword_format.setFontWeight(QFont.Weight.Bold)
keywords = ["def", "class", "if", "else", "elif", "while", "for", "return",
"import", "from", "as", "try", "except", "print", "True", "False", "None"]
for word in keywords:
self.rules.append((f"\\b{word}\\b", keyword_format))
# Strings
string_format = QTextCharFormat()
string_format.setForeground(QColor("#f1fa8c")) # Yellowish
self.rules.append(('".*"', string_format))
self.rules.append(("'.*'", string_format))
# Comments
comment_format = QTextCharFormat()
comment_format.setForeground(QColor("#6272a4")) # Grayish Blue
self.rules.append(("#[^\n]*", comment_format))
def highlightBlock(self, text):
import re
for pattern, fmt in self.rules:
for match in re.finditer(pattern, text):
self.setFormat(match.start(), match.end() - match.start(), fmt)
# -----------------------------------------------------------------------------
# Main Application Window
# -----------------------------------------------------------------------------
class CyberRunner(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("FUZZUTECH - PYTHON BROWSER RUNNER 2026")
self.resize(1200, 800)
# Load Stylesheet
try:
# robustly find style.qss relative to this script
script_dir = os.path.dirname(os.path.abspath(__file__))
style_path = os.path.join(script_dir, "style.qss")
with open(style_path, "r") as f:
self.setStyleSheet(f.read())
except FileNotFoundError:
print("Warning: style.qss not found at", style_path)
# Main Layout
main_widget = QWidget()
self.setCentralWidget(main_widget)
layout = QVBoxLayout(main_widget)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
# 1. Header
self.header = QLabel("⚡ FUZZUTECH TERMINAL // PYTHON RUNNER ⚡")
self.header.setObjectName("HeaderLabel")
self.header.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(self.header)
# 2. Main Content Area (Splitter)
splitter = QSplitter(Qt.Orientation.Horizontal)
# Left: Code Editor Container
editor_container = QWidget()
editor_layout = QVBoxLayout(editor_container)
editor_layout.setContentsMargins(10, 10, 5, 10)
editor_label = QLabel("INPUT_SOURCE // CODE.PY")
editor_label.setStyleSheet("color: #888; font-size: 10px; margin-bottom: 5px;")
editor_layout.addWidget(editor_label)
self.editor = QPlainTextEdit()
self.editor.setPlaceholderText("# Write Python code here...\nprint('Hello World')")
# Default font setup
font = QFont("Consolas", 12)
font.setStyleHint(QFont.StyleHint.Monospace)
self.editor.setFont(font)
self.highlighter = PythonHighlighter(self.editor.document())
editor_layout.addWidget(self.editor)
# Run Button Area
button_layout = QHBoxLayout()
self.run_btn = QPushButton("EXECUTE SEQUENCE [RUN]")
self.run_btn.setCursor(Qt.CursorShape.PointingHandCursor)
self.run_btn.clicked.connect(self.run_code)
# Add glow animation logic to button
self.glow_timer = QTimer(self)
self.glow_timer.timeout.connect(self.animate_glow)
self.glow_timer.start(2000)
button_layout.addStretch()
button_layout.addWidget(self.run_btn)
button_layout.addStretch()
editor_layout.addLayout(button_layout)
splitter.addWidget(editor_container)
# Right: Browser Output Container
output_container = QWidget()
output_layout = QVBoxLayout(output_container)
output_layout.setContentsMargins(5, 10, 10, 10)
output_label = QLabel("OUTPUT_STREAM // BROWSER_VIEW")
output_label.setStyleSheet("color: #888; font-size: 10px; margin-bottom: 5px;")
output_layout.addWidget(output_label)
self.browser = QWebEngineView()
# Set initial stylish content
initial_html = self.get_html_template("System Ready.<br>Waiting for input...", "info")
self.browser.setHtml(initial_html)
output_layout.addWidget(self.browser)
splitter.addWidget(output_container)
# Splitter styling
splitter.setSizes([600, 600]) # 50/50 split
splitter.setHandleWidth(2)
layout.addWidget(splitter)
# Status Bar
self.status = QStatusBar()
self.status.showMessage("System Online. Version 1.0. Cyberpunk Mode Active.")
self.setStatusBar(self.status)
def animate_glow(self):
# Toggle border color for subtle pulse effect
current_style = self.run_btn.styleSheet()
if "border-color: #00f3ff" in current_style:
self.run_btn.setStyleSheet("border-color: #008899; color: #008899;")
else:
self.run_btn.setStyleSheet("border-color: #00f3ff; color: #00f3ff;")
def get_html_template(self, content, type="output"):
# Dark Cyberpunk HTML Template
color = "#00ff41" if type == "output" else "#ff5555"
if type == "info":
color = "#00f3ff"
elif type == "error":
color = "#ff5555"
# Escape HTML characters to prevent rendering issues
import html
content = html.escape(content)
return f"""
<!DOCTYPE html>
<html>
<head>
<style>
body {{
background-color: #0d0d0d;
color: {color};
font-family: 'Consolas', monospace;
padding: 20px;
margin: 0;
overflow-x: hidden;
}}
.cursor {{
display: inline-block;
width: 10px;
height: 18px;
background-color: {color};
animation: blink 1s infinite;
vertical-align: text-bottom;
}}
@keyframes blink {{
0%, 100% {{ opacity: 1; }}
50% {{ opacity: 0; }}
}}
pre {{
white-space: pre-wrap;
word-wrap: break-word;
}}
.prompt {{
color: #888;
margin-bottom: 10px;
border-bottom: 1px solid #333;
padding-bottom: 5px;
}}
</style>
</head>
<body>
<div class="prompt">root@fuzzutech:~$ ./run_script.py</div>
<pre>{content}</pre>
<span class="cursor"></span>
</body>
</html>
"""
def run_code(self):
code = self.editor.toPlainText()
if not code.strip():
self.browser.setHtml(self.get_html_template("Error: No code to execute.", "error"))
return
# Visual feedback
self.status.showMessage("Executing script...")
self.run_btn.setText("RUNNING...")
self.run_btn.setEnabled(False)
QApplication.processEvents() # Force UI update
try:
# Write code to a temporary file
import tempfile
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False, encoding='utf-8') as tmp_file:
tmp_file.write(code)
tmp_filename = tmp_file.name
# Run the temporary file using subprocess
process = subprocess.Popen(
[sys.executable, tmp_filename],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
encoding='utf-8',
cwd=os.path.dirname(tmp_filename),
creationflags=subprocess.CREATE_NO_WINDOW if sys.platform == "win32" else 0
)
# Wait for output (simple synchronous wait for this prototype)
# 5 second timeout safety
stdout, stderr = process.communicate(timeout=5)
# Cleanup
try:
os.unlink(tmp_filename)
except:
pass
if stderr:
# Combine stdout and stderr if both exist, or just show stderr
output_text = ""
if stdout:
output_text += f"> Standard Output:\n{stdout}\n"
output_text += f"> Error Output:\n{stderr}"
self.browser.setHtml(self.get_html_template(output_text, "error"))
else:
self.browser.setHtml(self.get_html_template(stdout, "output"))
self.status.showMessage("Execution Complete.")
except subprocess.TimeoutExpired:
process.kill()
self.browser.setHtml(self.get_html_template("Error: Execution timed out (5s limit).", "error"))
self.status.showMessage("Execution Timed Out.")
try:
os.unlink(tmp_filename)
except:
pass
except Exception as e:
self.browser.setHtml(self.get_html_template(f"Execution Error: {str(e)}", "error"))
self.status.showMessage("Error Occurred.")
try:
if 'tmp_filename' in locals():
os.unlink(tmp_filename)
except:
pass
self.run_btn.setText("EXECUTE SEQUENCE [RUN]")
self.run_btn.setEnabled(True)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = CyberRunner()
window.show()
sys.exit(app.exec())
style.qss
/* Main Window Style */
QMainWindow {
background-color: #0d0d0d;
color: #e0e0e0;
font-family: 'Consolas', 'Courier New', monospace;
}
/* Header Style */
QLabel#HeaderLabel {
font-size: 24px;
font-weight: bold;
color: #00ff41; /* CRT Green */
padding: 10px;
border-bottom: 2px solid #00ff41;
background-color: rgba(0, 255, 65, 0.1);
letter-spacing: 2px;
}
/* Splitter Handle */
QSplitter::handle {
background-color: #333;
width: 2px;
}
/* Code Editor Area (Left) */
QPlainTextEdit {
background-color: #1a1a1a;
color: #00ff41; /* Green text for "Matrix" look */
border: 1px solid #333;
border-radius: 5px;
font-family: 'Consolas', monospace;
font-size: 14px;
padding: 8px;
selection-background-color: #004400;
}
/* Focus effects for editor */
QPlainTextEdit:focus {
border: 1px solid #00ff41;
box-shadow: 0 0 10px #00ff41; /* Note: box-shadow not standard QSS but serves as intent context */
}
/* Browser Output Area (Right) - Handled via WebEngine but container styled */
QWidget#OutputContainer {
background-color: #000;
border: 1px solid #00f3ff; /* Cyan border */
border-radius: 5px;
}
/* Buttons */
QPushButton {
background-color: rgba(0, 243, 255, 0.1);
color: #00f3ff;
border: 2px solid #00f3ff;
padding: 8px 16px;
border-radius: 4px;
font-weight: bold;
min-width: 80px;
font-size: 14px;
}
QPushButton:hover {
background-color: #00f3ff;
color: #000;
box-shadow: 0 0 15px #00f3ff;
}
QPushButton:pressed {
background-color: #008899;
border-color: #008899;
}
/* Scrollbars */
QScrollBar:vertical {
border: none;
background: #1a1a1a;
width: 10px;
margin: 0px;
}
QScrollBar::handle:vertical {
background: #333;
min-height: 20px;
border-radius: 5px;
}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
border: none;
background: none;
}
/* Status Bar */
QStatusBar {
background-color: #111;
color: #888;
border-top: 1px solid #333;
}
Comments
Post a Comment