From 10edb109df6e4ebd5e2b0755dcf03270dfccdf73 Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Mon, 28 Sep 2026 05:10:38 +0000 Subject: [PATCH 1/4] fix(typing): resolve mypy errors in api.routes.compute.dependencies.authentication --- .../api/routes/compute/dependencies/authentication.py | 9 +++++---- pyproject.toml | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gns3server/api/routes/compute/dependencies/authentication.py b/gns3server/api/routes/compute/dependencies/authentication.py index 14ba07f91..0412a4136 100644 --- a/gns3server/api/routes/compute/dependencies/authentication.py +++ b/gns3server/api/routes/compute/dependencies/authentication.py @@ -91,9 +91,9 @@ async def ws_compute_authentication(websocket: WebSocket) -> Union[None, WebSock if not separator: raise invalid_user_credentials_exc - username = secrets.compare_digest(username, server_settings.compute_username) - password = secrets.compare_digest(password, server_settings.compute_password.get_secret_value()) - if not (username and password): + username_valid = secrets.compare_digest(username, server_settings.compute_username) + password_valid = secrets.compare_digest(password, server_settings.compute_password.get_secret_value()) + if not (username_valid and password_valid): raise invalid_user_credentials_exc except HTTPException as e: @@ -101,5 +101,6 @@ async def ws_compute_authentication(websocket: WebSocket) -> Union[None, WebSock websocket_error = {"action": "log.error", "event": {"message": err_msg}} await websocket.send_json(websocket_error) log.error(err_msg) - return await websocket.close(code=1008) + await websocket.close(code=1008) + return None return websocket diff --git a/pyproject.toml b/pyproject.toml index 258447eb6..ce388d188 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -323,7 +323,6 @@ module = [ "gns3server.api.routes.compute.capabilities", # 1 "gns3server.api.routes.compute.cloud_nodes", # 14 "gns3server.api.routes.compute.compute", # 1 - "gns3server.api.routes.compute.dependencies.authentication", # 3 "gns3server.api.routes.compute.docker_nodes", # 26 "gns3server.api.routes.compute.dynamips_nodes", # 9 "gns3server.api.routes.compute.ethernet_hub_nodes", # 9 From bb0f29b8e6f352373d2b692de282ce1f8d2190f8 Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Mon, 28 Sep 2026 05:43:01 +0000 Subject: [PATCH 2/4] fix(typing): resolve mypy errors in api.routes.compute.docker_nodes --- gns3server/api/routes/compute/docker_nodes.py | 14 ++++++++------ pyproject.toml | 1 - 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/gns3server/api/routes/compute/docker_nodes.py b/gns3server/api/routes/compute/docker_nodes.py index 6091cf37b..9dee90dda 100644 --- a/gns3server/api/routes/compute/docker_nodes.py +++ b/gns3server/api/routes/compute/docker_nodes.py @@ -24,14 +24,16 @@ from fastapi import APIRouter, WebSocket, Depends, Body, status, HTTPException from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse from uuid import UUID -from typing import Union +from typing import Any, Union from gns3server import schemas from gns3server.compute.docker import Docker from gns3server.compute.docker.docker_vm import DockerVM from .dependencies.authentication import compute_authentication, ws_compute_authentication -responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project or Docker node"}} +responses: dict[int | str, dict[str, Any]] = { + 404: {"model": schemas.ErrorMessage, "description": "Could not find project or Docker node"} +} router = APIRouter(responses=responses) @@ -53,13 +55,13 @@ def dep_node(project_id: UUID, node_id: UUID) -> DockerVM: responses={409: {"model": schemas.ErrorMessage, "description": "Could not create Docker node"}}, dependencies=[Depends(compute_authentication)], ) -async def create_docker_node(project_id: UUID, node_data: schemas.DockerCreate) -> schemas.Docker: +async def create_docker_node(project_id: UUID, node_create: schemas.DockerCreate) -> schemas.Docker: """ Create a new Docker node. """ docker_manager = Docker.instance() - node_data = jsonable_encoder(node_data, exclude_unset=True) + node_data = jsonable_encoder(node_create, exclude_unset=True) container = await docker_manager.create_node( node_data.pop("name"), str(project_id), @@ -124,7 +126,7 @@ def get_docker_node(node: DockerVM = Depends(dep_node)) -> schemas.Docker: @router.put("/{node_id}", response_model=schemas.Docker, dependencies=[Depends(compute_authentication)]) -async def update_docker_node(node_data: schemas.DockerUpdate, node: DockerVM = Depends(dep_node)) -> schemas.Docker: +async def update_docker_node(node_update: schemas.DockerUpdate, node: DockerVM = Depends(dep_node)) -> schemas.Docker: """ Update a Docker node. """ @@ -152,7 +154,7 @@ async def update_docker_node(node_data: schemas.DockerUpdate, node: DockerVM = D ] changed = False - node_data = jsonable_encoder(node_data, exclude_unset=True) + node_data = jsonable_encoder(node_update, exclude_unset=True) for prop in props: # hasattr: startup_config_content only exists on IOLDockerVM if prop in node_data and hasattr(node, prop) and node_data[prop] != getattr(node, prop): diff --git a/pyproject.toml b/pyproject.toml index ce388d188..902af10ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -323,7 +323,6 @@ module = [ "gns3server.api.routes.compute.capabilities", # 1 "gns3server.api.routes.compute.cloud_nodes", # 14 "gns3server.api.routes.compute.compute", # 1 - "gns3server.api.routes.compute.docker_nodes", # 26 "gns3server.api.routes.compute.dynamips_nodes", # 9 "gns3server.api.routes.compute.ethernet_hub_nodes", # 9 "gns3server.api.routes.compute.ethernet_switch_nodes", # 16 From 904672559e742eec5ce0bfb42f2c91789a894a12 Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Mon, 28 Sep 2026 05:50:51 +0000 Subject: [PATCH 3/4] fix(typing): resolve mypy errors in api.routes.compute.dynamips_nodes --- .../api/routes/compute/dynamips_nodes.py | 25 +++++++++++-------- pyproject.toml | 1 - 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/gns3server/api/routes/compute/dynamips_nodes.py b/gns3server/api/routes/compute/dynamips_nodes.py index ce1c1b42b..ccfcd58fb 100644 --- a/gns3server/api/routes/compute/dynamips_nodes.py +++ b/gns3server/api/routes/compute/dynamips_nodes.py @@ -23,7 +23,7 @@ import os from fastapi import APIRouter, WebSocket, Body, Depends, status, HTTPException from fastapi.encoders import jsonable_encoder from fastapi.responses import StreamingResponse -from typing import List, Union +from typing import Any, List, Optional, Union from uuid import UUID from gns3server.compute.dynamips import Dynamips @@ -32,7 +32,9 @@ from gns3server import schemas from .dependencies.authentication import compute_authentication, ws_compute_authentication -responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project or Dynamips node"}} +responses: dict[int | str, dict[str, Any]] = { + 404: {"model": schemas.ErrorMessage, "description": "Could not find project or Dynamips node"} +} router = APIRouter(responses=responses) @@ -64,25 +66,26 @@ async def create_router(project_id: UUID, node_data: schemas.DynamipsCreate) -> dynamips_manager = Dynamips.instance() platform = node_data.platform + chassis: Optional[str] if not node_data.chassis and platform in DEFAULT_CHASSIS: chassis = DEFAULT_CHASSIS[platform] else: chassis = node_data.chassis - node_data = jsonable_encoder(node_data, exclude_unset=True) + data = jsonable_encoder(node_data, exclude_unset=True) vm = await dynamips_manager.create_node( - node_data.pop("name"), + data.pop("name"), str(project_id), - node_data.get("node_id"), - dynamips_id=node_data.get("dynamips_id"), + data.get("node_id"), + dynamips_id=data.get("dynamips_id"), platform=platform, - console=node_data.get("console"), - console_type=node_data.get("console_type", "telnet"), - aux=node_data.get("aux"), - aux_type=node_data.pop("aux_type", "none"), + console=data.get("console"), + console_type=data.get("console_type", "telnet"), + aux=data.get("aux"), + aux_type=data.pop("aux_type", "none"), chassis=chassis, node_type="dynamips", ) - await dynamips_manager.update_vm_settings(vm, node_data) + await dynamips_manager.update_vm_settings(vm, data) return vm.asdict() diff --git a/pyproject.toml b/pyproject.toml index 902af10ce..fb001c18a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -323,7 +323,6 @@ module = [ "gns3server.api.routes.compute.capabilities", # 1 "gns3server.api.routes.compute.cloud_nodes", # 14 "gns3server.api.routes.compute.compute", # 1 - "gns3server.api.routes.compute.dynamips_nodes", # 9 "gns3server.api.routes.compute.ethernet_hub_nodes", # 9 "gns3server.api.routes.compute.ethernet_switch_nodes", # 16 "gns3server.api.routes.compute.frame_relay_switch_nodes", # 9 From cacbc18ad11b544191817257a32a5d6804a8e90f Mon Sep 17 00:00:00 2001 From: Mark Paronyan Date: Mon, 28 Sep 2026 05:40:31 +0000 Subject: [PATCH 4/4] fix(typing): resolve mypy errors in api.routes.compute.ethernet_hub_nodes --- .../api/routes/compute/ethernet_hub_nodes.py | 23 +++++++++++-------- pyproject.toml | 1 - 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/gns3server/api/routes/compute/ethernet_hub_nodes.py b/gns3server/api/routes/compute/ethernet_hub_nodes.py index 350105789..150d18e64 100644 --- a/gns3server/api/routes/compute/ethernet_hub_nodes.py +++ b/gns3server/api/routes/compute/ethernet_hub_nodes.py @@ -18,6 +18,7 @@ API routes for Ethernet hub nodes. """ +from typing import Any import os from fastapi import APIRouter, Depends, Body, Path, status, HTTPException @@ -29,7 +30,9 @@ from gns3server.compute.dynamips import Dynamips from gns3server.compute.dynamips.nodes.ethernet_hub import EthernetHub from gns3server import schemas -responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project or Ethernet hub node"}} +responses: dict[int | str, dict[str, Any]] = { + 404: {"model": schemas.ErrorMessage, "description": "Could not find project or Ethernet hub node"} +} router = APIRouter(responses=responses) @@ -57,13 +60,13 @@ async def create_ethernet_hub(project_id: UUID, node_data: schemas.EthernetHubCr # Use the Dynamips Ethernet hub to simulate this node dynamips_manager = Dynamips.instance() - node_data = jsonable_encoder(node_data, exclude_unset=True) + data = jsonable_encoder(node_data, exclude_unset=True) node = await dynamips_manager.create_node( - node_data.pop("name"), + data.pop("name"), str(project_id), - node_data.get("node_id"), + data.get("node_id"), node_type="ethernet_hub", - ports=node_data.get("ports_mapping"), + ports=data.get("ports_mapping"), ) return node.asdict() @@ -97,11 +100,11 @@ async def update_ethernet_hub( Update an Ethernet hub. """ - node_data = jsonable_encoder(node_data, exclude_unset=True) - if "name" in node_data and node.name != node_data["name"]: - await node.set_name(node_data["name"]) - if "ports_mapping" in node_data: - node.ports_mapping = node_data["ports_mapping"] + data = jsonable_encoder(node_data, exclude_unset=True) + if "name" in data and node.name != data["name"]: + await node.set_name(data["name"]) + if "ports_mapping" in data: + node.ports_mapping = data["ports_mapping"] node.updated() return node.asdict() diff --git a/pyproject.toml b/pyproject.toml index fb001c18a..1ec09fbe7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -323,7 +323,6 @@ module = [ "gns3server.api.routes.compute.capabilities", # 1 "gns3server.api.routes.compute.cloud_nodes", # 14 "gns3server.api.routes.compute.compute", # 1 - "gns3server.api.routes.compute.ethernet_hub_nodes", # 9 "gns3server.api.routes.compute.ethernet_switch_nodes", # 16 "gns3server.api.routes.compute.frame_relay_switch_nodes", # 9 "gns3server.api.routes.compute.iou_nodes", # 15