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:
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
import asyncio
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
import threading
|
||||
from typing import Any
|
||||
|
||||
from ..logger import belief_scope, logger
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -235,4 +235,4 @@ class DatasetMapper:
|
||||
return
|
||||
# #endregion run_mapping
|
||||
# #endregion DatasetMapper
|
||||
# #endregion DatasetMapperModule
|
||||
# #endregion DatasetMapperModule
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user