diff --git a/backend/adapters/services/igdb.py b/backend/adapters/services/igdb.py index 6e03efb0c..a8a0229ae 100644 --- a/backend/adapters/services/igdb.py +++ b/backend/adapters/services/igdb.py @@ -7,12 +7,13 @@ from typing import TYPE_CHECKING import aiohttp import yarl -from adapters.services.igdb_types import Game from aiohttp.client import ClientTimeout -from config import IGDB_CLIENT_ID from fastapi import HTTPException, status -from logger.logger import log from unidecode import unidecode + +from adapters.services.igdb_types import Game +from config import IGDB_CLIENT_ID +from logger.logger import log from utils.context import ctx_aiohttp_session if TYPE_CHECKING: diff --git a/backend/adapters/services/mobygames.py b/backend/adapters/services/mobygames.py index 1ddc771c2..5061ea52e 100644 --- a/backend/adapters/services/mobygames.py +++ b/backend/adapters/services/mobygames.py @@ -6,10 +6,11 @@ from typing import Literal, overload import aiohttp import yarl -from adapters.services.mobygames_types import MobyGame, MobyGameBrief, MobyOutputFormat from aiohttp.client import ClientTimeout -from config import MOBYGAMES_API_KEY from fastapi import HTTPException, status + +from adapters.services.mobygames_types import MobyGame, MobyGameBrief, MobyOutputFormat +from config import MOBYGAMES_API_KEY from logger.logger import log from utils.context import ctx_aiohttp_session diff --git a/backend/adapters/services/retroachievements.py b/backend/adapters/services/retroachievements.py index 01a546130..770988d4f 100644 --- a/backend/adapters/services/retroachievements.py +++ b/backend/adapters/services/retroachievements.py @@ -6,6 +6,9 @@ from typing import cast import aiohttp import yarl +from aiohttp.client import ClientTimeout +from fastapi import HTTPException, status + from adapters.services.retroachievements_types import ( RAGameExtendedDetails, RAGameInfoAndUserProgress, @@ -13,9 +16,7 @@ from adapters.services.retroachievements_types import ( RAUserCompletionProgress, RAUserCompletionProgressResult, ) -from aiohttp.client import ClientTimeout from config import RETROACHIEVEMENTS_API_KEY -from fastapi import HTTPException, status from logger.logger import log from utils.context import ctx_aiohttp_session diff --git a/backend/adapters/services/screenscraper.py b/backend/adapters/services/screenscraper.py index 4ea2e82fe..0eed6263b 100644 --- a/backend/adapters/services/screenscraper.py +++ b/backend/adapters/services/screenscraper.py @@ -6,10 +6,11 @@ from typing import Final, cast import aiohttp import yarl -from adapters.services.screenscraper_types import SSGame from aiohttp.client import ClientTimeout -from config import SCREENSCRAPER_PASSWORD, SCREENSCRAPER_USER from fastapi import HTTPException, status + +from adapters.services.screenscraper_types import SSGame +from config import SCREENSCRAPER_PASSWORD, SCREENSCRAPER_USER from logger.logger import log from utils.context import ctx_aiohttp_session diff --git a/backend/adapters/services/steamgriddb.py b/backend/adapters/services/steamgriddb.py index fc3286d0b..457bb302f 100644 --- a/backend/adapters/services/steamgriddb.py +++ b/backend/adapters/services/steamgriddb.py @@ -7,6 +7,8 @@ from typing import Literal, cast import aiohttp import aiohttp.client_exceptions import yarl +from aiohttp.client import ClientTimeout + from adapters.services.steamgriddb_types import ( SGDBDimension, SGDBGame, @@ -17,7 +19,6 @@ from adapters.services.steamgriddb_types import ( SGDBTag, SGDBType, ) -from aiohttp.client import ClientTimeout from config import STEAMGRIDDB_API_KEY from exceptions.endpoint_exceptions import SGDBInvalidAPIKeyException from logger.logger import log diff --git a/backend/alembic/env.py b/backend/alembic/env.py index 9fed12b77..4a0296ba2 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -2,6 +2,8 @@ import sys from pathlib import Path from alembic import context +from sqlalchemy import create_engine + from config.config_manager import ConfigManager from logger.logger import unify_logger from models.assets import Save, Screenshot, State # noqa @@ -11,7 +13,6 @@ from models.firmware import Firmware # noqa from models.platform import Platform # noqa from models.rom import Rom, RomMetadata, SiblingRom # noqa from models.user import User # noqa -from sqlalchemy import create_engine # this is the Alembic Config object, which provides # access to the values within the .ini file in use. diff --git a/backend/alembic/versions/0009_models_refactor.py b/backend/alembic/versions/0009_models_refactor.py index 9a48ea38e..467760d3e 100644 --- a/backend/alembic/versions/0009_models_refactor.py +++ b/backend/alembic/versions/0009_models_refactor.py @@ -9,6 +9,7 @@ Create Date: 2023-09-12 18:18:27.158732 import sqlalchemy as sa from alembic import op from sqlalchemy.exc import OperationalError + from utils.database import CustomJSON, is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0012_add_regions_languages.py b/backend/alembic/versions/0012_add_regions_languages.py index b60010abe..83da434a8 100644 --- a/backend/alembic/versions/0012_add_regions_languages.py +++ b/backend/alembic/versions/0012_add_regions_languages.py @@ -8,6 +8,7 @@ Create Date: 2023-12-03 10:54:46.859106 import sqlalchemy as sa from alembic import op + from utils.database import CustomJSON, is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0014_asset_files.py b/backend/alembic/versions/0014_asset_files.py index a6755bf9e..9aeb10438 100644 --- a/backend/alembic/versions/0014_asset_files.py +++ b/backend/alembic/versions/0014_asset_files.py @@ -10,10 +10,11 @@ import os import sqlalchemy as sa from alembic import op -from config import ROMM_DB_DRIVER -from config.config_manager import SQLITE_DB_BASE_PATH, ConfigManager from sqlalchemy import create_engine, text from sqlalchemy.orm import sessionmaker + +from config import ROMM_DB_DRIVER +from config.config_manager import SQLITE_DB_BASE_PATH, ConfigManager from utils.database import CustomJSON, is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0015_mobygames_data.py b/backend/alembic/versions/0015_mobygames_data.py index b402b7340..f9fbddf68 100644 --- a/backend/alembic/versions/0015_mobygames_data.py +++ b/backend/alembic/versions/0015_mobygames_data.py @@ -8,6 +8,7 @@ Create Date: 2024-02-13 17:57:25.936825 import sqlalchemy as sa from alembic import op + from utils.database import CustomJSON, is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0019_resources_refactor.py b/backend/alembic/versions/0019_resources_refactor.py index 99430cad9..f69cabbb8 100644 --- a/backend/alembic/versions/0019_resources_refactor.py +++ b/backend/alembic/versions/0019_resources_refactor.py @@ -13,6 +13,7 @@ from urllib.parse import quote import sqlalchemy as sa from alembic import op + from config import RESOURCES_BASE_PATH # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0022_collections_.py b/backend/alembic/versions/0022_collections_.py index b0010e320..89db6c89c 100644 --- a/backend/alembic/versions/0022_collections_.py +++ b/backend/alembic/versions/0022_collections_.py @@ -12,8 +12,9 @@ import shutil import sqlalchemy as sa from alembic import op -from config import RESOURCES_BASE_PATH from sqlalchemy import inspect + +from config import RESOURCES_BASE_PATH from utils.database import CustomJSON # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0023_make_columns_non_nullable.py b/backend/alembic/versions/0023_make_columns_non_nullable.py index 11b9ac008..c9650258f 100644 --- a/backend/alembic/versions/0023_make_columns_non_nullable.py +++ b/backend/alembic/versions/0023_make_columns_non_nullable.py @@ -8,6 +8,7 @@ Create Date: 2024-07-07 13:44:25.811184 import sqlalchemy as sa from alembic import op + from utils.database import is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0024_sibling_roms_db_view.py b/backend/alembic/versions/0024_sibling_roms_db_view.py index 413db2db1..8c31e0219 100644 --- a/backend/alembic/versions/0024_sibling_roms_db_view.py +++ b/backend/alembic/versions/0024_sibling_roms_db_view.py @@ -8,6 +8,7 @@ Create Date: 2024-08-08 12:00:00.000000 import sqlalchemy as sa from alembic import op + from utils.database import is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0025_roms_hashes.py b/backend/alembic/versions/0025_roms_hashes.py index 0d14ade97..760957987 100644 --- a/backend/alembic/versions/0025_roms_hashes.py +++ b/backend/alembic/versions/0025_roms_hashes.py @@ -8,6 +8,7 @@ Create Date: 2024-08-11 21:50:53.301352 import sqlalchemy as sa from alembic import op + from config import IS_PYTEST_RUN, SCAN_TIMEOUT from endpoints.sockets.scan import scan_platforms from handler.redis_handler import high_prio_queue diff --git a/backend/alembic/versions/0026_romuser_status_fields.py b/backend/alembic/versions/0026_romuser_status_fields.py index e3e5f7f7b..351776eda 100644 --- a/backend/alembic/versions/0026_romuser_status_fields.py +++ b/backend/alembic/versions/0026_romuser_status_fields.py @@ -9,6 +9,7 @@ Create Date: 2024-08-29 15:52:56.031850 import sqlalchemy as sa from alembic import op from sqlalchemy.dialects.postgresql import ENUM + from utils.database import is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0027_platforms_data.py b/backend/alembic/versions/0027_platforms_data.py index 2254d6cf5..166e66806 100644 --- a/backend/alembic/versions/0027_platforms_data.py +++ b/backend/alembic/versions/0027_platforms_data.py @@ -8,6 +8,7 @@ Create Date: 2024-11-17 23:05:31.038917 import sqlalchemy as sa from alembic import op + from models.platform import DEFAULT_COVER_ASPECT_RATIO # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0033_rom_file_and_hashes.py b/backend/alembic/versions/0033_rom_file_and_hashes.py index 936cda2a6..382a2c1b9 100644 --- a/backend/alembic/versions/0033_rom_file_and_hashes.py +++ b/backend/alembic/versions/0033_rom_file_and_hashes.py @@ -8,11 +8,12 @@ Create Date: 2024-12-19 23:16:11.053536 import sqlalchemy as sa from alembic import op +from sqlalchemy.dialects.postgresql import ENUM + from config import IS_PYTEST_RUN, SCAN_TIMEOUT from endpoints.sockets.scan import scan_platforms from handler.redis_handler import high_prio_queue from handler.scan_handler import ScanType -from sqlalchemy.dialects.postgresql import ENUM from utils.database import CustomJSON, is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0034_virtual_collections_db_view.py b/backend/alembic/versions/0034_virtual_collections_db_view.py index a50db2b23..4ff2a6a78 100644 --- a/backend/alembic/versions/0034_virtual_collections_db_view.py +++ b/backend/alembic/versions/0034_virtual_collections_db_view.py @@ -8,6 +8,7 @@ Create Date: 2024-08-08 12:00:00.000000 import sqlalchemy as sa from alembic import op + from utils.database import CustomJSON, is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0035_screenscraper.py b/backend/alembic/versions/0035_screenscraper.py index 436455607..7d2cab16d 100644 --- a/backend/alembic/versions/0035_screenscraper.py +++ b/backend/alembic/versions/0035_screenscraper.py @@ -8,6 +8,7 @@ Create Date: 2025-01-02 18:58:55.557123 import sqlalchemy as sa from alembic import op + from utils.database import CustomJSON # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0036_screenscraper_platforms_id.py b/backend/alembic/versions/0036_screenscraper_platforms_id.py index ace94074b..d452b710f 100644 --- a/backend/alembic/versions/0036_screenscraper_platforms_id.py +++ b/backend/alembic/versions/0036_screenscraper_platforms_id.py @@ -8,6 +8,7 @@ Create Date: 2025-01-02 18:58:55.557123 import sqlalchemy as sa from alembic import op + from handler.metadata.ss_handler import SCREENSAVER_PLATFORM_LIST # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0037_virtual_rom_columns.py b/backend/alembic/versions/0037_virtual_rom_columns.py index 96fb55f3c..1b1b05e5e 100644 --- a/backend/alembic/versions/0037_virtual_rom_columns.py +++ b/backend/alembic/versions/0037_virtual_rom_columns.py @@ -8,6 +8,7 @@ Create Date: 2025-03-17 00:00:00.000000 import sqlalchemy as sa from alembic import op + from utils.database import is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0038_add_ssid_to_sibling_roms.py b/backend/alembic/versions/0038_add_ssid_to_sibling_roms.py index 9fa40e7b1..dd10ea78e 100644 --- a/backend/alembic/versions/0038_add_ssid_to_sibling_roms.py +++ b/backend/alembic/versions/0038_add_ssid_to_sibling_roms.py @@ -8,6 +8,7 @@ Create Date: 2025-04-23 00:00:00.000000 import sqlalchemy as sa from alembic import op + from utils.database import is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0039_add_retro_achievements.py b/backend/alembic/versions/0039_add_retro_achievements.py index d717285b6..a333082e5 100644 --- a/backend/alembic/versions/0039_add_retro_achievements.py +++ b/backend/alembic/versions/0039_add_retro_achievements.py @@ -8,6 +8,7 @@ Create Date: 2025-04-11 00:59:30.772416 import sqlalchemy as sa from alembic import op + from utils.database import CustomJSON # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0040_migrate_assets_paths.py b/backend/alembic/versions/0040_migrate_assets_paths.py index 1cda51aed..dd596f49f 100644 --- a/backend/alembic/versions/0040_migrate_assets_paths.py +++ b/backend/alembic/versions/0040_migrate_assets_paths.py @@ -8,9 +8,10 @@ Create Date: 2025-05-14 18:10:23.522345 import os from alembic import op +from sqlalchemy.sql import text + from config import ASSETS_BASE_PATH from logger.logger import log -from sqlalchemy.sql import text from utils.database import is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0041_assets_t_thumb_cleanup.py b/backend/alembic/versions/0041_assets_t_thumb_cleanup.py index 9bf965289..d14a7beea 100644 --- a/backend/alembic/versions/0041_assets_t_thumb_cleanup.py +++ b/backend/alembic/versions/0041_assets_t_thumb_cleanup.py @@ -10,6 +10,7 @@ import json from alembic import op from sqlalchemy.sql import text + from utils.database import is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0043_launchbox_id.py b/backend/alembic/versions/0043_launchbox_id.py index 46e37aaef..72aa974d1 100644 --- a/backend/alembic/versions/0043_launchbox_id.py +++ b/backend/alembic/versions/0043_launchbox_id.py @@ -9,6 +9,7 @@ Create Date: 2025-05-20 22:39:16.993191 import sqlalchemy as sa from alembic import op from sqlalchemy.dialects import postgresql + from utils.database import CustomJSON revision = "0043_launchbox_id" diff --git a/backend/alembic/versions/0045_roms_metadata_update.py b/backend/alembic/versions/0045_roms_metadata_update.py index dced8360d..b3baf2247 100644 --- a/backend/alembic/versions/0045_roms_metadata_update.py +++ b/backend/alembic/versions/0045_roms_metadata_update.py @@ -8,6 +8,7 @@ Create Date: 2025-03-17 00:00:00.000000 import sqlalchemy as sa from alembic import op + from utils.database import is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0046_migrate_platform_slugs.py b/backend/alembic/versions/0046_migrate_platform_slugs.py index d66bb3c08..a7ac0f0a2 100644 --- a/backend/alembic/versions/0046_migrate_platform_slugs.py +++ b/backend/alembic/versions/0046_migrate_platform_slugs.py @@ -8,6 +8,7 @@ Create Date: 2025-07-24 15:24:04.331946 import sqlalchemy as sa from alembic import op + from config.config_manager import config_manager as cm from handler.metadata.base_hander import UniversalPlatformSlug as UPS diff --git a/backend/alembic/versions/0047_smart_collections.py b/backend/alembic/versions/0047_smart_collections.py index 17a2c9133..90715dd52 100644 --- a/backend/alembic/versions/0047_smart_collections.py +++ b/backend/alembic/versions/0047_smart_collections.py @@ -8,6 +8,7 @@ Create Date: 2024-12-19 12:00:00.000000 import sqlalchemy as sa from alembic import op + from utils.database import CustomJSON # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0048_sibling_roms_more_ids.py b/backend/alembic/versions/0048_sibling_roms_more_ids.py index 9f728a928..f6eb2fa90 100644 --- a/backend/alembic/versions/0048_sibling_roms_more_ids.py +++ b/backend/alembic/versions/0048_sibling_roms_more_ids.py @@ -8,6 +8,7 @@ Create Date: 2025-01-27 00:00:00.000000 import sqlalchemy as sa from alembic import op + from utils.database import is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/0050_firmware_add_is_verified.py b/backend/alembic/versions/0050_firmware_add_is_verified.py index 9af9c898c..7da49e289 100644 --- a/backend/alembic/versions/0050_firmware_add_is_verified.py +++ b/backend/alembic/versions/0050_firmware_add_is_verified.py @@ -8,6 +8,7 @@ Create Date: 2025-08-22 04:42:22.367888 import sqlalchemy as sa from alembic import op + from models.firmware import Firmware from utils.database import is_postgresql diff --git a/backend/alembic/versions/1.6.2_.py b/backend/alembic/versions/1.6.2_.py index b34cabcd1..f1b72728b 100644 --- a/backend/alembic/versions/1.6.2_.py +++ b/backend/alembic/versions/1.6.2_.py @@ -9,6 +9,7 @@ Create Date: 2023-04-10 23:02:37.472055 import sqlalchemy as sa from alembic import op from sqlalchemy.exc import OperationalError + from utils.database import CustomJSON # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/1.6.3_.py b/backend/alembic/versions/1.6.3_.py index 78ea68474..db475705f 100644 --- a/backend/alembic/versions/1.6.3_.py +++ b/backend/alembic/versions/1.6.3_.py @@ -8,6 +8,7 @@ Create Date: 2023-04-10 23:13:43.591414 import sqlalchemy as sa from alembic import op + from utils.database import CustomJSON # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/1.8.1_.py b/backend/alembic/versions/1.8.1_.py index 258405f71..7d46c710e 100644 --- a/backend/alembic/versions/1.8.1_.py +++ b/backend/alembic/versions/1.8.1_.py @@ -8,6 +8,7 @@ Create Date: 2023-04-17 12:03:19.163501 import sqlalchemy as sa from alembic import op + from utils.database import CustomJSON, is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/1.8.3_.py b/backend/alembic/versions/1.8.3_.py index f2a17fc26..03dbea185 100644 --- a/backend/alembic/versions/1.8.3_.py +++ b/backend/alembic/versions/1.8.3_.py @@ -7,6 +7,7 @@ Create Date: 2023-05-17 12:59:44.344356 """ from alembic import op + from utils.database import is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/1.8_.py b/backend/alembic/versions/1.8_.py index 3c5b6d7d7..be7a79fe2 100644 --- a/backend/alembic/versions/1.8_.py +++ b/backend/alembic/versions/1.8_.py @@ -8,6 +8,7 @@ Create Date: 2023-04-17 12:03:19.163501 import sqlalchemy as sa from alembic import op + from utils.database import CustomJSON # revision identifiers, used by Alembic. diff --git a/backend/alembic/versions/2.0.0_.py b/backend/alembic/versions/2.0.0_.py index 709edec42..729ebcfd3 100644 --- a/backend/alembic/versions/2.0.0_.py +++ b/backend/alembic/versions/2.0.0_.py @@ -9,6 +9,7 @@ Create Date: 2023-08-10 22:18:24.012779 import sqlalchemy as sa from alembic import op from sqlalchemy.dialects.postgresql import ENUM + from utils.database import is_postgresql # revision identifiers, used by Alembic. diff --git a/backend/config/config_manager.py b/backend/config/config_manager.py index 0ca926e0d..e1a7b5be4 100644 --- a/backend/config/config_manager.py +++ b/backend/config/config_manager.py @@ -4,6 +4,9 @@ from typing import Final, NotRequired, TypedDict import pydash import yaml +from sqlalchemy import URL +from yaml.loader import SafeLoader + from config import ( DB_HOST, DB_NAME, @@ -22,8 +25,6 @@ from exceptions.config_exceptions import ( from logger.formatter import BLUE from logger.formatter import highlight as hl from logger.logger import log -from sqlalchemy import URL -from yaml.loader import SafeLoader ROMM_USER_CONFIG_PATH: Final = f"{ROMM_BASE_PATH}/config" ROMM_USER_CONFIG_FILE: Final = f"{ROMM_USER_CONFIG_PATH}/config.yml" diff --git a/backend/decorators/auth.py b/backend/decorators/auth.py index 2a93f7089..689423c5f 100644 --- a/backend/decorators/auth.py +++ b/backend/decorators/auth.py @@ -2,6 +2,13 @@ from typing import Any from authlib.integrations.starlette_client import OAuth from authlib.oidc.discovery import get_well_known_url +from fastapi import Security +from fastapi.security.http import HTTPBasic +from fastapi.security.oauth2 import OAuth2PasswordBearer +from fastapi.types import DecoratedCallable +from starlette.authentication import requires +from starlette.config import Config + from config import ( OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, @@ -11,10 +18,6 @@ from config import ( OIDC_SERVER_APPLICATION_URL, OIDC_TLS_CACERTFILE, ) -from fastapi import Security -from fastapi.security.http import HTTPBasic -from fastapi.security.oauth2 import OAuth2PasswordBearer -from fastapi.types import DecoratedCallable from handler.auth.constants import ( EDIT_SCOPES_MAP, FULL_SCOPES_MAP, @@ -22,8 +25,6 @@ from handler.auth.constants import ( WRITE_SCOPES_MAP, Scope, ) -from starlette.authentication import requires -from starlette.config import Config # Using the internal password flow oauth2_password_bearer = OAuth2PasswordBearer( diff --git a/backend/decorators/database.py b/backend/decorators/database.py index 4e226b1f3..f532e6cd0 100644 --- a/backend/decorators/database.py +++ b/backend/decorators/database.py @@ -1,9 +1,10 @@ import functools from fastapi import HTTPException, status +from sqlalchemy.exc import ProgrammingError + from handler.database.base_handler import sync_session from logger.logger import log -from sqlalchemy.exc import ProgrammingError def begin_session(func): diff --git a/backend/endpoints/auth.py b/backend/endpoints/auth.py index b79575c2e..10cdb447f 100644 --- a/backend/endpoints/auth.py +++ b/backend/endpoints/auth.py @@ -1,6 +1,10 @@ from datetime import datetime, timedelta, timezone from typing import Annotated, Final +from fastapi import Body, Depends, HTTPException, Request, status +from fastapi.responses import RedirectResponse +from fastapi.security.http import HTTPBasic + from config import OIDC_ENABLED, OIDC_REDIRECT_URI from decorators.auth import oauth from endpoints.forms.identity import OAuth2RequestForm @@ -11,9 +15,6 @@ from exceptions.auth_exceptions import ( OIDCNotConfiguredException, UserDisabledException, ) -from fastapi import Body, Depends, HTTPException, Request, status -from fastapi.responses import RedirectResponse -from fastapi.security.http import HTTPBasic from handler.auth import auth_handler, oauth_handler, oidc_handler from handler.database import db_user_handler from logger.formatter import CYAN diff --git a/backend/endpoints/collections.py b/backend/endpoints/collections.py index 917c16654..f09b3fdc8 100644 --- a/backend/endpoints/collections.py +++ b/backend/endpoints/collections.py @@ -1,6 +1,8 @@ import json from io import BytesIO +from fastapi import Request, UploadFile + from config import str_to_bool from decorators.auth import protected_route from endpoints.responses.collection import ( @@ -13,7 +15,6 @@ from exceptions.endpoint_exceptions import ( CollectionNotFoundInDatabaseException, CollectionPermissionError, ) -from fastapi import Request, UploadFile from handler.auth.constants import Scope from handler.database import db_collection_handler from handler.filesystem import fs_resource_handler diff --git a/backend/endpoints/configs.py b/backend/endpoints/configs.py index 9a57c93dc..78f5325b5 100644 --- a/backend/endpoints/configs.py +++ b/backend/endpoints/configs.py @@ -1,3 +1,5 @@ +from fastapi import HTTPException, Request, status + from config.config_manager import config_manager as cm from decorators.auth import protected_route from endpoints.responses.config import ConfigResponse @@ -5,7 +7,6 @@ from exceptions.config_exceptions import ( ConfigNotReadableException, ConfigNotWritableException, ) -from fastapi import HTTPException, Request, status from handler.auth.constants import Scope from logger.logger import log from utils.router import APIRouter diff --git a/backend/endpoints/feeds.py b/backend/endpoints/feeds.py index 1822bc99d..e1492affd 100644 --- a/backend/endpoints/feeds.py +++ b/backend/endpoints/feeds.py @@ -1,5 +1,8 @@ from collections.abc import Sequence +from fastapi import Request +from starlette.datastructures import URLPath + from config import DISABLE_DOWNLOAD_ENDPOINT_AUTH, FRONTEND_RESOURCES_PATH from decorators.auth import protected_route from endpoints.responses.feeds import ( @@ -13,13 +16,11 @@ from endpoints.responses.feeds import ( WebrcadeFeedItemSchema, WebrcadeFeedSchema, ) -from fastapi import Request from handler.auth.constants import Scope from handler.database import db_platform_handler, db_rom_handler from handler.metadata import meta_igdb_handler from handler.metadata.base_hander import SWITCH_PRODUCT_ID_REGEX, SWITCH_TITLEDB_REGEX from models.rom import Rom -from starlette.datastructures import URLPath from utils.router import APIRouter router = APIRouter( diff --git a/backend/endpoints/firmware.py b/backend/endpoints/firmware.py index 906872a17..e714ad7d7 100644 --- a/backend/endpoints/firmware.py +++ b/backend/endpoints/firmware.py @@ -1,9 +1,10 @@ +from fastapi import File, HTTPException, Request, UploadFile, status +from fastapi.responses import FileResponse + from config import DISABLE_DOWNLOAD_ENDPOINT_AUTH from decorators.auth import protected_route from endpoints.responses import BulkOperationResponse from endpoints.responses.firmware import AddFirmwareResponse, FirmwareSchema -from fastapi import File, HTTPException, Request, UploadFile, status -from fastapi.responses import FileResponse from handler.auth.constants import Scope from handler.database import db_firmware_handler, db_platform_handler from handler.filesystem import fs_firmware_handler diff --git a/backend/endpoints/platform.py b/backend/endpoints/platform.py index 8270287be..6c87c02ea 100644 --- a/backend/endpoints/platform.py +++ b/backend/endpoints/platform.py @@ -1,13 +1,14 @@ from datetime import datetime, timezone from typing import Annotated +from fastapi import Body +from fastapi import Path as PathVar +from fastapi import Request, status + from decorators.auth import protected_route from endpoints.responses.platform import PlatformSchema from exceptions.endpoint_exceptions import PlatformNotFoundInDatabaseException from exceptions.fs_exceptions import PlatformAlreadyExistsException -from fastapi import Body -from fastapi import Path as PathVar -from fastapi import Request, status from handler.auth.constants import Scope from handler.database import db_platform_handler from handler.filesystem import fs_platform_handler diff --git a/backend/endpoints/raw.py b/backend/endpoints/raw.py index c4464d63f..f3f292f07 100644 --- a/backend/endpoints/raw.py +++ b/backend/endpoints/raw.py @@ -1,6 +1,7 @@ -from decorators.auth import protected_route from fastapi import HTTPException, Request from fastapi.responses import FileResponse + +from decorators.auth import protected_route from handler.auth.constants import Scope from handler.filesystem import fs_asset_handler from utils.router import APIRouter diff --git a/backend/endpoints/responses/platform.py b/backend/endpoints/responses/platform.py index b1b249c8a..dfb11d734 100644 --- a/backend/endpoints/responses/platform.py +++ b/backend/endpoints/responses/platform.py @@ -1,8 +1,9 @@ from datetime import datetime -from models.platform import DEFAULT_COVER_ASPECT_RATIO from pydantic import Field, computed_field, field_validator +from models.platform import DEFAULT_COVER_ASPECT_RATIO + from .base import BaseModel from .firmware import FirmwareSchema diff --git a/backend/endpoints/responses/rom.py b/backend/endpoints/responses/rom.py index b8a87f34a..68ebdf9fd 100644 --- a/backend/endpoints/responses/rom.py +++ b/backend/endpoints/responses/rom.py @@ -4,8 +4,10 @@ import re from datetime import datetime, timezone from typing import NotRequired, TypedDict, get_type_hints -from endpoints.responses.assets import SaveSchema, ScreenshotSchema, StateSchema from fastapi import Request +from pydantic import computed_field, field_validator + +from endpoints.responses.assets import SaveSchema, ScreenshotSchema, StateSchema from handler.metadata.hasheous_handler import HasheousMetadata from handler.metadata.igdb_handler import IGDBMetadata from handler.metadata.launchbox_handler import LaunchboxMetadata @@ -14,7 +16,6 @@ from handler.metadata.ra_handler import RAMetadata from handler.metadata.ss_handler import SSMetadata from models.collection import Collection from models.rom import Rom, RomFileCategory, RomUserStatus -from pydantic import computed_field, field_validator from .base import BaseModel diff --git a/backend/endpoints/rom.py b/backend/endpoints/rom.py index 3c60ebc65..34a55be48 100644 --- a/backend/endpoints/rom.py +++ b/backend/endpoints/rom.py @@ -8,22 +8,6 @@ from urllib.parse import quote from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile, ZipInfo from anyio import Path, open_file -from config import ( - DEV_MODE, - DISABLE_DOWNLOAD_ENDPOINT_AUTH, - LIBRARY_BASE_PATH, - str_to_bool, -) -from decorators.auth import protected_route -from endpoints.responses import BulkOperationResponse -from endpoints.responses.rom import ( - DetailedRomSchema, - RomFileSchema, - RomUserSchema, - SimpleRomSchema, -) -from exceptions.endpoint_exceptions import RomNotFoundInDatabaseException -from exceptions.fs_exceptions import RomAlreadyExistsException from fastapi import ( Body, File, @@ -40,6 +24,28 @@ from fastapi import ( from fastapi.responses import Response from fastapi_pagination.ext.sqlalchemy import paginate from fastapi_pagination.limit_offset import LimitOffsetPage, LimitOffsetParams +from pydantic import BaseModel +from starlette.requests import ClientDisconnect +from starlette.responses import FileResponse +from streaming_form_data import StreamingFormDataParser +from streaming_form_data.targets import FileTarget, NullTarget + +from config import ( + DEV_MODE, + DISABLE_DOWNLOAD_ENDPOINT_AUTH, + LIBRARY_BASE_PATH, + str_to_bool, +) +from decorators.auth import protected_route +from endpoints.responses import BulkOperationResponse +from endpoints.responses.rom import ( + DetailedRomSchema, + RomFileSchema, + RomUserSchema, + SimpleRomSchema, +) +from exceptions.endpoint_exceptions import RomNotFoundInDatabaseException +from exceptions.fs_exceptions import RomAlreadyExistsException from handler.auth.constants import Scope from handler.database import db_platform_handler, db_rom_handler from handler.database.base_handler import sync_session @@ -55,11 +61,6 @@ from logger.formatter import BLUE from logger.formatter import highlight as hl from logger.logger import log from models.rom import RomFile -from pydantic import BaseModel -from starlette.requests import ClientDisconnect -from starlette.responses import FileResponse -from streaming_form_data import StreamingFormDataParser -from streaming_form_data.targets import FileTarget, NullTarget from utils.filesystem import sanitize_filename from utils.hashing import crc32_to_hex from utils.nginx import FileRedirectResponse, ZipContentLine, ZipResponse diff --git a/backend/endpoints/saves.py b/backend/endpoints/saves.py index 638bd56fb..cc8908d0a 100644 --- a/backend/endpoints/saves.py +++ b/backend/endpoints/saves.py @@ -1,9 +1,10 @@ from datetime import datetime, timezone +from fastapi import HTTPException, Request, UploadFile, status + from decorators.auth import protected_route from endpoints.responses.assets import SaveSchema from exceptions.endpoint_exceptions import RomNotFoundInDatabaseException -from fastapi import HTTPException, Request, UploadFile, status from handler.auth.constants import Scope from handler.database import db_rom_handler, db_save_handler, db_screenshot_handler from handler.filesystem import fs_asset_handler diff --git a/backend/endpoints/screenshots.py b/backend/endpoints/screenshots.py index d276b1010..dc70e5a9d 100644 --- a/backend/endpoints/screenshots.py +++ b/backend/endpoints/screenshots.py @@ -1,7 +1,8 @@ +from fastapi import HTTPException, Request, UploadFile, status + from decorators.auth import protected_route from endpoints.responses.assets import ScreenshotSchema from exceptions.endpoint_exceptions import RomNotFoundInDatabaseException -from fastapi import HTTPException, Request, UploadFile, status from handler.auth.constants import Scope from handler.database import db_rom_handler, db_screenshot_handler from handler.filesystem import fs_asset_handler diff --git a/backend/endpoints/search.py b/backend/endpoints/search.py index 62638f159..dd93cb103 100644 --- a/backend/endpoints/search.py +++ b/backend/endpoints/search.py @@ -1,9 +1,10 @@ import asyncio +from fastapi import HTTPException, Request, status + from decorators.auth import protected_route from endpoints.responses.search import SearchCoverSchema, SearchRomSchema from exceptions.endpoint_exceptions import SGDBInvalidAPIKeyException -from fastapi import HTTPException, Request, status from handler.auth.constants import Scope from handler.database import db_rom_handler from handler.metadata import ( diff --git a/backend/endpoints/sockets/scan.py b/backend/endpoints/sockets/scan.py index 91b1e23fc..4b12c7027 100644 --- a/backend/endpoints/sockets/scan.py +++ b/backend/endpoints/sockets/scan.py @@ -5,6 +5,9 @@ from itertools import batched from typing import Any, Final import socketio # type: ignore +from rq import Worker +from rq.job import Job + from config import DEV_MODE, REDIS_URL, SCAN_TIMEOUT from endpoints.responses.platform import PlatformSchema from endpoints.responses.rom import SimpleRomSchema @@ -36,8 +39,6 @@ from logger.logger import log from models.firmware import Firmware from models.platform import Platform from models.rom import Rom, RomFile -from rq import Worker -from rq.job import Job from utils import emoji from utils.context import initialize_context diff --git a/backend/endpoints/states.py b/backend/endpoints/states.py index aa2bb7490..000258e37 100644 --- a/backend/endpoints/states.py +++ b/backend/endpoints/states.py @@ -1,9 +1,10 @@ from datetime import datetime, timezone +from fastapi import HTTPException, Request, UploadFile, status + from decorators.auth import protected_route from endpoints.responses.assets import StateSchema from exceptions.endpoint_exceptions import RomNotFoundInDatabaseException -from fastapi import HTTPException, Request, UploadFile, status from handler.auth.constants import Scope from handler.database import db_rom_handler, db_screenshot_handler, db_state_handler from handler.filesystem import fs_asset_handler diff --git a/backend/endpoints/tasks.py b/backend/endpoints/tasks.py index b942701f5..490f6ff50 100644 --- a/backend/endpoints/tasks.py +++ b/backend/endpoints/tasks.py @@ -1,5 +1,8 @@ from datetime import datetime, timezone +from fastapi import HTTPException, Request +from rq.job import Job + from config import ( ENABLE_RESCAN_ON_FILESYSTEM_CHANGE, RESCAN_ON_FILESYSTEM_CHANGE_DELAY, @@ -8,10 +11,8 @@ from config import ( from decorators.auth import protected_route from endpoints.responses import TaskExecutionResponse, TaskStatusResponse from endpoints.responses.tasks import GroupedTasksDict, TaskInfo -from fastapi import HTTPException, Request from handler.auth.constants import Scope from handler.redis_handler import low_prio_queue -from rq.job import Job from tasks.manual.cleanup_orphaned_resources import cleanup_orphaned_resources_task from tasks.scheduled.convert_images_to_webp import convert_images_to_webp_task from tasks.scheduled.scan_library import scan_library_task diff --git a/backend/endpoints/user.py b/backend/endpoints/user.py index 2558f0abd..e51f59be2 100644 --- a/backend/endpoints/user.py +++ b/backend/endpoints/user.py @@ -1,11 +1,12 @@ from typing import Annotated, Any, cast +from fastapi import Body, Form, HTTPException +from fastapi import Path as PathVar +from fastapi import Request, status + from decorators.auth import protected_route from endpoints.forms.identity import UserForm from endpoints.responses.identity import InviteLinkSchema, UserSchema -from fastapi import Body, Form, HTTPException -from fastapi import Path as PathVar -from fastapi import Request, status from handler.auth import auth_handler from handler.auth.constants import Scope from handler.database import db_user_handler diff --git a/backend/exceptions/endpoint_exceptions.py b/backend/exceptions/endpoint_exceptions.py index 5c9e6dbd9..f96493951 100644 --- a/backend/exceptions/endpoint_exceptions.py +++ b/backend/exceptions/endpoint_exceptions.py @@ -1,4 +1,5 @@ from fastapi import HTTPException, status + from logger.logger import log diff --git a/backend/handler/auth/base_handler.py b/backend/handler/auth/base_handler.py index f742e8408..146169da4 100644 --- a/backend/handler/auth/base_handler.py +++ b/backend/handler/auth/base_handler.py @@ -2,20 +2,21 @@ import uuid from datetime import datetime, timedelta, timezone from typing import Any -from config import OIDC_ENABLED, ROMM_AUTH_SECRET_KEY, ROMM_BASE_URL -from decorators.auth import oauth -from exceptions.auth_exceptions import OAuthCredentialsException, UserDisabledException from fastapi import HTTPException, status -from handler.auth.constants import ALGORITHM, DEFAULT_OAUTH_TOKEN_EXPIRY, TokenPurpose -from handler.redis_handler import redis_client from joserfc import jwt from joserfc.errors import BadSignatureError, DecodeError from joserfc.jwk import OctKey +from passlib.context import CryptContext +from starlette.requests import HTTPConnection + +from config import OIDC_ENABLED, ROMM_AUTH_SECRET_KEY, ROMM_BASE_URL +from decorators.auth import oauth +from exceptions.auth_exceptions import OAuthCredentialsException, UserDisabledException +from handler.auth.constants import ALGORITHM, DEFAULT_OAUTH_TOKEN_EXPIRY, TokenPurpose +from handler.redis_handler import redis_client from logger.formatter import CYAN from logger.formatter import highlight as hl from logger.logger import log -from passlib.context import CryptContext -from starlette.requests import HTTPConnection class AuthHandler: diff --git a/backend/handler/auth/hybrid_auth.py b/backend/handler/auth/hybrid_auth.py index b8e6e6dbc..42ee1c104 100644 --- a/backend/handler/auth/hybrid_auth.py +++ b/backend/handler/auth/hybrid_auth.py @@ -1,10 +1,11 @@ -from config import KIOSK_MODE from fastapi.security.http import HTTPBasic -from handler.auth import auth_handler, oauth_handler -from models.user import User from starlette.authentication import AuthCredentials, AuthenticationBackend from starlette.requests import HTTPConnection +from config import KIOSK_MODE +from handler.auth import auth_handler, oauth_handler +from models.user import User + from .constants import READ_SCOPES diff --git a/backend/handler/auth/middleware.py b/backend/handler/auth/middleware.py index 24bae723d..b1a3dd860 100644 --- a/backend/handler/auth/middleware.py +++ b/backend/handler/auth/middleware.py @@ -1,7 +1,6 @@ import time from collections import namedtuple -from config import SESSION_MAX_AGE_SECONDS from joserfc import jwt from joserfc.errors import BadSignatureError from joserfc.jwk import OctKey @@ -10,6 +9,8 @@ from starlette.requests import HTTPConnection, Request from starlette.types import ASGIApp, Message, Receive, Scope, Send from starlette_csrf.middleware import CSRFMiddleware +from config import SESSION_MAX_AGE_SECONDS + class CustomCSRFMiddleware(CSRFMiddleware): async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: diff --git a/backend/handler/database/base_handler.py b/backend/handler/database/base_handler.py index a78b3d84d..8e079dff8 100644 --- a/backend/handler/database/base_handler.py +++ b/backend/handler/database/base_handler.py @@ -1,11 +1,12 @@ import logging import time -from config import DEV_SQL_ECHO -from config.config_manager import ConfigManager from sqlalchemy import create_engine, event from sqlalchemy.orm import sessionmaker +from config import DEV_SQL_ECHO +from config.config_manager import ConfigManager + sync_engine = create_engine( ConfigManager.get_db_engine(), pool_pre_ping=True, echo=False ) diff --git a/backend/handler/database/collections_handler.py b/backend/handler/database/collections_handler.py index 4b9abed3c..6c9264808 100644 --- a/backend/handler/database/collections_handler.py +++ b/backend/handler/database/collections_handler.py @@ -2,6 +2,9 @@ import functools from collections.abc import Sequence from typing import Any +from sqlalchemy import delete, insert, literal, or_, select, update +from sqlalchemy.orm import Query, Session, noload, selectinload + from decorators.database import begin_session from models.collection import ( Collection, @@ -10,8 +13,6 @@ from models.collection import ( VirtualCollection, ) from models.rom import Rom -from sqlalchemy import delete, insert, literal, or_, select, update -from sqlalchemy.orm import Query, Session, noload, selectinload from .base_handler import DBBaseHandler diff --git a/backend/handler/database/firmware_handler.py b/backend/handler/database/firmware_handler.py index 43e1bd0f7..c78fbb07b 100644 --- a/backend/handler/database/firmware_handler.py +++ b/backend/handler/database/firmware_handler.py @@ -1,9 +1,10 @@ from collections.abc import Sequence +from sqlalchemy import and_, delete, select, update +from sqlalchemy.orm import Session + from decorators.database import begin_session from models.firmware import Firmware -from sqlalchemy import and_, delete, select, update -from sqlalchemy.orm import Session from .base_handler import DBBaseHandler diff --git a/backend/handler/database/platforms_handler.py b/backend/handler/database/platforms_handler.py index 5eefb0307..05bda4e32 100644 --- a/backend/handler/database/platforms_handler.py +++ b/backend/handler/database/platforms_handler.py @@ -1,11 +1,12 @@ import functools from collections.abc import Sequence +from sqlalchemy import delete, or_, select, update +from sqlalchemy.orm import Query, Session, selectinload + from decorators.database import begin_session from models.platform import Platform from models.rom import Rom -from sqlalchemy import delete, or_, select, update -from sqlalchemy.orm import Query, Session, selectinload from .base_handler import DBBaseHandler diff --git a/backend/handler/database/roms_handler.py b/backend/handler/database/roms_handler.py index e5d3ff083..0032396c4 100644 --- a/backend/handler/database/roms_handler.py +++ b/backend/handler/database/roms_handler.py @@ -2,12 +2,6 @@ import functools from collections.abc import Iterable, Sequence from typing import Any -from config import ROMM_DB_DRIVER -from decorators.database import begin_session -from handler.metadata.base_hander import UniversalPlatformSlug as UPS -from models.assets import Save, Screenshot, State -from models.platform import Platform -from models.rom import Rom, RomFile, RomMetadata, RomUser from sqlalchemy import ( Integer, Row, @@ -29,6 +23,13 @@ from sqlalchemy import ( from sqlalchemy.orm import Query, Session, joinedload, noload, selectinload from sqlalchemy.sql.elements import KeyedColumnElement +from config import ROMM_DB_DRIVER +from decorators.database import begin_session +from handler.metadata.base_hander import UniversalPlatformSlug as UPS +from models.assets import Save, Screenshot, State +from models.platform import Platform +from models.rom import Rom, RomFile, RomMetadata, RomUser + from .base_handler import DBBaseHandler EJS_SUPPORTED_PLATFORMS = [ diff --git a/backend/handler/database/saves_handler.py b/backend/handler/database/saves_handler.py index f7d673a57..773debdbf 100644 --- a/backend/handler/database/saves_handler.py +++ b/backend/handler/database/saves_handler.py @@ -1,9 +1,10 @@ from collections.abc import Sequence +from sqlalchemy import and_, delete, select, update +from sqlalchemy.orm import Session + from decorators.database import begin_session from models.assets import Save -from sqlalchemy import and_, delete, select, update -from sqlalchemy.orm import Session from .base_handler import DBBaseHandler diff --git a/backend/handler/database/screenshots_handler.py b/backend/handler/database/screenshots_handler.py index 2ccdcb131..8635b41e3 100644 --- a/backend/handler/database/screenshots_handler.py +++ b/backend/handler/database/screenshots_handler.py @@ -1,12 +1,13 @@ from collections.abc import Sequence from functools import partial -from decorators.database import begin_session -from models.assets import Screenshot from sqlalchemy import delete, select, update from sqlalchemy.orm import Session from sqlalchemy.sql import Delete, Select, Update +from decorators.database import begin_session +from models.assets import Screenshot + from .base_handler import DBBaseHandler diff --git a/backend/handler/database/states_handler.py b/backend/handler/database/states_handler.py index 495fca4a5..8673443e4 100644 --- a/backend/handler/database/states_handler.py +++ b/backend/handler/database/states_handler.py @@ -1,9 +1,10 @@ from collections.abc import Sequence +from sqlalchemy import and_, delete, select, update +from sqlalchemy.orm import Session + from decorators.database import begin_session from models.assets import State -from sqlalchemy import and_, delete, select, update -from sqlalchemy.orm import Session from .base_handler import DBBaseHandler diff --git a/backend/handler/database/stats_handler.py b/backend/handler/database/stats_handler.py index ff5a6535e..8a0f1216d 100644 --- a/backend/handler/database/stats_handler.py +++ b/backend/handler/database/stats_handler.py @@ -1,8 +1,9 @@ +from sqlalchemy import distinct, func, select +from sqlalchemy.orm import Session + from decorators.database import begin_session from models.assets import Save, Screenshot, State from models.rom import Rom, RomFile -from sqlalchemy import distinct, func, select -from sqlalchemy.orm import Session from .base_handler import DBBaseHandler diff --git a/backend/handler/database/users_handler.py b/backend/handler/database/users_handler.py index 99049a8e2..fc7d2fb70 100644 --- a/backend/handler/database/users_handler.py +++ b/backend/handler/database/users_handler.py @@ -1,11 +1,12 @@ from collections.abc import Sequence -from decorators.database import begin_session -from models.user import Role, User from sqlalchemy import and_, delete, func, not_, select, update from sqlalchemy.orm import Session from sqlalchemy.sql import Delete, Select, Update +from decorators.database import begin_session +from models.user import Role, User + from .base_handler import DBBaseHandler diff --git a/backend/handler/filesystem/base_handler.py b/backend/handler/filesystem/base_handler.py index 85916b816..a79a61d3e 100644 --- a/backend/handler/filesystem/base_handler.py +++ b/backend/handler/filesystem/base_handler.py @@ -11,9 +11,10 @@ from tempfile import SpooledTemporaryFile from typing import BinaryIO from anyio import open_file +from starlette.datastructures import UploadFile + from config.config_manager import config_manager as cm from models.base import FILE_NAME_MAX_LENGTH -from starlette.datastructures import UploadFile from utils.filesystem import iter_directories, iter_files TAG_REGEX = re.compile(r"\(([^)]+)\)|\[([^]]+)\]") diff --git a/backend/handler/filesystem/resources_handler.py b/backend/handler/filesystem/resources_handler.py index 21a650f1c..0ff753f33 100644 --- a/backend/handler/filesystem/resources_handler.py +++ b/backend/handler/filesystem/resources_handler.py @@ -3,12 +3,13 @@ from io import BytesIO from pathlib import Path import httpx -from config import ENABLE_SCHEDULED_CONVERT_IMAGES_TO_WEBP, RESOURCES_BASE_PATH from fastapi import status +from PIL import Image, ImageFile, UnidentifiedImageError + +from config import ENABLE_SCHEDULED_CONVERT_IMAGES_TO_WEBP, RESOURCES_BASE_PATH from logger.logger import log from models.collection import Collection from models.rom import Rom -from PIL import Image, ImageFile, UnidentifiedImageError from tasks.scheduled.convert_images_to_webp import ImageConverter from utils.context import ctx_httpx_client diff --git a/backend/handler/filesystem/roms_handler.py b/backend/handler/filesystem/roms_handler.py index f221e02c2..bb2993ab3 100644 --- a/backend/handler/filesystem/roms_handler.py +++ b/backend/handler/filesystem/roms_handler.py @@ -13,6 +13,7 @@ from typing import IO, Any, Final, Literal, TypedDict import magic import zipfile_inflate64 # trunk-ignore(ruff/F401): Patches zipfile to support Enhanced Deflate + from config import LIBRARY_BASE_PATH from config.config_manager import config_manager as cm from exceptions.fs_exceptions import ( diff --git a/backend/handler/metadata/base_hander.py b/backend/handler/metadata/base_hander.py index d2521cd0d..6ff9c8c44 100644 --- a/backend/handler/metadata/base_hander.py +++ b/backend/handler/metadata/base_hander.py @@ -7,9 +7,10 @@ from functools import lru_cache from pathlib import Path from typing import Final, NotRequired, TypedDict +from strsimpy.jaro_winkler import JaroWinkler + from handler.redis_handler import async_cache from logger.logger import log -from strsimpy.jaro_winkler import JaroWinkler from tasks.scheduled.update_switch_titledb import ( SWITCH_PRODUCT_ID_KEY, SWITCH_TITLEDB_INDEX_KEY, diff --git a/backend/handler/metadata/hasheous_handler.py b/backend/handler/metadata/hasheous_handler.py index 74756c343..38d89ce7a 100644 --- a/backend/handler/metadata/hasheous_handler.py +++ b/backend/handler/metadata/hasheous_handler.py @@ -4,8 +4,9 @@ from typing import Any, NotRequired, TypedDict import httpx import pydash -from config import DEV_MODE, HASHEOUS_API_ENABLED from fastapi import HTTPException, status + +from config import DEV_MODE, HASHEOUS_API_ENABLED from logger.logger import log from models.rom import RomFile from utils import get_version diff --git a/backend/handler/metadata/igdb_handler.py b/backend/handler/metadata/igdb_handler.py index 22e27e91a..0c9df22d4 100644 --- a/backend/handler/metadata/igdb_handler.py +++ b/backend/handler/metadata/igdb_handler.py @@ -3,6 +3,8 @@ from typing import Final, NotRequired, TypedDict import httpx import pydash +from fastapi import status + from adapters.services.igdb import IGDBService from adapters.services.igdb_types import ( Game, @@ -11,7 +13,6 @@ from adapters.services.igdb_types import ( mark_list_expanded, ) from config import IGDB_CLIENT_ID, IGDB_CLIENT_SECRET, IS_PYTEST_RUN -from fastapi import status from handler.redis_handler import async_cache from logger.logger import log from utils.context import ctx_httpx_client diff --git a/backend/handler/metadata/launchbox_handler.py b/backend/handler/metadata/launchbox_handler.py index bf848b3f8..4761c2ec6 100644 --- a/backend/handler/metadata/launchbox_handler.py +++ b/backend/handler/metadata/launchbox_handler.py @@ -3,6 +3,7 @@ from datetime import datetime from typing import Final, NotRequired, TypedDict import pydash + from config import LAUNCHBOX_API_ENABLED, str_to_bool from handler.redis_handler import async_cache from logger.logger import log diff --git a/backend/handler/metadata/moby_handler.py b/backend/handler/metadata/moby_handler.py index 9420cbd47..78d7217ea 100644 --- a/backend/handler/metadata/moby_handler.py +++ b/backend/handler/metadata/moby_handler.py @@ -3,11 +3,12 @@ from typing import Final, NotRequired, TypedDict from urllib.parse import quote import pydash +from unidecode import unidecode as uc + from adapters.services.mobygames import MobyGamesService from adapters.services.mobygames_types import MobyGame from config import MOBYGAMES_API_KEY from logger.logger import log -from unidecode import unidecode as uc from .base_hander import ( PS2_OPL_REGEX, diff --git a/backend/handler/metadata/playmatch_handler.py b/backend/handler/metadata/playmatch_handler.py index 708329754..4b65f2d56 100644 --- a/backend/handler/metadata/playmatch_handler.py +++ b/backend/handler/metadata/playmatch_handler.py @@ -4,8 +4,9 @@ from typing import NotRequired, TypedDict import httpx import yarl -from config import PLAYMATCH_API_ENABLED from fastapi import HTTPException, status + +from config import PLAYMATCH_API_ENABLED from handler.metadata.base_hander import MetadataHandler from logger.logger import log from models.rom import RomFile diff --git a/backend/handler/metadata/ra_handler.py b/backend/handler/metadata/ra_handler.py index 10e13bd3f..c692669d8 100644 --- a/backend/handler/metadata/ra_handler.py +++ b/backend/handler/metadata/ra_handler.py @@ -5,6 +5,7 @@ from datetime import datetime from typing import NotRequired, TypedDict import pydash + from adapters.services.retroachievements import RetroAchievementsService from adapters.services.retroachievements_types import ( RAGameExtendedDetails, diff --git a/backend/handler/metadata/ss_handler.py b/backend/handler/metadata/ss_handler.py index 604c56540..966384aa0 100644 --- a/backend/handler/metadata/ss_handler.py +++ b/backend/handler/metadata/ss_handler.py @@ -5,11 +5,12 @@ from typing import Final, NotRequired, TypedDict from urllib.parse import quote import pydash +from unidecode import unidecode as uc + from adapters.services.screenscraper import ScreenScraperService from adapters.services.screenscraper_types import SSGame, SSGameDate from config import SCREENSCRAPER_PASSWORD, SCREENSCRAPER_USER from logger.logger import log -from unidecode import unidecode as uc from .base_hander import ( PS2_OPL_REGEX, diff --git a/backend/handler/redis_handler.py b/backend/handler/redis_handler.py index 423e680dc..29881cb3e 100644 --- a/backend/handler/redis_handler.py +++ b/backend/handler/redis_handler.py @@ -2,12 +2,13 @@ import os import sys from enum import Enum -from config import IS_PYTEST_RUN, REDIS_URL -from logger.logger import log from redis import Redis from redis.asyncio import Redis as AsyncRedis from rq import Queue +from config import IS_PYTEST_RUN, REDIS_URL +from logger.logger import log + class QueuePrio(Enum): HIGH = "high" diff --git a/backend/handler/socket_handler.py b/backend/handler/socket_handler.py index d7cd99037..03bed53f3 100644 --- a/backend/handler/socket_handler.py +++ b/backend/handler/socket_handler.py @@ -1,4 +1,5 @@ import socketio # type: ignore + from config import REDIS_URL from utils import json as json_module diff --git a/backend/logger/formatter.py b/backend/logger/formatter.py index 6e3733700..7e8d81db6 100644 --- a/backend/logger/formatter.py +++ b/backend/logger/formatter.py @@ -2,6 +2,7 @@ import logging from pprint import pformat from colorama import Fore, Style, init + from config import FORCE_COLOR, NO_COLOR RED = Fore.RED diff --git a/backend/main.py b/backend/main.py index dfd6eadde..49d5254de 100644 --- a/backend/main.py +++ b/backend/main.py @@ -5,9 +5,15 @@ from collections.abc import AsyncGenerator from contextlib import asynccontextmanager import alembic.config -import endpoints.sockets.scan # noqa import sentry_sdk import uvicorn +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from fastapi_pagination import add_pagination +from starlette.middleware.authentication import AuthenticationMiddleware +from startup import main + +import endpoints.sockets.scan # noqa from config import ( DEV_HOST, DEV_PORT, @@ -34,16 +40,11 @@ from endpoints import ( tasks, user, ) -from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware -from fastapi_pagination import add_pagination from handler.auth.constants import ALGORITHM from handler.auth.hybrid_auth import HybridAuthBackend from handler.auth.middleware import CustomCSRFMiddleware, SessionMiddleware from handler.socket_handler import socket_handler from logger.log_middleware import LOGGING_CONFIG, CustomLoggingMiddleware -from starlette.middleware.authentication import AuthenticationMiddleware -from startup import main from utils import get_version from utils.context import ( ctx_aiohttp_session, diff --git a/backend/models/assets.py b/backend/models/assets.py index c017fefa3..06eb8d0a1 100644 --- a/backend/models/assets.py +++ b/backend/models/assets.py @@ -3,14 +3,15 @@ from __future__ import annotations from functools import cached_property from typing import TYPE_CHECKING +from sqlalchemy import BigInteger, ForeignKey, String +from sqlalchemy.orm import Mapped, mapped_column, relationship + from models.base import ( FILE_EXTENSION_MAX_LENGTH, FILE_NAME_MAX_LENGTH, FILE_PATH_MAX_LENGTH, BaseModel, ) -from sqlalchemy import BigInteger, ForeignKey, String -from sqlalchemy.orm import Mapped, mapped_column, relationship if TYPE_CHECKING: from models.rom import Rom diff --git a/backend/models/collection.py b/backend/models/collection.py index f8e710e79..7dd479c6f 100644 --- a/backend/models/collection.py +++ b/backend/models/collection.py @@ -4,10 +4,11 @@ import base64 import json from typing import TYPE_CHECKING, Any -from config import FRONTEND_RESOURCES_PATH -from models.base import BaseModel from sqlalchemy import ForeignKey, String, Text, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column, relationship + +from config import FRONTEND_RESOURCES_PATH +from models.base import BaseModel from utils.database import CustomJSON if TYPE_CHECKING: diff --git a/backend/models/firmware.py b/backend/models/firmware.py index 489a3456a..e5f0796bf 100644 --- a/backend/models/firmware.py +++ b/backend/models/firmware.py @@ -5,6 +5,9 @@ from functools import cached_property from pathlib import Path from typing import TYPE_CHECKING, Final +from sqlalchemy import BigInteger, ForeignKey, String +from sqlalchemy.orm import Mapped, mapped_column, relationship + from handler.redis_handler import sync_cache from models.base import ( FILE_EXTENSION_MAX_LENGTH, @@ -12,8 +15,6 @@ from models.base import ( FILE_PATH_MAX_LENGTH, BaseModel, ) -from sqlalchemy import BigInteger, ForeignKey, String -from sqlalchemy.orm import Mapped, mapped_column, relationship if TYPE_CHECKING: from models.platform import Platform diff --git a/backend/models/platform.py b/backend/models/platform.py index 7d9a19c9e..52f0b393d 100644 --- a/backend/models/platform.py +++ b/backend/models/platform.py @@ -3,11 +3,12 @@ from __future__ import annotations from functools import cached_property from typing import TYPE_CHECKING -from models.base import BaseModel -from models.rom import Rom from sqlalchemy import String, func, select from sqlalchemy.orm import Mapped, column_property, mapped_column, relationship +from models.base import BaseModel +from models.rom import Rom + if TYPE_CHECKING: from models.firmware import Firmware diff --git a/backend/models/rom.py b/backend/models/rom.py index 09bed6413..4a0d53553 100644 --- a/backend/models/rom.py +++ b/backend/models/rom.py @@ -5,13 +5,6 @@ from datetime import datetime from functools import cached_property from typing import TYPE_CHECKING, Any -from config import FRONTEND_RESOURCES_PATH -from models.base import ( - FILE_EXTENSION_MAX_LENGTH, - FILE_NAME_MAX_LENGTH, - FILE_PATH_MAX_LENGTH, - BaseModel, -) from sqlalchemy import ( TIMESTAMP, BigInteger, @@ -24,6 +17,14 @@ from sqlalchemy import ( UniqueConstraint, ) from sqlalchemy.orm import Mapped, mapped_column, relationship + +from config import FRONTEND_RESOURCES_PATH +from models.base import ( + FILE_EXTENSION_MAX_LENGTH, + FILE_NAME_MAX_LENGTH, + FILE_PATH_MAX_LENGTH, + BaseModel, +) from utils.database import CustomJSON if TYPE_CHECKING: diff --git a/backend/models/user.py b/backend/models/user.py index acbbc1af9..c319585f5 100644 --- a/backend/models/user.py +++ b/backend/models/user.py @@ -4,6 +4,10 @@ import enum from datetime import datetime, timezone from typing import TYPE_CHECKING, Any +from sqlalchemy import TIMESTAMP, Enum, String +from sqlalchemy.orm import Mapped, mapped_column, relationship +from starlette.authentication import SimpleUser + from config import KIOSK_MODE from handler.auth.constants import ( EDIT_SCOPES, @@ -13,9 +17,6 @@ from handler.auth.constants import ( Scope, ) from models.base import BaseModel -from sqlalchemy import TIMESTAMP, Enum, String -from sqlalchemy.orm import Mapped, mapped_column, relationship -from starlette.authentication import SimpleUser from utils.database import CustomJSON if TYPE_CHECKING: diff --git a/backend/startup.py b/backend/startup.py index e55a69ad1..163acebe9 100644 --- a/backend/startup.py +++ b/backend/startup.py @@ -3,6 +3,8 @@ import asyncio import sentry_sdk +from opentelemetry import trace + from config import ( ENABLE_SCHEDULED_CONVERT_IMAGES_TO_WEBP, ENABLE_SCHEDULED_RESCAN, @@ -22,7 +24,6 @@ from handler.metadata.base_hander import ( from handler.redis_handler import async_cache from logger.logger import log from models.firmware import FIRMWARE_FIXTURES_DIR, KNOWN_BIOS_KEY -from opentelemetry import trace from tasks.scheduled.convert_images_to_webp import convert_images_to_webp_task from tasks.scheduled.scan_library import scan_library_task from tasks.scheduled.sync_retroachievements_progress import ( diff --git a/backend/tasks/scheduled/convert_images_to_webp.py b/backend/tasks/scheduled/convert_images_to_webp.py index 2d1ad9a0d..b983349bd 100644 --- a/backend/tasks/scheduled/convert_images_to_webp.py +++ b/backend/tasks/scheduled/convert_images_to_webp.py @@ -5,13 +5,14 @@ from dataclasses import dataclass from pathlib import Path from typing import Any, Dict, List +from PIL import Image, UnidentifiedImageError + from config import ( ENABLE_SCHEDULED_CONVERT_IMAGES_TO_WEBP, RESOURCES_BASE_PATH, SCHEDULED_CONVERT_IMAGES_TO_WEBP_CRON, ) from logger.logger import log -from PIL import Image, UnidentifiedImageError from tasks.tasks import PeriodicTask diff --git a/backend/tasks/scheduled/update_launchbox_metadata.py b/backend/tasks/scheduled/update_launchbox_metadata.py index 42c2f2aa9..2fdac9eb2 100644 --- a/backend/tasks/scheduled/update_launchbox_metadata.py +++ b/backend/tasks/scheduled/update_launchbox_metadata.py @@ -3,11 +3,12 @@ import zipfile from io import BytesIO from typing import Any +from defusedxml import ElementTree as ET + from config import ( ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA, SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON, ) -from defusedxml import ElementTree as ET from handler.metadata import meta_launchbox_handler from handler.metadata.launchbox_handler import ( LAUNCHBOX_FILES_KEY, diff --git a/backend/tasks/tasks.py b/backend/tasks/tasks.py index 847e18b3a..e806dd840 100644 --- a/backend/tasks/tasks.py +++ b/backend/tasks/tasks.py @@ -2,12 +2,13 @@ from abc import ABC, abstractmethod from typing import Any import httpx +from rq.job import Job +from rq_scheduler import Scheduler + from config import TASK_TIMEOUT from exceptions.task_exceptions import SchedulerException from handler.redis_handler import low_prio_queue from logger.logger import log -from rq.job import Job -from rq_scheduler import Scheduler from utils.context import ctx_httpx_client tasks_scheduler = Scheduler(queue=low_prio_queue, connection=low_prio_queue.connection) diff --git a/backend/tests/adapters/services/test_mobygames.py b/backend/tests/adapters/services/test_mobygames.py index fee9c3750..7530e976a 100644 --- a/backend/tests/adapters/services/test_mobygames.py +++ b/backend/tests/adapters/services/test_mobygames.py @@ -6,11 +6,12 @@ from unittest.mock import AsyncMock, MagicMock, patch import aiohttp import pytest import yarl +from fastapi import HTTPException, status + from adapters.services.mobygames import ( MobyGamesService, auth_middleware, ) -from fastapi import HTTPException, status INVALID_GAME_ID = 999999 diff --git a/backend/tests/adapters/services/test_rahasher.py b/backend/tests/adapters/services/test_rahasher.py index 432267754..5ae07e1c2 100644 --- a/backend/tests/adapters/services/test_rahasher.py +++ b/backend/tests/adapters/services/test_rahasher.py @@ -2,6 +2,7 @@ import asyncio from unittest.mock import AsyncMock, patch import pytest + from adapters.services.rahasher import ( RAHASHER_VALID_HASH_REGEX, RAHasherError, diff --git a/backend/tests/adapters/services/test_retroachivements.py b/backend/tests/adapters/services/test_retroachivements.py index 302bd146f..4fdcecbe0 100644 --- a/backend/tests/adapters/services/test_retroachivements.py +++ b/backend/tests/adapters/services/test_retroachivements.py @@ -3,11 +3,12 @@ from unittest.mock import AsyncMock, MagicMock, patch import aiohttp import pytest import yarl +from fastapi import HTTPException, status + from adapters.services.retroachievements import ( RetroAchievementsService, auth_middleware, ) -from fastapi import HTTPException, status INVALID_GAME_ID = 999999 diff --git a/backend/tests/adapters/services/test_screenscraper.py b/backend/tests/adapters/services/test_screenscraper.py index 24ad6a7fc..37ab7658f 100644 --- a/backend/tests/adapters/services/test_screenscraper.py +++ b/backend/tests/adapters/services/test_screenscraper.py @@ -7,6 +7,8 @@ from unittest.mock import AsyncMock, MagicMock, patch import aiohttp import pytest import yarl +from fastapi import HTTPException, status + from adapters.services.screenscraper import ( LOGIN_ERROR_CHECK, SS_DEV_ID, @@ -14,7 +16,6 @@ from adapters.services.screenscraper import ( ScreenScraperService, auth_middleware, ) -from fastapi import HTTPException, status INVALID_GAME_ID = 999999 INVALID_SYSTEM_ID = 999999 diff --git a/backend/tests/adapters/services/test_steamgriddb.py b/backend/tests/adapters/services/test_steamgriddb.py index 3560c126a..40b8794bb 100644 --- a/backend/tests/adapters/services/test_steamgriddb.py +++ b/backend/tests/adapters/services/test_steamgriddb.py @@ -5,6 +5,8 @@ from unittest.mock import AsyncMock, MagicMock, patch import aiohttp import pytest +from fastapi import HTTPException, status + from adapters.services.steamgriddb import ( SteamGridDBService, auth_middleware, @@ -16,7 +18,6 @@ from adapters.services.steamgriddb_types import ( SGDBTag, SGDBType, ) -from fastapi import HTTPException, status INVALID_GAME_ID = 999999 diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 63bc57276..b2762387a 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -1,5 +1,8 @@ import alembic.config import pytest +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + from config.config_manager import ConfigManager from handler.auth import auth_handler from handler.database import ( @@ -14,8 +17,6 @@ from models.assets import Save, Screenshot, State from models.platform import Platform from models.rom import Rom from models.user import Role, User -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker engine = create_engine(ConfigManager.get_db_engine(), pool_pre_ping=True) session = sessionmaker(bind=engine, expire_on_commit=False) diff --git a/backend/tests/endpoints/conftest.py b/backend/tests/endpoints/conftest.py index 8dcaf1b04..87a23d6a0 100644 --- a/backend/tests/endpoints/conftest.py +++ b/backend/tests/endpoints/conftest.py @@ -1,6 +1,7 @@ from datetime import timedelta import pytest + from endpoints.auth import ACCESS_TOKEN_EXPIRE_MINUTES, REFRESH_TOKEN_EXPIRE_DAYS from handler.auth import oauth_handler diff --git a/backend/tests/endpoints/sockets/test_scan.py b/backend/tests/endpoints/sockets/test_scan.py index c2b04d99c..778accfdc 100644 --- a/backend/tests/endpoints/sockets/test_scan.py +++ b/backend/tests/endpoints/sockets/test_scan.py @@ -1,6 +1,7 @@ from unittest.mock import Mock import pytest + from endpoints.sockets.scan import ScanStats, _should_scan_rom from handler.scan_handler import ScanType from models.rom import Rom diff --git a/backend/tests/endpoints/test_heartbeat.py b/backend/tests/endpoints/test_heartbeat.py index 7fb62f024..93d1f0386 100644 --- a/backend/tests/endpoints/test_heartbeat.py +++ b/backend/tests/endpoints/test_heartbeat.py @@ -2,6 +2,7 @@ import pytest from fastapi import status from fastapi.testclient import TestClient from main import app + from utils import get_version diff --git a/backend/tests/endpoints/test_identity.py b/backend/tests/endpoints/test_identity.py index e15331868..4f6dd7f20 100644 --- a/backend/tests/endpoints/test_identity.py +++ b/backend/tests/endpoints/test_identity.py @@ -4,13 +4,14 @@ from http import HTTPStatus from unittest import mock import pytest -from endpoints.auth import ACCESS_TOKEN_EXPIRE_MINUTES from fastapi import status from fastapi.testclient import TestClient +from main import app + +from endpoints.auth import ACCESS_TOKEN_EXPIRE_MINUTES from handler.auth import oauth_handler from handler.database.users_handler import DBUsersHandler from handler.redis_handler import sync_cache -from main import app from models.user import Role diff --git a/backend/tests/endpoints/test_oauth.py b/backend/tests/endpoints/test_oauth.py index 7ea5a0011..678aba163 100644 --- a/backend/tests/endpoints/test_oauth.py +++ b/backend/tests/endpoints/test_oauth.py @@ -1,11 +1,12 @@ import pytest -from endpoints.auth import ACCESS_TOKEN_EXPIRE_MINUTES from fastapi import status from fastapi.exceptions import HTTPException from fastapi.testclient import TestClient -from handler.auth.constants import EDIT_SCOPES from main import app +from endpoints.auth import ACCESS_TOKEN_EXPIRE_MINUTES +from handler.auth.constants import EDIT_SCOPES + @pytest.fixture def client(): diff --git a/backend/tests/endpoints/test_rom.py b/backend/tests/endpoints/test_rom.py index 179add401..b224ff36e 100644 --- a/backend/tests/endpoints/test_rom.py +++ b/backend/tests/endpoints/test_rom.py @@ -3,9 +3,10 @@ from unittest.mock import patch import pytest from fastapi import status from fastapi.testclient import TestClient +from main import app + from handler.filesystem.roms_handler import FSRomsHandler from handler.metadata.igdb_handler import IGDBHandler, IGDBRom -from main import app @pytest.fixture diff --git a/backend/tests/endpoints/test_tasks.py b/backend/tests/endpoints/test_tasks.py index a6a2699ca..d952601c7 100644 --- a/backend/tests/endpoints/test_tasks.py +++ b/backend/tests/endpoints/test_tasks.py @@ -4,6 +4,7 @@ import pytest from fastapi import status from fastapi.testclient import TestClient from main import app + from tasks.tasks import Task diff --git a/backend/tests/handler/auth/test_auth.py b/backend/tests/handler/auth/test_auth.py index eaf715d07..9e22f8e49 100644 --- a/backend/tests/handler/auth/test_auth.py +++ b/backend/tests/handler/auth/test_auth.py @@ -3,12 +3,13 @@ from base64 import b64encode import pytest from fastapi import status from fastapi.exceptions import HTTPException +from starlette.requests import HTTPConnection + from handler.auth import auth_handler, oauth_handler from handler.auth.constants import EDIT_SCOPES from handler.auth.hybrid_auth import HybridAuthBackend from handler.database import db_user_handler from models.user import User -from starlette.requests import HTTPConnection def test_verify_password(): diff --git a/backend/tests/handler/auth/test_oauth.py b/backend/tests/handler/auth/test_oauth.py index 9b3749062..c87704c35 100644 --- a/backend/tests/handler/auth/test_oauth.py +++ b/backend/tests/handler/auth/test_oauth.py @@ -1,7 +1,8 @@ import pytest -from decorators.auth import protected_route from fastapi import Request, status from fastapi.exceptions import HTTPException + +from decorators.auth import protected_route from handler.auth import oauth_handler from handler.database import db_user_handler from utils.router import APIRouter diff --git a/backend/tests/handler/auth/test_oidc.py b/backend/tests/handler/auth/test_oidc.py index a31d21003..298a14ae6 100644 --- a/backend/tests/handler/auth/test_oidc.py +++ b/backend/tests/handler/auth/test_oidc.py @@ -3,9 +3,10 @@ from unittest.mock import MagicMock import pytest from authlib.integrations.starlette_client.apps import StarletteOAuth2App from fastapi import HTTPException -from handler.auth.base_handler import OpenIDHandler from joserfc.jwt import Token +from handler.auth.base_handler import OpenIDHandler + # Mock constants OIDC_SERVER_APPLICATION_URL = "http://mock-oidc-server" OIDC_ENABLED = True diff --git a/backend/tests/handler/filesystem/test_assets_handler.py b/backend/tests/handler/filesystem/test_assets_handler.py index d6bdebf54..2a8504693 100644 --- a/backend/tests/handler/filesystem/test_assets_handler.py +++ b/backend/tests/handler/filesystem/test_assets_handler.py @@ -3,6 +3,7 @@ from pathlib import Path from unittest.mock import Mock import pytest + from handler.filesystem.assets_handler import ASSETS_BASE_PATH, FSAssetsHandler from models.user import User diff --git a/backend/tests/handler/filesystem/test_base_handler.py b/backend/tests/handler/filesystem/test_base_handler.py index 03a9f984f..d931991de 100644 --- a/backend/tests/handler/filesystem/test_base_handler.py +++ b/backend/tests/handler/filesystem/test_base_handler.py @@ -7,6 +7,7 @@ from unittest.mock import Mock, patch import pytest from fastapi import UploadFile + from handler.filesystem.base_handler import FSHandler from models.base import FILE_NAME_MAX_LENGTH diff --git a/backend/tests/handler/filesystem/test_firmware_handler.py b/backend/tests/handler/filesystem/test_firmware_handler.py index 9ee1cef26..ab6981840 100644 --- a/backend/tests/handler/filesystem/test_firmware_handler.py +++ b/backend/tests/handler/filesystem/test_firmware_handler.py @@ -5,6 +5,7 @@ from unittest.mock import patch import pytest from anyio import open_file + from config.config_manager import LIBRARY_BASE_PATH, Config from exceptions.fs_exceptions import FirmwareNotFoundException from handler.filesystem.firmware_handler import FSFirmwareHandler diff --git a/backend/tests/handler/filesystem/test_platforms_handler.py b/backend/tests/handler/filesystem/test_platforms_handler.py index 624770b2d..0350a5d8b 100644 --- a/backend/tests/handler/filesystem/test_platforms_handler.py +++ b/backend/tests/handler/filesystem/test_platforms_handler.py @@ -2,6 +2,7 @@ from pathlib import Path from unittest.mock import patch import pytest + from config.config_manager import LIBRARY_BASE_PATH, Config from handler.filesystem.platforms_handler import FSPlatformsHandler diff --git a/backend/tests/handler/filesystem/test_resources_handler.py b/backend/tests/handler/filesystem/test_resources_handler.py index 9030b52fb..4432105b6 100644 --- a/backend/tests/handler/filesystem/test_resources_handler.py +++ b/backend/tests/handler/filesystem/test_resources_handler.py @@ -3,6 +3,7 @@ from pathlib import Path from unittest.mock import Mock, patch import pytest + from config import RESOURCES_BASE_PATH from handler.filesystem.base_handler import CoverSize from handler.filesystem.resources_handler import FSResourcesHandler diff --git a/backend/tests/handler/filesystem/test_roms_handler.py b/backend/tests/handler/filesystem/test_roms_handler.py index 3f695521b..11b89f094 100644 --- a/backend/tests/handler/filesystem/test_roms_handler.py +++ b/backend/tests/handler/filesystem/test_roms_handler.py @@ -3,6 +3,7 @@ from pathlib import Path from unittest.mock import Mock import pytest + from config.config_manager import LIBRARY_BASE_PATH, Config from handler.filesystem.roms_handler import FileHash, FSRomsHandler from models.platform import Platform diff --git a/backend/tests/handler/metadata/test_base_handler.py b/backend/tests/handler/metadata/test_base_handler.py index 992746118..b56c24b42 100644 --- a/backend/tests/handler/metadata/test_base_handler.py +++ b/backend/tests/handler/metadata/test_base_handler.py @@ -3,6 +3,7 @@ import re from unittest.mock import AsyncMock, patch import pytest + from handler.metadata.base_hander import ( LEADING_ARTICLE_PATTERN, MAME_XML_KEY, diff --git a/backend/tests/handler/test_db_handler.py b/backend/tests/handler/test_db_handler.py index 0520e00f5..2715ada79 100644 --- a/backend/tests/handler/test_db_handler.py +++ b/backend/tests/handler/test_db_handler.py @@ -1,3 +1,5 @@ +from sqlalchemy.exc import IntegrityError + from handler.auth import auth_handler from handler.database import ( db_platform_handler, @@ -11,7 +13,6 @@ from models.assets import Save, Screenshot, State from models.platform import Platform from models.rom import Rom from models.user import Role, User -from sqlalchemy.exc import IntegrityError def test_platforms(): diff --git a/backend/tests/handler/test_fastapi.py b/backend/tests/handler/test_fastapi.py index b64d5c69e..e6e91594a 100644 --- a/backend/tests/handler/test_fastapi.py +++ b/backend/tests/handler/test_fastapi.py @@ -1,4 +1,5 @@ import pytest + from handler.scan_handler import MetadataSource, ScanType, scan_platform, scan_rom from models.platform import Platform from models.rom import Rom, RomFile diff --git a/backend/tests/tasks/test_scan_library.py b/backend/tests/tasks/test_scan_library.py index 2ae050c1a..182b2c0d7 100644 --- a/backend/tests/tasks/test_scan_library.py +++ b/backend/tests/tasks/test_scan_library.py @@ -1,6 +1,7 @@ from unittest.mock import AsyncMock, MagicMock import pytest + from handler.metadata.hasheous_handler import HasheousHandler from handler.metadata.igdb_handler import IGDBHandler from handler.metadata.launchbox_handler import LaunchboxHandler diff --git a/backend/tests/tasks/test_sync_retroachievements_progress.py b/backend/tests/tasks/test_sync_retroachievements_progress.py index 126d0b465..9e5770c33 100644 --- a/backend/tests/tasks/test_sync_retroachievements_progress.py +++ b/backend/tests/tasks/test_sync_retroachievements_progress.py @@ -1,6 +1,7 @@ from unittest.mock import MagicMock import pytest + from handler.database.users_handler import DBUsersHandler from handler.metadata.ra_handler import RAHandler from tasks.scheduled.sync_retroachievements_progress import ( diff --git a/backend/tests/tasks/test_tasks.py b/backend/tests/tasks/test_tasks.py index 9cf899f31..72f9c3c32 100644 --- a/backend/tests/tasks/test_tasks.py +++ b/backend/tests/tasks/test_tasks.py @@ -2,8 +2,9 @@ from unittest.mock import AsyncMock, MagicMock, patch import httpx import pytest -from exceptions.task_exceptions import SchedulerException from rq.job import Job + +from exceptions.task_exceptions import SchedulerException from tasks.tasks import PeriodicTask, RemoteFilePullTask, tasks_scheduler diff --git a/backend/tests/tasks/test_update_launchbox_metadata.py b/backend/tests/tasks/test_update_launchbox_metadata.py index 16281594b..36010dd77 100644 --- a/backend/tests/tasks/test_update_launchbox_metadata.py +++ b/backend/tests/tasks/test_update_launchbox_metadata.py @@ -3,6 +3,7 @@ from unittest.mock import AsyncMock, patch import anyio import pytest + from handler.metadata.launchbox_handler import ( LAUNCHBOX_FILES_KEY, LAUNCHBOX_MAME_KEY, diff --git a/backend/tests/tasks/test_update_switch_titledb.py b/backend/tests/tasks/test_update_switch_titledb.py index 0df115a56..868571c3d 100644 --- a/backend/tests/tasks/test_update_switch_titledb.py +++ b/backend/tests/tasks/test_update_switch_titledb.py @@ -2,6 +2,7 @@ import json from unittest.mock import AsyncMock, patch import pytest + from tasks.scheduled.update_switch_titledb import ( SWITCH_PRODUCT_ID_KEY, SWITCH_TITLEDB_INDEX_KEY, diff --git a/backend/tests/utils/test_cache.py b/backend/tests/utils/test_cache.py index e5695c9f0..c430cefa0 100644 --- a/backend/tests/utils/test_cache.py +++ b/backend/tests/utils/test_cache.py @@ -1,8 +1,9 @@ from unittest.mock import AsyncMock +from redis.asyncio import Redis as AsyncRedis + from handler.metadata.base_hander import MAME_XML_KEY, METADATA_FIXTURES_DIR from handler.redis_handler import async_cache -from redis.asyncio import Redis as AsyncRedis from utils.cache import conditionally_set_cache diff --git a/backend/tests/utils/test_router.py b/backend/tests/utils/test_router.py index 1185d4631..2c8723e45 100644 --- a/backend/tests/utils/test_router.py +++ b/backend/tests/utils/test_router.py @@ -2,6 +2,7 @@ import itertools import pytest from fastapi import Request + from utils.router import APIRouter diff --git a/backend/utils/cache.py b/backend/utils/cache.py index 593f6cbcc..f2b825b24 100644 --- a/backend/utils/cache.py +++ b/backend/utils/cache.py @@ -4,9 +4,10 @@ from itertools import batched from pathlib import Path from anyio import open_file -from logger.logger import log from redis.asyncio import Redis as AsyncRedis +from logger.logger import log + async def conditionally_set_cache(cache: AsyncRedis, key: str, file_path: Path) -> None: """Set the content of a JSON file to the cache, if it does not already exist or is outdated. diff --git a/backend/watcher.py b/backend/watcher.py index ddd1f8d70..acdd96159 100644 --- a/backend/watcher.py +++ b/backend/watcher.py @@ -6,6 +6,9 @@ from datetime import timedelta from typing import cast import sentry_sdk +from opentelemetry import trace +from rq.job import Job + from config import ( ENABLE_RESCAN_ON_FILESYSTEM_CHANGE, LIBRARY_BASE_PATH, @@ -29,8 +32,6 @@ from handler.scan_handler import MetadataSource, ScanType from logger.formatter import CYAN from logger.formatter import highlight as hl from logger.logger import log -from opentelemetry import trace -from rq.job import Job from tasks.tasks import tasks_scheduler from utils import get_version