jade-assistant / app.py
Madras1's picture
Upload app.py
ff01e21 verified
"""
HuggingFace Spaces Entry Point for Jade Bot
"""
import os
import socket
import logging
import asyncio
import httpx
from datetime import datetime
from fastapi import FastAPI, Request
from telegram import Update
from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler, filters
import uvicorn
import gradio as gr
# Direct IP for Telegram API
TELEGRAM_IP = "149.154.167.220"
def custom_getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
if "telegram" in str(host).lower():
return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (TELEGRAM_IP, port if port else 443))]
return socket._original_getaddrinfo(host, port, socket.AF_INET, type, proto, flags)
socket._original_getaddrinfo = socket.getaddrinfo
socket.getaddrinfo = custom_getaddrinfo
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)
logger = logging.getLogger(__name__)
bot_status = {"started_at": None, "is_running": False, "error": None}
application = None
app = FastAPI()
def get_status():
if bot_status.get("error"):
return f"πŸ”΄ Error: {bot_status['error']}"
if not bot_status["is_running"]:
return "🟑 Bot starting..."
return f"## 🟒 Jade Running!\n- Started: {bot_status.get('started_at')}"
@app.post("/webhook")
async def webhook(request: Request):
global application
if application:
data = await request.json()
update = Update.de_json(data, application.bot)
await application.process_update(update)
return {"ok": True}
async def setup_bot():
global application, bot_status
token = os.getenv("TELEGRAM_BOT_TOKEN")
space_url = os.getenv("SPACE_URL", "")
if not token:
bot_status["error"] = "TELEGRAM_BOT_TOKEN not set!"
return
if not space_url:
space_id = os.getenv("SPACE_ID", "")
if space_id:
space_url = f"https://{space_id.replace('/', '-')}.hf.space"
else:
bot_status["error"] = "SPACE_URL not set!"
return
logger.info(f"Space URL: {space_url}")
# Wait for network
await asyncio.sleep(3)
try:
from core import TelegramJadeAgent
from tools import ReminderManager
reminder_manager = ReminderManager()
agent = TelegramJadeAgent(reminder_manager=reminder_manager)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await context.bot.send_message(chat_id=update.effective_chat.id, text="Hi! I'm Jade 🌿")
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
chat_id = update.effective_chat.id
user_text = update.message.text
loop = asyncio.get_event_loop()
response = await loop.run_in_executor(None, agent.chat, chat_id, user_text)
await context.bot.send_message(chat_id=chat_id, text=response)
# Build with extended timeouts
from telegram.ext import Defaults
from telegram.request import HTTPXRequest
request = HTTPXRequest(
connection_pool_size=8,
read_timeout=30,
write_timeout=30,
connect_timeout=30,
pool_timeout=30
)
application = (
ApplicationBuilder()
.token(token)
.request(request)
.get_updates_request(request)
.build()
)
application.add_handler(CommandHandler('start', start))
application.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), handle_message))
webhook_url = f"{space_url}/webhook"
for attempt in range(5):
try:
logger.info(f"Attempt {attempt + 1}/5: Initializing...")
await application.initialize()
logger.info(f"Setting webhook to {webhook_url}...")
await application.bot.set_webhook(url=webhook_url, drop_pending_updates=True)
logger.info("βœ… Webhook set successfully!")
bot_status["started_at"] = datetime.now().strftime("%H:%M:%S")
bot_status["is_running"] = True
return
except Exception as e:
logger.warning(f"Attempt {attempt + 1} failed: {e}")
if attempt < 4:
await asyncio.sleep(10)
bot_status["error"] = "Failed after 5 attempts"
except Exception as e:
logger.error(f"Bot setup failed: {e}")
bot_status["error"] = str(e)
def create_gradio():
with gr.Blocks(title="Jade Bot") as demo:
gr.Markdown("# 🌿 Jade - 24h Personal Assistant")
status = gr.Markdown(get_status)
gr.Button("πŸ”„ Refresh").click(fn=get_status, outputs=status)
return demo
gradio_app = create_gradio()
app = gr.mount_gradio_app(app, gradio_app, path="/")
@app.on_event("startup")
async def startup_event():
logger.info("Starting bot setup...")
asyncio.create_task(setup_bot())
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)