mirror of
https://github.com/fusion44/blitz_api.git
synced 2026-08-14 12:02:46 +02:00
184 lines
6.1 KiB
Python
184 lines
6.1 KiB
Python
from enum import Enum
|
|
from typing import List, Optional, Protocol
|
|
|
|
from fastapi import Query
|
|
from pydantic.main import BaseModel
|
|
|
|
from app.api.error_report.report import Report
|
|
from app.api.models import ErrorMessage
|
|
from app.apps.constants import AppManagementProcessState, InstallMode
|
|
from app.external.result_type.src.result import Err, Ok, Result
|
|
|
|
|
|
class AppOnlineStatus(str, Enum):
|
|
ONLINE = "online"
|
|
OFFLINE = "offline"
|
|
|
|
|
|
class AppId(str, Enum):
|
|
ALBYHUB = "albyhub"
|
|
BTCPAYSERVER = "btcpayserver"
|
|
BTC_RPC_EXPLORER = "btc-rpc-explorer"
|
|
ELECTRS = "electrs"
|
|
JAM = "jam"
|
|
LNBITS = "lnbits"
|
|
MEMPOOL = "mempool"
|
|
RTL = "rtl"
|
|
THUNDERHUB = "thunderhub"
|
|
|
|
@staticmethod
|
|
def as_str_list() -> List[str]:
|
|
return [app_id.value for app_id in AppId]
|
|
|
|
@staticmethod
|
|
def from_str(label: str) -> Result["AppId", Report]:
|
|
try:
|
|
return Ok(AppId(label))
|
|
except ValueError:
|
|
return Err(Report(f"'{label}' is not a valid AvailableAppId"))
|
|
|
|
|
|
class AppStatus(BaseModel):
|
|
id: AppId = Query(..., description="Id of the applications")
|
|
version: Optional[str] = Query(None, description="Version of the application")
|
|
installed: bool = Query(False, description="Whether the application is installed")
|
|
configured: bool = Query(False, description="Whether the application is configured")
|
|
status: AppOnlineStatus = Query(
|
|
AppOnlineStatus.OFFLINE, description="Whether the application is online"
|
|
)
|
|
local_ip: Optional[str] = Query(
|
|
None, description="The local network IP of the application"
|
|
)
|
|
http_port: Optional[str] = Query(
|
|
None, description="The http port of the application"
|
|
)
|
|
https_port: Optional[str] = Query(
|
|
None, description="The https port of the application"
|
|
)
|
|
https_forced: Optional[bool] = Query(
|
|
None, description="Whether https is forced for this application"
|
|
)
|
|
https_self_signed: Optional[bool] = Query(
|
|
None, description="Whether the https certificate is self signed"
|
|
)
|
|
hidden_service: Optional[str] = Query(
|
|
None,
|
|
description="Whether the application is reachable via a tor hidden service",
|
|
)
|
|
address: Optional[str] = Query(
|
|
None, description="The full address where this application is reachable"
|
|
)
|
|
auth_method: Optional[str] = Query(
|
|
None, description="The authentication method this application uses"
|
|
)
|
|
details: Optional[dict] = Query(
|
|
None,
|
|
description=f"""Additional application specific details
|
|
|
|
This field can contain values for the following app ids:
|
|
- `{AppId.MEMPOOL.value}`: `is_indexed`, `index_info`
|
|
- `{AppId.BTC_RPC_EXPLORER.value}`: `is_indexed`, `index_info`
|
|
- `{AppId.ELECTRS.value}`: `initial_sync_done`, `block_height`,
|
|
`blockheightPercent`, `info_sync`,
|
|
`electrum_responding`,
|
|
""",
|
|
)
|
|
error: Optional[str] = Query(
|
|
None, description="Last known encountered error for this app."
|
|
)
|
|
|
|
|
|
class AppStatusQueryError(BaseModel):
|
|
id: AppId = Query(..., description="The app id")
|
|
error: str = Query(..., description="The error description")
|
|
|
|
|
|
class AppStatusQueryResult(BaseModel):
|
|
data: List[AppStatus] = Query(
|
|
[], description="Contains the successfully queried app statuses"
|
|
)
|
|
errors: List[AppStatusQueryError] = Query(
|
|
[], description="Contains the error messages for unsuccessful queries"
|
|
)
|
|
timestamp: int = Query(
|
|
0, description="The UTC timestamp of when the data was fetched"
|
|
)
|
|
|
|
|
|
class AppStatusUpdateTaskMessage(BaseModel):
|
|
state: AppManagementProcessState = Query(
|
|
..., description="The state of the app status update task"
|
|
)
|
|
message: AppStatusQueryResult | ErrorMessage | None = Query(
|
|
None,
|
|
description="""
|
|
The result of the app status update task, or an error message if the
|
|
task itself failed.
|
|
|
|
Note one the failure modes. There are two possible failure modes:
|
|
1. The task totally failed, in which case the message will be an error
|
|
message of type ErrorMessage.
|
|
2. The task failed to update fetch an app status, in which case the error
|
|
message will be in the AppStatusQueryResult errors list.
|
|
""",
|
|
)
|
|
|
|
|
|
class AppManageTaskMessage(BaseModel):
|
|
id: AppId = Query(..., description="Id of the application")
|
|
mode: InstallMode = Query(..., description="Install mode")
|
|
state: AppManagementProcessState = Query(
|
|
..., description="State of the installation process"
|
|
)
|
|
message: str | ErrorMessage | None = Query(
|
|
None, description="Details of the update (str, ErrorMessage, or None)"
|
|
)
|
|
|
|
def __str__(self) -> str:
|
|
return (
|
|
f"AppManageTaskMessage(id={self.id}, mode={self.mode}, "
|
|
f"state={self.state}, details={self.message})"
|
|
)
|
|
|
|
|
|
class AppUninstallInput(BaseModel):
|
|
app_id: AppId = Query(..., description="Id of the applications")
|
|
keep_data: bool = Query(True, description="Whether to keep the app data")
|
|
|
|
|
|
class RedisInterface(Protocol):
|
|
"""An interface for Redis operations to allow for dependency injection."""
|
|
|
|
async def get(self, name: str) -> bytes: ...
|
|
|
|
async def set(self, name: str, value: str, ex: Optional[int] = None) -> bool: ...
|
|
|
|
async def close(self) -> None: ...
|
|
|
|
|
|
class CacheOperations(Protocol):
|
|
"""Interface for cache operations to avoid circular dependencies."""
|
|
|
|
async def set_cached_app_status(
|
|
self, status: AppStatusQueryResult, redis=None
|
|
) -> Result[None, Report]: ...
|
|
|
|
async def get_cached_app_status(
|
|
self, redis=None
|
|
) -> Result[Optional[AppStatusQueryResult], Report]: ...
|
|
|
|
|
|
class ChannelOperations(Protocol):
|
|
"""Interface for channel notification operations."""
|
|
|
|
async def notify_key_change(
|
|
self, key: str, action: str, old_value=None, new_value=None
|
|
) -> Result[None, Report]: ...
|
|
|
|
async def connect(self) -> Result[None, Report]: ...
|
|
|
|
|
|
class CacheStatus(str, Enum):
|
|
UPDATING = "updating"
|
|
UPDATED = "updated"
|
|
ERROR = "error"
|