Skip to content

Commit

Permalink
feat(#237): implement app_status_advanced endpoint (#238)
Browse files Browse the repository at this point in the history
Some apps might give status information that is computationally to
expensive to include in the normal status endpoint which can be polled
more often.

closes #237
  • Loading branch information
fusion44 committed Jan 17, 2025
1 parent 3523839 commit c9e8236
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 1 deletion.
4 changes: 4 additions & 0 deletions app/apps/impl/apps_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ async def get_app_status_single(self, app_id: str):
async def get_app_status(self):
raise NotImplementedError()

@abstractmethod
async def get_app_status_advanced(self, app_id: str):
raise NotImplementedError()

@abstractmethod
async def get_app_status_sub(self):
raise NotImplementedError()
Expand Down
3 changes: 3 additions & 0 deletions app/apps/impl/native_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ async def get_app_status_single(self, app_id: str):
async def get_app_status(self):
raise _NotImplemented()

async def get_app_status_advanced(self, app_id: str):
raise _NotImplemented()

async def get_app_status_sub(self):
raise _NotImplemented()

Expand Down
70 changes: 70 additions & 0 deletions app/apps/impl/raspiblitz.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"mempool",
"thunderhub",
"jam",
"electrs",
}


Expand Down Expand Up @@ -97,6 +98,7 @@ async def get_app_status_single(self, app_id):
"isIndexed": data["isIndexed"],
"indexInfo": data["indexInfo"],
}

return {
"id": app_id,
"version": version,
Expand Down Expand Up @@ -125,6 +127,18 @@ async def get_app_status_single(self, app_id):
"error": f"script result processing error: {script_call}",
}

async def get_app_status_advanced(self, app_id):
if app_id not in available_app_ids:
raise HTTPException(
status.HTTP_400_BAD_REQUEST,
detail=f"App id invalid. Available app ids: {available_app_ids}",
)

if app_id == "electrs":
return await _do_electrs_status_advanced()

return {}

async def get_app_status(self):
appStatusList: List = []
for appID in available_app_ids:
Expand Down Expand Up @@ -346,3 +360,59 @@ async def run_bonus_script(self, app_id: str, params: str):
logging.debug(f"updatedAppData: {updatedAppData}")
logging.debug(f"params: {params}")
return


async def _do_electrs_status_advanced():
app_id = "electrs"
script_call = (
os.path.join(SHELL_SCRIPT_PATH, "config.scripts", f"bonus.{app_id}.sh")
+ " status showAddress"
)

try:
result = await call_sudo_script(script_call)
except:
# script had error or was not able to deliver all requested data fields
logging.warning(f"error on calling: {script_call}")
return {
"id": f"{app_id}",
"error": f"script not working for api: {script_call}",
}

try:
data = parse_key_value_text(result)
except:
logging.warning(f"error on parsing: {result}")
return {
"id": f"{app_id}",
"error": f"script result parsing error: {script_call}",
}

if data["serviceInstalled"] == "0":
return {
"id": app_id,
"error": "Service not installed.",
}

if data["serviceRunning"] == "0":
return {
"id": app_id,
"error": "Service installed, but not running.",
}

if "initialSynced" not in data:
logging.warning(f"error on calling: {script_call}")
return {
"id": app_id,
"error": f"script not working for api: {script_call}",
}

return {
"version": data["version"],
"localIP": data["localIP"],
"publicIP": data["publicIP"],
"portTCP": data["portTCP"],
"portSSL": data["portSSL"],
"TORaddress": data["TORaddress"],
"initialSyncDone": data["initialSynced"] == "1",
}
19 changes: 18 additions & 1 deletion app/apps/router.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from fastapi import APIRouter, HTTPException
from fastapi import APIRouter, HTTPException, Path
from fastapi.params import Depends
from loguru import logger
from pydantic import BaseModel
Expand Down Expand Up @@ -36,6 +36,23 @@ async def get_single_status(id):
return await repo.get_app_status_single(id)


@router.get(
"/status_advanced/{id}",
name=f"{_PREFIX}/status_advanced",
summary="Get the advanced status of a single app by id.",
description="""Some apps might give status information that is computationally
to expensive to include in the normal status endpoint.
> ℹ️ _This endpoint is not implemented on all platforms_
""",
dependencies=[Depends(JWTBearer())],
responses={400: {"description": ("If no or invalid app id is given.")}},
)
@logger.catch(exclude=(HTTPException,))
async def get_single_status_advanced(id: str = Path(..., required=True)):
return await repo.get_app_status_advanced(id)


@router.get(
"/status-sub",
name=f"{_PREFIX}/status-sub",
Expand Down
4 changes: 4 additions & 0 deletions app/apps/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ async def get_app_status():
return await apps.get_app_status()


async def get_app_status_advanced(app_id: str):
return await apps.get_app_status_advanced(app_id)


async def get_app_status_sub():
return await apps.get_app_status_sub()

Expand Down

0 comments on commit c9e8236

Please sign in to comment.