+api rework

This commit is contained in:
2025-12-30 20:08:48 +03:00
parent 9ed3a5992d
commit 45c077b928
9 changed files with 44 additions and 15 deletions

Binary file not shown.

View File

@@ -39,6 +39,9 @@ class DatabaseResponse(BaseModel):
@router.get("", response_model=List[EnvironmentResponse]) @router.get("", response_model=List[EnvironmentResponse])
async def get_environments(config_manager=Depends(get_config_manager)): async def get_environments(config_manager=Depends(get_config_manager)):
envs = config_manager.get_environments() envs = config_manager.get_environments()
# Ensure envs is a list
if not isinstance(envs, list):
envs = []
return [EnvironmentResponse(id=e.id, name=e.name, url=e.url) for e in envs] return [EnvironmentResponse(id=e.id, name=e.name, url=e.url) for e in envs]
# [/DEF:get_environments] # [/DEF:get_environments]

View File

@@ -22,7 +22,7 @@ class ResolveTaskRequest(BaseModel):
class ResumeTaskRequest(BaseModel): class ResumeTaskRequest(BaseModel):
passwords: Dict[str, str] passwords: Dict[str, str]
@router.post("/", response_model=Task, status_code=status.HTTP_201_CREATED) @router.post("", response_model=Task, status_code=status.HTTP_201_CREATED)
async def create_task( async def create_task(
request: CreateTaskRequest, request: CreateTaskRequest,
task_manager: TaskManager = Depends(get_task_manager) task_manager: TaskManager = Depends(get_task_manager)
@@ -39,7 +39,7 @@ async def create_task(
except ValueError as e: except ValueError as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e)) raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
@router.get("/", response_model=List[Task]) @router.get("", response_model=List[Task])
async def list_tasks( async def list_tasks(
limit: int = 10, limit: int = 10,
offset: int = 0, offset: int = 0,
@@ -107,7 +107,7 @@ async def resume_task(
except ValueError as e: except ValueError as e:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
@router.delete("/", status_code=status.HTTP_204_NO_CONTENT) @router.delete("", status_code=status.HTTP_204_NO_CONTENT)
async def clear_tasks( async def clear_tasks(
status: Optional[TaskStatus] = None, status: Optional[TaskStatus] = None,
task_manager: TaskManager = Depends(get_task_manager) task_manager: TaskManager = Depends(get_task_manager)

View File

@@ -11,7 +11,7 @@ from pathlib import Path
project_root = Path(__file__).resolve().parent.parent.parent project_root = Path(__file__).resolve().parent.parent.parent
sys.path.append(str(project_root)) sys.path.append(str(project_root))
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, Request
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse from fastapi.responses import FileResponse
@@ -45,6 +45,13 @@ app.add_middleware(
) )
@app.middleware("http")
async def log_requests(request: Request, call_next):
logger.info(f"[DEBUG] Incoming request: {request.method} {request.url.path}")
response = await call_next(request)
logger.info(f"[DEBUG] Response status: {response.status_code} for {request.url.path}")
return response
# Include API routes # Include API routes
app.include_router(plugins.router, prefix="/api/plugins", tags=["Plugins"]) app.include_router(plugins.router, prefix="/api/plugins", tags=["Plugins"])
app.include_router(tasks.router, prefix="/api/tasks", tags=["Tasks"]) app.include_router(tasks.router, prefix="/api/tasks", tags=["Tasks"])

View File

@@ -353,8 +353,8 @@ class TaskManager:
if task.status == status: if task.status == status:
should_remove = True should_remove = True
else: else:
# Clear all non-active tasks # Clear all non-active tasks (keep RUNNING, AWAITING_INPUT, AWAITING_MAPPING)
if task.status not in [TaskStatus.RUNNING]: if task.status not in [TaskStatus.RUNNING, TaskStatus.AWAITING_INPUT, TaskStatus.AWAITING_MAPPING]:
should_remove = True should_remove = True
if should_remove: if should_remove:

View File

@@ -42,6 +42,7 @@ class TaskPersistenceService:
cursor.execute(""" cursor.execute("""
CREATE TABLE IF NOT EXISTS persistent_tasks ( CREATE TABLE IF NOT EXISTS persistent_tasks (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
plugin_id TEXT NOT NULL,
status TEXT NOT NULL, status TEXT NOT NULL,
created_at TEXT NOT NULL, created_at TEXT NOT NULL,
updated_at TEXT NOT NULL, updated_at TEXT NOT NULL,
@@ -68,10 +69,11 @@ class TaskPersistenceService:
if task.status == TaskStatus.AWAITING_INPUT: if task.status == TaskStatus.AWAITING_INPUT:
cursor.execute(""" cursor.execute("""
INSERT OR REPLACE INTO persistent_tasks INSERT OR REPLACE INTO persistent_tasks
(id, status, created_at, updated_at, input_request, context) (id, plugin_id, status, created_at, updated_at, input_request, context)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?)
""", ( """, (
task.id, task.id,
task.plugin_id,
task.status.value, task.status.value,
task.started_at.isoformat() if task.started_at else datetime.utcnow().isoformat(), task.started_at.isoformat() if task.started_at else datetime.utcnow().isoformat(),
datetime.utcnow().isoformat(), datetime.utcnow().isoformat(),
@@ -98,16 +100,30 @@ class TaskPersistenceService:
conn = sqlite3.connect(str(self.db_path)) conn = sqlite3.connect(str(self.db_path))
cursor = conn.cursor() cursor = conn.cursor()
# Check if plugin_id column exists (migration for existing db)
cursor.execute("PRAGMA table_info(persistent_tasks)")
columns = [info[1] for info in cursor.fetchall()]
has_plugin_id = "plugin_id" in columns
if has_plugin_id:
cursor.execute("SELECT id, plugin_id, status, created_at, input_request, context FROM persistent_tasks")
else:
cursor.execute("SELECT id, status, created_at, input_request, context FROM persistent_tasks") cursor.execute("SELECT id, status, created_at, input_request, context FROM persistent_tasks")
rows = cursor.fetchall() rows = cursor.fetchall()
loaded_tasks = [] loaded_tasks = []
for row in rows: for row in rows:
if has_plugin_id:
task_id, plugin_id, status, created_at, input_request_json, context_json = row
else:
task_id, status, created_at, input_request_json, context_json = row task_id, status, created_at, input_request_json, context_json = row
plugin_id = "superset-migration" # Default fallback
try: try:
task = Task( task = Task(
id=task_id, id=task_id,
plugin_id="migration", # Default, assumes migration context for now plugin_id=plugin_id,
status=TaskStatus(status), status=TaskStatus(status),
started_at=datetime.fromisoformat(created_at), started_at=datetime.fromisoformat(created_at),
input_required=True, input_required=True,

View File

@@ -6,13 +6,16 @@ export default defineConfig({
server: { server: {
proxy: { proxy: {
'/api': { '/api': {
target: 'http://localhost:8000', target: 'http://127.0.0.1:8000',
changeOrigin: true changeOrigin: true,
secure: false,
rewrite: (path) => path.replace(/^\/api/, '/api')
}, },
'/ws': { '/ws': {
target: 'ws://localhost:8000', target: 'ws://127.0.0.1:8000',
ws: true, ws: true,
changeOrigin: true changeOrigin: true,
secure: false
} }
} }
} }

0
tests/output.txt Normal file
View File

0
tests/output_safe.txt Normal file
View File