From 6877637507bc4f97e7c9a8e3505befe1837654d9 Mon Sep 17 00:00:00 2001 From: Lukas Date: Tue, 10 Mar 2026 15:48:00 +0100 Subject: [PATCH] Fix startup crash caused by top-level geoip2 import geoip2 is an optional dependency used only when a MaxMind mmdb path is configured. Importing it unconditionally at module level caused the server to crash on startup with ModuleNotFoundError when the package was absent from the environment. Move the imports under TYPE_CHECKING (for static analysis) and add lazy local imports inside init_geoip() and _geoip_lookup() where geoip2 is actually needed at runtime. The server now starts normally without a MaxMind database, and geoip2 is loaded on demand if the feature is used. --- backend/app/services/geo_service.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/backend/app/services/geo_service.py b/backend/app/services/geo_service.py index 93b869c..50ba24b 100644 --- a/backend/app/services/geo_service.py +++ b/backend/app/services/geo_service.py @@ -42,13 +42,13 @@ import time from dataclasses import dataclass from typing import TYPE_CHECKING -import geoip2.database -import geoip2.errors import structlog if TYPE_CHECKING: import aiohttp import aiosqlite + import geoip2.database + import geoip2.errors log: structlog.stdlib.BoundLogger = structlog.get_logger() @@ -154,6 +154,8 @@ def init_geoip(mmdb_path: str | None) -> None: return from pathlib import Path # noqa: PLC0415 + import geoip2.database # noqa: PLC0415 + if not Path(mmdb_path).is_file(): log.warning("geoip_mmdb_not_found", path=mmdb_path) return @@ -176,6 +178,8 @@ def _geoip_lookup(ip: str) -> GeoInfo | None: """ if _geoip_reader is None: return None + import geoip2.errors # noqa: PLC0415 + try: response = _geoip_reader.country(ip) code: str | None = response.country.iso_code or None