From c1f4de425aa266bcd78e3285e9bb1f9ad484d7a4 Mon Sep 17 00:00:00 2001 From: Junyan Qin Date: Mon, 10 Mar 2025 22:34:45 +0800 Subject: [PATCH] refactor: move entities --- pkg/api/http/controller/groups/models.py | 27 ++++++++++++++ pkg/api/http/controller/groups/user.py | 2 +- pkg/api/http/controller/main.py | 2 +- pkg/api/http/service/model.py | 35 +++++++++++++++++++ pkg/api/http/service/user.py | 2 +- pkg/core/app.py | 3 ++ pkg/core/stages/build_app.py | 4 +++ .../entities => entity}/__init__.py | 0 pkg/entity/persistence/__init__.py | 0 .../entities => entity/persistence}/base.py | 1 + pkg/entity/persistence/model.py | 19 ++++++++++ .../entities => entity/persistence}/user.py | 2 ++ pkg/persistence/mgr.py | 7 +++- pkg/provider/modelmgr/modelmgr.py | 9 ++--- 14 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 pkg/api/http/controller/groups/models.py create mode 100644 pkg/api/http/service/model.py rename pkg/{persistence/entities => entity}/__init__.py (100%) create mode 100644 pkg/entity/persistence/__init__.py rename pkg/{persistence/entities => entity/persistence}/base.py (82%) create mode 100644 pkg/entity/persistence/model.py rename pkg/{persistence/entities => entity/persistence}/user.py (67%) diff --git a/pkg/api/http/controller/groups/models.py b/pkg/api/http/controller/groups/models.py new file mode 100644 index 00000000..e8921d5f --- /dev/null +++ b/pkg/api/http/controller/groups/models.py @@ -0,0 +1,27 @@ +import quart + +from .. import group +from .....entity.persistence import model + + +@group.group_class('models/llm', '/api/v1/provider/models/llm') +class LLMModelsRouterGroup(group.RouterGroup): + + async def initialize(self) -> None: + @self.route('', methods=['GET', 'POST']) + async def _() -> str: + if quart.request.method == 'GET': + return self.success(data={ + 'models': await self.ap.model_service.get_llm_models() + }) + elif quart.request.method == 'POST': + pass + + @self.route('/', methods=['GET', 'PUT', 'DELETE']) + async def _(model_uuid: str) -> str: + if quart.request.method == 'GET': + pass + elif quart.request.method == 'PUT': + pass + elif quart.request.method == 'DELETE': + pass \ No newline at end of file diff --git a/pkg/api/http/controller/groups/user.py b/pkg/api/http/controller/groups/user.py index ce8e7448..adf7d87c 100644 --- a/pkg/api/http/controller/groups/user.py +++ b/pkg/api/http/controller/groups/user.py @@ -3,7 +3,7 @@ import sqlalchemy import argon2 from .. import group -from .....persistence.entities import user +from .....entity.persistence import user @group.group_class('user', '/api/v1/user') diff --git a/pkg/api/http/controller/main.py b/pkg/api/http/controller/main.py index acbfa104..e644e7e4 100644 --- a/pkg/api/http/controller/main.py +++ b/pkg/api/http/controller/main.py @@ -7,7 +7,7 @@ import quart import quart_cors from ....core import app, entities as core_entities -from .groups import logs, system, settings, plugins, stats, user +from .groups import logs, system, settings, plugins, stats, user, models from . import group diff --git a/pkg/api/http/service/model.py b/pkg/api/http/service/model.py new file mode 100644 index 00000000..729b815c --- /dev/null +++ b/pkg/api/http/service/model.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +import sqlalchemy + +from ....core import app +from ....entity.persistence import model + + +class ModelsService: + + ap: app.Application + + def __init__(self, ap: app.Application) -> None: + self.ap = ap + + async def get_llm_models(self) -> list[model.LLMModel]: + result = await self.ap.persistence_mgr.execute_async( + sqlalchemy.select(model.LLMModel) + ) + + result_list = result.all() + + return result_list + + async def create_llm_model(self, model: model.LLMModel) -> None: + pass + + async def get_llm_model(self, model_uuid: str) -> model.LLMModel: + pass + + async def update_llm_model(self, model: model.LLMModel) -> None: + pass + + async def delete_llm_model(self, model_uuid: str) -> None: + pass diff --git a/pkg/api/http/service/user.py b/pkg/api/http/service/user.py index 93774778..b09eef3c 100644 --- a/pkg/api/http/service/user.py +++ b/pkg/api/http/service/user.py @@ -6,7 +6,7 @@ import jwt import datetime from ....core import app -from ....persistence.entities import user +from ....entity.persistence import user from ....utils import constants diff --git a/pkg/core/app.py b/pkg/core/app.py index 8fd36d63..9f359239 100644 --- a/pkg/core/app.py +++ b/pkg/core/app.py @@ -25,6 +25,7 @@ from ..utils import version as version_mgr, proxy as proxy_mgr, announce as anno from ..persistence import mgr as persistencemgr from ..api.http.controller import main as http_controller from ..api.http.service import user as user_service +from ..api.http.service import model as model_service from ..discover import engine as discover_engine from ..utils import logcache, ip from . import taskmgr @@ -112,6 +113,8 @@ class Application: user_service: user_service.UserService = None + model_service: model_service.ModelsService = None + def __init__(self): pass diff --git a/pkg/core/stages/build_app.py b/pkg/core/stages/build_app.py index e4fd0ea5..067044e5 100644 --- a/pkg/core/stages/build_app.py +++ b/pkg/core/stages/build_app.py @@ -18,6 +18,7 @@ from ...platform import manager as im_mgr from ...persistence import mgr as persistencemgr from ...api.http.controller import main as http_controller from ...api.http.service import user as user_service +from ...api.http.service import model as model_service from ...discover import engine as discover_engine from ...utils import logcache from .. import taskmgr @@ -123,5 +124,8 @@ class BuildAppStage(stage.BootingStage): user_service_inst = user_service.UserService(ap) ap.user_service = user_service_inst + model_service_inst = model_service.ModelsService(ap) + ap.model_service = model_service_inst + ctrl = controller.Controller(ap) ap.ctrl = ctrl diff --git a/pkg/persistence/entities/__init__.py b/pkg/entity/__init__.py similarity index 100% rename from pkg/persistence/entities/__init__.py rename to pkg/entity/__init__.py diff --git a/pkg/entity/persistence/__init__.py b/pkg/entity/persistence/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pkg/persistence/entities/base.py b/pkg/entity/persistence/base.py similarity index 82% rename from pkg/persistence/entities/base.py rename to pkg/entity/persistence/base.py index b0d8b5db..9d9ea759 100644 --- a/pkg/persistence/entities/base.py +++ b/pkg/entity/persistence/base.py @@ -1,4 +1,5 @@ import sqlalchemy.orm +import pydantic class Base(sqlalchemy.orm.DeclarativeBase): diff --git a/pkg/entity/persistence/model.py b/pkg/entity/persistence/model.py new file mode 100644 index 00000000..9ef875db --- /dev/null +++ b/pkg/entity/persistence/model.py @@ -0,0 +1,19 @@ +import sqlalchemy + +from .base import Base + + +class LLMModel(Base): + """LLM 模型""" + __tablename__ = 'llm_models' + + uuid = sqlalchemy.Column(sqlalchemy.String(255), primary_key=True) + name = sqlalchemy.Column(sqlalchemy.String(255), nullable=False) + description = sqlalchemy.Column(sqlalchemy.String(255), nullable=False) + requester = sqlalchemy.Column(sqlalchemy.String(255), nullable=False) + requester_config = sqlalchemy.Column(sqlalchemy.JSON, nullable=False, default={}) + api_keys = sqlalchemy.Column(sqlalchemy.JSON, nullable=False) + abilities = sqlalchemy.Column(sqlalchemy.JSON, nullable=False, default=[]) + extra_args = sqlalchemy.Column(sqlalchemy.JSON, nullable=False, default={}) + updated_at = sqlalchemy.Column(sqlalchemy.DateTime, nullable=False) + created_at = sqlalchemy.Column(sqlalchemy.DateTime, nullable=False) \ No newline at end of file diff --git a/pkg/persistence/entities/user.py b/pkg/entity/persistence/user.py similarity index 67% rename from pkg/persistence/entities/user.py rename to pkg/entity/persistence/user.py index 55597b4f..b15969c1 100644 --- a/pkg/persistence/entities/user.py +++ b/pkg/entity/persistence/user.py @@ -9,3 +9,5 @@ class User(Base): id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True) user = sqlalchemy.Column(sqlalchemy.String(255), nullable=False) password = sqlalchemy.Column(sqlalchemy.String(255), nullable=False) + created_at = sqlalchemy.Column(sqlalchemy.DateTime, nullable=False) + updated_at = sqlalchemy.Column(sqlalchemy.DateTime, nullable=False) diff --git a/pkg/persistence/mgr.py b/pkg/persistence/mgr.py index 0eef4800..b2e674c4 100644 --- a/pkg/persistence/mgr.py +++ b/pkg/persistence/mgr.py @@ -7,7 +7,7 @@ import sqlalchemy.ext.asyncio as sqlalchemy_asyncio import sqlalchemy from . import database -from .entities import user, base +from ..entity.persistence import user, model, base from ..core import app from .databases import sqlite @@ -34,6 +34,11 @@ class PersistenceManager: await self.create_tables() + # auto migrate + async with self.get_db_engine().connect() as conn: + await conn.run_sync(self.meta.drop_all) + await conn.run_sync(self.meta.create_all) + async def create_tables(self): # TODO: 对扩展友好 diff --git a/pkg/provider/modelmgr/modelmgr.py b/pkg/provider/modelmgr/modelmgr.py index e8c231c5..3d86dfad 100644 --- a/pkg/provider/modelmgr/modelmgr.py +++ b/pkg/provider/modelmgr/modelmgr.py @@ -6,6 +6,7 @@ from . import entities, requester from ...core import app from ...discover import engine from . import token +from ...entity.persistence import model from .requesters import bailianchatcmpl, chatcmpl, anthropicmsgs, moonshotchatcmpl, deepseekchatcmpl, ollamachat, giteeaichatcmpl, volcarkchatcmpl, xaichatcmpl, zhipuaichatcmpl, lmstudiochatcmpl, siliconflowchatcmpl, volcarkchatcmpl FETCH_MODEL_LIST_URL = "https://api.qchatgpt.rockchin.top/api/v2/fetch/model_list" @@ -23,12 +24,16 @@ class ModelManager: requesters: dict[str, requester.LLMAPIRequester] token_mgrs: dict[str, token.TokenManager] + + models: list[model.LLMModel] def __init__(self, ap: app.Application): self.ap = ap + self.requester_components = [] self.model_list = [] self.requesters = {} self.token_mgrs = {} + self.models = [] async def get_model_by_name(self, name: str) -> entities.LLMModelInfo: """通过名称获取模型 @@ -46,10 +51,6 @@ class ModelManager: for k, v in self.ap.provider_cfg.data['keys'].items(): self.token_mgrs[k] = token.TokenManager(k, v) - # for api_cls in requester.preregistered_requesters: - # api_inst = api_cls(self.ap) - # await api_inst.initialize() - # self.requesters[api_inst.name] = api_inst for component in self.requester_components: api_cls = component.get_python_component_class() api_inst = api_cls(self.ap)