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 |
|