test fix 3
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 9s
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 9s
This commit is contained in:
@@ -3,8 +3,10 @@ import asyncio
|
|||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from typing import Optional, Any, Dict, List
|
from typing import Optional, Any, Dict, List, Union
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from src.Models.packets import PacketDBModel
|
||||||
from fastapi import APIRouter, Query, WebSocket, WebSocketDisconnect, HTTPException
|
from fastapi import APIRouter, Query, WebSocket, WebSocketDisconnect, HTTPException
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
@@ -14,30 +16,75 @@ logger = logging.getLogger("packets_router")
|
|||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
def _serialize_row_for_json(row: Dict[str, Any]) -> Dict[str, Any]:
|
def _serialize_row_for_json(row: Union[Dict[str, Any], PacketDBModel, BaseModel]) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Convert DB row / pkt_info to a JSON-serializable dict.
|
Convert a DB row or PacketDBModel into a JSON-serializable dict.
|
||||||
- If 'raw' is bytes, produce 'raw_b64' and drop 'raw'.
|
|
||||||
- Fallback to str() for unknown/unserializable values.
|
- If `row` is a Pydantic model (PacketDBModel or BaseModel), use `.dict()` to get a plain dict.
|
||||||
|
- If `raw` is bytes/bytearray, produce `raw_b64` and drop `raw`.
|
||||||
|
- If `raw_b64` already exists, do not re-encode.
|
||||||
|
- For values that cannot be JSON serialized, fall back to str(value).
|
||||||
"""
|
"""
|
||||||
|
# If given a Pydantic model, convert to dict first
|
||||||
|
if isinstance(row, BaseModel):
|
||||||
|
d: Dict[str, Any] = row.dict(by_alias=True, exclude_none=True)
|
||||||
|
else:
|
||||||
|
# copy to avoid mutating caller's dict
|
||||||
|
d = dict(row)
|
||||||
|
|
||||||
|
# If raw_b64 already present, prefer it. If raw present and bytes, convert.
|
||||||
|
raw_val = d.get("raw")
|
||||||
|
if raw_val is not None and isinstance(raw_val, (bytes, bytearray)):
|
||||||
|
# convert to base64 string and remove raw
|
||||||
|
try:
|
||||||
|
d["raw_b64"] = base64.b64encode(raw_val).decode("ascii")
|
||||||
|
d.pop("raw", None)
|
||||||
|
except Exception:
|
||||||
|
# keep raw as str fallback
|
||||||
|
try:
|
||||||
|
d["raw_b64"] = base64.b64encode(bytes(raw_val)).decode("ascii")
|
||||||
|
d.pop("raw", None)
|
||||||
|
except Exception:
|
||||||
|
logger.exception("Failed to base64-encode raw bytes for row id=%s", d.get("id"))
|
||||||
|
d["raw_b64"] = str(raw_val)
|
||||||
|
d.pop("raw", None)
|
||||||
|
|
||||||
|
# Ensure final dict is JSON-safe: try json.dumps on each value, fallback to str()
|
||||||
out: Dict[str, Any] = {}
|
out: Dict[str, Any] = {}
|
||||||
for k, v in row.items():
|
for k, v in d.items():
|
||||||
if k == "raw" and isinstance(v, (bytes, bytearray)):
|
# skip any private/internal keys if needed (optional)
|
||||||
out["raw_b64"] = base64.b64encode(v).decode("ascii")
|
# if k.startswith("_"):
|
||||||
continue
|
# continue
|
||||||
# try to JSON serialize the value directly
|
|
||||||
|
# raw_b64: ensure it's a str
|
||||||
|
if k == "raw_b64" and isinstance(v, (bytes, bytearray)):
|
||||||
|
try:
|
||||||
|
out["raw_b64"] = base64.b64encode(v).decode("ascii")
|
||||||
|
continue
|
||||||
|
except Exception:
|
||||||
|
out["raw_b64"] = str(v)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# JSON-serializable check
|
||||||
try:
|
try:
|
||||||
json.dumps({k: v})
|
json.dumps({k: v})
|
||||||
out[k] = v
|
out[k] = v
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
out[k] = str(v)
|
# convert non-serializable to string representation
|
||||||
|
try:
|
||||||
|
out[k] = str(v)
|
||||||
|
except Exception:
|
||||||
|
out[k] = "<unserializable>"
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
async def _serialize_rows(rows: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
async def _serialize_rows(rows: List[Union[Dict[str, Any], PacketDBModel]]) -> List[Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
Serialize a list of DB rows or PacketDBModel instances into JSON-ready dicts.
|
||||||
|
Keeps the same order as input.
|
||||||
|
"""
|
||||||
return [_serialize_row_for_json(r) for r in rows]
|
return [_serialize_row_for_json(r) for r in rows]
|
||||||
|
|
||||||
|
|
||||||
@router.get("/packets")
|
@router.get("/packets")
|
||||||
async def get_packets(limit: int = Query(100, ge=1, le=10000)):
|
async def get_packets(limit: int = Query(100, ge=1, le=10000)):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user