[feat]:[FL-194][删除AtpModel系统,保留AtpAsset]

- 删除AtpModel、AtpModelVersion、AtpSimulationRun模型及相关代码
- 删除/api/v1/atp/models API端点
- 将engine status功能迁移到atp_asset_service
- 更新路由和模型注册,移除atp_model引用
- 删除相关测试文件
- 更新fl_analysis_service使用atp_asset_service的_truncate_output

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
chengkai3
2026-06-27 10:13:51 +08:00
parent 16bdd76eaf
commit b8f61a72aa
14 changed files with 99 additions and 2276 deletions
-2
View File
@@ -4,7 +4,6 @@ from .v1.admin import router as admin_router
from .v1.admin_files import router as admin_files_router
from .v1.ai_chat import router as ai_chat_router
from .v1.atp_assets import router as atp_assets_router
from .v1.atp_models import router as atp_models_router
from .v1.auth import router as auth_router
from .v1.documents import router as documents_router
from .v1.elevation import router as elevation_router
@@ -30,7 +29,6 @@ v1_router.include_router(admin_router)
v1_router.include_router(admin_files_router)
v1_router.include_router(ai_chat_router)
v1_router.include_router(atp_assets_router)
v1_router.include_router(atp_models_router)
v1_router.include_router(documents_router)
v1_router.include_router(task_monitor_router)
v1_router.include_router(scheduled_tasks_router)
+2 -2
View File
@@ -19,8 +19,8 @@ from ...schemas.atp_asset import (
AtpAssetRunListResponse,
AtpAssetRunRequest,
AtpAssetUpdateRequest,
AtpEngineStatusResponse,
)
from ...schemas.atp_model import AtpEngineStatusResponse
from ...services.atp_asset_service import (
activate_release,
create_asset,
@@ -28,6 +28,7 @@ from ...services.atp_asset_service import (
create_release_from_archive,
delete_asset,
get_asset_by_id,
get_engine_status,
get_release_by_id,
get_run_detail,
list_assets,
@@ -40,7 +41,6 @@ from ...services.atp_asset_service import (
update_asset,
update_release,
)
from ...services.atp_model_service import get_engine_status
router = APIRouter(prefix="/atp", tags=["atp-assets"], dependencies=[Depends(require_enabled_menu_route)])
-222
View File
@@ -1,222 +0,0 @@
from __future__ import annotations
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from ...core.database import get_db
from ...core.dependencies import CurrentUser, require_any_permission, require_enabled_menu_route, require_permission
from ...schemas.atp_model import (
AtpEngineStatusResponse,
AtpModelCreateRequest,
AtpModelListResponse,
AtpModelSummary,
AtpModelUpdateRequest,
AtpModelVersionCreateRequest,
AtpModelVersionDetail,
AtpModelVersionListResponse,
AtpModelVersionUpdateRequest,
AtpSimulationRunDetail,
AtpSimulationRunListResponse,
AtpSimulationRunRequest,
)
from ...services.atp_model_service import (
activate_model_version,
create_model,
create_model_version,
delete_model,
get_engine_status,
get_model_by_id,
get_model_run_detail,
get_model_version_by_id,
list_model_runs,
list_model_versions,
list_models,
run_model_version,
serialize_model,
serialize_version_detail,
update_model,
update_model_version,
)
router = APIRouter(prefix="/atp/models", tags=["atp-models"], dependencies=[Depends(require_enabled_menu_route)])
@router.get("/engine/status", response_model=AtpEngineStatusResponse)
def get_atp_engine_status_endpoint(
_: CurrentUser = Depends(require_any_permission("atp.read", "atp.run", "atp.manage")),
) -> AtpEngineStatusResponse:
return get_engine_status()
@router.get("", response_model=AtpModelListResponse)
def get_atp_model_list(
keyword: str | None = Query(default=None),
status_filter: str | None = Query(default=None, alias="status"),
limit: int = Query(default=100, ge=1, le=500),
offset: int = Query(default=0, ge=0),
_: CurrentUser = Depends(require_any_permission("atp.read", "atp.run", "atp.manage")),
db: Session = Depends(get_db),
) -> AtpModelListResponse:
return list_models(db, keyword=keyword, status_filter=status_filter, limit=limit, offset=offset)
@router.post("", response_model=AtpModelSummary)
def create_atp_model_endpoint(
payload: AtpModelCreateRequest,
current_user: CurrentUser = Depends(require_permission("atp.manage")),
db: Session = Depends(get_db),
) -> AtpModelSummary:
created = create_model(db, payload, actor_user_id=current_user.user.id)
if not created:
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Model code already exists")
return created
@router.get("/{model_id}", response_model=AtpModelSummary)
def get_atp_model_detail(
model_id: str,
_: CurrentUser = Depends(require_any_permission("atp.read", "atp.run", "atp.manage")),
db: Session = Depends(get_db),
) -> AtpModelSummary:
item = get_model_by_id(db, model_id)
if not item:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Model not found")
version_count = int(len(item.versions))
run_count = int(len(item.runs))
last_run = item.runs[0] if item.runs else None
return serialize_model(
item,
version_count=version_count,
run_count=run_count,
last_run_status=last_run.status if last_run else None,
last_run_date=last_run.create_date if last_run else None,
)
@router.patch("/{model_id}", response_model=AtpModelSummary)
def update_atp_model_endpoint(
model_id: str,
payload: AtpModelUpdateRequest,
current_user: CurrentUser = Depends(require_permission("atp.manage")),
db: Session = Depends(get_db),
) -> AtpModelSummary:
updated = update_model(db, model_id, payload, actor_user_id=current_user.user.id)
if not updated:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Model not found")
return updated
@router.delete("/{model_id}")
def delete_atp_model_endpoint(
model_id: str,
_: CurrentUser = Depends(require_permission("atp.manage")),
db: Session = Depends(get_db),
) -> dict[str, bool]:
deleted = delete_model(db, model_id)
if not deleted:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Model not found")
return {"success": True}
@router.get("/{model_id}/versions", response_model=AtpModelVersionListResponse)
def get_atp_model_versions(
model_id: str,
limit: int = Query(default=100, ge=1, le=500),
offset: int = Query(default=0, ge=0),
_: CurrentUser = Depends(require_any_permission("atp.read", "atp.run", "atp.manage")),
db: Session = Depends(get_db),
) -> AtpModelVersionListResponse:
if not get_model_by_id(db, model_id):
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Model not found")
return list_model_versions(db, model_id=model_id, limit=limit, offset=offset)
@router.post("/{model_id}/versions", response_model=AtpModelVersionDetail)
def create_atp_model_version_endpoint(
model_id: str,
payload: AtpModelVersionCreateRequest,
current_user: CurrentUser = Depends(require_permission("atp.manage")),
db: Session = Depends(get_db),
) -> AtpModelVersionDetail:
return create_model_version(db, model_id=model_id, payload=payload, actor_user_id=current_user.user.id)
@router.get("/{model_id}/versions/{version_id}", response_model=AtpModelVersionDetail)
def get_atp_model_version_detail(
model_id: str,
version_id: str,
_: CurrentUser = Depends(require_any_permission("atp.read", "atp.run", "atp.manage")),
db: Session = Depends(get_db),
) -> AtpModelVersionDetail:
item = get_model_version_by_id(db, model_id=model_id, version_id=version_id)
if not item:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Version not found")
return serialize_version_detail(item)
@router.patch("/{model_id}/versions/{version_id}", response_model=AtpModelVersionDetail)
def update_atp_model_version_endpoint(
model_id: str,
version_id: str,
payload: AtpModelVersionUpdateRequest,
current_user: CurrentUser = Depends(require_permission("atp.manage")),
db: Session = Depends(get_db),
) -> AtpModelVersionDetail:
return update_model_version(
db,
model_id=model_id,
version_id=version_id,
payload=payload,
actor_user_id=current_user.user.id,
)
@router.post("/{model_id}/versions/{version_id}/activate", response_model=AtpModelSummary)
def activate_atp_model_version_endpoint(
model_id: str,
version_id: str,
current_user: CurrentUser = Depends(require_permission("atp.manage")),
db: Session = Depends(get_db),
) -> AtpModelSummary:
return activate_model_version(
db,
model_id=model_id,
version_id=version_id,
actor_user_id=current_user.user.id,
)
@router.get("/{model_id}/runs", response_model=AtpSimulationRunListResponse)
def get_atp_model_runs(
model_id: str,
limit: int = Query(default=100, ge=1, le=500),
offset: int = Query(default=0, ge=0),
_: CurrentUser = Depends(require_any_permission("atp.read", "atp.run", "atp.manage")),
db: Session = Depends(get_db),
) -> AtpSimulationRunListResponse:
if not get_model_by_id(db, model_id):
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Model not found")
return list_model_runs(db, model_id=model_id, limit=limit, offset=offset)
@router.post("/{model_id}/runs", response_model=AtpSimulationRunDetail)
def run_atp_model_endpoint(
model_id: str,
payload: AtpSimulationRunRequest,
current_user: CurrentUser = Depends(require_any_permission("atp.run", "atp.manage")),
db: Session = Depends(get_db),
) -> AtpSimulationRunDetail:
return run_model_version(db, model_id=model_id, payload=payload, actor_user_id=current_user.user.id)
@router.get("/{model_id}/runs/{run_id}", response_model=AtpSimulationRunDetail)
def get_atp_model_run_detail(
model_id: str,
run_id: str,
_: CurrentUser = Depends(require_any_permission("atp.read", "atp.run", "atp.manage")),
db: Session = Depends(get_db),
) -> AtpSimulationRunDetail:
if not get_model_by_id(db, model_id):
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Model not found")
return get_model_run_detail(db, model_id=model_id, run_id=run_id)
+1 -2
View File
@@ -4,12 +4,11 @@ Import all model modules during package initialization so SQLAlchemy can
resolve string-based relationships regardless of route/service import order.
"""
from . import ai_chat, atp_asset, atp_model, audit_log, auth_session, document, elevation, file_storage, fl_analysis, lightning_event, lightning_sample, line, line_tower, menu, object_group, rbac, scheduled_task, system_message, system_param, tower_model, tower_profile, user, wine, worker_registry
from . import ai_chat, atp_asset, audit_log, auth_session, document, elevation, file_storage, fl_analysis, lightning_event, lightning_sample, line, line_tower, menu, object_group, rbac, scheduled_task, system_message, system_param, tower_model, tower_profile, user, wine, worker_registry
__all__ = [
"ai_chat",
"atp_asset",
"atp_model",
"audit_log",
"auth_session",
"document",
-152
View File
@@ -1,152 +0,0 @@
from __future__ import annotations
from datetime import datetime
from typing import Any
from uuid import uuid4
from sqlalchemy import JSON, DateTime, ForeignKey, Index, Integer, String, Text, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship
from ..core.database import Base
from .base import utcnow
class AtpModel(Base):
__tablename__ = "atp_model"
__table_args__ = (
UniqueConstraint("code", name="uq_atp_model_code"),
Index("idx_atp_model_status", "status"),
Index("idx_atp_model_source", "source_type"),
)
id: Mapped[str] = mapped_column(
String(32),
primary_key=True,
default=lambda: uuid4().hex,
)
code: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
name: Mapped[str] = mapped_column(String(255), nullable=False)
source_type: Mapped[str] = mapped_column(String(32), default="atpdraw", index=True)
description: Mapped[str] = mapped_column(Text(), default="")
status: Mapped[str] = mapped_column(String(20), default="enabled", index=True)
tags_json: Mapped[list[str]] = mapped_column(JSON, default=list)
latest_version_no: Mapped[int] = mapped_column(Integer, default=0)
active_version_no: Mapped[int | None] = mapped_column(Integer)
create_date: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, index=True)
create_user: Mapped[str | None] = mapped_column(String(64), index=True)
update_date: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=utcnow,
onupdate=utcnow,
)
update_user: Mapped[str | None] = mapped_column(String(64), index=True)
versions: Mapped[list[AtpModelVersion]] = relationship(
"AtpModelVersion",
back_populates="model",
lazy="selectin",
cascade="all, delete-orphan",
order_by="AtpModelVersion.version_no.desc()",
)
runs: Mapped[list[AtpSimulationRun]] = relationship(
"AtpSimulationRun",
back_populates="model",
lazy="selectin",
cascade="all, delete-orphan",
order_by="AtpSimulationRun.create_date.desc()",
)
class AtpModelVersion(Base):
__tablename__ = "atp_model_version"
__table_args__ = (
UniqueConstraint("model_id", "version_no", name="uq_atp_model_version_model_no"),
Index("idx_atp_model_version_status", "status"),
Index("idx_atp_model_version_model_status", "model_id", "status"),
Index("idx_atp_model_version_content_hash", "content_hash"),
)
id: Mapped[str] = mapped_column(
String(32),
primary_key=True,
default=lambda: uuid4().hex,
)
model_id: Mapped[str] = mapped_column(
String(32),
ForeignKey("atp_model.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
version_no: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
version_tag: Mapped[str | None] = mapped_column(String(64), index=True)
status: Mapped[str] = mapped_column(String(20), default="draft", index=True)
entry_file: Mapped[str | None] = mapped_column(String(255))
change_note: Mapped[str] = mapped_column(Text(), default="")
artifact_manifest_json: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict)
graph_json: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict)
atp_text: Mapped[str] = mapped_column(Text(), default="")
content_hash: Mapped[str] = mapped_column(String(64), index=True)
create_date: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, index=True)
create_user: Mapped[str | None] = mapped_column(String(64), index=True)
update_date: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=utcnow,
onupdate=utcnow,
)
update_user: Mapped[str | None] = mapped_column(String(64), index=True)
model: Mapped[AtpModel] = relationship("AtpModel", back_populates="versions", lazy="selectin")
runs: Mapped[list[AtpSimulationRun]] = relationship(
"AtpSimulationRun",
back_populates="version",
lazy="selectin",
order_by="AtpSimulationRun.create_date.desc()",
)
class AtpSimulationRun(Base):
__tablename__ = "atp_simulation_run"
__table_args__ = (
Index("idx_atp_simulation_run_status", "status"),
Index("idx_atp_simulation_run_model", "model_id", "create_date"),
)
id: Mapped[str] = mapped_column(
String(32),
primary_key=True,
default=lambda: uuid4().hex,
)
model_id: Mapped[str] = mapped_column(
String(32),
ForeignKey("atp_model.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
version_id: Mapped[str | None] = mapped_column(
String(32),
ForeignKey("atp_model_version.id", ondelete="SET NULL"),
index=True,
)
status: Mapped[str] = mapped_column(String(20), default="pending", index=True)
engine_mode: Mapped[str] = mapped_column(String(20), default="wine", index=True)
task_id: Mapped[str | None] = mapped_column(String(128), index=True)
engine_command: Mapped[str | None] = mapped_column(String(1000))
working_dir: Mapped[str | None] = mapped_column(String(1000))
timeout_seconds: Mapped[int] = mapped_column(Integer, default=600)
exit_code: Mapped[int | None] = mapped_column(Integer)
started_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
finished_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
duration_ms: Mapped[int | None] = mapped_column(Integer)
stdout_text: Mapped[str | None] = mapped_column(Text())
stderr_text: Mapped[str | None] = mapped_column(Text())
error_message: Mapped[str | None] = mapped_column(Text())
create_date: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, index=True)
create_user: Mapped[str | None] = mapped_column(String(64), index=True)
update_date: Mapped[datetime] = mapped_column(
DateTime(timezone=True),
default=utcnow,
onupdate=utcnow,
)
update_user: Mapped[str | None] = mapped_column(String(64), index=True)
model: Mapped[AtpModel] = relationship("AtpModel", back_populates="runs", lazy="selectin")
version: Mapped[AtpModelVersion | None] = relationship("AtpModelVersion", back_populates="runs", lazy="selectin")
+13
View File
@@ -209,3 +209,16 @@ class AtpAssetRunRequest(BaseModel):
class AtpAssetReleaseUploadResponse(BaseModel):
task_id: str
status: str
class AtpEngineStatusResponse(BaseModel):
mode: AtpAssetEngineMode
available: bool
executable_path: str
resolved_executable: str | None = None
storage_root: str
workdir: str
default_timeout_seconds: int
max_timeout_seconds: int
checks: dict[str, dict[str, Any]] = Field(default_factory=dict)
error: str | None = None
-155
View File
@@ -1,155 +0,0 @@
from __future__ import annotations
from datetime import datetime
from typing import Any, Literal
from pydantic import BaseModel, Field
AtpModelStatus = Literal["enabled", "disabled"]
AtpModelSourceType = Literal["atpdraw", "atp", "manual"]
AtpModelVersionStatus = Literal["draft", "released", "archived"]
AtpSimulationRunStatus = Literal["pending", "running", "success", "failed"]
AtpEngineMode = Literal["wine", "native"]
class AtpModelSummary(BaseModel):
id: str
code: str
name: str
source_type: AtpModelSourceType
description: str
status: AtpModelStatus
tags_json: list[str] = Field(default_factory=list)
latest_version_no: int = 0
active_version_no: int | None = None
version_count: int = 0
run_count: int = 0
last_run_status: AtpSimulationRunStatus | None = None
last_run_date: datetime | None = None
create_date: datetime
create_user: str | None = None
update_date: datetime
update_user: str | None = None
class AtpModelListResponse(BaseModel):
items: list[AtpModelSummary]
total: int
class AtpModelCreateRequest(BaseModel):
code: str = Field(min_length=1, max_length=64)
name: str = Field(min_length=1, max_length=255)
source_type: AtpModelSourceType = "atpdraw"
description: str = Field(default="", max_length=8000)
status: AtpModelStatus = "enabled"
tags_json: list[str] = Field(default_factory=list, max_length=128)
class AtpModelUpdateRequest(BaseModel):
name: str | None = Field(default=None, min_length=1, max_length=255)
source_type: AtpModelSourceType | None = None
description: str | None = Field(default=None, max_length=8000)
status: AtpModelStatus | None = None
tags_json: list[str] | None = Field(default=None, max_length=128)
class AtpModelVersionSummary(BaseModel):
id: str
model_id: str
version_no: int
version_tag: str | None = None
status: AtpModelVersionStatus
entry_file: str | None = None
change_note: str
artifact_manifest_json: dict[str, Any] = Field(default_factory=dict)
content_hash: str
atp_text_size: int
create_date: datetime
create_user: str | None = None
update_date: datetime
update_user: str | None = None
class AtpModelVersionDetail(AtpModelVersionSummary):
atp_text: str
graph_json: dict[str, Any] = Field(default_factory=dict)
class AtpModelVersionListResponse(BaseModel):
items: list[AtpModelVersionSummary]
total: int
class AtpModelVersionCreateRequest(BaseModel):
version_tag: str | None = Field(default=None, max_length=64)
status: AtpModelVersionStatus = "released"
entry_file: str | None = Field(default=None, max_length=255)
change_note: str = Field(default="", max_length=8000)
artifact_manifest_json: dict[str, Any] = Field(default_factory=dict)
graph_json: dict[str, Any] = Field(default_factory=dict)
atp_text: str = Field(min_length=1)
class AtpModelVersionUpdateRequest(BaseModel):
version_tag: str | None = Field(default=None, max_length=64)
status: AtpModelVersionStatus | None = None
entry_file: str | None = Field(default=None, max_length=255)
change_note: str | None = Field(default=None, max_length=8000)
artifact_manifest_json: dict[str, Any] | None = None
graph_json: dict[str, Any] | None = None
atp_text: str | None = Field(default=None, min_length=1)
class AtpSimulationRunSummary(BaseModel):
id: str
model_id: str
version_id: str | None = None
version_no: int | None = None
task_id: str | None = None
status: AtpSimulationRunStatus
engine_mode: AtpEngineMode
engine_command: str | None = None
working_dir: str | None = None
timeout_seconds: int
exit_code: int | None = None
started_at: datetime | None = None
finished_at: datetime | None = None
duration_ms: int | None = None
error_message: str | None = None
stdout_size: int = 0
stderr_size: int = 0
create_date: datetime
create_user: str | None = None
class AtpSimulationRunDetail(AtpSimulationRunSummary):
stdout_text: str | None = None
stderr_text: str | None = None
class AtpSimulationRunListResponse(BaseModel):
items: list[AtpSimulationRunSummary]
total: int
class AtpSimulationRunRequest(BaseModel):
version_id: str | None = None
version_no: int | None = Field(default=None, ge=1)
timeout_seconds: int | None = Field(default=None, ge=1)
extra_args: list[str] = Field(default_factory=list, max_length=32)
environment: dict[str, str] = Field(default_factory=dict, max_length=16)
dry_run: bool = False
class AtpEngineStatusResponse(BaseModel):
mode: AtpEngineMode
available: bool
executable_path: str
resolved_executable: str | None = None
storage_root: str
workdir: str
default_timeout_seconds: int
max_timeout_seconds: int
checks: dict[str, dict[str, Any]] = Field(default_factory=dict)
error: str | None = None
+82
View File
@@ -41,8 +41,11 @@ from ..schemas.atp_asset import (
AtpAssetRunSummary,
AtpAssetSummary,
AtpAssetUpdateRequest,
AtpEngineStatusResponse,
)
from .legacy_atp_adapter import build_legacy_atp_status_checks
from .push_service import publish_topic
from .wine_probe import probe_wine_binary
from .storage_driver import (
StorageDriver,
StorageDriverError,
@@ -164,6 +167,85 @@ def _resolve_binary(raw_path: str) -> str | None:
return None
def _resolve_storage_root() -> Path:
root = Path(settings.atp_storage_root).expanduser()
return root.resolve(strict=False)
def _resolve_engine_workdir() -> Path:
configured = Path(settings.atp_engine_workdir).expanduser()
if configured.is_absolute():
return configured.resolve(strict=False)
return (_resolve_storage_root() / configured).resolve(strict=False)
def _resolve_wine_engine_executable() -> tuple[str | None, str | None, str | None]:
wine_binary = _resolve_binary(settings.wine_binary_path)
if not wine_binary:
return None, None, "Wine binary not found"
allowed_root = Path(settings.wine_allowed_root).expanduser().resolve(strict=False)
configured = Path(settings.atp_engine_executable).expanduser()
if not configured.is_absolute():
configured = (allowed_root / configured).resolve(strict=False)
else:
configured = configured.resolve(strict=False)
if not configured.is_relative_to(allowed_root):
return wine_binary, None, f"ATP engine executable must be inside {allowed_root}"
if not configured.exists() or not configured.is_file():
return wine_binary, None, f"ATP engine executable not found: {configured}"
probe = probe_wine_binary(wine_binary)
return wine_binary, str(configured), None if probe.available else (probe.error or "Wine binary unavailable")
def _resolve_native_engine_executable() -> tuple[str | None, str | None]:
resolved = _resolve_binary(settings.atp_engine_executable)
if not resolved:
return None, "ATP engine executable not found"
return resolved, None
def get_engine_status() -> AtpEngineStatusResponse:
mode = _resolve_engine_mode()
storage_root = str(_resolve_storage_root())
workdir = str(_resolve_engine_workdir())
checks = build_legacy_atp_status_checks()
if mode == "wine":
wine_binary, resolved_engine, error = _resolve_wine_engine_executable()
available = error is None
executable_path = settings.atp_engine_executable.strip()
resolved_binary = f"{wine_binary} -> {resolved_engine}" if wine_binary and resolved_engine else wine_binary
return AtpEngineStatusResponse(
mode="wine",
available=available,
executable_path=executable_path,
resolved_executable=resolved_binary,
storage_root=storage_root,
workdir=workdir,
default_timeout_seconds=settings.atp_engine_default_timeout_seconds,
max_timeout_seconds=settings.atp_engine_max_timeout_seconds,
checks=checks,
error=error,
)
resolved_engine, error = _resolve_native_engine_executable()
return AtpEngineStatusResponse(
mode="native",
available=error is None,
executable_path=settings.atp_engine_executable.strip(),
resolved_executable=resolved_engine,
storage_root=storage_root,
workdir=workdir,
default_timeout_seconds=settings.atp_engine_default_timeout_seconds,
max_timeout_seconds=settings.atp_engine_max_timeout_seconds,
checks=checks,
error=error,
)
def _resolve_mount(db: Session, mount_code: str) -> FileStorageMount:
mount = db.execute(
select(FileStorageMount)
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -31,7 +31,7 @@ from ..schemas.fl_analysis import (
FlAnalysisTowerResultListResponse,
FlAnalysisTowerResultSummary,
)
from .atp_model_service import _truncate_output
from .atp_asset_service import _truncate_output
from .fl_analysis_external import execute_external_waveform_tower_analysis, resolve_external_waveform_job
from .legacy_atp_adapter import execute_legacy_atp_tower_analysis, resolve_legacy_atp_job
from .fl_analysis_report import build_report_document, build_report_summary_payload
-20
View File
@@ -1,20 +0,0 @@
from __future__ import annotations
from typing import Any
from ..core.celery_app import celery_app
from ..services.atp_model_service import execute_model_run_job
@celery_app.task(name="app.tasks.atp_model_tasks.execute_atp_model_run_job")
def execute_atp_model_run_job(
run_id: str,
payload_data: dict[str, Any],
actor_user_id: str | None,
) -> dict[str, str]:
execute_model_run_job(
run_id=run_id,
payload_data=payload_data,
actor_user_id=actor_user_id,
)
return {"run_id": run_id, "status": "done"}