1. 入口点注册
后端扩展通过 Python 的 entry_points 机制注册到 Jupyter Server:
# 在 setup.py 或 pyproject.toml 中定义
entry_points={
"jupyter_server.extensions": [
"lf_ai_backend = lf_ai_backend:_load_jupyter_server_extension"
]
}
这告诉 Jupyter Server 扩展模块是 lf_ai_backend
,加载函数是 _load_jupyter_server_extension
。
2. 扩展发现过程
- Jupyter Server 启动时,扫描所有已安装包的 entry_points
- 查找
jupyter_server.extensions
组下的所有条目 - 加载每个注册的扩展模块
3. 扩展加载流程
一个典型的加载过程:
-
导入扩展模块:Jupyter Server 导入
lf_ai_backend
模块 -
查找并调用加载函数:调用
_load_jupyter_server_extension
函数,传入server_app
参数 -
扩展初始化:扩展在加载函数中执行初始化代码:
def _load_jupyter_server_extension(server_app): # 获取 web_app 实例 web_app = server_app.web_app base_url = web_app.settings['base_url'] # 初始化服务和状态 ai_service = AIService(log=server_app.log) web_app.settings["lf_ai_service"] = ai_service # 注册处理程序 host_pattern = ".*$" handlers = [...] web_app.add_handlers(host_pattern, handlers)
4. 路由注册机制
扩展通过 Tornado 的路由机制添加自定义端点:
-
创建继承自
APIHandler
的处理类:class TestHandler(APIHandler): @tornado.web.authenticated def get(self): # 处理 GET 请求
-
注册路由和处理程序:
web_app.add_handlers(host_pattern, [ (url_path_join(base_url, "lf-ai-extension", "api", "test"), TestHandler) ])
5. 状态共享机制
扩展可以在 web_app.settings 中存储状态,实现共享:
web_app.settings["lf_ai_service"] = ai_service
web_app.settings["lf_ai_chat_history"] = []
在任何处理程序中可以访问这些共享状态:
class SomeHandler(APIHandler):
def get(self):
ai_service = self.settings["lf_ai_service"]
# 使用 ai_service
6. 请求处理流程
当客户端发起请求时:
- Jupyter Server 接收请求并匹配路由
- 找到对应的处理程序类
- 实例化处理程序并调用相应的方法(GET/POST/PUT 等)
- 处理程序执行逻辑并返回响应
7. 服务持久化
- 扩展加载时创建的服务和状态在 Jupyter Server 的生命周期内保持活跃
- 可以在处理程序之间共享状态和服务实例
- 服务关闭时,可以实现清理逻辑
8. WebSocket 支持
对于需要实时通信的场景,可以实现 WebSocket 处理程序:
class RootChatHandler(tornado.websocket.WebSocketHandler):
def open(self):
# 建立连接
def on_message(self, message):
# 处理消息
def on_close(self):
# 连接关闭
这种架构设计使 Jupyter 扩展可以无缝集成到 Jupyter Server 中,提供强大的自定义功能,同时保持与 Jupyter 核心功能的兼容性。