mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
- 删除全部 Python 源码 (src/) 及 Alembic 迁移脚本,归档至 _deprecated_py_src/ - 重构 Rust gateway ai_pipeline: 拆分 planner/finalize 模块,新增 contracts/adaptation 层 - 重组 handlers 模块为 admin/public/proxy/internal/shared 子模块结构 - 新增 executor 模块,引入 Rust 原生数据库迁移 (aether-data/migrations) - 简化 CI/Docker 构建流程,移除 base image 二级构建,统一为单一 app image - 移除 Python 相关基础设施文件 (entrypoint.sh, gunicorn_conf.py, Dockerfile.base)
681 lines
22 KiB
Python
681 lines
22 KiB
Python
"""
|
|
Provider 操作 API 路由
|
|
|
|
提供 Provider 操作相关的 API 端点:
|
|
- 架构列表
|
|
- 连接管理
|
|
- 操作执行(余额查询、签到等)
|
|
- 配置管理
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import asdict, dataclass, is_dataclass
|
|
from typing import Any
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, Query, Request
|
|
from pydantic import BaseModel, Field
|
|
from sqlalchemy.orm import Session
|
|
|
|
from src.api.base.admin_adapter import AdminApiAdapter
|
|
from src.api.base.context import ApiRequestContext
|
|
from src.api.base.pipeline import get_pipeline
|
|
from src.database import get_db
|
|
from src.models.database import Provider
|
|
from src.services.provider_ops import (
|
|
ConnectorAuthType,
|
|
ProviderActionType,
|
|
ProviderOpsConfig,
|
|
ProviderOpsService,
|
|
get_registry,
|
|
)
|
|
|
|
router = APIRouter(prefix="/api/admin/provider-ops", tags=["Provider Operations"])
|
|
pipeline = get_pipeline()
|
|
|
|
|
|
# ==================== Request/Response Models ====================
|
|
|
|
|
|
class ArchitectureInfo(BaseModel):
|
|
"""架构信息"""
|
|
|
|
architecture_id: str
|
|
display_name: str
|
|
description: str
|
|
credentials_schema: dict[str, Any]
|
|
supported_auth_types: list[dict[str, Any]]
|
|
supported_actions: list[dict[str, Any]]
|
|
default_connector: str | None
|
|
|
|
|
|
class ConnectorConfigRequest(BaseModel):
|
|
"""连接器配置请求"""
|
|
|
|
auth_type: str = Field(..., description="认证类型")
|
|
config: dict[str, Any] = Field(default_factory=dict, description="连接器配置")
|
|
credentials: dict[str, Any] = Field(default_factory=dict, description="凭据信息")
|
|
|
|
|
|
class ActionConfigRequest(BaseModel):
|
|
"""操作配置请求"""
|
|
|
|
enabled: bool = Field(True, description="是否启用")
|
|
config: dict[str, Any] = Field(default_factory=dict, description="操作配置")
|
|
|
|
|
|
class SaveConfigRequest(BaseModel):
|
|
"""保存配置请求"""
|
|
|
|
architecture_id: str = Field("generic_api", description="架构 ID")
|
|
base_url: str | None = Field(None, description="API 基础地址")
|
|
connector: ConnectorConfigRequest
|
|
actions: dict[str, ActionConfigRequest] = Field(default_factory=dict)
|
|
schedule: dict[str, str] = Field(default_factory=dict, description="定时任务配置")
|
|
|
|
|
|
class ConnectRequest(BaseModel):
|
|
"""连接请求"""
|
|
|
|
credentials: dict[str, Any] | None = Field(None, description="凭据(可选,使用已保存的)")
|
|
|
|
|
|
class ExecuteActionRequest(BaseModel):
|
|
"""执行操作请求"""
|
|
|
|
config: dict[str, Any] | None = Field(None, description="操作配置(覆盖默认)")
|
|
|
|
|
|
class ConnectionStatusResponse(BaseModel):
|
|
"""连接状态响应"""
|
|
|
|
status: str
|
|
auth_type: str
|
|
connected_at: str | None
|
|
expires_at: str | None
|
|
last_error: str | None
|
|
|
|
|
|
class ActionResultResponse(BaseModel):
|
|
"""操作结果响应"""
|
|
|
|
status: str
|
|
action_type: str
|
|
data: Any | None
|
|
message: str | None
|
|
executed_at: str
|
|
response_time_ms: int | None
|
|
cache_ttl_seconds: int
|
|
|
|
|
|
class ProviderOpsStatusResponse(BaseModel):
|
|
"""Provider 操作状态响应"""
|
|
|
|
provider_id: str
|
|
is_configured: bool
|
|
architecture_id: str | None
|
|
connection_status: ConnectionStatusResponse
|
|
enabled_actions: list[str]
|
|
|
|
|
|
class ProviderOpsConfigResponse(BaseModel):
|
|
"""Provider 操作配置响应(脱敏)"""
|
|
|
|
provider_id: str
|
|
is_configured: bool
|
|
architecture_id: str | None = None
|
|
base_url: str | None = None
|
|
connector: dict[str, Any] | None = None
|
|
|
|
|
|
class VerifyAuthResponse(BaseModel):
|
|
"""验证认证响应"""
|
|
|
|
success: bool
|
|
message: str | None = None
|
|
data: dict[str, Any] | None = None
|
|
updated_credentials: dict[str, Any] | None = None
|
|
|
|
|
|
# ==================== Helper Functions ====================
|
|
|
|
|
|
def _serialize_data(data: Any) -> Any:
|
|
"""序列化 dataclass 为字典,用于 JSON 响应"""
|
|
if data is None:
|
|
return None
|
|
if is_dataclass(data) and not isinstance(data, type):
|
|
return asdict(data)
|
|
return data
|
|
|
|
|
|
def _build_action_result_response(result: Any) -> ActionResultResponse:
|
|
return ActionResultResponse(
|
|
status=result.status.value,
|
|
action_type=result.action_type.value,
|
|
data=_serialize_data(result.data),
|
|
message=result.message,
|
|
executed_at=result.executed_at.isoformat(),
|
|
response_time_ms=result.response_time_ms,
|
|
cache_ttl_seconds=result.cache_ttl_seconds,
|
|
)
|
|
|
|
|
|
def _resolve_provider_base_url(
|
|
provider_id: str,
|
|
db: Session,
|
|
*,
|
|
saved_config: ProviderOpsConfig | None = None,
|
|
) -> str | None:
|
|
base_url = saved_config.base_url if saved_config else None
|
|
if base_url:
|
|
return base_url
|
|
|
|
provider = db.query(Provider).filter(Provider.id == provider_id).first()
|
|
if not provider:
|
|
return None
|
|
|
|
if provider.endpoints:
|
|
for endpoint in provider.endpoints:
|
|
if endpoint.base_url:
|
|
return endpoint.base_url
|
|
|
|
provider_config = provider.config or {}
|
|
return provider_config.get("base_url") or provider.website
|
|
|
|
|
|
def _list_architectures_response() -> list[dict[str, Any]]:
|
|
registry = get_registry()
|
|
return registry.to_dict_list()
|
|
|
|
|
|
def _get_architecture_response(architecture_id: str) -> dict[str, Any]:
|
|
registry = get_registry()
|
|
arch = registry.get(architecture_id)
|
|
if not arch:
|
|
raise HTTPException(status_code=404, detail=f"架构 {architecture_id} 不存在")
|
|
return arch.to_dict()
|
|
|
|
|
|
def _get_provider_ops_status_response(provider_id: str, db: Session) -> ProviderOpsStatusResponse:
|
|
service = ProviderOpsService(db)
|
|
config = service.get_config(provider_id)
|
|
conn_state = service.get_connection_status(provider_id)
|
|
|
|
enabled_actions = []
|
|
if config:
|
|
for action_type, action_config in config.actions.items():
|
|
if action_config.get("enabled", True):
|
|
enabled_actions.append(action_type)
|
|
|
|
return ProviderOpsStatusResponse(
|
|
provider_id=provider_id,
|
|
is_configured=config is not None,
|
|
architecture_id=config.architecture_id if config else None,
|
|
connection_status=ConnectionStatusResponse(
|
|
status=conn_state.status.value,
|
|
auth_type=conn_state.auth_type.value,
|
|
connected_at=conn_state.connected_at.isoformat() if conn_state.connected_at else None,
|
|
expires_at=conn_state.expires_at.isoformat() if conn_state.expires_at else None,
|
|
last_error=conn_state.last_error,
|
|
),
|
|
enabled_actions=enabled_actions,
|
|
)
|
|
|
|
|
|
def _get_provider_ops_config_response(
|
|
provider_id: str,
|
|
db: Session,
|
|
) -> ProviderOpsConfigResponse:
|
|
service = ProviderOpsService(db)
|
|
config = service.get_config(provider_id)
|
|
|
|
if not config:
|
|
return ProviderOpsConfigResponse(
|
|
provider_id=provider_id,
|
|
is_configured=False,
|
|
)
|
|
|
|
masked_credentials = service.get_masked_credentials(config.connector_credentials)
|
|
base_url = _resolve_provider_base_url(provider_id, db, saved_config=config)
|
|
|
|
return ProviderOpsConfigResponse(
|
|
provider_id=provider_id,
|
|
is_configured=True,
|
|
architecture_id=config.architecture_id,
|
|
base_url=base_url,
|
|
connector={
|
|
"auth_type": config.connector_auth_type.value,
|
|
"config": config.connector_config,
|
|
"credentials": masked_credentials,
|
|
},
|
|
)
|
|
|
|
|
|
def _save_provider_ops_config_response(
|
|
provider_id: str,
|
|
payload: SaveConfigRequest,
|
|
db: Session,
|
|
) -> dict[str, Any]:
|
|
service = ProviderOpsService(db)
|
|
credentials = service.merge_credentials_with_saved(
|
|
provider_id, dict(payload.connector.credentials)
|
|
)
|
|
|
|
config = ProviderOpsConfig(
|
|
architecture_id=payload.architecture_id,
|
|
base_url=payload.base_url,
|
|
connector_auth_type=ConnectorAuthType(payload.connector.auth_type),
|
|
connector_config=payload.connector.config,
|
|
connector_credentials=credentials,
|
|
actions={
|
|
action_type: {"enabled": action_config.enabled, "config": action_config.config}
|
|
for action_type, action_config in payload.actions.items()
|
|
},
|
|
schedule=payload.schedule,
|
|
)
|
|
|
|
success = service.save_config(provider_id, config)
|
|
if not success:
|
|
raise HTTPException(status_code=404, detail="Provider 不存在")
|
|
|
|
return {"success": True, "message": "配置保存成功"}
|
|
|
|
|
|
async def _verify_provider_auth_response(
|
|
provider_id: str,
|
|
payload: SaveConfigRequest,
|
|
db: Session,
|
|
) -> VerifyAuthResponse:
|
|
service = ProviderOpsService(db)
|
|
base_url = payload.base_url or _resolve_provider_base_url(provider_id, db)
|
|
if not base_url:
|
|
return VerifyAuthResponse(
|
|
success=False,
|
|
message="请提供 API 地址",
|
|
)
|
|
|
|
credentials = service.merge_credentials_with_saved(
|
|
provider_id, dict(payload.connector.credentials)
|
|
)
|
|
result = await service.verify_auth(
|
|
base_url=base_url,
|
|
architecture_id=payload.architecture_id,
|
|
auth_type=ConnectorAuthType(payload.connector.auth_type),
|
|
config=payload.connector.config,
|
|
credentials=credentials,
|
|
provider_id=provider_id,
|
|
)
|
|
|
|
return VerifyAuthResponse(
|
|
success=result.get("success", False),
|
|
message=result.get("message"),
|
|
data=result.get("data"),
|
|
updated_credentials=result.get("updated_credentials"),
|
|
)
|
|
|
|
|
|
def _delete_provider_ops_config_response(provider_id: str, db: Session) -> dict[str, Any]:
|
|
service = ProviderOpsService(db)
|
|
success = service.delete_config(provider_id)
|
|
if not success:
|
|
raise HTTPException(status_code=404, detail="Provider 不存在")
|
|
return {"success": True, "message": "配置已删除"}
|
|
|
|
|
|
async def _connect_provider_response(
|
|
provider_id: str,
|
|
payload: ConnectRequest,
|
|
db: Session,
|
|
) -> dict[str, Any]:
|
|
service = ProviderOpsService(db)
|
|
success, message = await service.connect(provider_id, payload.credentials)
|
|
if not success:
|
|
raise HTTPException(status_code=400, detail=message)
|
|
return {"success": True, "message": message}
|
|
|
|
|
|
async def _disconnect_provider_response(provider_id: str, db: Session) -> dict[str, Any]:
|
|
service = ProviderOpsService(db)
|
|
await service.disconnect(provider_id)
|
|
return {"success": True, "message": "已断开连接"}
|
|
|
|
|
|
async def _execute_action_response(
|
|
provider_id: str,
|
|
action_type: str,
|
|
payload: ExecuteActionRequest,
|
|
db: Session,
|
|
) -> ActionResultResponse:
|
|
service = ProviderOpsService(db)
|
|
try:
|
|
action_type_enum = ProviderActionType(action_type)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=f"无效的操作类型: {action_type}") from exc
|
|
|
|
result = await service.execute_action(provider_id, action_type_enum, payload.config)
|
|
return _build_action_result_response(result)
|
|
|
|
|
|
async def _get_balance_response(
|
|
provider_id: str,
|
|
refresh: bool,
|
|
db: Session,
|
|
) -> ActionResultResponse:
|
|
service = ProviderOpsService(db)
|
|
result = await service.query_balance_with_cache(provider_id, trigger_refresh=refresh)
|
|
return _build_action_result_response(result)
|
|
|
|
|
|
async def _refresh_balance_response(provider_id: str, db: Session) -> ActionResultResponse:
|
|
service = ProviderOpsService(db)
|
|
result = await service.query_balance(provider_id)
|
|
return _build_action_result_response(result)
|
|
|
|
|
|
async def _checkin_response(provider_id: str, db: Session) -> ActionResultResponse:
|
|
service = ProviderOpsService(db)
|
|
result = await service.checkin(provider_id)
|
|
return _build_action_result_response(result)
|
|
|
|
|
|
async def _batch_query_balance_response(
|
|
provider_ids: list[str] | None,
|
|
db: Session,
|
|
) -> dict[str, ActionResultResponse]:
|
|
service = ProviderOpsService(db)
|
|
results = await service.batch_query_balance(provider_ids)
|
|
return {
|
|
provider_id: _build_action_result_response(result)
|
|
for provider_id, result in results.items()
|
|
}
|
|
|
|
|
|
# ==================== Routes ====================
|
|
|
|
|
|
@router.get("/architectures", response_model=list[ArchitectureInfo])
|
|
async def list_architectures(request: Request, db: Session = Depends(get_db)) -> Any:
|
|
"""获取所有可用的架构"""
|
|
adapter = AdminProviderOpsListArchitecturesAdapter()
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.get("/architectures/{architecture_id}", response_model=ArchitectureInfo)
|
|
async def get_architecture(
|
|
architecture_id: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""获取指定架构的详情"""
|
|
adapter = AdminProviderOpsGetArchitectureAdapter(architecture_id=architecture_id)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.get("/providers/{provider_id}/status", response_model=ProviderOpsStatusResponse)
|
|
async def get_provider_ops_status(
|
|
provider_id: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""获取 Provider 的操作状态"""
|
|
adapter = AdminProviderOpsStatusAdapter(provider_id=provider_id)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.get("/providers/{provider_id}/config", response_model=ProviderOpsConfigResponse)
|
|
async def get_provider_ops_config(
|
|
provider_id: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""获取 Provider 的操作配置(脱敏)"""
|
|
adapter = AdminProviderOpsConfigAdapter(provider_id=provider_id)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.put("/providers/{provider_id}/config")
|
|
async def save_provider_ops_config(
|
|
provider_id: str,
|
|
payload: SaveConfigRequest,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""保存 Provider 的操作配置"""
|
|
adapter = AdminProviderOpsSaveConfigAdapter(provider_id=provider_id, payload=payload)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.post("/providers/{provider_id}/verify", response_model=VerifyAuthResponse)
|
|
async def verify_provider_auth(
|
|
provider_id: str,
|
|
payload: SaveConfigRequest,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""验证 Provider 认证配置"""
|
|
adapter = AdminProviderOpsVerifyAuthAdapter(provider_id=provider_id, payload=payload)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.delete("/providers/{provider_id}/config")
|
|
async def delete_provider_ops_config(
|
|
provider_id: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""删除 Provider 的操作配置"""
|
|
adapter = AdminProviderOpsDeleteConfigAdapter(provider_id=provider_id)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.post("/providers/{provider_id}/connect")
|
|
async def connect_provider(
|
|
provider_id: str,
|
|
payload: ConnectRequest,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""建立与 Provider 的连接"""
|
|
adapter = AdminProviderOpsConnectAdapter(provider_id=provider_id, payload=payload)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.post("/providers/{provider_id}/disconnect")
|
|
async def disconnect_provider(
|
|
provider_id: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""断开与 Provider 的连接"""
|
|
adapter = AdminProviderOpsDisconnectAdapter(provider_id=provider_id)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.post(
|
|
"/providers/{provider_id}/actions/{action_type}",
|
|
response_model=ActionResultResponse,
|
|
)
|
|
async def execute_action(
|
|
provider_id: str,
|
|
action_type: str,
|
|
payload: ExecuteActionRequest,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""执行指定操作"""
|
|
adapter = AdminProviderOpsExecuteActionAdapter(
|
|
provider_id=provider_id,
|
|
action_type=action_type,
|
|
payload=payload,
|
|
)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.get("/providers/{provider_id}/balance", response_model=ActionResultResponse)
|
|
async def get_balance(
|
|
provider_id: str,
|
|
request: Request,
|
|
refresh: bool = True,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""获取余额(优先返回缓存,后台异步刷新)"""
|
|
adapter = AdminProviderOpsGetBalanceAdapter(provider_id=provider_id, refresh=refresh)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.post("/providers/{provider_id}/balance", response_model=ActionResultResponse)
|
|
async def refresh_balance(
|
|
provider_id: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""立即刷新余额(同步等待结果)"""
|
|
adapter = AdminProviderOpsRefreshBalanceAdapter(provider_id=provider_id)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.post("/providers/{provider_id}/checkin", response_model=ActionResultResponse)
|
|
async def checkin(
|
|
provider_id: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""签到(快捷方法)"""
|
|
adapter = AdminProviderOpsCheckinAdapter(provider_id=provider_id)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
@router.post("/batch/balance")
|
|
async def batch_query_balance(
|
|
request: Request,
|
|
provider_ids: list[str] | None = Query(None),
|
|
db: Session = Depends(get_db),
|
|
) -> Any:
|
|
"""批量查询余额"""
|
|
adapter = AdminProviderOpsBatchBalanceAdapter(provider_ids=provider_ids)
|
|
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=adapter.mode)
|
|
|
|
|
|
# ==================== Adapters ====================
|
|
|
|
|
|
class AdminProviderOpsListArchitecturesAdapter(AdminApiAdapter):
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return _list_architectures_response()
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsGetArchitectureAdapter(AdminApiAdapter):
|
|
architecture_id: str
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return _get_architecture_response(self.architecture_id)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsStatusAdapter(AdminApiAdapter):
|
|
provider_id: str
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return _get_provider_ops_status_response(self.provider_id, context.db)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsConfigAdapter(AdminApiAdapter):
|
|
provider_id: str
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return _get_provider_ops_config_response(self.provider_id, context.db)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsSaveConfigAdapter(AdminApiAdapter):
|
|
provider_id: str
|
|
payload: SaveConfigRequest
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return _save_provider_ops_config_response(self.provider_id, self.payload, context.db)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsVerifyAuthAdapter(AdminApiAdapter):
|
|
provider_id: str
|
|
payload: SaveConfigRequest
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return await _verify_provider_auth_response(self.provider_id, self.payload, context.db)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsDeleteConfigAdapter(AdminApiAdapter):
|
|
provider_id: str
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return _delete_provider_ops_config_response(self.provider_id, context.db)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsConnectAdapter(AdminApiAdapter):
|
|
provider_id: str
|
|
payload: ConnectRequest
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return await _connect_provider_response(self.provider_id, self.payload, context.db)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsDisconnectAdapter(AdminApiAdapter):
|
|
provider_id: str
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return await _disconnect_provider_response(self.provider_id, context.db)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsExecuteActionAdapter(AdminApiAdapter):
|
|
provider_id: str
|
|
action_type: str
|
|
payload: ExecuteActionRequest
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return await _execute_action_response(
|
|
self.provider_id,
|
|
self.action_type,
|
|
self.payload,
|
|
context.db,
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsGetBalanceAdapter(AdminApiAdapter):
|
|
provider_id: str
|
|
refresh: bool
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return await _get_balance_response(self.provider_id, self.refresh, context.db)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsRefreshBalanceAdapter(AdminApiAdapter):
|
|
provider_id: str
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return await _refresh_balance_response(self.provider_id, context.db)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsCheckinAdapter(AdminApiAdapter):
|
|
provider_id: str
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return await _checkin_response(self.provider_id, context.db)
|
|
|
|
|
|
@dataclass
|
|
class AdminProviderOpsBatchBalanceAdapter(AdminApiAdapter):
|
|
provider_ids: list[str] | None
|
|
|
|
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
|
return await _batch_query_balance_response(self.provider_ids, context.db)
|