fix: ui.py — force PYTHONIOENCODING=utf-8 and NO_COLOR=1 in subprocess to prevent Windows cp1252 crash"
Browse files- alpha_factory/ui.py +26 -21
alpha_factory/ui.py
CHANGED
|
@@ -11,7 +11,6 @@ import duckdb
|
|
| 11 |
import gradio as gr
|
| 12 |
from pathlib import Path
|
| 13 |
|
| 14 |
-
# Load .env so HF_TOKEN is available
|
| 15 |
try:
|
| 16 |
from dotenv import load_dotenv
|
| 17 |
load_dotenv()
|
|
@@ -52,7 +51,7 @@ def get_alphas_from_db(limit=50):
|
|
| 52 |
def get_alpha_cards():
|
| 53 |
rows = get_alphas_from_db()
|
| 54 |
if not rows:
|
| 55 |
-
return [["
|
| 56 |
data = []
|
| 57 |
for row in rows:
|
| 58 |
alpha_id, submitted_at, expression, theme, archetype, tag, neutral, decay, fields, verdict = row
|
|
@@ -74,9 +73,15 @@ def get_full_expression(evt: gr.SelectData):
|
|
| 74 |
|
| 75 |
|
| 76 |
def run_batch(batch_size):
|
| 77 |
-
"""Run pipeline as subprocess
|
| 78 |
env = os.environ.copy()
|
| 79 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
if "HF_TOKEN" not in env:
|
| 81 |
token = os.getenv("HF_TOKEN", "")
|
| 82 |
if token:
|
|
@@ -86,29 +91,29 @@ def run_batch(batch_size):
|
|
| 86 |
result = subprocess.run(
|
| 87 |
[sys.executable, "-m", "alpha_factory.run", "--dry-run", "--batch-size", str(int(batch_size))],
|
| 88 |
capture_output=True,
|
| 89 |
-
text=True,
|
| 90 |
-
encoding="utf-8",
|
| 91 |
-
errors="replace",
|
| 92 |
env=env,
|
| 93 |
-
timeout=
|
| 94 |
cwd=str(Path.cwd()),
|
| 95 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
log = ""
|
| 97 |
-
if
|
| 98 |
-
log
|
| 99 |
-
if result.returncode != 0 and
|
| 100 |
-
log += "\n\n--- ERRORS ---\n" +
|
| 101 |
if not log.strip():
|
| 102 |
log = f"Process exited with code {result.returncode}"
|
| 103 |
return log
|
| 104 |
except subprocess.TimeoutExpired:
|
| 105 |
-
return "ERROR: Pipeline timed out after
|
| 106 |
except Exception as e:
|
| 107 |
return f"ERROR: {str(e)}"
|
| 108 |
|
| 109 |
|
| 110 |
def generate_and_refresh(batch_size):
|
| 111 |
-
"""Run batch then refresh the table."""
|
| 112 |
log = run_batch(batch_size)
|
| 113 |
table = get_alpha_cards()
|
| 114 |
return table, log
|
|
@@ -117,20 +122,20 @@ def generate_and_refresh(batch_size):
|
|
| 117 |
def build_ui():
|
| 118 |
with gr.Blocks(title="Alpha Factory") as app:
|
| 119 |
gr.Markdown("""
|
| 120 |
-
#
|
| 121 |
View, copy, and manage alphas generated by the pipeline.
|
| 122 |
""")
|
| 123 |
|
| 124 |
with gr.Row():
|
| 125 |
with gr.Column(scale=1):
|
| 126 |
batch_size_input = gr.Number(value=3, label="Batch Size", minimum=1, maximum=20)
|
| 127 |
-
generate_btn = gr.Button("
|
| 128 |
-
refresh_btn = gr.Button("
|
| 129 |
gr.Markdown("*Dry run mode — no BRAIN submissions*")
|
| 130 |
with gr.Column(scale=3):
|
| 131 |
stats_md = gr.Markdown(f"**Alphas in store:** {len(get_alphas_from_db())}")
|
| 132 |
|
| 133 |
-
gr.Markdown("###
|
| 134 |
|
| 135 |
alpha_table = gr.Dataframe(
|
| 136 |
value=get_alpha_cards(),
|
|
@@ -139,14 +144,14 @@ def build_ui():
|
|
| 139 |
wrap=True,
|
| 140 |
)
|
| 141 |
|
| 142 |
-
gr.Markdown("###
|
| 143 |
full_expr = gr.Textbox(
|
| 144 |
label="Full Expression",
|
| 145 |
lines=6,
|
| 146 |
-
interactive=True,
|
| 147 |
)
|
| 148 |
|
| 149 |
-
gr.Markdown("###
|
| 150 |
pipeline_log = gr.Textbox(label="Output", lines=15, interactive=False)
|
| 151 |
|
| 152 |
# Events
|
|
|
|
| 11 |
import gradio as gr
|
| 12 |
from pathlib import Path
|
| 13 |
|
|
|
|
| 14 |
try:
|
| 15 |
from dotenv import load_dotenv
|
| 16 |
load_dotenv()
|
|
|
|
| 51 |
def get_alpha_cards():
|
| 52 |
rows = get_alphas_from_db()
|
| 53 |
if not rows:
|
| 54 |
+
return [["—", "—", "—", "—", "—", "—", "—", "Run a batch first"]]
|
| 55 |
data = []
|
| 56 |
for row in rows:
|
| 57 |
alpha_id, submitted_at, expression, theme, archetype, tag, neutral, decay, fields, verdict = row
|
|
|
|
| 73 |
|
| 74 |
|
| 75 |
def run_batch(batch_size):
|
| 76 |
+
"""Run pipeline as subprocess with forced UTF-8 to avoid Windows encoding crash."""
|
| 77 |
env = os.environ.copy()
|
| 78 |
+
# Force UTF-8 output — prevents Rich/Windows cp1252 crash
|
| 79 |
+
env["PYTHONIOENCODING"] = "utf-8"
|
| 80 |
+
env["PYTHONLEGACYWINDOWSSTDIO"] = "utf-8"
|
| 81 |
+
# Disable Rich color/formatting when piped (cleaner output)
|
| 82 |
+
env["NO_COLOR"] = "1"
|
| 83 |
+
env["TERM"] = "dumb"
|
| 84 |
+
# Ensure HF_TOKEN passes through
|
| 85 |
if "HF_TOKEN" not in env:
|
| 86 |
token = os.getenv("HF_TOKEN", "")
|
| 87 |
if token:
|
|
|
|
| 91 |
result = subprocess.run(
|
| 92 |
[sys.executable, "-m", "alpha_factory.run", "--dry-run", "--batch-size", str(int(batch_size))],
|
| 93 |
capture_output=True,
|
|
|
|
|
|
|
|
|
|
| 94 |
env=env,
|
| 95 |
+
timeout=180,
|
| 96 |
cwd=str(Path.cwd()),
|
| 97 |
)
|
| 98 |
+
# Decode with utf-8, replace errors
|
| 99 |
+
stdout = result.stdout.decode("utf-8", errors="replace") if result.stdout else ""
|
| 100 |
+
stderr = result.stderr.decode("utf-8", errors="replace") if result.stderr else ""
|
| 101 |
+
|
| 102 |
log = ""
|
| 103 |
+
if stdout:
|
| 104 |
+
log = stdout[-3000:]
|
| 105 |
+
if result.returncode != 0 and stderr:
|
| 106 |
+
log += "\n\n--- ERRORS ---\n" + stderr[-2000:]
|
| 107 |
if not log.strip():
|
| 108 |
log = f"Process exited with code {result.returncode}"
|
| 109 |
return log
|
| 110 |
except subprocess.TimeoutExpired:
|
| 111 |
+
return "ERROR: Pipeline timed out after 180 seconds. Try smaller batch size."
|
| 112 |
except Exception as e:
|
| 113 |
return f"ERROR: {str(e)}"
|
| 114 |
|
| 115 |
|
| 116 |
def generate_and_refresh(batch_size):
|
|
|
|
| 117 |
log = run_batch(batch_size)
|
| 118 |
table = get_alpha_cards()
|
| 119 |
return table, log
|
|
|
|
| 122 |
def build_ui():
|
| 123 |
with gr.Blocks(title="Alpha Factory") as app:
|
| 124 |
gr.Markdown("""
|
| 125 |
+
# Alpha Factory — Generated Alphas
|
| 126 |
View, copy, and manage alphas generated by the pipeline.
|
| 127 |
""")
|
| 128 |
|
| 129 |
with gr.Row():
|
| 130 |
with gr.Column(scale=1):
|
| 131 |
batch_size_input = gr.Number(value=3, label="Batch Size", minimum=1, maximum=20)
|
| 132 |
+
generate_btn = gr.Button("Generate New Batch", variant="primary")
|
| 133 |
+
refresh_btn = gr.Button("Refresh Table")
|
| 134 |
gr.Markdown("*Dry run mode — no BRAIN submissions*")
|
| 135 |
with gr.Column(scale=3):
|
| 136 |
stats_md = gr.Markdown(f"**Alphas in store:** {len(get_alphas_from_db())}")
|
| 137 |
|
| 138 |
+
gr.Markdown("### Click any row to see full expression")
|
| 139 |
|
| 140 |
alpha_table = gr.Dataframe(
|
| 141 |
value=get_alpha_cards(),
|
|
|
|
| 144 |
wrap=True,
|
| 145 |
)
|
| 146 |
|
| 147 |
+
gr.Markdown("### Full Expression — Ctrl+A then Ctrl+C to copy")
|
| 148 |
full_expr = gr.Textbox(
|
| 149 |
label="Full Expression",
|
| 150 |
lines=6,
|
| 151 |
+
interactive=True,
|
| 152 |
)
|
| 153 |
|
| 154 |
+
gr.Markdown("### Pipeline Log")
|
| 155 |
pipeline_log = gr.Textbox(label="Output", lines=15, interactive=False)
|
| 156 |
|
| 157 |
# Events
|