From 38db76dd143e71108e745bada217c3c07b8a82d6 Mon Sep 17 00:00:00 2001 From: anti Date: Mon, 20 Apr 2026 18:30:32 -0400 Subject: [PATCH] fix(api): document 400 on topology read endpoints for schemathesis contract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DECNET's app-level RequestValidationError handler remaps structural 422→400, including query/path constraint violations (limit bounds, the next-subnet base pattern, etc.). Schemathesis fuzzing will drive those code paths and fail response_schema_conformance unless 400 is declared in responses={}. Adds the entry to every phase-3 read route. --- decnet/web/router/topology/api_catalog.py | 2 ++ decnet/web/router/topology/api_get_topology.py | 2 ++ decnet/web/router/topology/api_list_topologies.py | 1 + 3 files changed, 5 insertions(+) diff --git a/decnet/web/router/topology/api_catalog.py b/decnet/web/router/topology/api_catalog.py index 44c44114..728f26a8 100644 --- a/decnet/web/router/topology/api_catalog.py +++ b/decnet/web/router/topology/api_catalog.py @@ -30,6 +30,7 @@ router = APIRouter() tags=["MazeNET Topologies"], response_model=ServiceCatalogResponse, responses={ + 400: {"description": "Malformed query parameters"}, 401: {"description": "Missing or invalid credentials"}, 403: {"description": "Insufficient permissions"}, }, @@ -70,6 +71,7 @@ async def api_next_subnet( tags=["MazeNET Topologies"], response_model=NextIPResponse, responses={ + 400: {"description": "Malformed path parameters"}, 401: {"description": "Missing or invalid credentials"}, 403: {"description": "Insufficient permissions"}, 404: {"description": "Topology or LAN not found"}, diff --git a/decnet/web/router/topology/api_get_topology.py b/decnet/web/router/topology/api_get_topology.py index dd9ebaa9..11a1535b 100644 --- a/decnet/web/router/topology/api_get_topology.py +++ b/decnet/web/router/topology/api_get_topology.py @@ -23,6 +23,7 @@ router = APIRouter() tags=["MazeNET Topologies"], response_model=TopologyDetail, responses={ + 400: {"description": "Malformed path parameters"}, 401: {"description": "Missing or invalid credentials"}, 403: {"description": "Insufficient permissions"}, 404: {"description": "Topology not found"}, @@ -49,6 +50,7 @@ async def api_get_topology( tags=["MazeNET Topologies"], response_model=list[TopologyStatusEventRow], responses={ + 400: {"description": "Malformed query parameters"}, 401: {"description": "Missing or invalid credentials"}, 403: {"description": "Insufficient permissions"}, 404: {"description": "Topology not found"}, diff --git a/decnet/web/router/topology/api_list_topologies.py b/decnet/web/router/topology/api_list_topologies.py index f1df8ab3..af97c90f 100644 --- a/decnet/web/router/topology/api_list_topologies.py +++ b/decnet/web/router/topology/api_list_topologies.py @@ -17,6 +17,7 @@ router = APIRouter() tags=["MazeNET Topologies"], response_model=TopologyListResponse, responses={ + 400: {"description": "Malformed query parameters"}, 401: {"description": "Missing or invalid credentials"}, 403: {"description": "Insufficient permissions"}, },