File size: 2,809 Bytes
5d658a8
 
 
2ceaa55
 
5d658a8
 
8daa0fb
1e947e0
1fcc069
 
8daa0fb
2ceaa55
c968025
4a1c368
 
a27e4b0
5d658a8
2ceaa55
 
 
 
 
 
 
1e947e0
c968025
1e947e0
4a1c368
 
c968025
 
 
 
 
 
 
 
 
4a1c368
 
2ceaa55
8daa0fb
a27e4b0
8daa0fb
a27e4b0
 
 
 
8daa0fb
2ceaa55
8daa0fb
 
c968025
 
 
 
 
 
 
 
 
 
 
 
 
 
9d1a72a
5d658a8
 
2ceaa55
 
 
 
c968025
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
"""
app.py
Hugging Face Spaces entry point for Ginchiee Bot.
Runs a minimal Python HTTP server on port 7860 to keep the Space alive,
while running the Telegram bot in the background via asyncio.
"""

import asyncio
import logging
import os
import sys
import threading

import gradio as gr
import spaces

from main import build_app

# ── Logging ────────────────────────────────────────────────────────────────────
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
    handlers=[logging.StreamHandler(sys.stdout)],
)
logger = logging.getLogger("app")
bot_thread: threading.Thread | None = None


@spaces.GPU
def zero_gpu_runtime_probe() -> str:
    """Provide the callback ZeroGPU requires without using GPU for Telegram polling."""
    return "ZeroGPU runtime is registered. Telegram polling does not require GPU."


def bot_worker_status() -> str:
    if bot_thread and bot_thread.is_alive():
        return "Telegram polling worker is active."
    return "Telegram polling worker is not running. Check the Space logs."


# ── Telegram Bot Worker ────────────────────────────────────────────────────────
def start_bot_worker():
    logger.info("Starting Telegram bot worker thread...")
    try:
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        app = build_app()
        app.run_polling(stop_signals=None, drop_pending_updates=False)
    except Exception as e:
        logger.error(f"FATAL: Telegram bot crashed: {e}", exc_info=True)


with gr.Blocks(title="Ginchiee Bot") as demo:
    gr.Markdown("# Ginchiee Bot\nTelegram AI Health & Diet Companion")
    worker_status = gr.Textbox(
        label="Telegram worker",
        value="Telegram polling worker is starting.",
        interactive=False,
    )
    refresh_status = gr.Button("Refresh worker status")
    refresh_status.click(bot_worker_status, outputs=worker_status, api_name=False)

    # The callback is hidden because it only exists to register the ZeroGPU runtime.
    zero_gpu_trigger = gr.Button(visible=False)
    zero_gpu_status = gr.Textbox(visible=False)
    zero_gpu_trigger.click(zero_gpu_runtime_probe, outputs=zero_gpu_status, api_name=False)


if __name__ == "__main__":
    bot_thread = threading.Thread(target=start_bot_worker, daemon=True)
    bot_thread.start()

    port = int(os.getenv("PORT", "7860"))
    logger.info(f"Starting Gradio status page on port {port}...")
    demo.launch(server_name="0.0.0.0", server_port=port, show_error=True)