diff --git a/backend/app/api/auth.py b/backend/app/api/auth.py index 27bce42..1eebb36 100644 --- a/backend/app/api/auth.py +++ b/backend/app/api/auth.py @@ -39,6 +39,8 @@ class UserCreate(BaseModel): username: str email: str password: str + agreed_terms: bool = False + agreed_terms_version: str | None = None @field_validator("email") @classmethod @@ -47,6 +49,13 @@ class UserCreate(BaseModel): raise ValueError("邮箱格式无效") return v.lower() + @field_validator("agreed_terms") + @classmethod + def must_agree_terms(cls, v: bool) -> bool: + if not v: + raise ValueError("必须同意用户协议和隐私政策") + return v + class UserResponse(BaseModel): """用户响应模型""" @@ -54,6 +63,7 @@ class UserResponse(BaseModel): username: str email: str role: str + phone: str | None = None class Config: from_attributes = True @@ -65,6 +75,9 @@ class MeResponse(BaseModel): username: str email: str role: str + phone: str | None = None + status: str = "active" + is_email_verified: bool = False workspaces: list = [] current_workspace_id: str | None = None @@ -91,7 +104,10 @@ async def register(user_data: UserCreate, db: Session = Depends(get_db)): user = User( username=user_data.username, email=user_data.email, - password_hash=hashed_password + password_hash=hashed_password, + agreed_terms=user_data.agreed_terms, + agreed_terms_version=user_data.agreed_terms_version, + agreed_terms_at=datetime.utcnow() if user_data.agreed_terms else None, ) db.add(user) db.commit() @@ -180,6 +196,8 @@ async def get_current_user( user = db.query(User).filter(User.id == user_id).first() if user is None: raise NotFoundError("用户", user_id) + if user.status == "deleted": + raise UnauthorizedError("账号已注销") return user @@ -213,6 +231,9 @@ async def get_me( "username": user.username, "email": user.email, "role": user.role, + "phone": user.phone, + "status": user.status or "active", + "is_email_verified": user.is_email_verified or False, "workspaces": workspaces, "current_workspace_id": current_ws_id if current_ws_id else None, } @@ -423,6 +444,99 @@ async def reset_password(body: ResetPasswordRequest, db: Session = Depends(get_d return {"message": "密码重置成功,请使用新密码登录"} +# ─── 修改密码 ─────────────────────────────────────────────── + +class ChangePasswordRequest(BaseModel): + old_password: str + new_password: str + + @field_validator("new_password") + @classmethod + def password_length(cls, v: str) -> str: + if len(v) < 6: + raise ValueError("密码不少于6个字符") + if len(v) > 32: + raise ValueError("密码不超过32个字符") + return v + + +@router.put("/change-password") +async def change_password( + body: ChangePasswordRequest, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db), +): + """修改密码(需提供旧密码验证)。""" + if not verify_password(body.old_password, current_user.password_hash): + raise HTTPException(status_code=400, detail="旧密码错误") + + current_user.password_hash = get_password_hash(body.new_password) + db.commit() + + logger.info("用户 %s 修改密码成功", current_user.username) + return {"message": "密码修改成功"} + + +# ─── 账号注销 ─────────────────────────────────────────────── + +class DeleteAccountRequest(BaseModel): + password: str + + +@router.delete("/account") +async def delete_account( + body: DeleteAccountRequest, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db), +): + """注销账号(需提供密码确认)。软删除:设置 status='deleted'。""" + if not verify_password(body.password, current_user.password_hash): + raise HTTPException(status_code=400, detail="密码错误") + + # 软删除用户 + current_user.status = "deleted" + current_user.email = f"deleted_{current_user.id}@deleted.local" + current_user.phone = None + current_user.feishu_open_id = None + db.commit() + + logger.info("用户 %s 账号已注销", current_user.username) + return {"message": "账号已注销"} + + +# ─── 绑定手机号 ────────────────────────────────────────────── + +class BindPhoneRequest(BaseModel): + phone: str + code: str | None = None # 验证码(对接短信服务后可启用) + + @field_validator("phone") + @classmethod + def phone_format(cls, v: str) -> str: + if not re.match(r"^1[3-9]\d{9}$", v): + raise ValueError("手机号格式无效") + return v + + +@router.put("/phone") +async def bind_phone( + body: BindPhoneRequest, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db), +): + """绑定或修改手机号。""" + # 检查手机号是否已被其他用户绑定 + existing = db.query(User).filter(User.phone == body.phone, User.id != current_user.id).first() + if existing: + raise ConflictError("该手机号已被其他用户绑定") + + current_user.phone = body.phone + db.commit() + + logger.info("用户 %s 绑定手机号成功", current_user.username) + return {"message": "手机号绑定成功", "phone": body.phone} + + async def get_optional_user( token: str | None = Depends(oauth2_scheme_optional), db: Session = Depends(get_db) diff --git a/backend/app/api/legal.py b/backend/app/api/legal.py new file mode 100644 index 0000000..5e22e50 --- /dev/null +++ b/backend/app/api/legal.py @@ -0,0 +1,161 @@ +""" +用户协议 & 隐私政策 API +""" +from fastapi import APIRouter, Depends +from pydantic import BaseModel +from sqlalchemy.orm import Session +from datetime import datetime + +from app.core.database import get_db +from app.core.exceptions import ConflictError +from app.api.auth import get_current_user +from app.models.user import User + +router = APIRouter( + prefix="/api/v1/legal", + tags=["legal"], +) + +# ─── 协议版本 ─────────────────────────────────────────────── + +CURRENT_TERMS_VERSION = "1.0" +CURRENT_PRIVACY_VERSION = "1.0" + +# ─── 内容 ─────────────────────────────────────────────────── + +PRIVACY_POLICY = """# 天工智能体平台 隐私政策 + +**更新日期:2026年7月1日** +**生效日期:2026年7月1日** + +## 一、信息收集 + +1. 您在注册账户时提供的个人信息,包括用户名、邮箱地址和手机号码。 +2. 您在使用智能体对话功能时产生的对话内容和交互记录。 +3. 设备信息:我们可能收集您的设备型号、操作系统版本、设备标识符等信息用于优化服务。 + +## 二、信息使用 + +1. 为您提供智能体对话、语音识别、推送通知等核心服务。 +2. 改善产品质量和用户体验,包括对话模型的训练和优化。 +3. 提供客户支持和故障排除。 + +## 三、信息存储和保护 + +1. 您的数据存储在中国境内的服务器上。 +2. 我们采用加密传输、访问控制、数据备份等安全措施保护您的信息。 +3. 对话数据在您主动删除或账号注销后将在30天内清除。 + +## 四、信息共享 + +1. 未经您的明确同意,我们不会将您的个人信息共享给第三方。 +2. 法律法规要求披露的除外。 + +## 五、您的权利 + +1. 您可以随时查看、修改您的个人信息。 +2. 您可以导出您的对话数据。 +3. 您可以注销账号并要求删除数据。 + +## 六、联系我们 + +如有隐私相关问题,请联系:support@tiangong.ai +""" + +USER_AGREEMENT = """# 天工智能体平台 用户协议 + +**更新日期:2026年7月1日** +**生效日期:2026年7月1日** + +## 一、总则 + +1. 天工智能体平台(以下简称"本平台")是一个提供AI智能体服务的在线平台。 +2. 您注册和使用本平台即表示您已阅读、理解并同意本协议的全部条款。 + +## 二、账号管理 + +1. 您应当提供真实、准确的注册信息。 +2. 您对账号下的所有活动负责,请妥善保管账号和密码。 +3. 您不得将账号转让、出借或出售给他人。 + +## 三、使用规范 + +1. 您不得利用本平台从事违法活动,包括但不限于: + - 生成、传播违法或有害内容 + - 侵犯他人知识产权或隐私权 + - 干扰或破坏平台正常运行 +2. 您不得对智能体进行恶意引导、注入攻击或其他危害系统安全的行为。 + +## 四、知识产权 + +1. 平台本身的软件、界面设计、商标等知识产权归平台所有。 +2. 您创建的智能体配置归您所有。 +3. 您与智能体对话产生的内容归您所有。 + +## 五、免责声明 + +1. AI生成内容仅供参考,不构成专业建议。 +2. 平台不对AI生成内容的准确性、完整性负责。 +3. 因不可抗力或第三方原因导致的服务中断,平台不承担责任。 + +## 六、协议变更 + +1. 我们可能会不时更新本协议,更新后会通过应用内通知告知。 +2. 如果您不同意更新后的条款,您可以停止使用本平台并注销账号。 + +## 七、法律适用与争议解决 + +1. 本协议适用中华人民共和国法律。 +2. 因本协议产生的争议,双方应协商解决;协商不成的,提交平台所在地法院管辖。 +""" + + +# ─── Response/Request Models ────────────────────────────────── + +class LegalContentResponse(BaseModel): + content: str + version: str + + +class AgreeRequest(BaseModel): + terms_version: str | None = None + privacy_version: str | None = None + + +class AgreeResponse(BaseModel): + message: str + agreed_terms: bool + agreed_terms_version: str + + +# ─── Endpoints ──────────────────────────────────────────────── + +@router.get("/privacy", response_model=LegalContentResponse) +async def get_privacy_policy(): + """获取隐私政策内容。""" + return LegalContentResponse(content=PRIVACY_POLICY, version=CURRENT_PRIVACY_VERSION) + + +@router.get("/terms", response_model=LegalContentResponse) +async def get_user_agreement(): + """获取用户协议内容。""" + return LegalContentResponse(content=USER_AGREEMENT, version=CURRENT_TERMS_VERSION) + + +@router.post("/agree", response_model=AgreeResponse) +async def agree_terms( + body: AgreeRequest, + current_user: User = Depends(get_current_user), + db: Session = Depends(get_db), +): + """记录用户同意协议。""" + current_user.agreed_terms = True + current_user.agreed_terms_version = body.terms_version or CURRENT_TERMS_VERSION + current_user.agreed_terms_at = datetime.utcnow() + db.commit() + + return AgreeResponse( + message="协议同意已记录", + agreed_terms=True, + agreed_terms_version=current_user.agreed_terms_version, + ) diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 806b835..ed6397e 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -110,6 +110,10 @@ class Settings(BaseSettings): FEISHU_APP_SECRET: str = "" FEISHU_VERIFICATION_TOKEN: str = "" + # 平台管理员凭据(所有 bootstrap 脚本从环境变量读取,不再硬编码默认值) + PLATFORM_USERNAME: str = "" + PLATFORM_PASSWORD: str = "" + # 安全加固 — HSTS(生产环境建议启用,开发环境保持关闭) HSTS_ENABLED: bool = False HSTS_MAX_AGE: int = 31536000 # 默认 1 年 diff --git a/backend/app/main.py b/backend/app/main.py index 4a09eb0..22e2c38 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -510,7 +510,7 @@ async def startup_event(): logger.error(f"定时任务调度器启动失败: {e}") # 注册路由 -from app.api import auth, workspaces, uploads, workflows, executions, websocket, execution_logs, data_sources, agents, platform_templates, model_configs, webhooks, template_market, batch_operations, collaboration, permissions, monitoring, alert_rules, node_test, node_templates, tools, agent_chat, agent_branches, agent_monitoring, knowledge_base, knowledge_dashboard, agent_schedules, notifications, feishu_bind, approval, orchestration_templates, plugins, agent_market, goals, tasks, system_logs, audit_logs, feedback, agent_swarm, push, voice, fcm, scene_contracts, teams, agent_memory +from app.api import auth, workspaces, uploads, workflows, executions, websocket, execution_logs, data_sources, agents, platform_templates, model_configs, webhooks, template_market, batch_operations, collaboration, permissions, monitoring, alert_rules, node_test, node_templates, tools, agent_chat, agent_branches, agent_monitoring, knowledge_base, knowledge_dashboard, agent_schedules, notifications, feishu_bind, approval, orchestration_templates, plugins, agent_market, goals, tasks, system_logs, audit_logs, feedback, agent_swarm, push, voice, fcm, scene_contracts, teams, agent_memory, legal app.include_router(auth.router) app.include_router(workspaces.router) @@ -557,6 +557,7 @@ app.include_router(knowledge_dashboard.router) app.include_router(scene_contracts.router) app.include_router(teams.router) app.include_router(agent_memory.router) +app.include_router(legal.router) if __name__ == "__main__": import uvicorn diff --git a/backend/app/models/user.py b/backend/app/models/user.py index 269e072..769e30b 100644 --- a/backend/app/models/user.py +++ b/backend/app/models/user.py @@ -1,7 +1,7 @@ """ 用户模型 """ -from sqlalchemy import Column, String, DateTime, func +from sqlalchemy import Boolean, Column, String, DateTime, func from sqlalchemy.dialects.mysql import CHAR from sqlalchemy.orm import relationship from app.core.database import Base @@ -19,6 +19,12 @@ class User(Base): role = Column(String(20), default="user", comment="角色: admin/user(保留字段,用于向后兼容)") feishu_open_id = Column(String(64), nullable=True, comment="飞书用户 open_id,用于推送通知") feishu_default_agent_id = Column(CHAR(36), nullable=True, comment="飞书对话默认 Agent ID") + phone = Column(String(20), nullable=True, comment="手机号") + status = Column(String(20), default="active", comment="账号状态: active/disabled/deleted") + is_email_verified = Column(Boolean, default=False, comment="邮箱是否已验证") + agreed_terms = Column(Boolean, default=False, comment="是否同意用户协议") + agreed_terms_version = Column(String(20), nullable=True, comment="同意的协议版本") + agreed_terms_at = Column(DateTime, nullable=True, comment="同意协议的时间") created_at = Column(DateTime, default=func.now(), comment="创建时间") updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), comment="更新时间") diff --git a/backend/scripts/bootstrap_scene_templates.py b/backend/scripts/bootstrap_scene_templates.py index 2e9380f..c7ccbfd 100644 --- a/backend/scripts/bootstrap_scene_templates.py +++ b/backend/scripts/bootstrap_scene_templates.py @@ -22,8 +22,8 @@ from typing import Any, Dict, List, Optional, Tuple import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") TEMPLATES: List[Tuple[str, str, str]] = [ ("模板-客服标准", "知你客服14号", "场景模板:标准客服 + 全量工具基线"), diff --git a/backend/scripts/compare_homework_agents.py b/backend/scripts/compare_homework_agents.py index 40bddf4..cf53666 100644 --- a/backend/scripts/compare_homework_agents.py +++ b/backend/scripts/compare_homework_agents.py @@ -16,8 +16,8 @@ from typing import Any, Dict, List, Optional import requests BACKEND = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") NAMES = ["学生作业管理助手", "学生作业管理助手2号"] diff --git a/backend/scripts/create_ai_learning_assistant.py b/backend/scripts/create_ai_learning_assistant.py index 851fe19..91afd3b 100644 --- a/backend/scripts/create_ai_learning_assistant.py +++ b/backend/scripts/create_ai_learning_assistant.py @@ -25,8 +25,8 @@ from typing import Any, Dict, Optional import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") AGENT_NAME = os.getenv("AGENT_NAME", "AI学习助手") MODEL = os.getenv("MODEL", "deepseek-v4-flash") PROVIDER = os.getenv("PROVIDER", "deepseek") diff --git a/backend/scripts/create_complex_enterprise_agent.py b/backend/scripts/create_complex_enterprise_agent.py index b4114b9..dc0b2d0 100644 --- a/backend/scripts/create_complex_enterprise_agent.py +++ b/backend/scripts/create_complex_enterprise_agent.py @@ -159,8 +159,8 @@ def _via_requests() -> int: import requests base = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") - user = os.getenv("PLATFORM_USERNAME", "admin") - pwd = os.getenv("PLATFORM_PASSWORD", "123456") + user = os.getenv("PLATFORM_USERNAME") + pwd = os.getenv("PLATFORM_PASSWORD") wf = build_complex_workflow() _validate_local(wf) @@ -250,8 +250,8 @@ def _via_testclient() -> int: lr = c.post( "/api/v1/auth/login", data={ - "username": os.getenv("PLATFORM_USERNAME", "admin"), - "password": os.getenv("PLATFORM_PASSWORD", "123456"), + "username": os.getenv("PLATFORM_USERNAME"), + "password": os.getenv("PLATFORM_PASSWORD"), }, headers={"Content-Type": "application/x-www-form-urlencoded"}, ) diff --git a/backend/scripts/create_education_agents_batch.py b/backend/scripts/create_education_agents_batch.py index 166e32b..0374e84 100644 --- a/backend/scripts/create_education_agents_batch.py +++ b/backend/scripts/create_education_agents_batch.py @@ -31,8 +31,8 @@ if BACKEND_DIR not in sys.path: sys.path.insert(0, BACKEND_DIR) BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") PROVIDER = os.getenv( "EDU_LLM_PROVIDER", diff --git a/backend/scripts/create_enterprise_scenario_agents.py b/backend/scripts/create_enterprise_scenario_agents.py index 2a60a3f..37b5269 100644 --- a/backend/scripts/create_enterprise_scenario_agents.py +++ b/backend/scripts/create_enterprise_scenario_agents.py @@ -506,8 +506,8 @@ def main(argv: Optional[List[str]] = None) -> int: lr = c.post( "/api/v1/auth/login", data={ - "username": os.getenv("PLATFORM_USERNAME", "admin"), - "password": os.getenv("PLATFORM_PASSWORD", "123456"), + "username": os.getenv("PLATFORM_USERNAME"), + "password": os.getenv("PLATFORM_PASSWORD"), }, headers={"Content-Type": "application/x-www-form-urlencoded"}, ) @@ -534,8 +534,8 @@ def main(argv: Optional[List[str]] = None) -> int: lr = requests.post( f"{base}/api/v1/auth/login", data={ - "username": os.getenv("PLATFORM_USERNAME", "admin"), - "password": os.getenv("PLATFORM_PASSWORD", "123456"), + "username": os.getenv("PLATFORM_USERNAME"), + "password": os.getenv("PLATFORM_PASSWORD"), }, headers={"Content-Type": "application/x-www-form-urlencoded"}, timeout=20, diff --git a/backend/scripts/create_gov_media_agents_batch.py b/backend/scripts/create_gov_media_agents_batch.py index ef5d004..3a492c7 100644 --- a/backend/scripts/create_gov_media_agents_batch.py +++ b/backend/scripts/create_gov_media_agents_batch.py @@ -30,8 +30,8 @@ if BACKEND_DIR not in sys.path: sys.path.insert(0, BACKEND_DIR) BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") PROVIDER = os.getenv( "CROSS_LLM_PROVIDER", diff --git a/backend/scripts/create_homework_manager_agent.py b/backend/scripts/create_homework_manager_agent.py index 08c2f70..68728d6 100644 --- a/backend/scripts/create_homework_manager_agent.py +++ b/backend/scripts/create_homework_manager_agent.py @@ -34,8 +34,8 @@ if BACKEND_DIR not in sys.path: sys.path.insert(0, BACKEND_DIR) BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") AGENT_NAME = os.getenv("AGENT_NAME", "学生作业管理助手") FAST_PROFILE = "2号" in AGENT_NAME or os.getenv("HOMEWORK_FAST_AGENT", "").strip().lower() in ( "1", diff --git a/backend/scripts/create_intelligent_tutor_agent.py b/backend/scripts/create_intelligent_tutor_agent.py index bd1eef0..91ea18d 100644 --- a/backend/scripts/create_intelligent_tutor_agent.py +++ b/backend/scripts/create_intelligent_tutor_agent.py @@ -24,8 +24,8 @@ if BACKEND_DIR not in sys.path: sys.path.insert(0, BACKEND_DIR) BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") AGENT_NAME = os.getenv("AGENT_NAME", "智能助教") PROVIDER = os.getenv("TUTOR_LLM_PROVIDER", os.getenv("ENTERPRISE_LLM_PROVIDER", "deepseek")) diff --git a/backend/scripts/create_learning_assistant_agent.py b/backend/scripts/create_learning_assistant_agent.py index fbe31a0..4c9e136 100644 --- a/backend/scripts/create_learning_assistant_agent.py +++ b/backend/scripts/create_learning_assistant_agent.py @@ -29,8 +29,8 @@ from typing import Any, Dict, List, Optional import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") AGENT_NAME = os.getenv("AGENT_NAME", "智能学习助手(KG+RAG)") SUBJECT = os.getenv("SUBJECT", "通用") LEVEL = os.getenv("LEVEL", "中级") diff --git a/backend/scripts/create_learning_assistant_agent_v1.py b/backend/scripts/create_learning_assistant_agent_v1.py index 4ccf948..4aa965d 100644 --- a/backend/scripts/create_learning_assistant_agent_v1.py +++ b/backend/scripts/create_learning_assistant_agent_v1.py @@ -33,8 +33,8 @@ from typing import Any, Dict, Optional import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") AGENT_NAME = os.getenv("AGENT_NAME", "智能学习助手1号") SUBJECT = os.getenv("SUBJECT", "通用") LEVEL = os.getenv("LEVEL", "中级") diff --git a/backend/scripts/create_main_agent.py b/backend/scripts/create_main_agent.py index 6c17f5e..b6a5575 100644 --- a/backend/scripts/create_main_agent.py +++ b/backend/scripts/create_main_agent.py @@ -23,8 +23,8 @@ from typing import Any, Dict, Optional import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") SOURCE_NAME = os.getenv("SOURCE_AGENT_NAME", "知你客服14号") TARGET_NAME = os.getenv("TARGET_NAME", "主控台Main Agent") diff --git a/backend/scripts/create_router_invoke_demo_agent.py b/backend/scripts/create_router_invoke_demo_agent.py index 4a89720..bbec0ff 100644 --- a/backend/scripts/create_router_invoke_demo_agent.py +++ b/backend/scripts/create_router_invoke_demo_agent.py @@ -29,8 +29,8 @@ from typing import Any, Dict, List, Optional import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") CHILD_AGENT_NAME = os.getenv("CHILD_AGENT_NAME", "知你客服16号") DEMO_AGENT_NAME = os.getenv("DEMO_AGENT_NAME", "演示-主链路委派invoke") diff --git a/backend/scripts/create_zhini_kefu_10.py b/backend/scripts/create_zhini_kefu_10.py index 4ff338a..dd9564a 100644 --- a/backend/scripts/create_zhini_kefu_10.py +++ b/backend/scripts/create_zhini_kefu_10.py @@ -20,8 +20,8 @@ import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") SOURCE_AGENT_ID = os.getenv("ZHINI_9_AGENT_ID", "de5932d6-3c05-4b27-ab08-f6cb403ce4b9") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") NEW_NAME = "知你客服10号" NEW_DESC = ( diff --git a/backend/scripts/create_zhini_kefu_11.py b/backend/scripts/create_zhini_kefu_11.py index 034032b..91531e7 100644 --- a/backend/scripts/create_zhini_kefu_11.py +++ b/backend/scripts/create_zhini_kefu_11.py @@ -16,8 +16,8 @@ import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") SOURCE_AGENT_ID = os.getenv("ZHINI_10_AGENT_ID", "c853482b-d298-44e4-9862-c84318f71abb") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") NEW_NAME = "知你客服11号" NEW_DESC = ( diff --git a/backend/scripts/create_zhini_kefu_12.py b/backend/scripts/create_zhini_kefu_12.py index 6b98f05..3f467f3 100644 --- a/backend/scripts/create_zhini_kefu_12.py +++ b/backend/scripts/create_zhini_kefu_12.py @@ -16,8 +16,8 @@ import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") SOURCE_AGENT_ID = os.getenv("ZHINI_11_AGENT_ID", "d39748ad-277f-48ac-9eb5-168ad2f1b470") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") NEW_NAME = "知你客服12号" NEW_DESC = ( diff --git a/backend/scripts/create_zhini_kefu_13.py b/backend/scripts/create_zhini_kefu_13.py index 1dce4ff..7724116 100644 --- a/backend/scripts/create_zhini_kefu_13.py +++ b/backend/scripts/create_zhini_kefu_13.py @@ -27,8 +27,8 @@ from typing import Any, Dict, List, Optional, Tuple import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") SOURCE_NAME = os.getenv("SOURCE_AGENT_NAME", "知你客服12号") TARGET_NAME = os.getenv("TARGET_NAME", "知你客服13号") diff --git a/backend/scripts/create_zhini_kefu_14.py b/backend/scripts/create_zhini_kefu_14.py index 9a4f408..6d1d1c8 100644 --- a/backend/scripts/create_zhini_kefu_14.py +++ b/backend/scripts/create_zhini_kefu_14.py @@ -27,8 +27,8 @@ from typing import Any, Dict, List, Optional, Tuple import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") SOURCE_NAME = os.getenv("SOURCE_AGENT_NAME", "知你客服13号") TARGET_NAME = os.getenv("TARGET_NAME", "知你客服14号") diff --git a/backend/scripts/create_zhini_kefu_15.py b/backend/scripts/create_zhini_kefu_15.py index 166367e..ecf0e4e 100644 --- a/backend/scripts/create_zhini_kefu_15.py +++ b/backend/scripts/create_zhini_kefu_15.py @@ -26,8 +26,8 @@ from typing import Any, Dict, List, Optional, Tuple import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") SOURCE_NAME = os.getenv("SOURCE_AGENT_NAME", "知你客服14号") TARGET_NAME = os.getenv("TARGET_NAME", "知你客服15号") diff --git a/backend/scripts/create_zhini_kefu_16.py b/backend/scripts/create_zhini_kefu_16.py index 08bf35d..c4044fd 100644 --- a/backend/scripts/create_zhini_kefu_16.py +++ b/backend/scripts/create_zhini_kefu_16.py @@ -29,8 +29,8 @@ from typing import Any, Dict, List, Optional, Tuple import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") SOURCE_NAME = os.getenv("SOURCE_AGENT_NAME", "知你客服15号") TARGET_NAME = os.getenv("TARGET_NAME", "知你客服16号") diff --git a/backend/scripts/create_zhini_kefu_17.py b/backend/scripts/create_zhini_kefu_17.py index e26da7a..424769c 100644 --- a/backend/scripts/create_zhini_kefu_17.py +++ b/backend/scripts/create_zhini_kefu_17.py @@ -24,8 +24,8 @@ from typing import Any, Dict, List, Optional, Tuple import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") SOURCE_NAME = os.getenv("SOURCE_AGENT_NAME", "知你客服15号") TARGET_NAME = os.getenv("TARGET_NAME", "知你客服17号") diff --git a/backend/scripts/create_zhini_kefu_7.py b/backend/scripts/create_zhini_kefu_7.py index 9d67ab8..065d360 100644 --- a/backend/scripts/create_zhini_kefu_7.py +++ b/backend/scripts/create_zhini_kefu_7.py @@ -17,8 +17,8 @@ import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") SOURCE_AGENT_ID = os.getenv("ZHINI_6_AGENT_ID", "2acc84d5-814b-4d61-9703-94a4b117375f") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") NEW_NAME = "知你客服7号" NEW_DESC = ( diff --git a/backend/scripts/create_zhini_kefu_8.py b/backend/scripts/create_zhini_kefu_8.py index 934ff91..6c0ec0d 100644 --- a/backend/scripts/create_zhini_kefu_8.py +++ b/backend/scripts/create_zhini_kefu_8.py @@ -19,8 +19,8 @@ import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") # 默认从 7 号复制;也可通过环境变量指定 SOURCE_AGENT_ID = os.getenv("ZHINI_7_AGENT_ID", "688c2c41-dcd1-4285-b193-6bed00c485c2") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") NEW_NAME = "知你客服8号" NEW_DESC = ( diff --git a/backend/scripts/create_zhini_kefu_9.py b/backend/scripts/create_zhini_kefu_9.py index 94b8467..695c5da 100644 --- a/backend/scripts/create_zhini_kefu_9.py +++ b/backend/scripts/create_zhini_kefu_9.py @@ -20,8 +20,8 @@ import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") SOURCE_AGENT_ID = os.getenv("ZHINI_8_AGENT_ID", "d7b64bf6-c8e3-4dc7-befc-03a98d5ff741") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") NEW_NAME = "知你客服9号" NEW_DESC = ( diff --git a/backend/scripts/debug_cache_query.py b/backend/scripts/debug_cache_query.py index 9d9946a..85925c6 100644 --- a/backend/scripts/debug_cache_query.py +++ b/backend/scripts/debug_cache_query.py @@ -1,3 +1,4 @@ +import os """单次执行后打印 cache-query 与 llm-unified 输出,用于排查记忆。""" import json import requests @@ -9,7 +10,7 @@ MSG = "我叫李小红" r = requests.post( B + "/api/v1/auth/login", - data={"username": "admin", "password": "123456"}, + data={"username": os.getenv("PLATFORM_USERNAME"), "password": os.getenv("PLATFORM_PASSWORD")}, headers={"Content-Type": "application/x-www-form-urlencoded"}, timeout=15, ) diff --git a/backend/scripts/e2e_enterprise_multilane_agent.py b/backend/scripts/e2e_enterprise_multilane_agent.py index b1d1380..de751b9 100644 --- a/backend/scripts/e2e_enterprise_multilane_agent.py +++ b/backend/scripts/e2e_enterprise_multilane_agent.py @@ -42,8 +42,8 @@ def _login_requests(base: str) -> Dict[str, str]: r = requests.post( f"{base}/api/v1/auth/login", data={ - "username": os.getenv("PLATFORM_USERNAME", "admin"), - "password": os.getenv("PLATFORM_PASSWORD", "123456"), + "username": os.getenv("PLATFORM_USERNAME"), + "password": os.getenv("PLATFORM_PASSWORD"), }, headers={"Content-Type": "application/x-www-form-urlencoded"}, timeout=20, @@ -189,8 +189,8 @@ def _run_testclient() -> int: r = c.post( "/api/v1/auth/login", data={ - "username": os.getenv("PLATFORM_USERNAME", "admin"), - "password": os.getenv("PLATFORM_PASSWORD", "123456"), + "username": os.getenv("PLATFORM_USERNAME"), + "password": os.getenv("PLATFORM_PASSWORD"), }, headers={"Content-Type": "application/x-www-form-urlencoded"}, ) diff --git a/backend/scripts/e2e_platform_capability_smoke.py b/backend/scripts/e2e_platform_capability_smoke.py index 003be70..4370dea 100644 --- a/backend/scripts/e2e_platform_capability_smoke.py +++ b/backend/scripts/e2e_platform_capability_smoke.py @@ -26,8 +26,8 @@ from typing import Any, Dict import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") def _h() -> Dict[str, str]: diff --git a/backend/scripts/e2e_platform_capability_smoke_testclient.py b/backend/scripts/e2e_platform_capability_smoke_testclient.py index 7ac4bb0..252b7af 100644 --- a/backend/scripts/e2e_platform_capability_smoke_testclient.py +++ b/backend/scripts/e2e_platform_capability_smoke_testclient.py @@ -23,7 +23,7 @@ def main() -> int: c = TestClient(app) r = c.post( "/api/v1/auth/login", - data={"username": os.getenv("PLATFORM_USERNAME", "admin"), "password": os.getenv("PLATFORM_PASSWORD", "123456")}, + data={"username": os.getenv("PLATFORM_USERNAME"), "password": os.getenv("PLATFORM_PASSWORD")}, headers={"Content-Type": "application/x-www-form-urlencoded"}, ) if r.status_code != 200: diff --git a/backend/scripts/e2e_router_invoke_demo.py b/backend/scripts/e2e_router_invoke_demo.py index c97279b..a357aaf 100644 --- a/backend/scripts/e2e_router_invoke_demo.py +++ b/backend/scripts/e2e_router_invoke_demo.py @@ -19,8 +19,8 @@ from typing import Any, Dict, Optional import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") DEMO_AGENT_NAME = os.getenv("DEMO_AGENT_NAME", "演示-主链路委派invoke") diff --git a/backend/scripts/e2e_subworkflow_chain.py b/backend/scripts/e2e_subworkflow_chain.py index 9afb7d0..4a692ea 100644 --- a/backend/scripts/e2e_subworkflow_chain.py +++ b/backend/scripts/e2e_subworkflow_chain.py @@ -14,8 +14,8 @@ from typing import Any, Dict, Optional import requests BASE = os.getenv("PLATFORM_BASE_URL", "http://127.0.0.1:8037").rstrip("/") -USER = os.getenv("PLATFORM_USERNAME", "admin") -PWD = os.getenv("PLATFORM_PASSWORD", "123456") +USER = os.getenv("PLATFORM_USERNAME") +PWD = os.getenv("PLATFORM_PASSWORD") CHILD_NAME = "E2E-Subworkflow-Child" PARENT_NAME = "E2E-Subworkflow-Parent" diff --git a/backend/scripts/generate_android_agent.py b/backend/scripts/generate_android_agent.py index 16909e1..69785be 100755 --- a/backend/scripts/generate_android_agent.py +++ b/backend/scripts/generate_android_agent.py @@ -15,7 +15,7 @@ from datetime import datetime import uuid -def generate_android_agent(db: Session, username: str = "admin"): +def generate_android_agent(db: Session, username: str | None = None): """生成Android应用开发助手Agent""" print("=" * 60) print("生成Android应用开发助手Agent") @@ -385,7 +385,7 @@ def main(): """主函数""" db = SessionLocal() try: - generate_android_agent(db, username="admin") + generate_android_agent(db, username=os.getenv("PLATFORM_USERNAME")) finally: db.close() diff --git a/backend/scripts/generate_batch_agents.py b/backend/scripts/generate_batch_agents.py index 2c566a8..a49ccd5 100755 --- a/backend/scripts/generate_batch_agents.py +++ b/backend/scripts/generate_batch_agents.py @@ -524,7 +524,7 @@ def generate_creative_writing_agent(db: Session, user: User): } -def generate_batch_agents(db: Session, username: str = "admin"): +def generate_batch_agents(db: Session, username: str | None = None): """批量生成Agent""" print("=" * 60) print("批量生成Agent") @@ -617,7 +617,7 @@ def main(): """主函数""" db = SessionLocal() try: - generate_batch_agents(db, username="admin") + generate_batch_agents(db, username=os.getenv("PLATFORM_USERNAME")) finally: db.close() diff --git a/backend/scripts/generate_chat_agent.py b/backend/scripts/generate_chat_agent.py index 255e1ae..cbca362 100644 --- a/backend/scripts/generate_chat_agent.py +++ b/backend/scripts/generate_chat_agent.py @@ -490,7 +490,7 @@ def main(): db = SessionLocal() try: # 获取或创建测试用户 - user = db.query(User).filter(User.username == "admin").first() + user = db.query(User).filter(User.username == os.getenv("PLATFORM_USERNAME")).first() if not user: print("请先创建admin用户") return diff --git a/backend/scripts/generate_complex_agent.py b/backend/scripts/generate_complex_agent.py index df0811b..e605d12 100755 --- a/backend/scripts/generate_complex_agent.py +++ b/backend/scripts/generate_complex_agent.py @@ -15,7 +15,7 @@ from datetime import datetime import uuid -def generate_complex_agent_with_templates(db: Session, username: str = "admin"): +def generate_complex_agent_with_templates(db: Session, username: str | None = None): """生成包含多个节点模板的复杂Agent""" print("=" * 60) print("生成复杂Agent(包含多个节点模板)") @@ -292,7 +292,7 @@ if __name__ == "__main__": parser.add_argument( "--username", type=str, - default="admin", + default=None, help="创建Agent的用户名(默认: admin)" ) diff --git a/backend/scripts/generate_content_agent.py b/backend/scripts/generate_content_agent.py index 142bfaf..7b3fe56 100755 --- a/backend/scripts/generate_content_agent.py +++ b/backend/scripts/generate_content_agent.py @@ -17,7 +17,7 @@ import uuid import json -def generate_content_agent(db: Session, username: str = "admin"): +def generate_content_agent(db: Session, username: str | None = None): """生成内容生成助手Agent""" print("=" * 60) print("生成内容生成助手Agent") @@ -479,7 +479,7 @@ if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description="生成内容生成助手Agent") - parser.add_argument("--username", type=str, default="admin", help="用户名") + parser.add_argument("--username", type=str, default=None, help="用户名") args = parser.parse_args() diff --git a/backend/scripts/generate_fake_agents.py b/backend/scripts/generate_fake_agents.py index df0525d..38286d1 100755 --- a/backend/scripts/generate_fake_agents.py +++ b/backend/scripts/generate_fake_agents.py @@ -227,7 +227,7 @@ def generate_workflow_config(agent_type: str) -> dict: return base_configs["默认"] -def generate_fake_agents(db: Session, username: str = "admin", count: int = None): +def generate_fake_agents(db: Session, username: str | None = None, count: int = None): """生成假数据""" print("=" * 60) print("生成Agent假数据") @@ -316,7 +316,7 @@ if __name__ == "__main__": parser.add_argument( "--username", type=str, - default="admin", + default=None, help="创建Agent的用户名(默认: admin)" ) parser.add_argument( diff --git a/backend/scripts/generate_smart_agent.py b/backend/scripts/generate_smart_agent.py index 82e4c9c..cca1ca5 100755 --- a/backend/scripts/generate_smart_agent.py +++ b/backend/scripts/generate_smart_agent.py @@ -17,7 +17,7 @@ import uuid import json -def generate_smart_agent(db: Session, username: str = "admin"): +def generate_smart_agent(db: Session, username: str | None = None): """生成智能需求分析与解决方案生成Agent""" print("=" * 60) print("生成智能需求分析与解决方案生成Agent") @@ -451,7 +451,7 @@ if __name__ == "__main__": parser.add_argument( "--username", type=str, - default="admin", + default=None, help="创建Agent的用户名(默认: admin)" ) diff --git a/backend/scripts/generate_test_agent.py b/backend/scripts/generate_test_agent.py index 9d9a9f4..becef66 100755 --- a/backend/scripts/generate_test_agent.py +++ b/backend/scripts/generate_test_agent.py @@ -15,7 +15,7 @@ from datetime import datetime import uuid -def generate_test_agent(db: Session, username: str = "admin"): +def generate_test_agent(db: Session, username: str | None = None): """生成测试Agent(左右连接)""" print("=" * 60) print("生成测试Agent(左右连接演示)") @@ -224,7 +224,7 @@ def main(): """主函数""" db = SessionLocal() try: - generate_test_agent(db, username="admin") + generate_test_agent(db, username=os.getenv("PLATFORM_USERNAME")) finally: db.close() diff --git a/backend/scripts/set_admin.py b/backend/scripts/set_admin.py index 194bcce..57108dd 100755 --- a/backend/scripts/set_admin.py +++ b/backend/scripts/set_admin.py @@ -19,8 +19,12 @@ def set_admin(): print("=" * 60) print() - # 查找admin用户 - admin_user = db.query(User).filter(User.username == "admin").first() + target_username = os.getenv("PLATFORM_USERNAME") + if not target_username: + print("❌ 请设置 PLATFORM_USERNAME 环境变量指定要提升为管理员的用户名") + return + # 查找目标用户 + admin_user = db.query(User).filter(User.username == target_username).first() if not admin_user: print("❌ 未找到admin用户,请先创建admin用户") diff --git a/backend/scripts/test_homework_agent_hello.py b/backend/scripts/test_homework_agent_hello.py index cd850ae..1435f8c 100644 --- a/backend/scripts/test_homework_agent_hello.py +++ b/backend/scripts/test_homework_agent_hello.py @@ -22,8 +22,8 @@ import requests def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="测试学生作业管理助手发送“你好”") parser.add_argument("--base-url", default="http://127.0.0.1:8037", help="后端地址") - parser.add_argument("--username", default="admin", help="登录用户名") - parser.add_argument("--password", default="123456", help="登录密码") + parser.add_argument("--username", default=None, help="登录用户名") + parser.add_argument("--password", default=None, help="登录密码") parser.add_argument("--agent-name", default="学生作业管理助手", help="目标 Agent 名称") parser.add_argument("--message", default="你好", help="发送内容") parser.add_argument("--timeout-seconds", type=int, default=90, help="轮询超时秒数") diff --git a/backend/scripts/update_zhini7_prompt.py b/backend/scripts/update_zhini7_prompt.py index a8fefc7..4f69904 100644 --- a/backend/scripts/update_zhini7_prompt.py +++ b/backend/scripts/update_zhini7_prompt.py @@ -1,3 +1,4 @@ +import os import re import requests @@ -10,7 +11,7 @@ prompt = m.group(1).strip() r = requests.post( f"{BASE}/api/v1/auth/login", - data={"username": "admin", "password": "123456"}, + data={"username": os.getenv("PLATFORM_USERNAME"), "password": os.getenv("PLATFORM_PASSWORD")}, headers={"Content-Type": "application/x-www-form-urlencoded"}, timeout=15, )