Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,48 +1,49 @@
|
|
| 1 |
"""
|
| 2 |
Gradio UI that calls the remote animation server.
|
| 3 |
-
|
| 4 |
ANIM_API_URL=http://211.233.58.201:7788/
|
| 5 |
"""
|
| 6 |
|
| 7 |
-
import os,
|
| 8 |
from datetime import datetime
|
| 9 |
|
| 10 |
import gradio as gr
|
| 11 |
import httpx
|
| 12 |
from gradio_client import Client, handle_file
|
| 13 |
|
|
|
|
| 14 |
logging.basicConfig(
|
| 15 |
level=logging.INFO,
|
| 16 |
format="%(asctime)s [%(levelname)s] %(message)s"
|
| 17 |
)
|
| 18 |
log = logging.getLogger(__name__)
|
| 19 |
|
| 20 |
-
#
|
| 21 |
-
# κΈ°λ³Έ μ μ μ£Όμ β λ΄λΆ(Loopback) μ¬λΆμ λ°λΌ μλ νλ¨ + νκ²½λ³μ μ¬μ μ
|
| 22 |
-
# ------------------------------------------------------------------ #
|
| 23 |
_DEFAULT_URL = "http://127.0.0.1:7788/"
|
| 24 |
REMOTE_URL = "http://211.233.58.201:7788/"
|
| 25 |
-
API_URL
|
| 26 |
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
|
| 33 |
-
#
|
| 34 |
def make_client() -> Client:
|
| 35 |
-
"""
|
| 36 |
-
|
|
|
|
|
|
|
|
|
|
| 37 |
return Client(API_URL, timeout=timeout, retries=3)
|
| 38 |
|
| 39 |
def test_api_connection():
|
| 40 |
now = datetime.now().strftime("%H:%M:%S")
|
| 41 |
try:
|
| 42 |
client = make_client()
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
msg = f"[{now}] μλ² μ°κ²° μ±κ³΅ β
(ready={ready})"
|
| 46 |
log.info(msg)
|
| 47 |
return True, msg
|
| 48 |
except Exception as e:
|
|
@@ -50,18 +51,17 @@ def test_api_connection():
|
|
| 50 |
log.error(msg)
|
| 51 |
return False, msg
|
| 52 |
|
| 53 |
-
# ------------------------------------------------------------------ #
|
| 54 |
def generate_animation(image, audio, guidance_scale, steps, progress=gr.Progress()):
|
| 55 |
start = datetime.now().strftime("%H:%M:%S")
|
| 56 |
-
logs
|
| 57 |
try:
|
| 58 |
if image is None or audio is None:
|
| 59 |
raise ValueError("μ΄λ―Έμ§μ μ€λμ€λ₯Ό λͺ¨λ μ
λ‘λνμΈμ.")
|
| 60 |
|
| 61 |
progress(0.05, desc="νμΌ μ€λΉ")
|
| 62 |
client = make_client()
|
| 63 |
-
progress(0.15, desc="μλ² νΈμΆ μ€β¦ (μ΅λ 2-3λΆ μμ)")
|
| 64 |
|
|
|
|
| 65 |
result = client.predict(
|
| 66 |
image_path=handle_file(image),
|
| 67 |
audio_path=handle_file(audio),
|
|
@@ -77,41 +77,47 @@ def generate_animation(image, audio, guidance_scale, steps, progress=gr.Progress
|
|
| 77 |
return anim, comp, "\n".join(logs)
|
| 78 |
else:
|
| 79 |
raise RuntimeError(f"μμμΉ λͺ»ν λ°ν νμ: {type(result)}")
|
|
|
|
| 80 |
except Exception as e:
|
| 81 |
logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] μ€λ₯: {e}")
|
| 82 |
return None, None, "\n".join(logs)
|
| 83 |
|
| 84 |
-
#
|
| 85 |
with gr.Blocks(title="Animation Generator Client") as demo:
|
| 86 |
gr.Markdown("# π¬ Animation Generator β Client UI")
|
| 87 |
|
| 88 |
-
#
|
| 89 |
status_box = gr.Textbox(label="API μν", interactive=False)
|
| 90 |
test_btn = gr.Button("μλ² μ°κ²° ν
μ€νΈ")
|
| 91 |
test_btn.click(test_api_connection, outputs=[status_box, status_box])
|
| 92 |
|
| 93 |
gr.Markdown("---")
|
|
|
|
| 94 |
with gr.Row():
|
| 95 |
with gr.Column():
|
| 96 |
-
img_in = gr.Image(type="filepath", label="Portrait")
|
| 97 |
-
aud_in = gr.Audio(type="filepath", label="Audio")
|
| 98 |
scale = gr.Slider(1, 10, value=3.0, step=0.1, label="Guidance Scale")
|
| 99 |
steps = gr.Slider(5, 30, value=10, step=1, label="Inference Steps")
|
| 100 |
-
gen_btn = gr.Button("π Generate")
|
| 101 |
with gr.Column():
|
| 102 |
anim_out = gr.Video(label="Animation Result")
|
| 103 |
-
comp_out = gr.Video(label="Side-by-
|
| 104 |
-
with gr.Accordion("λ‘κ·Έ", open=False):
|
| 105 |
-
log_out = gr.Textbox(label="μ€ν λ‘κ·Έ", lines=12, max_lines=20, interactive=False)
|
| 106 |
|
| 107 |
-
|
|
|
|
|
|
|
|
|
|
| 108 |
gen_btn.click(
|
| 109 |
generate_animation,
|
| 110 |
inputs=[img_in, aud_in, scale, steps],
|
| 111 |
-
outputs=[anim_out, comp_out, log_out]
|
| 112 |
)
|
| 113 |
|
|
|
|
| 114 |
if __name__ == "__main__":
|
| 115 |
-
demo.queue(max_size=4).launch(
|
| 116 |
-
|
| 117 |
-
|
|
|
|
|
|
|
|
|
| 1 |
"""
|
| 2 |
Gradio UI that calls the remote animation server.
|
| 3 |
+
νκ²½λ³μ ANIM_API_URL λ‘ μλ² μ£Όμλ₯Ό μ€μ νμΈμ
|
| 4 |
ANIM_API_URL=http://211.233.58.201:7788/
|
| 5 |
"""
|
| 6 |
|
| 7 |
+
import os, logging
|
| 8 |
from datetime import datetime
|
| 9 |
|
| 10 |
import gradio as gr
|
| 11 |
import httpx
|
| 12 |
from gradio_client import Client, handle_file
|
| 13 |
|
| 14 |
+
# ββββββββββββββββββββββββββ λ‘κΉ
ββββββββββββββββββββββββββββ #
|
| 15 |
logging.basicConfig(
|
| 16 |
level=logging.INFO,
|
| 17 |
format="%(asctime)s [%(levelname)s] %(message)s"
|
| 18 |
)
|
| 19 |
log = logging.getLogger(__name__)
|
| 20 |
|
| 21 |
+
# βββββββββββββββββββββ μλ² URL κ²°μ λ‘μ§ βββββββββββββββββββββ #
|
|
|
|
|
|
|
| 22 |
_DEFAULT_URL = "http://127.0.0.1:7788/"
|
| 23 |
REMOTE_URL = "http://211.233.58.201:7788/"
|
| 24 |
+
API_URL = os.getenv("ANIM_API_URL", REMOTE_URL)
|
| 25 |
|
| 26 |
+
# Hugging Face Space 컨ν
μ΄λ μμμ 127.0.0.1 μ¬μ©νλ©΄ μΈλΆ μ μ λΆκ°
|
| 27 |
+
if "127.0.0.1" in API_URL and os.getenv("HF_SPACE") == "true":
|
| 28 |
+
raise RuntimeError(
|
| 29 |
+
"HF Space λ΄λΆμμλ ANIM_API_URL μ κ³΅μΈ IPλ λλ©μΈμΌλ‘ μ€μ ν΄μΌ ν©λλ€."
|
| 30 |
+
)
|
| 31 |
|
| 32 |
+
# ββββββββββββββββββββββββ ν¬νΌ ν¨μ βββββββββββββββββββββββββ #
|
| 33 |
def make_client() -> Client:
|
| 34 |
+
"""
|
| 35 |
+
httpx.Timeout μ 0.27+ μμ 4κ° λλ default λͺ¨λ μ§μ ν΄μΌ ν¨
|
| 36 |
+
connect 30s β’ read/write 120s β’ pool 30s
|
| 37 |
+
"""
|
| 38 |
+
timeout = httpx.Timeout(connect=30.0, read=120.0, write=120.0, pool=30.0)
|
| 39 |
return Client(API_URL, timeout=timeout, retries=3)
|
| 40 |
|
| 41 |
def test_api_connection():
|
| 42 |
now = datetime.now().strftime("%H:%M:%S")
|
| 43 |
try:
|
| 44 |
client = make_client()
|
| 45 |
+
ready = client.get("/healthz")["ready"]
|
| 46 |
+
msg = f"[{now}] μλ² μ°κ²° μ±κ³΅ β
(ready={ready})"
|
|
|
|
| 47 |
log.info(msg)
|
| 48 |
return True, msg
|
| 49 |
except Exception as e:
|
|
|
|
| 51 |
log.error(msg)
|
| 52 |
return False, msg
|
| 53 |
|
|
|
|
| 54 |
def generate_animation(image, audio, guidance_scale, steps, progress=gr.Progress()):
|
| 55 |
start = datetime.now().strftime("%H:%M:%S")
|
| 56 |
+
logs = [f"[{start}] μμ² μμ"]
|
| 57 |
try:
|
| 58 |
if image is None or audio is None:
|
| 59 |
raise ValueError("μ΄λ―Έμ§μ μ€λμ€λ₯Ό λͺ¨λ μ
λ‘λνμΈμ.")
|
| 60 |
|
| 61 |
progress(0.05, desc="νμΌ μ€λΉ")
|
| 62 |
client = make_client()
|
|
|
|
| 63 |
|
| 64 |
+
progress(0.15, desc="μλ² νΈμΆ μ€β¦ (μ΅λ 2~3λΆ)")
|
| 65 |
result = client.predict(
|
| 66 |
image_path=handle_file(image),
|
| 67 |
audio_path=handle_file(audio),
|
|
|
|
| 77 |
return anim, comp, "\n".join(logs)
|
| 78 |
else:
|
| 79 |
raise RuntimeError(f"μμμΉ λͺ»ν λ°ν νμ: {type(result)}")
|
| 80 |
+
|
| 81 |
except Exception as e:
|
| 82 |
logs.append(f"[{datetime.now().strftime('%H:%M:%S')}] μ€λ₯: {e}")
|
| 83 |
return None, None, "\n".join(logs)
|
| 84 |
|
| 85 |
+
# ββββββββββββββββββββββββββ UI μ μ βββββββββββββββββββββββββ #
|
| 86 |
with gr.Blocks(title="Animation Generator Client") as demo:
|
| 87 |
gr.Markdown("# π¬ Animation Generator β Client UI")
|
| 88 |
|
| 89 |
+
# μλ² μν 체ν¬
|
| 90 |
status_box = gr.Textbox(label="API μν", interactive=False)
|
| 91 |
test_btn = gr.Button("μλ² μ°κ²° ν
μ€νΈ")
|
| 92 |
test_btn.click(test_api_connection, outputs=[status_box, status_box])
|
| 93 |
|
| 94 |
gr.Markdown("---")
|
| 95 |
+
|
| 96 |
with gr.Row():
|
| 97 |
with gr.Column():
|
| 98 |
+
img_in = gr.Image(type="filepath", label="Portrait Image")
|
| 99 |
+
aud_in = gr.Audio(type="filepath", label="Driving Audio")
|
| 100 |
scale = gr.Slider(1, 10, value=3.0, step=0.1, label="Guidance Scale")
|
| 101 |
steps = gr.Slider(5, 30, value=10, step=1, label="Inference Steps")
|
| 102 |
+
gen_btn = gr.Button("π Generate")
|
| 103 |
with gr.Column():
|
| 104 |
anim_out = gr.Video(label="Animation Result")
|
| 105 |
+
comp_out = gr.Video(label="Side-by-Side")
|
|
|
|
|
|
|
| 106 |
|
| 107 |
+
with gr.Accordion("μ€ν λ‘κ·Έ", open=False):
|
| 108 |
+
log_out = gr.Textbox(label="Logs", lines=12, max_lines=20, interactive=False)
|
| 109 |
+
|
| 110 |
+
# λ²νΌ μ΄λ²€νΈ μ°κ²°
|
| 111 |
gen_btn.click(
|
| 112 |
generate_animation,
|
| 113 |
inputs=[img_in, aud_in, scale, steps],
|
| 114 |
+
outputs=[anim_out, comp_out, log_out]
|
| 115 |
)
|
| 116 |
|
| 117 |
+
# ββββββββββββββββββββββββββ μ€ν βββββββββββββββββββββββββββ #
|
| 118 |
if __name__ == "__main__":
|
| 119 |
+
demo.queue(max_size=4).launch(
|
| 120 |
+
server_name="0.0.0.0",
|
| 121 |
+
server_port=7860,
|
| 122 |
+
show_api=False
|
| 123 |
+
)
|