chore: eliminate all deprecation warnings from tests and linter

Warnings fixed:
- datetime.utcnow() → datetime.now(UTC) across 48+ files (src/ + tests/)
- datetime.utcnow (callback ref) → lambda: datetime.now(UTC) in model fields (18 files)
- Pydantic class Config → model_config = ConfigDict(...) (16 files)
- Pydantic .dict() → .model_dump() (8 files)
- ConfigDict(allow_population_by_field_name=True) → validate_by_name=True
- SQLAlchemy declarative_base() import path updated
- FastAPI on_event → lifespan context manager (app.py)
- Import sorting (ruff I001) auto-fixed across all files
- Fixed broken re-export chains that ruff F401 cleanup broke:
  _validate_bcp47: service.py now imports from dictionary_validation directly
  job_to_response: _job_routes.py and test imports from service_utils directly
  fetch_datasource_metadata: restored re-export in service.py
- Added missing TranslateJobService import in _job_routes.py (was deleted by F401)
- Added ConfigDict(protected_namespaces=()) for DashboardDatasetItem schema field
- pytest.ini: replaced deprecated importmode with asyncio_mode

All 440 tests pass with zero deprecation warnings.
This commit is contained in:
2026-05-26 19:18:28 +03:00
parent eda346979b
commit 4205618ee6
182 changed files with 779 additions and 897 deletions

View File

@@ -12,12 +12,11 @@
# @SIDE_EFFECT None
# @DATA_CONTRACT TokenPayload -> JWT string
from datetime import UTC, datetime, timedelta
import hashlib
import uuid
from datetime import datetime, timedelta, timezone
from jose import jwt
from jose.exceptions import JWTError
from sqlalchemy.orm import Session
from ...models.auth import TokenBlacklist
@@ -34,7 +33,7 @@ from .config import auth_config
def create_access_token(data: dict, expires_delta: timedelta | None = None) -> str:
with belief_scope("create_access_token"):
to_encode = data.copy()
now = datetime.now(timezone.utc)
now = datetime.now(UTC)
if expires_delta:
expire = now + expires_delta
else:
@@ -101,7 +100,7 @@ def _hash_token(token: str) -> str:
# @PRE db is a valid SQLAlchemy session.
# @POST Expired blacklist rows are removed.
def _prune_blacklist(db: Session) -> None:
now = datetime.now(timezone.utc)
now = datetime.now(UTC)
db.query(TokenBlacklist).filter(TokenBlacklist.expires_at < now).delete()
db.commit()
@@ -131,7 +130,7 @@ def blacklist_token(token: str, db: Session) -> None:
if isinstance(exp_raw, datetime):
expires_at = exp_raw
else:
expires_at = datetime.fromtimestamp(exp_raw, tz=timezone.utc)
expires_at = datetime.fromtimestamp(exp_raw, tz=UTC)
existing = db.query(TokenBlacklist).filter(TokenBlacklist.jti == jti).first()
if existing:

View File

