Merge pull request #2930 from markparonyan/mypy-db-templates-images

fix(typing): resolve the remaining mypy errors (18 modules)
This commit is contained in:
Jeremy Grossmann authored and GitHub committed 2026-09-29 21:37:14 +02:00
commit e90be1ebac
25 files changed
+201 -147

No files matched your search

+6 -2
View File
@@ -16,12 +16,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import uuid
from datetime import datetime
from typing import Optional
from fastapi.encoders import jsonable_encoder
from sqlalchemy import Column, DateTime, func, inspect
from sqlalchemy.types import TypeDecorator, CHAR, VARCHAR
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
@@ -105,7 +107,9 @@ class BaseTable(Base):
__abstract__ = True
created_at = Column(DateTime, server_default=func.current_timestamp())
updated_at = Column(DateTime, server_default=func.current_timestamp(), onupdate=func.current_timestamp())
updated_at: Mapped[Optional[datetime]] = mapped_column(
DateTime, server_default=func.current_timestamp(), onupdate=func.current_timestamp()
)
__mapper_args__ = {"eager_defaults": True}
+3 -3
View File
@@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from sqlalchemy import Table, Column, String, ForeignKey, BigInteger, Integer
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Mapped, mapped_column, relationship
from .base import Base, BaseTable, GUID
@@ -32,9 +32,9 @@ image_template_map = Table(
class Image(BaseTable):
__tablename__ = "images"
image_id = Column(Integer, primary_key=True, autoincrement=True)
image_id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
filename = Column(String, index=True)
path = Column(String, unique=True)
path: Mapped[str] = mapped_column(String, unique=True, nullable=True)
image_type = Column(String)
image_size = Column(BigInteger)
checksum = Column(String, index=True)
+5 -3
View File
@@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from sqlalchemy import Column, Boolean, ForeignKey, CheckConstraint, Index, Integer, String, text, JSON
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Mapped, mapped_column, relationship
from .base import BaseTable, generate_uuid, GUID
@@ -36,11 +36,13 @@ class LLMModelConfig(BaseTable):
config_id = Column(GUID, primary_key=True, default=generate_uuid)
name = Column(String(100), nullable=False) # Configuration name (table-level for indexing)
model_type = Column(String(50), nullable=False) # Model type: text, vision, stt, tts, multimodal, etc.
config = Column(JSON, nullable=False) # Config fields: provider, base_url, model, temperature, api_key, etc.
config: Mapped[dict] = mapped_column(
JSON, nullable=False
) # Config fields: provider, base_url, model, temperature, api_key, etc.
user_id = Column(GUID, ForeignKey("users.user_id", ondelete="CASCADE"), nullable=True)
group_id = Column(GUID, ForeignKey("user_groups.user_group_id", ondelete="CASCADE"), nullable=True)
is_default = Column(Boolean, default=False, nullable=False)
version = Column(Integer, default=0, nullable=False) # Optimistic locking version
version: Mapped[int] = mapped_column(Integer, default=0, nullable=False) # Optimistic locking version
# Relationships
user = relationship("User", backref="llm_model_configs")
+5 -3
View File
@@ -15,8 +15,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import uuid
from sqlalchemy import Table, Column, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Mapped, mapped_column, relationship
from .base import Base, BaseTable, generate_uuid, GUID
@@ -36,7 +38,7 @@ resource_pool_map = Table(
class Resource(BaseTable):
__tablename__ = "resources"
resource_id = Column(GUID, primary_key=True)
resource_id: Mapped[uuid.UUID] = mapped_column(GUID, primary_key=True)
name = Column(String, unique=True, index=True)
resource_type = Column(String)
resource_pools = relationship("ResourcePool", secondary=resource_pool_map, back_populates="resources")
@@ -45,6 +47,6 @@ class Resource(BaseTable):
class ResourcePool(BaseTable):
__tablename__ = "resource_pools"
resource_pool_id = Column(GUID, primary_key=True, default=generate_uuid)
resource_pool_id: Mapped[uuid.UUID] = mapped_column(GUID, primary_key=True, default=generate_uuid)
name = Column(String, unique=True, index=True)
resources = relationship("Resource", secondary=resource_pool_map, back_populates="resource_pools")
+4 -2
View File
@@ -15,8 +15,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import uuid
from sqlalchemy import Column, String, Boolean, event
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Mapped, mapped_column, relationship
from .base import BaseTable, generate_uuid, GUID
from .privileges import privilege_role_map
@@ -29,7 +31,7 @@ log = logging.getLogger(__name__)
class Role(BaseTable):
__tablename__ = "roles"
role_id = Column(GUID, primary_key=True, default=generate_uuid)
role_id: Mapped[uuid.UUID] = mapped_column(GUID, primary_key=True, default=generate_uuid)
name = Column(String, unique=True, index=True)
description = Column(String)
is_builtin = Column(Boolean, default=False)
+8 -4
View File
@@ -15,8 +15,11 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Optional
from sqlalchemy import Table, Boolean, Column, Integer, String, DateTime, ForeignKey, event
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Mapped, mapped_column, relationship
from .base import Base, BaseTable, generate_uuid, GUID
@@ -24,6 +27,7 @@ from gns3server.config import Config
from gns3server.services import auth_service
import logging
import uuid
log = logging.getLogger(__name__)
@@ -43,8 +47,8 @@ class User(BaseTable):
email = Column(String, unique=True, index=True)
full_name = Column(String)
hashed_password = Column(String)
last_login = Column(DateTime)
token_version = Column(Integer, default=0, nullable=False, server_default="0")
last_login: Mapped[Optional[datetime]] = mapped_column(DateTime)
token_version: Mapped[int] = mapped_column(Integer, default=0, nullable=False, server_default="0")
is_active = Column(Boolean, default=True)
is_superadmin = Column(Boolean, default=False)
groups = relationship("UserGroup", secondary=user_group_map, back_populates="users")
@@ -72,7 +76,7 @@ def create_default_super_admin(target, connection, **kw):
class UserGroup(BaseTable):
__tablename__ = "user_groups"
user_group_id = Column(GUID, primary_key=True, default=generate_uuid)
user_group_id: Mapped[uuid.UUID] = mapped_column(GUID, primary_key=True, default=generate_uuid)
name = Column(String, unique=True, index=True)
is_builtin = Column(Boolean, default=False)
users = relationship("User", secondary=user_group_map, back_populates="groups")
+5 -4
View File
@@ -15,9 +15,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from uuid import UUID
from typing import Optional, List
from typing import Optional, List, cast
from datetime import datetime, timezone
from sqlalchemy import select, update, delete, func
from sqlalchemy.engine import CursorResult
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
@@ -67,13 +68,13 @@ class ApiKeysRepository(BaseRepository):
query = update(models.ApiKey).where(models.ApiKey.api_key_id == api_key_id).values(revoked=True)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
async def restore_api_key(self, api_key_id: UUID) -> bool:
query = update(models.ApiKey).where(models.ApiKey.api_key_id == api_key_id).values(revoked=False)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
async def update_last_used(self, api_key_id: UUID) -> None:
query = update(models.ApiKey).where(models.ApiKey.api_key_id == api_key_id).values(last_used_at=func.now())
@@ -84,4 +85,4 @@ class ApiKeysRepository(BaseRepository):
query = delete(models.ApiKey).where(models.ApiKey.api_key_id == api_key_id)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
+5 -3
View File
@@ -19,6 +19,8 @@ from uuid import UUID
from typing import Optional, List, Union
from sqlalchemy import select, update, delete
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.engine import CursorResult
from typing import cast
from .base import BaseRepository
@@ -47,7 +49,7 @@ class ComputesRepository(BaseRepository):
query = select(models.Compute)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def create_compute(self, compute_create: schemas.ComputeCreate) -> models.Compute:
@@ -58,7 +60,7 @@ class ComputesRepository(BaseRepository):
host=compute_create.host,
port=compute_create.port,
user=compute_create.user,
password=compute_create.password.get_secret_value(),
password=compute_create.password.get_secret_value() if compute_create.password else None,
)
self._db_session.add(db_compute)
await self._db_session.commit()
@@ -87,4 +89,4 @@ class ComputesRepository(BaseRepository):
query = delete(models.Compute).where(models.Compute.compute_id == compute_id)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
+9 -8
View File
@@ -17,8 +17,9 @@
import os
from typing import Optional, List
from typing import Optional, List, cast
from sqlalchemy import select, delete, update
from sqlalchemy.engine import CursorResult
from sqlalchemy.ext.asyncio import AsyncSession
from .base import BaseRepository
@@ -50,7 +51,7 @@ class ImagesRepository(BaseRepository):
result = await self._db_session.execute(query)
return result.scalars().one_or_none()
async def get_image_by_checksum(self, checksum: str, image_dir: str = None) -> Optional[models.Image]:
async def get_image_by_checksum(self, checksum: str, image_dir: Optional[str] = None) -> Optional[models.Image]:
"""
Get an image by its checksum.
"""
@@ -76,9 +77,9 @@ class ImagesRepository(BaseRepository):
else:
query = select(models.Image)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def get_image_templates(self, image_id: int) -> Optional[List[models.Template]]:
async def get_image_templates(self, image_id: int) -> List[models.Template]:
"""
Get all templates that an image belongs to.
"""
@@ -86,7 +87,7 @@ class ImagesRepository(BaseRepository):
query = select(models.Template).join(models.Template.images).filter(models.Image.image_id == image_id)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def add_image(self, image_name, image_type, image_size, path, checksum, checksum_algorithm) -> models.Image:
"""
@@ -108,7 +109,7 @@ class ImagesRepository(BaseRepository):
await self._db_session.refresh(db_image)
return db_image
async def update_image(self, image_path: str, checksum: str, checksum_algorithm: str) -> models.Image:
async def update_image(self, image_path: str, checksum: str, checksum_algorithm: str) -> Optional[models.Image]:
"""
Update an image.
"""
@@ -142,9 +143,9 @@ class ImagesRepository(BaseRepository):
query = delete(models.Image).where(models.Image.filename == image_name)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
async def prune_images(self, skip_images: list[str] = None) -> int:
async def prune_images(self, skip_images: Optional[list[str]] = None) -> int:
"""
Prune images not attached to any template.
"""
+18 -17
View File
@@ -16,8 +16,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from uuid import UUID
from typing import Optional, List, Dict, Any
from typing import Optional, List, Dict, Any, cast
from sqlalchemy import select, update, delete, and_
from sqlalchemy.engine import CursorResult
from datetime import datetime
import logging
@@ -63,7 +64,7 @@ class LLMModelConfigsRepository(BaseRepository):
.order_by(models.LLMModelConfig.created_at)
)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def get_user_default_config(self, user_id: UUID) -> Optional[models.LLMModelConfig]:
"""Get a user's default LLM model configuration."""
@@ -182,7 +183,7 @@ class LLMModelConfigsRepository(BaseRepository):
)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
async def set_user_default_config(self, user_id: UUID, config_id: UUID) -> bool:
"""Set a user's default LLM model configuration."""
@@ -202,7 +203,7 @@ class LLMModelConfigsRepository(BaseRepository):
)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
# Group configuration methods
@@ -222,7 +223,7 @@ class LLMModelConfigsRepository(BaseRepository):
.order_by(models.LLMModelConfig.created_at)
)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def get_group_default_config(self, group_id: UUID) -> Optional[models.LLMModelConfig]:
"""Get a group's default LLM model configuration."""
@@ -341,7 +342,7 @@ class LLMModelConfigsRepository(BaseRepository):
)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
async def set_group_default_config(self, group_id: UUID, config_id: UUID) -> bool:
"""Set a group's default LLM model configuration."""
@@ -361,7 +362,7 @@ class LLMModelConfigsRepository(BaseRepository):
)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
# Inheritance methods
@@ -441,21 +442,21 @@ class LLMModelConfigsRepository(BaseRepository):
)
# Select default_config with proper priority:
# 1. User's config marked with is_default: true
# 2. Group's config marked with is_default: true
# 3. First config in the list (user configs come first)
for config in configs_with_source:
if config["is_default"] and config["source"] == "user":
default_config = config
# 1. User's entry marked with is_default: true
# 2. Group's entry marked with is_default: true
# 3. First entry in the list (user configs come first)
for entry in configs_with_source:
if entry["is_default"] and entry["source"] == "user":
default_config = entry
break
if default_config is None:
for config in configs_with_source:
if config["is_default"] and config["source"] == "group":
default_config = config
for entry in configs_with_source:
if entry["is_default"] and entry["source"] == "group":
default_config = entry
break
# Fallback to first config if no default is marked
# Fallback to first entry if no default is marked
if default_config is None and configs_with_source:
default_config = configs_with_source[0]
+8 -7
View File
@@ -16,8 +16,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from uuid import UUID
from typing import Optional, List, Union
from typing import Optional, List, Union, cast
from sqlalchemy import select, update, delete
from sqlalchemy.engine import CursorResult
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
@@ -52,7 +53,7 @@ class ResourcePoolsRepository(BaseRepository):
query = select(models.Resource)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def create_resource(self, resource: schemas.ResourceCreate) -> models.Resource:
"""
@@ -75,7 +76,7 @@ class ResourcePoolsRepository(BaseRepository):
query = delete(models.Resource).where(models.Resource.resource_id == resource_id)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
async def get_resource_memberships(self, resource_id: UUID) -> List[models.ResourcePool]:
"""
@@ -89,7 +90,7 @@ class ResourcePoolsRepository(BaseRepository):
)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def get_resource_pool(self, resource_pool_id: UUID) -> Optional[models.ResourcePool]:
"""
@@ -116,7 +117,7 @@ class ResourcePoolsRepository(BaseRepository):
query = select(models.ResourcePool)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def create_resource_pool(self, resource_pool: schemas.ResourcePoolCreate) -> models.ResourcePool:
"""
@@ -166,7 +167,7 @@ class ResourcePoolsRepository(BaseRepository):
query = delete(models.ResourcePool).where(models.ResourcePool.resource_pool_id == resource_pool_id)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
async def add_resource_to_pool(
self, resource_pool_id: UUID, resource: models.Resource
@@ -225,4 +226,4 @@ class ResourcePoolsRepository(BaseRepository):
)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
+13 -12
View File
@@ -17,8 +17,9 @@
from uuid import UUID
from urllib.parse import urlparse
from typing import Optional, List, Union
from typing import Optional, List, Union, cast
from sqlalchemy import select, update, delete
from sqlalchemy.engine import CursorResult
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
@@ -62,9 +63,9 @@ class RbacRepository(BaseRepository):
query = select(models.Role).options(selectinload(models.Role.privileges))
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def create_role(self, role_create: schemas.RoleCreate) -> models.Role:
async def create_role(self, role_create: schemas.RoleCreate) -> Optional[models.Role]:
"""
Create a new role.
"""
@@ -100,7 +101,7 @@ class RbacRepository(BaseRepository):
query = delete(models.Role).where(models.Role.role_id == role_id)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
async def add_privilege_to_role(self, role_id: UUID, privilege: models.Privilege) -> Union[None, models.Role]:
"""
@@ -149,7 +150,7 @@ class RbacRepository(BaseRepository):
query = select(models.Privilege).join(models.Privilege.roles).filter(models.Role.role_id == role_id)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def get_privilege(self, privilege_id: UUID) -> Optional[models.Privilege]:
"""
@@ -176,7 +177,7 @@ class RbacRepository(BaseRepository):
query = select(models.Privilege)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def get_ace(self, ace_id: UUID) -> Optional[models.ACE]:
"""
@@ -203,7 +204,7 @@ class RbacRepository(BaseRepository):
query = select(models.ACE)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def get_aces_for_path(self, path: str) -> List[models.ACE]:
"""
@@ -218,7 +219,7 @@ class RbacRepository(BaseRepository):
.options(selectinload(models.ACE.user), selectinload(models.ACE.group), selectinload(models.ACE.role))
)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def check_ace_exists(self, path: str) -> bool:
"""
@@ -264,7 +265,7 @@ class RbacRepository(BaseRepository):
query = delete(models.ACE).where(models.ACE.ace_id == ace_id)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
async def delete_all_ace_starting_with_path(self, path: str) -> None:
"""
@@ -273,7 +274,7 @@ class RbacRepository(BaseRepository):
query = delete(models.ACE).where(models.ACE.path.startswith(path)).execution_options(synchronize_session=False)
result = await self._db_session.execute(query)
log.debug(f"{result.rowcount} ACE(s) have been deleted")
log.debug(f"{cast(CursorResult, result).rowcount} ACE(s) have been deleted")
@staticmethod
def _check_path_with_aces(path: str, aces) -> bool:
@@ -297,7 +298,7 @@ class RbacRepository(BaseRepository):
return True # only allow if the path is the original path or the ACE is set to propagate
return False
async def _get_resources_in_pools(self, aces, path: str = None) -> List[models.Resource]:
async def _get_resources_in_pools(self, aces, path: Optional[str] = None) -> List[models.Resource]:
"""
Get all resources in pools.
"""
@@ -392,7 +393,7 @@ class RbacRepository(BaseRepository):
all_resources = result.scalars().all()
# Precompute pool_id -> set of project_ids
pool_to_projects = {}
pool_to_projects: dict[str, set[str]] = {}
for r in all_resources:
if r.resource_type == "project":
for pool in r.resource_pools:
+11 -8
View File
@@ -16,8 +16,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from uuid import UUID
from typing import Optional, List, Union
from typing import Optional, List, Union, cast
from sqlalchemy import select, update, delete, func
from sqlalchemy.engine import CursorResult
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
@@ -72,7 +73,7 @@ class UsersRepository(BaseRepository):
query = select(models.User)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def create_user(self, user: schemas.UserCreate) -> models.User:
"""
@@ -88,7 +89,9 @@ class UsersRepository(BaseRepository):
await self._db_session.refresh(db_user)
return db_user
async def update_user(self, user_id: UUID, user_update: schemas.UserUpdate) -> Optional[models.User]:
async def update_user(
self, user_id: UUID, user_update: Union[schemas.UserUpdate, schemas.LoggedInUserUpdate]
) -> Optional[models.User]:
"""
Update a user.
"""
@@ -129,7 +132,7 @@ class UsersRepository(BaseRepository):
query = delete(models.User).where(models.User.user_id == user_id)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
async def authenticate_user(self, username: str, password: str) -> Optional[models.User]:
"""
@@ -168,7 +171,7 @@ class UsersRepository(BaseRepository):
query = select(models.UserGroup).join(models.UserGroup.users).filter(models.User.user_id == user_id)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def get_user_group(self, user_group_id: UUID) -> Optional[models.UserGroup]:
"""
@@ -195,7 +198,7 @@ class UsersRepository(BaseRepository):
query = select(models.UserGroup)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
async def create_user_group(self, user_group: schemas.UserGroupCreate) -> models.UserGroup:
"""
@@ -233,7 +236,7 @@ class UsersRepository(BaseRepository):
query = delete(models.UserGroup).where(models.UserGroup.user_group_id == user_group_id)
result = await self._db_session.execute(query)
await self._db_session.commit()
return result.rowcount > 0
return cast(CursorResult, result).rowcount > 0
async def add_member_to_user_group(self, user_group_id: UUID, user: models.User) -> Union[None, models.UserGroup]:
"""
@@ -285,4 +288,4 @@ class UsersRepository(BaseRepository):
query = select(models.User).join(models.User.groups).filter(models.UserGroup.user_group_id == user_group_id)
result = await self._db_session.execute(query)
return result.scalars().all()
return list(result.scalars().all())
+9 -9
View File
@@ -171,7 +171,7 @@ async def disconnect_from_db(app: FastAPI) -> None:
log.info(f"Disconnected from database")
async def get_computes(app: FastAPI) -> List[dict]:
async def get_computes(app: FastAPI) -> List[schemas.Compute]:
computes = []
async with AsyncSession(app.state._db_engine) as db_session:
@@ -201,12 +201,12 @@ async def discover_images_on_filesystem(app: FastAPI) -> None:
continue
for image_type in ("qemu", "ios", "iou"):
discovered_images = await discover_images(image_type, existing_image_paths)
for image in discovered_images:
log.info(f"Adding discovered image '{image['path']}' to the database")
for image_info in discovered_images:
log.info(f"Adding discovered image '{image_info['path']}' to the database")
try:
await images_repository.add_image(**image)
await images_repository.add_image(**image_info)
except SQLAlchemyError as e:
log.warning(f"Error while adding image '{image['path']}' to the database: {e}")
log.warning(f"Error while adding image '{image_info['path']}' to the database: {e}")
# monitor if images have been manually added
asyncio.create_task(monitor_images_on_filesystem(app))
@@ -237,7 +237,7 @@ class EventHandler(PatternMatchingEventHandler):
Watchdog event handler.
"""
def __init__(self, queue: asyncio.Queue, loop: asyncio.BaseEventLoop, **kwargs):
def __init__(self, queue: asyncio.Queue, loop: asyncio.AbstractEventLoop, **kwargs):
self._loop = loop
self._queue = queue
@@ -274,7 +274,7 @@ class EventIterator(object):
async def monitor_images_on_filesystem(app: FastAPI):
def watchdog(
path: str, queue: asyncio.Queue, loop: asyncio.BaseEventLoop, app: FastAPI, recursive: bool = False
path: str, queue: asyncio.Queue, loop: asyncio.AbstractEventLoop, app: FastAPI, recursive: bool = False
) -> None:
"""
Thread to monitor a directory for new images.
@@ -295,7 +295,7 @@ async def monitor_images_on_filesystem(app: FastAPI):
loop.call_soon_threadsafe(queue.put_nowait, None)
break
queue = asyncio.Queue()
queue: asyncio.Queue = asyncio.Queue()
loop = asyncio.get_event_loop()
server_config = Config.instance().settings.Server
image_dir = os.path.expanduser(server_config.images_path)
@@ -348,7 +348,7 @@ async def get_user_llm_config_full(user_id: str, app: FastAPI) -> Optional[dict]
from gns3server.utils.encryption import decrypt, is_encrypted
try:
user_uuid = UUID(user_id) if isinstance(user_id, str) else user_id
user_uuid = UUID(user_id)
async with AsyncSession(app.state._db_engine, expire_on_commit=False) as session:
repo = LLMModelConfigsRepository(session)