Spaces:
Running
on
Zero
Running
on
Zero
Added Zip instead of single files to make loading in Hueforge correct
Browse files
app.py
CHANGED
|
@@ -71,7 +71,6 @@ gradio.blocks.Blocks.call_function = sentry_call_fn
|
|
| 71 |
import gradio as gr
|
| 72 |
import pandas as pd
|
| 73 |
import os
|
| 74 |
-
import subprocess
|
| 75 |
import time
|
| 76 |
import sys
|
| 77 |
from datetime import datetime
|
|
@@ -333,7 +332,7 @@ def run_autoforge_process(cmd, log_path):
|
|
| 333 |
|
| 334 |
exit_code = 0
|
| 335 |
with open(log_path, "w", buffering=1, encoding="utf-8") as log_f, \
|
| 336 |
-
|
| 337 |
try:
|
| 338 |
sys.argv = ["autoforge"] + cli_args
|
| 339 |
autoforge_main.main() # runs until completion
|
|
@@ -532,7 +531,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 532 |
)
|
| 533 |
expected_cols = ["Brand", " Name", " TD", " Color"]
|
| 534 |
if not all(
|
| 535 |
-
|
| 536 |
):
|
| 537 |
gr.Error(
|
| 538 |
f"CSV must contain columns: {', '.join(expected_cols)}. Found: {loaded_script_df.columns.tolist()}"
|
|
@@ -544,8 +543,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 544 |
)
|
| 545 |
current_script_df = filament_df_state.value
|
| 546 |
if (
|
| 547 |
-
|
| 548 |
-
|
| 549 |
):
|
| 550 |
return current_script_df.rename(
|
| 551 |
columns={
|
|
@@ -583,8 +582,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 583 |
|
| 584 |
def save_filaments_to_file_for_download(current_script_df_from_state):
|
| 585 |
if (
|
| 586 |
-
|
| 587 |
-
|
| 588 |
):
|
| 589 |
gr.Warning("Filament table is empty. Nothing to save.")
|
| 590 |
return None
|
|
@@ -742,8 +741,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 742 |
|
| 743 |
with gr.Row():
|
| 744 |
download_results = gr.File(
|
| 745 |
-
label="Download
|
| 746 |
-
file_count="
|
| 747 |
interactive=True,
|
| 748 |
visible=False,
|
| 749 |
)
|
|
@@ -751,9 +750,9 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 751 |
# --- Backend Function for Running the Script ---
|
| 752 |
@spaces.GPU(duration=150)
|
| 753 |
def execute_autoforge_script(
|
| 754 |
-
|
| 755 |
):
|
| 756 |
-
|
| 757 |
log_output = []
|
| 758 |
|
| 759 |
# 0. Validate Inputs
|
|
@@ -769,8 +768,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 769 |
|
| 770 |
# 1. Save current filaments
|
| 771 |
if (
|
| 772 |
-
|
| 773 |
-
|
| 774 |
):
|
| 775 |
gr.Error("Filament table is empty. Please add filaments.")
|
| 776 |
capture_exception(
|
|
@@ -826,9 +825,9 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 826 |
item for item in get_script_args_info() if item["name"] == arg_name
|
| 827 |
] # get full list to check type
|
| 828 |
if (
|
| 829 |
-
|
| 830 |
-
|
| 831 |
-
|
| 832 |
):
|
| 833 |
continue
|
| 834 |
else:
|
|
@@ -906,7 +905,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 906 |
exc_str = exc_text(e)
|
| 907 |
self.exc = e
|
| 908 |
capture_exception(e) # still goes to Sentry
|
| 909 |
-
|
| 910 |
# make the error visible in the UI console
|
| 911 |
with open(self.log_path, "a", encoding="utf-8") as lf:
|
| 912 |
lf.write(
|
|
@@ -923,11 +922,11 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 923 |
try:
|
| 924 |
worker = Worker(command, log_file)
|
| 925 |
worker.start()
|
| 926 |
-
|
| 927 |
preview_mtime = 0
|
| 928 |
last_push = 0
|
| 929 |
file_pos = 0 # how far we've read
|
| 930 |
-
|
| 931 |
while worker.is_alive() or file_pos < os.path.getsize(log_file):
|
| 932 |
# read any new console text
|
| 933 |
with open(log_file, "r", encoding="utf-8") as lf:
|
|
@@ -935,7 +934,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 935 |
new_txt = lf.read()
|
| 936 |
file_pos = lf.tell()
|
| 937 |
log_output += new_txt
|
| 938 |
-
|
| 939 |
now = time.time()
|
| 940 |
if now - last_push >= 1.0: # one-second UI tick
|
| 941 |
current_preview = _maybe_new_preview()
|
|
@@ -945,9 +944,9 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 945 |
gr.update(), # placeholder for download widget
|
| 946 |
)
|
| 947 |
last_push = now
|
| 948 |
-
|
| 949 |
time.sleep(0.05)
|
| 950 |
-
|
| 951 |
worker.join() # make sure it’s done
|
| 952 |
except RuntimeError as e:
|
| 953 |
# Show toast to user
|
|
@@ -956,10 +955,10 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 956 |
capture_exception(e)
|
| 957 |
|
| 958 |
with open(log_file, "r", encoding="utf-8") as lf:
|
| 959 |
-
|
| 960 |
-
|
| 961 |
-
|
| 962 |
-
|
| 963 |
yield (
|
| 964 |
"".join(log_output),
|
| 965 |
current_preview,
|
|
@@ -1034,6 +1033,20 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 1034 |
if out_png is None:
|
| 1035 |
log_output += "\nWarning: final_model.png not found in output."
|
| 1036 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1037 |
sentry_sdk.capture_event( # moved inside the same scope
|
| 1038 |
{
|
| 1039 |
"message": "Autoforge process finished",
|
|
@@ -1084,9 +1097,9 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
| 1084 |
"".join(log_output), # progress_output
|
| 1085 |
out_png, # final_image_preview (same as before)
|
| 1086 |
gr.update( # download_results
|
| 1087 |
-
value=
|
| 1088 |
-
visible=
|
| 1089 |
-
interactive=
|
| 1090 |
),
|
| 1091 |
)
|
| 1092 |
|
|
|
|
| 71 |
import gradio as gr
|
| 72 |
import pandas as pd
|
| 73 |
import os
|
|
|
|
| 74 |
import time
|
| 75 |
import sys
|
| 76 |
from datetime import datetime
|
|
|
|
| 332 |
|
| 333 |
exit_code = 0
|
| 334 |
with open(log_path, "w", buffering=1, encoding="utf-8") as log_f, \
|
| 335 |
+
redirect_stdout(log_f), redirect_stderr(log_f), parallel_backend("threading", n_jobs=-1):
|
| 336 |
try:
|
| 337 |
sys.argv = ["autoforge"] + cli_args
|
| 338 |
autoforge_main.main() # runs until completion
|
|
|
|
| 531 |
)
|
| 532 |
expected_cols = ["Brand", " Name", " TD", " Color"]
|
| 533 |
if not all(
|
| 534 |
+
col in loaded_script_df.columns for col in expected_cols
|
| 535 |
):
|
| 536 |
gr.Error(
|
| 537 |
f"CSV must contain columns: {', '.join(expected_cols)}. Found: {loaded_script_df.columns.tolist()}"
|
|
|
|
| 543 |
)
|
| 544 |
current_script_df = filament_df_state.value
|
| 545 |
if (
|
| 546 |
+
current_script_df is not None
|
| 547 |
+
and not current_script_df.empty
|
| 548 |
):
|
| 549 |
return current_script_df.rename(
|
| 550 |
columns={
|
|
|
|
| 582 |
|
| 583 |
def save_filaments_to_file_for_download(current_script_df_from_state):
|
| 584 |
if (
|
| 585 |
+
current_script_df_from_state is None
|
| 586 |
+
or current_script_df_from_state.empty
|
| 587 |
):
|
| 588 |
gr.Warning("Filament table is empty. Nothing to save.")
|
| 589 |
return None
|
|
|
|
| 741 |
|
| 742 |
with gr.Row():
|
| 743 |
download_results = gr.File(
|
| 744 |
+
label="Download Results (zip)",
|
| 745 |
+
file_count="single",
|
| 746 |
interactive=True,
|
| 747 |
visible=False,
|
| 748 |
)
|
|
|
|
| 750 |
# --- Backend Function for Running the Script ---
|
| 751 |
@spaces.GPU(duration=150)
|
| 752 |
def execute_autoforge_script(
|
| 753 |
+
current_filaments_df_state_val, input_image, *accordion_param_values
|
| 754 |
):
|
| 755 |
+
|
| 756 |
log_output = []
|
| 757 |
|
| 758 |
# 0. Validate Inputs
|
|
|
|
| 768 |
|
| 769 |
# 1. Save current filaments
|
| 770 |
if (
|
| 771 |
+
current_filaments_df_state_val is None
|
| 772 |
+
or current_filaments_df_state_val.empty
|
| 773 |
):
|
| 774 |
gr.Error("Filament table is empty. Please add filaments.")
|
| 775 |
capture_exception(
|
|
|
|
| 825 |
item for item in get_script_args_info() if item["name"] == arg_name
|
| 826 |
] # get full list to check type
|
| 827 |
if (
|
| 828 |
+
arg_info_list
|
| 829 |
+
and arg_info_list[0]["type"] == "checkbox"
|
| 830 |
+
and arg_widget_val is False
|
| 831 |
):
|
| 832 |
continue
|
| 833 |
else:
|
|
|
|
| 905 |
exc_str = exc_text(e)
|
| 906 |
self.exc = e
|
| 907 |
capture_exception(e) # still goes to Sentry
|
| 908 |
+
|
| 909 |
# make the error visible in the UI console
|
| 910 |
with open(self.log_path, "a", encoding="utf-8") as lf:
|
| 911 |
lf.write(
|
|
|
|
| 922 |
try:
|
| 923 |
worker = Worker(command, log_file)
|
| 924 |
worker.start()
|
| 925 |
+
|
| 926 |
preview_mtime = 0
|
| 927 |
last_push = 0
|
| 928 |
file_pos = 0 # how far we've read
|
| 929 |
+
|
| 930 |
while worker.is_alive() or file_pos < os.path.getsize(log_file):
|
| 931 |
# read any new console text
|
| 932 |
with open(log_file, "r", encoding="utf-8") as lf:
|
|
|
|
| 934 |
new_txt = lf.read()
|
| 935 |
file_pos = lf.tell()
|
| 936 |
log_output += new_txt
|
| 937 |
+
|
| 938 |
now = time.time()
|
| 939 |
if now - last_push >= 1.0: # one-second UI tick
|
| 940 |
current_preview = _maybe_new_preview()
|
|
|
|
| 944 |
gr.update(), # placeholder for download widget
|
| 945 |
)
|
| 946 |
last_push = now
|
| 947 |
+
|
| 948 |
time.sleep(0.05)
|
| 949 |
+
|
| 950 |
worker.join() # make sure it’s done
|
| 951 |
except RuntimeError as e:
|
| 952 |
# Show toast to user
|
|
|
|
| 955 |
capture_exception(e)
|
| 956 |
|
| 957 |
with open(log_file, "r", encoding="utf-8") as lf:
|
| 958 |
+
lf.seek(file_pos)
|
| 959 |
+
new_txt = lf.read()
|
| 960 |
+
file_pos = lf.tell()
|
| 961 |
+
log_output += new_txt
|
| 962 |
yield (
|
| 963 |
"".join(log_output),
|
| 964 |
current_preview,
|
|
|
|
| 1033 |
if out_png is None:
|
| 1034 |
log_output += "\nWarning: final_model.png not found in output."
|
| 1035 |
|
| 1036 |
+
zip_path = None
|
| 1037 |
+
if files_to_offer:
|
| 1038 |
+
zip_path = os.path.join(run_output_dir_val, "autoforge_results.zip")
|
| 1039 |
+
log_output += f"\nZipping results to {os.path.basename(zip_path)}..."
|
| 1040 |
+
try:
|
| 1041 |
+
with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_STORED) as zf:
|
| 1042 |
+
for f in files_to_offer:
|
| 1043 |
+
zf.write(f, os.path.basename(f))
|
| 1044 |
+
log_output += " done."
|
| 1045 |
+
except Exception as e:
|
| 1046 |
+
capture_exception(e)
|
| 1047 |
+
log_output += f"\nError creating zip file: {e}"
|
| 1048 |
+
zip_path = None # Don't offer a broken zip
|
| 1049 |
+
|
| 1050 |
sentry_sdk.capture_event( # moved inside the same scope
|
| 1051 |
{
|
| 1052 |
"message": "Autoforge process finished",
|
|
|
|
| 1097 |
"".join(log_output), # progress_output
|
| 1098 |
out_png, # final_image_preview (same as before)
|
| 1099 |
gr.update( # download_results
|
| 1100 |
+
value=zip_path,
|
| 1101 |
+
visible=bool(zip_path),
|
| 1102 |
+
interactive=bool(zip_path),
|
| 1103 |
),
|
| 1104 |
)
|
| 1105 |
|