@@ -12,9 +12,8 @@
# @SIDE_EFFECT Writes auth audit log entries
# @DATA_CONTRACT AuthEvent -> LogEntry
import copy
from datetime import UTC, datetime
import re
from datetime import datetime
from typing import Any
from ..logger import belief_scope, logger
@@ -52,7 +51,7 @@ def _mask_details(details: dict[str, Any] | None) -> dict[str, Any] | None:
# dict are masked to prevent credential leakage — see [SEC:L-1].
def log_security_event(event_type: str, username: str, details: dict = None):
with belief_scope("log_security_event", f"{event_type}:{username}"):
timestamp = datetime.utcnow().isoformat()
timestamp = datetime.now(UTC).isoformat()
logger.info(
"[AUDIT][%s][%s] User: %s",
timestamp,

View File

@@ -124,7 +124,7 @@ class BeliefFormatter(logging.Formatter):
# #region LogEntry [C:1] [TYPE Class] [SEMANTICS log,entry,record,pydantic]
# @BRIEF A Pydantic model representing a single, structured log entry.
class LogEntry(BaseModel):
timestamp: datetime = Field(default_factory=datetime.utcnow)
timestamp: datetime = Field(default_factory=lambda: datetime.now(UTC))
level: str
message: str
context: dict[str, Any] | None = None

View File

@@ -7,9 +7,9 @@
# Window resets after ATTEMPT_WINDOW seconds of no activity.
# @REJECTED Redis-backed limiter — not available in all deployments.
# Per-user limiting — user isn't known until after auth.
import time
import threading
from collections import defaultdict
import threading
import time
# ── Configuration ──
MAX_ATTEMPTS: int = 10 # Max failed attempts per window

View File

@@ -172,8 +172,7 @@ def remove_banner_from_position(position_json: dict, chart_id: int) -> dict:
del position_json[md_key]
# Remove ROW entry
if row_key in position_json:
del position_json[row_key]
position_json.pop(row_key, None)
# Remove ROW from GRID_ID children
grid = position_json.get("GRID_ID")

View File

@@ -127,7 +127,7 @@ class JobLifecycle:
f"Starting execution of task {task_id} for plugin '{plugin.name}'"
)
task.status = TaskStatus.RUNNING
task.started_at = datetime.utcnow()
task.started_at = datetime.now(UTC)
self.persistence_service.persist_task(task)
if add_log_callback:
add_log_callback(
@@ -181,7 +181,7 @@ class JobLifecycle:
metadata={"error_type": type(e).__name__},
)
finally:
task.finished_at = datetime.utcnow()
task.finished_at = datetime.now(UTC)
self.event_bus.flush_task_logs(task_id)
self.persistence_service.persist_task(task)
logger.info(

View File

@@ -34,7 +34,6 @@
import asyncio
from concurrent.futures import ThreadPoolExecutor
import threading
from typing import Any
from ..logger import belief_scope, logger

View File

@@ -9,12 +9,12 @@
# @POST Task models exported with immutable IDs
# @SIDE_EFFECT Defines task data schema
# @DATA_CONTRACT TaskInput -> TaskModel
from datetime import datetime
from datetime import UTC, datetime
from enum import Enum
from typing import Any
import uuid
from pydantic import BaseModel, Field
from pydantic import BaseModel, ConfigDict, Field
# #region TaskStatus [TYPE Enum]
@@ -41,7 +41,7 @@ class LogLevel(str, Enum):
# optional_fields: {timestamp: datetime, level: str, source: str, context: dict, metadata: dict}
# }
class LogEntry(BaseModel):
timestamp: datetime = Field(default_factory=datetime.utcnow)
timestamp: datetime = Field(default_factory=lambda: datetime.now(UTC))
level: str = Field(default="INFO")
message: str
source: str = Field(
@@ -65,8 +65,7 @@ class TaskLog(BaseModel):
source: str
message: str
metadata: dict[str, Any] | None = None
class Config:
from_attributes = True
model_config = ConfigDict(from_attributes=True)
# #endregion TaskLog
# #region LogFilter [TYPE Class]
class LogFilter(BaseModel):

View File

@@ -9,7 +9,7 @@
# @RELATION DEPENDS_ON -> [TaskGraph]
# @RELATION DEPENDS_ON -> [TasksSessionLocal]
# @INVARIANT Database schema must match the TaskRecord model structure.
from datetime import datetime
from datetime import UTC, datetime
import json
import re
@@ -179,7 +179,7 @@ class TaskPersistenceService:
# Store logs as JSON, converting datetime to string
record.logs = []
for log in task.logs:
log_dict = log.dict()
log_dict = log.model_dump()
if isinstance(log_dict.get("timestamp"), datetime):
log_dict["timestamp"] = log_dict["timestamp"].isoformat()
# Also clean up any datetimes in context
@@ -244,7 +244,7 @@ class TaskPersistenceService:
log_data = dict(log_data)
log_data["timestamp"] = (
self._parse_datetime(log_data.get("timestamp"))
or datetime.utcnow()
or datetime.now(UTC)
)
logs.append(LogEntry(**log_data))
started_at = self._parse_datetime(record.started_at)

View File

@@ -235,4 +235,4 @@ class DatasetMapper:
return
# #endregion run_mapping
# #endregion DatasetMapper
# #endregion DatasetMapperModule
# #endregion DatasetMapperModule

View File

@@ -11,7 +11,7 @@ from __future__ import annotations
# #region SupersetCompilationAdapter.imports [TYPE Block]
from dataclasses import dataclass
from datetime import datetime
from datetime import UTC, datetime
from typing import Any
from src.core.config_models import Environment
@@ -140,7 +140,7 @@ class SupersetCompilationAdapter:
compiled_by="superset",
error_code=None,
error_details=None,
compiled_at=datetime.utcnow(),
compiled_at=datetime.now(UTC),
)
logger.reflect(
"Superset-generated SQL preview captured successfully",

View File

@@ -3,7 +3,7 @@
# @RELATION DEPENDS_ON -> [LogEntry]
# @RELATION DEPENDS_ON -> [CotJsonFormatter]
from collections import deque
from datetime import datetime
from datetime import UTC, datetime
import logging
from typing import Any
@@ -12,7 +12,7 @@ from pydantic import BaseModel, Field
# #region LogEntry [C:1] [TYPE Class] [SEMANTICS log,entry,record,pydantic]
class LogEntry(BaseModel):
timestamp: datetime = Field(default_factory=datetime.utcnow)
timestamp: datetime = Field(default_factory=lambda: datetime.now(UTC))
level: str
message: str
context: dict[str, Any] | None = None