mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-22 19:02:23 +03:00
Merge pull request #2965 from GNS3/drop-python-3.10
Drop Python 3.10 support
This commit is contained in:
commit
24634b8f0d
2
.github/workflows/testing.yml
vendored
2
.github/workflows/testing.yml
vendored
@ -17,7 +17,7 @@ jobs:
|
|||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v7
|
||||||
|
|||||||
@ -23,16 +23,11 @@ This module handles Docker API operations via aiohttp Unix socket.
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import sys
|
from asyncio import timeout as async_timeout
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
if sys.version_info >= (3, 11):
|
|
||||||
from asyncio import timeout as async_timeout
|
|
||||||
else:
|
|
||||||
from async_timeout import timeout as async_timeout
|
|
||||||
|
|
||||||
from gns3server.utils import parse_version
|
from gns3server.utils import parse_version
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
@ -671,11 +671,7 @@ class BaseNode:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# keep forwarding websocket data in both direction
|
# keep forwarding websocket data in both direction
|
||||||
if sys.version_info >= (3, 11, 0):
|
aws = [asyncio.create_task(ws_forward(telnet_writer)), asyncio.create_task(telnet_forward(telnet_reader))]
|
||||||
# Starting with Python 3.11, passing coroutine objects to wait() directly is forbidden.
|
|
||||||
aws = [asyncio.create_task(ws_forward(telnet_writer)), asyncio.create_task(telnet_forward(telnet_reader))]
|
|
||||||
else:
|
|
||||||
aws = [ws_forward(telnet_writer), telnet_forward(telnet_reader)]
|
|
||||||
|
|
||||||
done, pending = await asyncio.wait(aws, return_when=asyncio.FIRST_COMPLETED)
|
done, pending = await asyncio.wait(aws, return_when=asyncio.FIRST_COMPLETED)
|
||||||
for task in done:
|
for task in done:
|
||||||
@ -762,11 +758,7 @@ class BaseNode:
|
|||||||
log.warning(f"Exception while forwarding VNC data to WebSocket: {e!r}")
|
log.warning(f"Exception while forwarding VNC data to WebSocket: {e!r}")
|
||||||
|
|
||||||
# Keep forwarding WebSocket data in both directions
|
# Keep forwarding WebSocket data in both directions
|
||||||
if sys.version_info >= (3, 11, 0):
|
aws = [asyncio.create_task(ws_forward(vnc_writer)), asyncio.create_task(vnc_forward(vnc_reader))]
|
||||||
# Starting with Python 3.11, passing coroutine objects to wait() directly is forbidden.
|
|
||||||
aws = [asyncio.create_task(ws_forward(vnc_writer)), asyncio.create_task(vnc_forward(vnc_reader))]
|
|
||||||
else:
|
|
||||||
aws = [ws_forward(vnc_writer), vnc_forward(vnc_reader)]
|
|
||||||
|
|
||||||
done, pending = await asyncio.wait(aws, return_when=asyncio.FIRST_COMPLETED)
|
done, pending = await asyncio.wait(aws, return_when=asyncio.FIRST_COMPLETED)
|
||||||
for task in done:
|
for task in done:
|
||||||
|
|||||||
@ -19,19 +19,14 @@ import asyncio
|
|||||||
import io
|
import io
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
from asyncio import timeout as asynctimeout
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
|
|
||||||
if sys.version_info >= (3, 11):
|
|
||||||
from asyncio import timeout as asynctimeout
|
|
||||||
else:
|
|
||||||
from async_timeout import timeout as asynctimeout
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from ..controller.controller_error import (
|
from ..controller.controller_error import (
|
||||||
ComputeConflictError,
|
ComputeConflictError,
|
||||||
ComputeError,
|
ComputeError,
|
||||||
|
|||||||
@ -16,11 +16,11 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import List, Optional, Union, cast
|
from typing import Any, List, Optional, Union, cast
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from sqlalchemy import delete, select, update
|
from sqlalchemy import Select, delete, select, update
|
||||||
from sqlalchemy.engine import CursorResult
|
from sqlalchemy.engine import CursorResult
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
@ -331,7 +331,7 @@ class RbacRepository(BaseRepository):
|
|||||||
Retrieve all user ACEs matching the user_id and privilege name.
|
Retrieve all user ACEs matching the user_id and privilege name.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
query = (
|
query: Select[Any, Any, Any, Any] = (
|
||||||
select(models.ACE.path, models.ACE.propagate, models.ACE.allowed, models.Privilege.name)
|
select(models.ACE.path, models.ACE.propagate, models.ACE.allowed, models.Privilege.name)
|
||||||
.join(models.Privilege.roles)
|
.join(models.Privilege.roles)
|
||||||
.join(models.Role.acl_entries)
|
.join(models.Role.acl_entries)
|
||||||
@ -349,7 +349,7 @@ class RbacRepository(BaseRepository):
|
|||||||
Retrieve all group ACEs matching the user_id and privilege name.
|
Retrieve all group ACEs matching the user_id and privilege name.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
query = (
|
query: Select[Any, Any, Any, Any] = (
|
||||||
select(models.ACE.path, models.ACE.propagate, models.ACE.allowed, models.Privilege.name)
|
select(models.ACE.path, models.ACE.propagate, models.ACE.allowed, models.Privilege.name)
|
||||||
.join(models.Privilege.roles)
|
.join(models.Privilege.roles)
|
||||||
.join(models.Role.acl_entries)
|
.join(models.Role.acl_entries)
|
||||||
|
|||||||
@ -255,9 +255,9 @@ class Server:
|
|||||||
else:
|
else:
|
||||||
log.info(f"Compute authentication is enabled with username '{config.Server.compute_username}'")
|
log.info(f"Compute authentication is enabled with username '{config.Server.compute_username}'")
|
||||||
|
|
||||||
# we only support Python 3 version >= 3.9
|
# we only support Python 3 version >= 3.11
|
||||||
if sys.version_info < (3, 9, 0):
|
if sys.version_info < (3, 11, 0):
|
||||||
raise SystemExit("Python 3.9 or higher is required")
|
raise SystemExit("Python 3.11 or higher is required")
|
||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
f"Running with Python {sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]} and has PID {os.getpid()}"
|
f"Running with Python {sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]} and has PID {os.getpid()}"
|
||||||
|
|||||||
@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "gns3-server"
|
name = "gns3-server"
|
||||||
description = "GNS3 graphical interface for the GNS3 server."
|
description = "GNS3 server (controller and compute) for GNS3 network simulator"
|
||||||
license-files = ["LICENSE"]
|
license-files = ["LICENSE"]
|
||||||
authors = [
|
authors = [
|
||||||
{ name = "Jeremy Grossmann", email = "developers@gns3.com" }
|
{ name = "Jeremy Grossmann", email = "developers@gns3.com" }
|
||||||
]
|
]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.11"
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Development Status :: 5 - Production/Stable",
|
"Development Status :: 5 - Production/Stable",
|
||||||
"Environment :: Console",
|
"Environment :: Console",
|
||||||
@ -21,10 +21,10 @@ classifiers = [
|
|||||||
"Natural Language :: English",
|
"Natural Language :: English",
|
||||||
"Operating System :: POSIX :: Linux",
|
"Operating System :: POSIX :: Linux",
|
||||||
"Programming Language :: Python :: 3 :: Only",
|
"Programming Language :: Python :: 3 :: Only",
|
||||||
"Programming Language :: Python :: 3.10",
|
|
||||||
"Programming Language :: Python :: 3.11",
|
"Programming Language :: Python :: 3.11",
|
||||||
"Programming Language :: Python :: 3.12",
|
"Programming Language :: Python :: 3.12",
|
||||||
"Programming Language :: Python :: 3.13",
|
"Programming Language :: Python :: 3.13",
|
||||||
|
"Programming Language :: Python :: 3.14",
|
||||||
"Programming Language :: Python :: Implementation :: CPython"
|
"Programming Language :: Python :: Implementation :: CPython"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -1,19 +1,17 @@
|
|||||||
# GNS3 Server Core Dependencies
|
# GNS3 Server Core Dependencies
|
||||||
uvicorn==0.54.0
|
uvicorn==0.54.0
|
||||||
pydantic==2.13.5
|
pydantic==2.13.5
|
||||||
fastapi==0.141.1
|
fastapi==0.142.4
|
||||||
python-multipart==0.0.32
|
python-multipart==0.0.32
|
||||||
websockets==16.1.1 # version 16.1.1 is the last version that supports Python 3.10
|
websockets==16.1.1 # google-genai 2.10.0 has requirement websockets<17.0
|
||||||
aiohttp>=3.14.3,<3.15
|
aiohttp>=3.14.4,<3.15
|
||||||
aiofiles>=25.1.0,<26.0
|
aiofiles>=25.1.0,<26.0
|
||||||
Jinja2>=3.1.6,<3.2
|
Jinja2>=3.1.6,<3.2
|
||||||
sentry-sdk>=2.70.0,<3 # optional dependency
|
sentry-sdk>=2.70.0,<3 # optional dependency
|
||||||
psutil>=7.2.2
|
psutil>=7.2.2
|
||||||
async-timeout>=5.0.1,<5.1; python_version < '3.11' # this library has effectively been upstreamed into Python 3.11+
|
|
||||||
distro>=1.9.0
|
distro>=1.9.0
|
||||||
py-cpuinfo>=9.0.0,<10.0
|
py-cpuinfo>=9.0.0,<10.0
|
||||||
greenlet==3.5.3; python_version >= '3.13' # necessary to run sqlalchemy on Python >= 3.13
|
sqlalchemy[asyncio]==2.1.4
|
||||||
sqlalchemy==2.0.54 # version 2.0.54 is the last version that supports Python 3.10
|
|
||||||
aiosqlite==0.22.1
|
aiosqlite==0.22.1
|
||||||
alembic==1.20
|
alembic==1.20
|
||||||
bcrypt==5.0.0
|
bcrypt==5.0.0
|
||||||
@ -22,7 +20,7 @@ email-validator==2.3.0
|
|||||||
watchdog==6.0.0
|
watchdog==6.0.0
|
||||||
zstandard==0.25.0
|
zstandard==0.25.0
|
||||||
platformdirs>=2.4.0 # fastmcp-slim >=3.4 requires >=4.0.0; upper bound removed for compatibility
|
platformdirs>=2.4.0 # fastmcp-slim >=3.4 requires >=4.0.0; upper bound removed for compatibility
|
||||||
truststore>=0.10.4; python_version >= '3.10'
|
truststore>=0.10.4
|
||||||
|
|
||||||
# Shared dependencies (also used by AI Copilot)
|
# Shared dependencies (also used by AI Copilot)
|
||||||
telnetlib3==5.0.1,<6
|
telnetlib3==5.0.1,<6
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user