Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def patched_save_to_yml(yml_path, cm):
from fastapi import Depends, FastAPI, HTTPException, Request, status # noqa: E402
from fastapi.exceptions import RequestValidationError # noqa: E402
from fastapi.middleware.cors import CORSMiddleware # noqa: E402
from fastapi.middleware.gzip import GZipMiddleware # noqa: E402
from fastapi.responses import JSONResponse # noqa: E402
from fastapi.security import HTTPBasic, HTTPBasicCredentials # noqa: E402
from hummingbot.client.config.client_config_map import GatewayConfigMap # noqa: E402
Expand Down Expand Up @@ -364,6 +365,10 @@ async def lifespan(app: FastAPI):
allow_headers=settings.cors.allow_headers,
)

# Compress responses for clients that send Accept-Encoding: gzip. These payloads are highly
# repetitive JSON and compress ~14x; small responses are left alone via minimum_size.
app.add_middleware(GZipMiddleware, minimum_size=1000)


@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
Expand Down
7 changes: 6 additions & 1 deletion routers/bot_orchestration.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ async def get_bot_runs(
deployment_status: str = None,
limit: int = 100,
offset: int = 0,
include_final_status: bool = False,
bots_manager: BotsOrchestrator = Depends(get_bots_orchestrator)
):
"""
Expand All @@ -270,6 +271,9 @@ async def get_bot_runs(
deployment_status: Filter by deployment status (DEPLOYED, FAILED, ARCHIVED)
limit: Maximum number of results to return
offset: Number of results to skip
include_final_status: Include the final status snapshot for each run. Off by
default because the blob can be ~89 KB per record (~99% of the payload);
use GET /bot-runs/{bot_run_id} to fetch it for a single run.
bots_manager: Bot orchestrator service dependency

Returns:
Expand All @@ -284,7 +288,8 @@ async def get_bot_runs(
run_status=run_status,
deployment_status=deployment_status,
limit=limit,
offset=offset
offset=offset,
include_final_status=include_final_status
)

return {
Expand Down
26 changes: 20 additions & 6 deletions services/bots_orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,13 @@ async def get_bot_runs(
deployment_status: Optional[str] = None,
limit: int = 100,
offset: int = 0,
include_final_status: bool = False,
) -> List[Dict]:
"""Get bot runs with optional filtering, serialized as dictionaries."""
"""Get bot runs with optional filtering, serialized as dictionaries.

``final_status`` is omitted by default: the blob is ~99% of a run record's
bytes (up to ~89 KB each) and is only meaningful on the detail endpoint.
"""
async with self.db_manager.get_session_context() as session:
bot_run_repo = BotRunRepository(session)
bot_runs = await bot_run_repo.get_bot_runs(
Expand All @@ -496,7 +501,10 @@ async def get_bot_runs(
limit=limit,
offset=offset,
)
return [self._serialize_bot_run(run) for run in bot_runs]
return [
self._serialize_bot_run(run, include_final_status=include_final_status)
for run in bot_runs
]

async def get_bot_run_stats(self) -> Dict[str, Any]:
"""Get statistics about bot runs."""
Expand Down Expand Up @@ -560,9 +568,13 @@ async def create_bot_run(self, **kwargs):
# Don't fail the deployment if bot run creation fails

@staticmethod
def _serialize_bot_run(run) -> Dict:
"""Serialize a BotRun ORM object into a JSON-friendly dictionary."""
return {
def _serialize_bot_run(run, include_final_status: bool = True) -> Dict:
"""Serialize a BotRun ORM object into a JSON-friendly dictionary.

Set ``include_final_status=False`` to drop the (large) final status blob,
e.g. for list responses.
"""
serialized = {
"id": run.id,
"bot_name": run.bot_name,
"instance_name": run.instance_name,
Expand All @@ -576,9 +588,11 @@ def _serialize_bot_run(run) -> Dict:
"deployment_status": run.deployment_status,
"run_status": run.run_status,
"deployment_config": run.deployment_config,
"final_status": run.final_status,
"error_message": run.error_message,
}
if include_final_status:
serialized["final_status"] = run.final_status
return serialized

# ============================================
# Stop & Archive orchestration
Expand Down
Loading