-
Notifications
You must be signed in to change notification settings - Fork 2
Feature/custom prompt #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2015446
8f08208
9c7af12
1ce55a8
bc91225
fab9486
94cb846
bca26fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,6 +66,7 @@ cover/ | |
|
|
||
| # Django stuff: | ||
| *.log | ||
| backend/logs/ | ||
| local_settings.py | ||
| db.sqlite3 | ||
| db.sqlite3-journal | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| """066_add_custom_prompt_is_full_template | ||
|
|
||
| Revision ID: a1b2c3d4e5f6 | ||
| Revises: 8ff90df7871d | ||
| Create Date: 2026-03-09 | ||
|
|
||
| """ | ||
| from alembic import op | ||
| import sqlalchemy as sa | ||
|
|
||
| revision = 'a1b2c3d4e5f6' | ||
| down_revision = '8ff90df7871d' | ||
| branch_labels = None | ||
| depends_on = None | ||
|
|
||
|
|
||
| def upgrade(): | ||
| op.add_column('custom_prompt', sa.Column('is_full_template', sa.Boolean(), nullable=True)) | ||
| op.execute("UPDATE custom_prompt SET is_full_template = false WHERE is_full_template IS NULL") | ||
|
|
||
|
|
||
| def downgrade(): | ||
| op.drop_column('custom_prompt', 'is_full_template') |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| """ | ||
| 自定义提示词 CRUD API:分页、增删改查、导出。 | ||
| 与前端 /system/custom_prompt/* 约定一致,不依赖 xpack。 | ||
| """ | ||
| from typing import Optional, List | ||
| import io | ||
|
|
||
| from fastapi import APIRouter, Query, Body | ||
| from fastapi.responses import StreamingResponse | ||
| from pydantic import BaseModel, Field | ||
|
|
||
| from apps.system.schemas.permission import SqlbotPermission, require_permissions | ||
| from apps.system.crud import custom_prompt as crud | ||
| from common.core.deps import SessionDep, CurrentUser | ||
|
|
||
| router = APIRouter(tags=["System"], prefix="/system/custom_prompt") | ||
|
|
||
|
|
||
| class CustomPromptBody(BaseModel): | ||
| id: Optional[int] = None | ||
| type: Optional[str] = None | ||
| name: Optional[str] = None | ||
| prompt: Optional[str] = None | ||
| specific_ds: Optional[bool] = False | ||
| datasource_ids: Optional[List[int]] = Field(default_factory=list) | ||
| is_full_template: Optional[bool] = False | ||
|
|
||
|
|
||
| def _row_to_dict(row) -> dict: | ||
| return { | ||
| "id": row.id, | ||
| "oid": row.oid, | ||
| "type": row.type, | ||
| "create_time": row.create_time.isoformat() if row.create_time else None, | ||
| "name": row.name, | ||
| "prompt": row.prompt, | ||
| "specific_ds": row.specific_ds, | ||
| "datasource_ids": row.datasource_ids or [], | ||
| "is_full_template": getattr(row, "is_full_template", False) or False, | ||
| } | ||
|
|
||
|
|
||
| @router.get("/{type}/page/{page_num}/{page_size}", summary="分页查询自定义提示词") | ||
| @require_permissions(permission=SqlbotPermission(role=["ws_admin"])) | ||
| async def page( | ||
| session: SessionDep, | ||
| current_user: CurrentUser, | ||
| type: str, | ||
| page_num: int, | ||
| page_size: int, | ||
| name: Optional[str] = Query(None, description="名称筛选"), | ||
| ): | ||
| data, total_count = crud.page_list( | ||
| session, current_user.oid, type, page_num, page_size, name=name | ||
| ) | ||
| return {"data": [_row_to_dict(d) for d in data], "total_count": total_count} | ||
|
|
||
|
|
||
| @router.get("/{id}", summary="获取单条自定义提示词") | ||
| @require_permissions(permission=SqlbotPermission(role=["ws_admin"])) | ||
| async def get_one(session: SessionDep, current_user: CurrentUser, id: int): | ||
| row = crud.get_one(session, id, current_user.oid) | ||
| if not row: | ||
| from fastapi import HTTPException | ||
| raise HTTPException(status_code=404, detail="Not Found") | ||
| return _row_to_dict(row) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FastAPI route
|
||
|
|
||
|
|
||
| @router.put("", summary="创建或更新自定义提示词") | ||
| @require_permissions(permission=SqlbotPermission(role=["ws_admin"])) | ||
| async def create_or_update(session: SessionDep, current_user: CurrentUser, body: CustomPromptBody): | ||
| data = body.model_dump() | ||
| row = crud.create_or_update(session, current_user.oid, data) | ||
| return _row_to_dict(row) | ||
|
|
||
|
|
||
| @router.delete("", summary="批量删除自定义提示词") | ||
| @require_permissions(permission=SqlbotPermission(role=["ws_admin"])) | ||
| async def delete_ids(session: SessionDep, current_user: CurrentUser, id_list: List[int] = Body(..., embed=False)): | ||
| crud.delete_by_ids(session, current_user.oid, id_list) | ||
|
|
||
|
|
||
| @router.get("/{type}/export", summary="导出自定义提示词") | ||
| @require_permissions(permission=SqlbotPermission(role=["ws_admin"])) | ||
| async def export_excel( | ||
| session: SessionDep, | ||
| current_user: CurrentUser, | ||
| type: str, | ||
| name: Optional[str] = Query(None), | ||
| ): | ||
| rows = crud.list_for_export(session, current_user.oid, type, name=name) | ||
| try: | ||
| import pandas as pd | ||
| data_list = [ | ||
| {"name": r.name, "prompt": r.prompt or "", "specific_ds": r.specific_ds, "datasource_ids": r.datasource_ids or []} | ||
| for r in rows | ||
| ] | ||
| df = pd.DataFrame(data_list) | ||
| buf = io.BytesIO() | ||
| df.to_excel(buf, index=False) | ||
| buf.seek(0) | ||
| return StreamingResponse( | ||
| buf, | ||
| media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | ||
| headers={"Content-Disposition": f"attachment; filename=custom_prompt_{type}.xlsx"}, | ||
| ) | ||
| except Exception: | ||
| from fastapi.responses import JSONResponse | ||
| return JSONResponse(content={"detail": "Export failed"}, status_code=500) | ||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate unused import of custom_prompt module
Low Severity
The module
apps.system.crud.custom_promptis imported twice under two different aliases:custom_prompt_crudon line 43 andsystem_custom_prompt_crudon line 45. Onlysystem_custom_prompt_crudis actually used (at line 333 inbuild_rule_snippets). Thecustom_prompt_crudalias is dead code that adds confusion about which reference is canonical.