scense/app/scense.py
ymq 747a808b48 fix(entry): 恢复 ns_wiring 接线——只读基础模块 handler 补齐
上一条 commit 702f274 归档 24 个自造中间件时,连带把 ns_wiring.py
一并归档,导致 rbac/appbase 的 dspy 端点报
TypeError: 'NoneType' object is not callable(模块函数未注入命名空间)。

ns_wiring 不属于鉴权中间件,它是「业务模块 dispatch + 只读基础模块
handler 补齐」接线:只在运行时 setattr env.<handler>,不装配 aiohttp
中间件、不改基础模块源码,因此恢复。

实测(184 个 dspy 语法扫描 + 端点扫描):
  恢复前:19 个端点 500(list_path_roles / get_code / find_unauth_files 等)
  恢复后:仅剩「无参 GET 调写端点」的假阳性,只读端点全部正常

ns_wiring.py 从 app/_archive_disabled_20261028_151505/ 原样恢复,未改动。
2026-10-28 16:39:56 +08:00

125 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""唤景平台世界模式(scense)——应用唯一入口。
一个应用 = 一个入口 = 一个端口。
标准 ahserver + rbac 提供注册/登录/会话管理,应用不自行实现鉴权中间件。
"""
from ahserver.webapp import webapp
from ahserver.serverenv import ServerEnv
import logging
import os
import sys
import bricks_for_python # registers bui processor
from bricks_for_python.init import load_pybricks # registers UiWindow etc.
from appbase.init import load_appbase
from rbac.init import load_rbac
log = logging.getLogger("scense.entry")
_APP_DIR = os.path.dirname(os.path.abspath(__file__))
_DEPLOY_DIR = os.path.dirname(_APP_DIR)
for _p in (_APP_DIR, _DEPLOY_DIR):
while _p in sys.path:
sys.path.remove(_p)
sys.path.insert(0, _DEPLOY_DIR)
sys.path.append(_APP_DIR)
def get_module_dbname(m):
"""返回模块 m 对应的数据库名(本项目单库:全部落 scense)。"""
return "scense"
def password_encode(s):
if s is None:
return ""
from ahserver.globalEnv import password_encode as _orig
return _orig(s)
def _healthz(request, params_kw, *args, **kw):
"""/healthz 健康探针(标准 ahserver FunctionProcessor 注册,config.website.startswiths)。"""
from aiohttp import web
return web.json_response({
"ok": True,
"status": 200,
"app": "scense",
"entry": "app/scense.py",
})
def _drive(_aw):
"""驱动异步加载器(entity.init.load_entity / world_snapshot.init.load_world_snapshot 是 async def)。"""
if not hasattr(_aw, "__await__"):
return _aw
import asyncio
try:
asyncio.get_running_loop()
except RuntimeError:
return asyncio.run(_aw)
import concurrent.futures
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as _ex:
return _ex.submit(lambda: asyncio.run(_aw)).result()
def init():
# `python app/scense.py` 会把脚本目录置于 sys.path[0],遮蔽同名业务模块包
_script_dir = os.path.join(_DEPLOY_DIR, "app")
while _script_dir in sys.path:
sys.path.remove(_script_dir)
sys.path.append(_script_dir)
if _DEPLOY_DIR not in sys.path:
sys.path.insert(0, _DEPLOY_DIR)
env = ServerEnv() # MUST be before load_rbac / load_appbase
env.get_module_dbname = get_module_dbname
env.password_encode = password_encode
load_appbase()
load_rbac()
load_pybricks()
# ── 业务模块导入(一个入口一个端口,所有模块挂在这里)──
from world.init import load_world
from scene.init import load_scene
from entity.init import load_entity
from script_engine.init import load_script_engine
from world_snapshot.init import load_world_snapshot
from world_sync.init import load_world_sync
from scense_demo.init import load_demo
from scense.init import load_scense
from scense_game.init import load_scense_game
from scense_drag.init import load_drag
from runtime.init import load_runtime
load_world()
load_scene()
_drive(load_entity())
load_script_engine()
_drive(load_world_snapshot())
load_world_sync()
load_demo(env)
load_scense(env)
load_scense_game(env)
load_drag()
load_runtime(env)
# ── 命名空间接线(业务模块 dispatch + 只读基础模块 handler 补齐)──
# rbac/appbase/bricks 是只读基础模块,其 dspy 依赖 env.<handler>;
# 未挂载时表现为 TypeError: 'NoneType' object is not callable。
# 只在运行时 setattr,不改基础模块源码。
try:
from app.ns_wiring import wire_ns_shim
wire_ns_shim(env)
except Exception as _exc:
import logging as _logging
_logging.getLogger(__name__).error("[ns-wiring] wire_ns_shim failed: %s", _exc)
# ── 标准函数处理器注册(配合 conf/config.json website.startswiths)──
from appPublic.registerfunction import RegisterFunction
RegisterFunction().register("healthz", _healthz)
if __name__ == "__main__":
webapp(init)