import os import time import threading import random import logging import torch import torch.nn.functional as F from flask import Flask, request, jsonify # --- CONFIGURATION --- MAX_IDLE_TIME = 3600 CLEANUP_INTERVAL = 300 # ⚠️ ไฟล์ Vector ภาษาไทยที่เราเพิ่งอบเสร็จ VECTOR_FILE = "vectors_th_fasttext.pt" # --- รายชื่อคำศัพท์สำหรับสุ่มเป็น "คำตอบ" (Secret Word) --- KIDS_WORDS = [ # 👨‍👩‍👧‍👦 ครอบครัว & คน & อาชีพ "พ่อ", "แม่", "ลูก", "พี่", "น้อง", "ปู่", "ย่า", "ตา", "ยาย", "ลุง", "ป้า", "น้า", "ครู", "นักเรียน", "หมอ", "พยาบาล", "ตำรวจ", "ทหาร", "เพื่อน", "คน", "เด็ก", "ผู้ชาย", "ผู้หญิง", "ชาวนา", "พ่อค้า", "แม่ค้า", "นักบิน", "คนขับรถ", "ดารา", "นักร้อง", "ช่างภาพ", "พ่อครัว", "พระ", "เณร", "โจร", "ยักษ์", "นางฟ้า", "เจ้าหญิง", "เจ้าชาย", "กษัตริย์", "ราชินี", # 🐶 สัตว์บก & สัตว์เลี้ยง "หมา", "แมว", "ไก่", "เป็ด", "นก", "ช้าง", "ม้า", "วัว","หมู", "ลิง", "เสือ", "สิงโต", "กระต่าย", "เต่า", "งู", "กบ", "มด", "ผึ้ง", "ยุง", "หมี", "ยีราฟ", "ม้าลาย", "จระเข้", "แกะ", "แพะ", "กวาง", "จิ้งจก", "หนอน", "ผีเสื้อ", "แมงมุม", "แมลงสาบ", "กระรอก", "หนู", "จิ้งจอก", "หมาป่า", # 🐟 สัตว์น้ำ "ปลา", "กุ้ง", "หอย", "ปู", "ปลาหมึก", "ฉลาม", "โลมา", "วาฬ", "แมงกะพรุน", "ดาวทะเล", # 🏠 สิ่งของในบ้าน & ของใช้ส่วนตัว "บ้าน", "โต๊ะ", "เก้าอี้", "เตียง", "หมอน", "ผ้าห่ม","กระจก", "นาฬิกา", "หวี", "สบู่", "ยาสีฟัน", "แปรงสีฟัน", "แชมพู", "ผ้าเช็ดตัว", "แป้ง", "ถังขยะ", "ไม้กวาด", "ไม้ถูพื้น", "จาน", "ชาม", "ช้อน","แก้ว", "ขวด", "มีด", "เขียง", "หม้อ", "กระทะ", "ถังน้ำ", "กุญแจ", "ไฟฉาย", "เทียน", "ธูป", "แจกัน", "รูปภาพ", # 📺 เครื่องใช้ไฟฟ้า & เทคโนโลยี "คอมพิวเตอร์", "โทรศัพท์", "ทีวี", "ตู้เย็น", "พัดลม", "แอร์", "หม้อหุงข้าว", "เตารีด", "เครื่องซักผ้า", "ไมโครเวฟ", "หลอดไฟ", "ปลั๊กไฟ", "วิทยุ", "ลำโพง", "กล้อง", # ✏️ โรงเรียน & เครื่องเขียน "โรงเรียน", "หนังสือ", "สมุด", "ดินสอ", "ปากกา", "ยางลบ", "ไม้บรรทัด", "กบเหลาดินสอ", "กระเป๋า", "กระดาน", "ชอล์ก", "สี", "พู่กัน", "กรรไกร", "กาว", "กล่องดินสอ", "ลูกโลก", "ธงชาติ", # 🚗 ยานพาหนะ & การเดินทาง "รถ", "รถยนต์", "รถมอเตอร์ไซค์", "จักรยาน", "รถเมล์", "รถตู้", "รถไฟ", "เรือ", "เครื่องบิน", "จรวด", "รถพยาบาล", "รถดับเพลิง", "รถตำรวจ", "รถบรรทุก", "รถแท็กซี่","ถนน", "สะพาน", "ทางม้าลาย", # 🌳 ธรรมชาติ & สิ่งแวดล้อม "ฟ้า", "ฝน", "เมฆ", "แดด", "ลม", "ดิน", "หิน", "ทราย", "น้ำ", "ไฟ", "ภูเขา", "ทะเล", "แม่น้ำ", "ลำธาร", "น้ำตก", "ป่า", "ถ้ำ", "เกาะ", "ชายหาด", "ต้นไม้", "ดอกไม้", "ใบไม้", "หญ้า", "รากไม้", "กิ่งไม้", "ผลไม้", "พระอาทิตย์", "พระจันทร์", "ดาว", "รุ้ง", "หิมะ", "ภูเขาไฟ", "คลื่น", "ฝุ่น", "ควัน", # 🍉 ผลไม้ & ผัก "กล้วย", "ส้ม", "แตงโม", "มะม่วง", "แอปเปิ้ล", "องุ่น", "ทุเรียน", "เงาะ", "ลำไย", "มังคุด", "สตรอว์เบอร์รี", "มะพร้าว", "สับปะรด", "ชมพู่", "ฝรั่ง", "มะละกอ", "ผัก", "ข้าวโพด", "แตงกวา", "มะเขือเทศ", "ฟักทอง", "แครอท", "ผักบุ้ง", "พริก", "มะนาว", "หัวหอม", "กระเทียม", # 🍜 อาหาร & ขนม "ข้าว", "ข้าวผัด", "ไข่เจียว", "ไข่ต้ม", "ก๋วยเตี๋ยว", "ส้มตำ", "ไก่ทอด", "หมูปิ้ง", "ลูกชิ้น", "ขนม", "ขนมปัง", "เค้ก", "ไอศกรีม", "ช็อกโกแลต", "ลูกอม", "เยลลี่", "คุกกี้", "โดนัท", "น้ำ", "นม", "น้ำอัดลม", "น้ำส้ม", "น้ำแข็ง", "น้ำตาล", "เกลือ", "น้ำปลา", # 👕 ร่างกาย & เครื่องแต่งกาย "หัว", "ตา", "หู", "จมูก", "ปาก", "ฟัน", "ลิ้น", "แก้ม", "คาง", "หน้าผาก", "คอ", "มือ", "นิ้ว", "แขน", "เล็บ", "ท้อง", "หลัง", "ขา", "เข่า", "เท้า", "ผม", "ผิว", "เลือด", "กระดูก", "เสื้อ", "กางเกง", "กระโปรง", "รองเท้า", "ถุงเท้า", "หมวก", "เข็มขัด", "แว่นตา", "หน้ากาก", "แหวน", "สร้อย", # 🏥 สถานที่ต่างๆ "บ้าน", "โรงพยาบาล", "วัด", "ตลาด", "สวนสัตว์", "ห้าง", "ร้านค้า", "สวนสนุก", "สวนสาธารณะ", "สนามเด็กเล่น", "ห้องน้ำ", "ห้องนอน", "ห้องครัว", "ห้องนั่งเล่น", "สนามบิน", "โรงแรม", "ธนาคาร", "ไปรษณีย์", "สถานีตำรวจ", # 🎨 สี & รูปร่าง "สีแดง", "สีเหลือง", "สีชมพู", "สีเขียว", "สีส้ม", "สีฟ้า", "สีน้ำเงิน", "สีม่วง", "สีดำ", "สีขาว", "สีเทา", "สีน้ำตาล", "วงกลม", "สี่เหลี่ยม", "สามเหลี่ยม", "ดาว", "หัวใจ", # ⚽ กีฬา & ของเล่น "ฟุตบอล", "บาสเกตบอล", "ว่ายน้ำ", "วิ่ง", "มวย", "แบดมินตัน", "ตุ๊กตา", "ลูกบอล", "หุ่นยนต์", "รถบังคับ", "ตัวต่อ", "ลูกโป่ง","เกม", # 😊 ความรู้สึกและคำขยาย (Adjectives) "ดี", "เลว", "ชั่ว", "เก่ง", "ฉลาด","น่ารัก", "สวย", "หล่อ", "อ้วน", "ผอม", "สูง", "เตี้ย", "ใหญ่", "เล็ก", "ยาว", "สั้น", "กว้าง", "แคบ", "หนา", "บาง", "หนัก", "เบา", "แข็ง", "นิ่ม", "นุ่ม", "เหนียว", "ลื่น", "เรียบ", "ตรง", "โค้ง", "งอ", "กลม", "ลึก", "ตื้น", "ไกล", "ใกล้", "เร็ว", "ช้า", "ดัง", "เบา", "เงียบ", "สว่าง", "มืด", "ร้อน", "หนาว", "เย็น", "อุ่น", "เปียก", "แห้ง", "สะอาด", "สกปรก", "ใหม่", "เก่า", "แก่", "หนุ่ม", "สาว", "รวย", "จน", "ถูก", "แพง", "ง่าย", "ยาก", "เยอะ", "น้อย", "หมด", "เต็ม", "ว่าง", "หิว", "อิ่ม", "ง่วง", "เหนื่อย", "สบาย", "ป่วย", "เจ็บ", "คัน", "ปวด", "หอม", "เหม็น", "อร่อย", "หวาน", "เปรี้ยว", "เค็ม", "เผ็ด", "ขม", "มัน", "สด", "เน่า", "สุก", "ดิบ", "กรอบ", "เละ", "จริง", "ปลอม", "ผิด", "ถูก", # 🕒 เวลาและฤดูกาล (Time & Seasons) "เวลา", "นาฬิกา", "วินาที", "นาที", "ชั่วโมง", "วัน", "สัปดาห์", "เดือน", "ปี", "เช้า", "สาย", "เที่ยง", "บ่าย", "เย็น", "ค่ำ", "ดึก", "รุ่งเช้า", "เมื่อวาน", "วันนี้", "พรุ่งนี้", "มะรืน", "อดีต", "ปัจจุบัน", "อนาคต", "ฤดูร้อน", "ฤดูฝน", "ฤดูหนาว", "เทศกาล", "ปีใหม่", "สงกรานต์", "ลอยกระทง", "วันเด็ก", # 🏙️ สถานที่ (Places) "เมือง", "ชนบท", "หมู่บ้าน", "จังหวัด", "ประเทศ", "โลก", "จักรวาล", "อวกาศ", "สนามบิน", "ท่าเรือ", "สถานีรถไฟ", "ป้ายรถเมล์", "ทางด่วน", "ถนนใหญ่", "ซอย", "สะพาน", "อุโมงค์", "ทางม้าลาย", "สี่แยก", "วงเวียน", "ฟุตบาท", "ทางเดิน", "ตึก", "อาคาร", "คอนโด", "หอพัก", "โรงแรม", "รีสอร์ท", "กระท่อม", "ปราสาท", "วัง", "พิพิธภัณฑ์", "ห้องสมุด", "โรงหนัง", "สวนสนุก", "สวนน้ำ", "สนามกีฬา", "สระว่ายน้ำ", "ยิม", "ร้านอาหาร", "ร้านกาแฟ", "ร้านหนังสือ", "ร้านตัดผม", "ร้านขายยา", "ตลาดนัด", "ซุปเปอร์มาร์เก็ต", "เซเว่น", "ปั๊มน้ำมัน", "อู่ซ่อมรถ", "โรงงาน", "บริษัท", "ที่ทำงาน", "สถานีดับเพลิง", "คุก", "ศาล", "อำเภอ", "เทศบาล", "รัฐสภา", "วัด", "โบสถ์", "ศาลเจ้า", "เจดีย์", "เมรุ", "ป่าช้า", "สุสาน", # 🎸 ดนตรีและศิลปะ (Music & Arts) "ดนตรี", "เพลง", "นักร้อง", "วงดนตรี", "คอนเสิร์ต", "ทำนอง", "จังหวะ", "เสียง", "กีตาร์", "เปียโน", "กลอง", "ไวโอลิน","ทรัมเป็ต", "ขลุ่ย", "แคน", "ระนาด", "กลองยาว", "พิณ", "ซอ", "อูคูเลเล่", "ไมโครโฟน", "ลำโพง", "ศิลปะ", "รูปวาด", "ภาพถ่าย", "สีน้ำ", "สีเทียน", "สีไม้", "พู่กัน", "จานสี", "ดินน้ำมัน", "กาว", "กรรไกร", "คัตเตอร์", "ไม้บรรทัด", "ยางลบ", "ละคร", "การ์ตูน", "หนัง", "นิทาน", "เรื่องเล่า", "บทกวี", "กลอน", "เต้น", "รำ", # 🔧 เครื่องมือและเทคโนโลยี (Tools & Tech) "ค้อน", "ตะปู", "ไขควง","เลื่อย", "สว่าน", "คีม", "ประแจ", "ตลับเมตร", "บันได", "เชือก", "โซ่", "กุญแจ", "แม่กุญแจ", "ลูกกุญแจ", "ไฟแช็ก", "ไม้ขีด", "อินเทอร์เน็ต", "ไวไฟ", "เว็บไซต์","เกม", "หน้าจอ", "เมาส์", "คีย์บอร์ด", "หูฟัง", "สายชาร์จ", "แบตเตอรี่", "ถ่าน", "รีโมท","สวิตช์ไฟ", "หุ่นยนต์", "ดาวเทียม", "จรวด", "ยานอวกาศ", "มนุษย์ต่างดาว", # 🦁 สัตว์เพิ่มเติม (More Animals) "นกแก้ว", "นกอินทรี", "นกฮูก", "นกเพนกวิน", "นกกระจอกเทศ", "นกยูง", "หงส์", "ห่าน", "ไก่งวง", "ค้างคาว", "ตุ๊กแก", "กิ้งก่า", "ตะขาบ", "แมงป่อง", "ปลวก", "เหา", "เห็บ", "หมัด","พยาธิ", "ไส้เดือน", "ทาก", "หอยทาก", "แมลงปอ", "ตั๊กแตน", "จิ้งหรีด", "จักจั่น", "ด้วง", "ต่อ", "แตน", "แมลงวัน", "หิ่งห้อย", "แมงมุม", "วาฬ", "โลมา", "แมวน้ำ", "สิงโตทะเล", "วอลรัส", "นาก", "บีเวอร์", "ตุ่น", "เม่น", "สลอธ", "โคอาล่า", "จิงโจ้","อัลปาก้า", "ลา", # 🥦 ผักผลไม้และอาหารเพิ่มเติม (More Food) "ทุเรียน", "มังคุด", "ลำไย", "ลิ้นจี่", "ขนุน","พุทรา", "มะขาม", "มะยม","เสาวรส", "แก้วมังกร","เชอร์รี่", "บลูเบอร์รี่", "อะโวคาโด", "ลูกพีช", "ลูกพลับ", "สาลี่", "ลูกเกด", "ถั่ว", "งา", "พริกไทย", "ขิง", "ข่า", "ตะไคร้", "ใบมะกรูด", "โหระพา", "กะเพรา", "สะระแหน่", "ผักชี", "ต้นหอม", "ขึ้นฉ่าย", "ผักกาด", "คะน้า", "กวางตุ้ง", "บุ้ง", "กระหล่ำปลี", "บล็อกโคลี่", "เห็ด", "หน่อไม้", "ยอดมะพร้าว", "เผือก", "มัน", "ก๋วยจั๊บ", "ราดหน้า", "ผัดซีอิ๊ว", "ผัดไทย", "หอยทอด", "ข้าวมันไก่", "ข้าวขาหมู", "ข้าวหมูแดง", "แกงเขียวหวาน", "แกงส้ม", "ต้มยำกุ้ง", "ต้มข่าไก่", "ไข่พะโล้", "น้ำพริก", "ปลาทู", "ไข่ดาว", "ไข่ตุ๋น", "ไส้กรอก", "แฮม", "เบคอน", "ชีส", "เนย", "นมข้น", "น้ำเชื่อม", "น้ำผึ้ง", "ซอส", "น้ำส้มสายชู", "ผงชูรส", "ทองหยิบ", "ทองหยอด", "ฝอยทอง", "เม็ดขนุน", "สังขยา", "วุ้น", "เฉาก๊วย", "ลอดช่อง", # 👔 เสื้อผ้าและเครื่องแต่งกาย (Clothing) "เสื้อยืด", "เสื้อเชิ้ต", "เสื้อกล้าม", "เสื้อกันหนาว", "เสื้อกันฝน", "ชุดนักเรียน", "ชุดนอน","ผ้าขาวม้า", "เข็มขัด", "เนคไท", "โบว์", "กิ๊บ", "ยางรัดผม", "ที่คาดผม", "หมวกแก๊ป", "หมวกกันน็อค", "ผ้าพันคอ", "ถุงมือ", "ถุงเท้า", "รองเท้าแตะ", "รองเท้าผ้าใบ", "รองเท้าหนัง", "รองเท้าส้นสูง", "สร้อยคอ", "สร้อยข้อมือ", "กำไล", "ต่างหู", "แหวน", "นาฬิกาข้อมือ", "แว่นกันแดด", "ร่ม", "กระเป๋าเป้","พวงกุญแจ", # 🏥 สุขภาพและร่างกาย (Health & Body) "สมอง", "หัวใจ", "ปอด", "กระเพาะ", "ลำไส้", "ตับ", "ไต", "เลือด", "น้ำลาย", "ขี้หู", "ขี้ตา", "เล็บมือ", "เล็บเท้า", "ข้อศอก", "หัวไหล่", "หน้าอก", "เอว", "สะโพก","ผิวหนัง", "ขน", "หนวด", "เครา", "ลักยิ้ม", "ปาน", "แผล", "ไข้", "ไอ", "จาม", "หวัด", "ปวดหัว", "ปวดท้อง","ยา", "ยาน้ำ", "ยาฉีด", "เข็มฉีดยา", "ผ้าพันแผล", "รถเข็น", "ไม้เท้า", # 🌪️ ธรรมชาติและภัยพิบัติ (Nature) "แผ่นดินไหว", "น้ำท่วม", "ไฟไหม้", "พายุ", "สึนามิ", "ภูเขาไฟระเบิด", "โรคระบาด", "อากาศ", "ออกซิเจน", "คาร์บอน", "ฝุ่น", "ควัน", "หมอก", "น้ำค้าง", "ลูกเห็บ", "รุ้งกินน้ำ", "ดาวตก", "สุริยุปราคา", "จันทรุปราคา", "ข้างขึ้น", "ข้างแรม", "น้ำขึ้น", "น้ำลง", "บ่อน้ำ", "หนองน้ำ", "บึง", "คลอง", "เขื่อน", "ถ้ำ", "หน้าผา", "หุบเขา", "ทะเลทราย", "ขั้วโลก", "ป่าชายเลน", "ป่าดงดิบ", # 👨‍👩‍👧‍👦 อาชีพและบทบาท (More Careers) "ประธานาธิบดี", "นายก", "ผู้ว่า", "กำนัน", "ผู้ใหญ่บ้าน", "นักการเมือง", "นักธุรกิจ", "พนักงาน", "เลขา", "เจ้านาย", "ลูกน้อง", "แม่บ้าน", "คนสวน", "คนขับรถ", "วินมอไซค์", "กระเป๋ารถเมล์", "แอร์โฮสเตส", "กัปตัน", "นักบินอวกาศ", "นักวิทยาศาสตร์", "นักสืบ", "ทนาย", "อัยการ", "ผู้พิพากษา", "ช่างไฟ", "ช่างประปา", "ช่างไม้", "ช่างปูน", "ช่างแอร์", "ช่างคอม", "ช่างภาพ", "นักข่าว", "นักเขียน", "บรรณาธิการ", "ผู้กำกับ", "ดารา", "นายแบบ", "นางแบบ", "นักกีฬา","กรรมการ", "เชียร์ลีดเดอร์", "ชาวประมง", "ชาวสวน", "ชาวไร่", "หมอดู", "พระสงฆ์", "แม่ชี", "สามเณร", "บาทหลวง" ] # --- SETUP --- log = logging.getLogger('werkzeug') log.setLevel(logging.ERROR) app = Flask(__name__) vocabulary = [] vocab_vectors = None active_servers = {} def initialize_system(): global vocabulary, vocab_vectors print("------------------------------------------------") print(f"🚀 System Initializing... (FastText TH Mode)") if os.path.exists(VECTOR_FILE): print(f"💾 Found {VECTOR_FILE}! Loading pre-computed data...") try: # โหลดไฟล์เข้า CPU data = torch.load(VECTOR_FILE, map_location=torch.device('cpu'), weights_only=False) vocabulary = data['vocabulary'] # แปลงเป็น FloatTensor และ Normalize เพื่อความเร็วแสง vocab_vectors = data['vectors'].float() vocab_vectors = F.normalize(vocab_vectors, p=2, dim=1) print(f"✅ Loaded {len(vocabulary)} words and vectors instantly!") except Exception as e: print(f"❌ Error loading file: {e}") raise e else: print(f"⚠️ {VECTOR_FILE} NOT FOUND! Please upload the file.") return threading.Thread(target=garbage_collector, daemon=True).start() print("✅ SERVER READY! (Startup time: Ultra Fast!)") print("------------------------------------------------") def garbage_collector(): while True: time.sleep(CLEANUP_INTERVAL) try: now = time.time() to_delete = [sid for sid, data in active_servers.items() if now - data['last_active'] > MAX_IDLE_TIME] for sid in to_delete: del active_servers[sid] if to_delete: print(f"🧹 Cleaned up {len(to_delete)} inactive servers.", flush=True) except Exception as e: print(f"Error in cleanup: {e}", flush=True) initialize_system() @app.get("/") def home(): return f"Contexto Thai (FastText) Server Running! Dict Size: {len(vocabulary)}" @app.route('/new_game', methods=['POST']) def start_new_game(): try: data = request.json server_id = data.get('server_id') if not server_id: return jsonify({"error": "No server_id"}), 400 if not KIDS_WORDS: return jsonify({"error": "KIDS_WORDS is empty in server script"}), 500 secret_word = random.choice(KIDS_WORDS) try: secret_index = vocabulary.index(secret_word) except ValueError: print(f"⚠️ คำลับ '{secret_word}' ไม่มีในดิกชันนารี (สุ่มใหม่)", flush=True) secret_word = "หมา" # Fallback กันเหนียว secret_index = vocabulary.index(secret_word) secret_vec = vocab_vectors[secret_index].unsqueeze(0) # คำนวณ Cosine Similarity ด้วย PyTorch ตรงๆ (เร็วปรี๊ดดด) scores = F.cosine_similarity(secret_vec, vocab_vectors) scores_list = scores.tolist() pairs = [] for i in range(len(vocabulary)): pairs.append((vocabulary[i], scores_list[i])) pairs.sort(key=lambda x: x[1], reverse=True) # ตัดคำลับ (ตัวเอง) ทิ้ง แล้วค่อยเรียงลิสต์ sorted_words = [p[0] for p in pairs if p[0] != secret_word] # ยัดคำลับกลับไปที่อันดับ 0 (Rank 1) เสมอ sorted_words.insert(0, secret_word) active_servers[server_id] = { "words": sorted_words, "last_active": time.time() } print(f"🔥 GAME START: Server [{server_id}] | Secret: {secret_word}", flush=True) return jsonify({"message": "OK", "server_id": server_id}) except Exception as e: print(f"❌ ERROR: {e}", flush=True) return jsonify({"error": str(e)}), 500 @app.route('/guess', methods=['POST']) def guess_word(): try: data = request.json server_id = data.get('server_id') guess = data.get('word', '').strip() if server_id not in active_servers: return jsonify({"error": "Server not found"}), 404 active_servers[server_id]['last_active'] = time.time() ranked_list = active_servers[server_id]['words'] if guess == ranked_list[0]: return jsonify({"rank": 1, "word": guess}) try: rank = ranked_list.index(guess) + 1 return jsonify({"rank": rank, "word": guess}) except ValueError: return jsonify({"rank": 99999, "word": guess}) except Exception as e: return jsonify({"error": str(e)}), 500 @app.route('/hint', methods=['POST']) def get_hint(): try: data = request.json server_id = data.get('server_id') current_rank = data.get('current_rank') if not server_id or server_id not in active_servers: return jsonify({"error": "Game not found"}), 404 if current_rank is None: return jsonify({"error": "current_rank is required"}), 400 current_rank = int(current_rank) hint_rank = current_rank // 2 if hint_rank < 1: hint_rank = 1 word_list = active_servers[server_id]['words'] if hint_rank > len(word_list): hint_rank = len(word_list) hint_word = word_list[hint_rank - 1] return jsonify({"rank": hint_rank, "word": hint_word}) except Exception as e: return jsonify({"error": str(e)}), 500 @app.route('/answer', methods=['POST']) def get_answer(): try: data = request.json server_id = data.get('server_id') if server_id not in active_servers: return jsonify({"error": "Game not found"}), 404 answer = active_servers[server_id]['words'][0] return jsonify({"answer": answer}) except Exception as e: return jsonify({"error": str(e)}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=7860)