Beltbot / webapi /settings.py
SupantBT's picture
plugin core + monitor (main 443d2aa)
ede84b4 verified
Raw History Blame Contribute Delete
3.74 kB
"""
webapi/settings.py — ค่าตั้งทั้งหมดของ backend อ่านจาก environment (HF Space → Settings → Variables/Secrets)
ไม่มีค่าไหนผูกกับแบรนด์ — แบรนด์และโมเดลรูปอยู่ใน image_models.yaml
"""
from __future__ import annotations
import os
from dataclasses import dataclass, field
def _int(name: str, default: int) -> int:
try:
return int(os.environ.get(name, default))
except ValueError:
return default
def _list(name: str, default: str) -> list[str]:
return [x.strip() for x in os.environ.get(name, default).split(",") if x.strip()]
@dataclass
class Settings:
# ── บอท ──
bot_module: str = field(default_factory=lambda: os.environ.get("BOT_MODULE", "assistant"))
warm_on_start: bool = field(default_factory=lambda: os.environ.get("WARM_ON_START", "1") == "1")
# ── ความปลอดภัย ──
# ตั้ง PROXY_SECRET ให้ตรงกับฝั่ง Vercel → Space รับเฉพาะคำขอที่ผ่าน Vercel
# และเชื่อ X-Client-IP ที่ Vercel ส่งมา (ไม่ตั้ง = ใช้ X-Forwarded-For ของ HF และไม่เชื่อ X-Client-IP)
proxy_secret: str = field(default_factory=lambda: os.environ.get("PROXY_SECRET", ""))
allowed_origins: list[str] = field(default_factory=lambda: _list("ALLOWED_ORIGINS", ""))
# ── rate limit ต่อ IP ──
rl_per_minute: int = field(default_factory=lambda: _int("RL_PER_MINUTE", 8))
rl_per_hour: int = field(default_factory=lambda: _int("RL_PER_HOUR", 60))
rl_images_per_hour: int = field(default_factory=lambda: _int("RL_IMAGES_PER_HOUR", 15))
# เพดานรวมทั้งระบบต่อวัน (กันโควตา Gemini หมด) 0 = ไม่จำกัด
global_per_day: int = field(default_factory=lambda: _int("GLOBAL_PER_DAY", 1500))
# จำนวนเทิร์นที่ประมวลผลพร้อมกัน (CPU ฟรีของ HF มี 2 คอร์)
max_concurrent: int = field(default_factory=lambda: _int("MAX_CONCURRENT", 2))
queue_wait_s: int = field(default_factory=lambda: _int("QUEUE_WAIT_S", 20))
# ── ข้อความ / รูป ──
max_text_chars: int = field(default_factory=lambda: _int("MAX_TEXT_CHARS", 1000))
max_image_bytes: int = field(default_factory=lambda: _int("MAX_IMAGE_BYTES", 5 * 1024 * 1024))
max_image_pixels: int = field(default_factory=lambda: _int("MAX_IMAGE_PIXELS", 40_000_000))
image_max_side: int = field(default_factory=lambda: _int("IMAGE_MAX_SIDE", 1600))
# ── session ──
session_ttl_s: int = field(default_factory=lambda: _int("SESSION_TTL_S", 2 * 3600))
max_sessions: int = field(default_factory=lambda: _int("MAX_SESSIONS", 3000))
max_turns: int = field(default_factory=lambda: _int("MAX_TURNS", 40))
# ── รูปที่บอทส่งกลับ (drawing ของ Movex) — เสิร์ฟได้เฉพาะไฟล์ใต้โฟลเดอร์เหล่านี้ ──
media_roots: list[str] = field(default_factory=lambda: _list("MEDIA_ROOTS", "image,images"))
# แทนรหัสภายใน movex_chain_… ในคำตอบด้วยรหัสที่ลูกค้าอ่านได้ (GRAPH-001) — ชั้นแสดงผลเท่านั้น
scrub_internal_ids: bool = field(default_factory=lambda: os.environ.get("SCRUB_INTERNAL_IDS", "1") == "1")
settings = Settings()