átlagos kiegészítséek jó sok
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
from typing import Any, Optional, Dict
|
||||
import logging
|
||||
import os
|
||||
import json
|
||||
from decimal import Decimal
|
||||
from datetime import datetime, timezone
|
||||
|
||||
@@ -10,6 +11,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
# Modellek importálása a központi helyről
|
||||
from app.models import ExchangeRate, AssetCost, AssetTelemetry
|
||||
from app.models.system.system import SystemParameter, ParameterScope
|
||||
from app.db.session import AsyncSessionLocal
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -59,25 +61,211 @@ class CostService:
|
||||
raise e
|
||||
|
||||
class ConfigService:
|
||||
"""
|
||||
MB 2.0 Alapvető konfigurációs szerviz.
|
||||
Kezeli az AI szolgáltatások (Ollama) dinamikus beállításait és promptjait.
|
||||
"""
|
||||
async def get_setting(self, db: AsyncSession, key: str, default: Any = None) -> Any:
|
||||
Egyszerű konfigurációs szolgáltatás a SystemParameter tábla lekérdezéséhez.
|
||||
Támogatja a különböző típusú értékek lekérését alapértelmezett értékkel.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
async def get(db: AsyncSession, key: str, default: Any = None, scope_level: ParameterScope = ParameterScope.GLOBAL, scope_id: Optional[str] = None) -> Any:
|
||||
"""
|
||||
Lekéri a kért beállítást.
|
||||
1. Megnézi a környezeti változókat (NAGYBETŰVEL).
|
||||
2. Ha nincs ilyen ENV, visszaadja a kódba égetett 'default' értéket.
|
||||
"""
|
||||
env_val = os.getenv(key.upper())
|
||||
if env_val is not None:
|
||||
# Automatikus típuskonverzió a default paraméter típusa alapján
|
||||
if isinstance(default, int): return int(env_val)
|
||||
if isinstance(default, float): return float(env_val)
|
||||
if isinstance(default, bool): return str(env_val).lower() in ('true', '1', 'yes')
|
||||
return env_val
|
||||
Általános lekérdezés a SystemParameter táblából.
|
||||
|
||||
Args:
|
||||
db: AsyncSession
|
||||
key: A konfigurációs kulcs
|
||||
default: Alapértelmezett érték, ha a kulcs nem található
|
||||
scope_level: A paraméter scope-ja (global, country, region, user)
|
||||
scope_id: A scope azonosítója (pl. országkód, user_id)
|
||||
|
||||
Returns:
|
||||
A talált érték (a megfelelő típusban) vagy a default.
|
||||
"""
|
||||
from sqlalchemy import select, and_, cast, String
|
||||
|
||||
try:
|
||||
# Convert scope_level to lowercase string for comparison
|
||||
# PostgreSQL enum expects lowercase values, but Python Enum may be uppercase
|
||||
scope_str = scope_level.value.lower() if hasattr(scope_level, 'value') else str(scope_level).lower()
|
||||
|
||||
# Build query with cast to avoid strict enum type mismatch
|
||||
query = select(SystemParameter).where(
|
||||
and_(
|
||||
SystemParameter.key == key,
|
||||
cast(SystemParameter.scope_level, String) == scope_str,
|
||||
SystemParameter.is_active == True
|
||||
)
|
||||
)
|
||||
if scope_id is None:
|
||||
query = query.where(SystemParameter.scope_id.is_(None))
|
||||
else:
|
||||
query = query.where(SystemParameter.scope_id == scope_id)
|
||||
|
||||
result = await db.execute(query)
|
||||
param = result.scalar_one_or_none()
|
||||
|
||||
if param is None:
|
||||
# Opcionálisan beilleszthetjük a default értéket a táblába
|
||||
# await ConfigService._insert_default(db, key, default, scope_level, scope_id)
|
||||
return default
|
||||
|
||||
# A value oszlop JSONB, lehet dict, list, string, number, bool
|
||||
db_value = param.value
|
||||
|
||||
# Típuskonverzió a default típusa alapján
|
||||
if default is None:
|
||||
return db_value
|
||||
|
||||
if isinstance(default, int):
|
||||
if isinstance(db_value, (int, float, str)):
|
||||
try:
|
||||
return int(db_value)
|
||||
except (ValueError, TypeError):
|
||||
return default
|
||||
return default
|
||||
elif isinstance(default, float):
|
||||
if isinstance(db_value, (int, float, str)):
|
||||
try:
|
||||
return float(db_value)
|
||||
except (ValueError, TypeError):
|
||||
return default
|
||||
return default
|
||||
elif isinstance(default, bool):
|
||||
if isinstance(db_value, bool):
|
||||
return db_value
|
||||
elif isinstance(db_value, str):
|
||||
return db_value.lower() in ('true', '1', 'yes', 'on')
|
||||
elif isinstance(db_value, int):
|
||||
return db_value != 0
|
||||
return default
|
||||
elif isinstance(default, str):
|
||||
if isinstance(db_value, str):
|
||||
return db_value
|
||||
elif isinstance(db_value, (dict, list)):
|
||||
return json.dumps(db_value)
|
||||
else:
|
||||
return str(db_value)
|
||||
elif isinstance(default, dict) and isinstance(db_value, dict):
|
||||
return db_value
|
||||
elif isinstance(default, list) and isinstance(db_value, list):
|
||||
return db_value
|
||||
else:
|
||||
# Egyébként visszaadjuk a db_value-t
|
||||
return db_value
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"ConfigService.get error for key '{key}': {e}")
|
||||
return default
|
||||
|
||||
async def get_setting(self, db: AsyncSession, key: str, default: Any = None, region_code: Optional[str] = None, org_id: Optional[int] = None, **kwargs) -> Any:
|
||||
"""
|
||||
Általános beállítás lekérése a régi kód kompatibilitásához.
|
||||
|
||||
Args:
|
||||
db: AsyncSession
|
||||
key: A konfigurációs kulcs
|
||||
default: Alapértelmezett érték
|
||||
region_code: Országkód (pl. "HU") - COUNTRY scope
|
||||
org_id: Szervezet azonosító - ORGANIZATION scope
|
||||
**kwargs: További paraméterek (pl. user_id)
|
||||
|
||||
Returns:
|
||||
A talált érték vagy default.
|
||||
"""
|
||||
from app.models.system.system import ParameterScope
|
||||
|
||||
# Scope meghatározása
|
||||
if org_id is not None:
|
||||
scope_level = ParameterScope.ORGANIZATION
|
||||
scope_id = str(org_id)
|
||||
elif region_code is not None:
|
||||
scope_level = ParameterScope.COUNTRY
|
||||
scope_id = region_code
|
||||
else:
|
||||
scope_level = ParameterScope.GLOBAL
|
||||
scope_id = None
|
||||
|
||||
# További scope-ok (pl. user) a kwargs-ból
|
||||
if 'user_id' in kwargs:
|
||||
scope_level = ParameterScope.USER
|
||||
scope_id = str(kwargs['user_id'])
|
||||
|
||||
return await ConfigService.get(db, key, default, scope_level, scope_id)
|
||||
|
||||
@staticmethod
|
||||
async def get_int(db: AsyncSession, key: str, default: int, scope_level: ParameterScope = ParameterScope.GLOBAL, scope_id: Optional[str] = None) -> int:
|
||||
"""Egész szám lekérése."""
|
||||
value = await ConfigService.get(db, key, default, scope_level, scope_id)
|
||||
if isinstance(value, int):
|
||||
return value
|
||||
try:
|
||||
return int(value)
|
||||
except (ValueError, TypeError):
|
||||
return default
|
||||
|
||||
@staticmethod
|
||||
async def get_str(db: AsyncSession, key: str, default: str, scope_level: ParameterScope = ParameterScope.GLOBAL, scope_id: Optional[str] = None) -> str:
|
||||
"""Szöveg lekérése."""
|
||||
value = await ConfigService.get(db, key, default, scope_level, scope_id)
|
||||
if isinstance(value, str):
|
||||
return value
|
||||
return str(value)
|
||||
|
||||
@staticmethod
|
||||
async def get_bool(db: AsyncSession, key: str, default: bool, scope_level: ParameterScope = ParameterScope.GLOBAL, scope_id: Optional[str] = None) -> bool:
|
||||
"""Logikai érték lekérése."""
|
||||
value = await ConfigService.get(db, key, default, scope_level, scope_id)
|
||||
if isinstance(value, bool):
|
||||
return value
|
||||
if isinstance(value, str):
|
||||
return value.lower() in ('true', '1', 'yes', 'on')
|
||||
if isinstance(value, int):
|
||||
return value != 0
|
||||
return default
|
||||
|
||||
@staticmethod
|
||||
async def get_float(db: AsyncSession, key: str, default: float, scope_level: ParameterScope = ParameterScope.GLOBAL, scope_id: Optional[str] = None) -> float:
|
||||
"""Lebegőpontos szám lekérése."""
|
||||
value = await ConfigService.get(db, key, default, scope_level, scope_id)
|
||||
if isinstance(value, float):
|
||||
return value
|
||||
try:
|
||||
return float(value)
|
||||
except (ValueError, TypeError):
|
||||
return default
|
||||
|
||||
@staticmethod
|
||||
async def get_json(db: AsyncSession, key: str, default: dict, scope_level: ParameterScope = ParameterScope.GLOBAL, scope_id: Optional[str] = None) -> dict:
|
||||
"""JSON objektum lekérése."""
|
||||
value = await ConfigService.get(db, key, default, scope_level, scope_id)
|
||||
if isinstance(value, dict):
|
||||
return value
|
||||
if isinstance(value, str):
|
||||
try:
|
||||
return json.loads(value)
|
||||
except json.JSONDecodeError:
|
||||
return default
|
||||
return default
|
||||
|
||||
@staticmethod
|
||||
async def _insert_default(db: AsyncSession, key: str, default: Any, scope_level: ParameterScope, scope_id: Optional[str] = None) -> None:
|
||||
"""Opcionális: beszúrja a default értéket a táblába, hogy látható legyen az Admin UI-ban."""
|
||||
try:
|
||||
from app.models.system.system import SystemParameter
|
||||
param = SystemParameter(
|
||||
key=key,
|
||||
category="auto_inserted",
|
||||
value=default if isinstance(default, (dict, list)) else {"value": default},
|
||||
scope_level=scope_level,
|
||||
scope_id=scope_id,
|
||||
is_active=True,
|
||||
description=f"Auto-inserted default value for {key}"
|
||||
)
|
||||
db.add(param)
|
||||
await db.commit()
|
||||
except Exception as e:
|
||||
logger.debug(f"Could not insert default for {key}: {e}")
|
||||
await db.rollback()
|
||||
|
||||
# A példány, amit a többi modul (pl. az auth_service, ai_service) importálni próbál
|
||||
config = ConfigService()
|
||||
Reference in New Issue
Block a user