Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/agent_execution/docker_sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@

# Docker SDK
try:
from docker.errors import DockerException, NotFound
from docker.errors import DockerException, NotFound # type: ignore[attr-defined]

import docker
import docker # type: ignore[attr-defined]

DOCKER_AVAILABLE = True
except ImportError:
DOCKER_AVAILABLE = False
DockerException = Exception
docker = None # type: ignore[assignment]


# =============================================================================
Expand Down Expand Up @@ -142,7 +143,7 @@ def __init__(

self._client = None

def _get_docker_client(self) -> "docker.DockerClient":
def _get_docker_client(self) -> "docker.DockerClient": # type: ignore[misc]
"""Get or create Docker client."""
if not DOCKER_AVAILABLE:
raise ImportError(
Expand All @@ -152,9 +153,9 @@ def _get_docker_client(self) -> "docker.DockerClient":
if self._client is None:
try:
# Try to connect to Docker daemon
self._client = docker.from_env()
self._client = docker.from_env() # type: ignore[union-attr]
# Verify connection
self._client.ping()
self._client.ping() # type: ignore[union-attr]
except DockerException as e:
raise RuntimeError(
f"Failed to connect to Docker daemon: {e}. "
Expand Down
51 changes: 20 additions & 31 deletions src/utils/error_tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
capture_exception(e)
"""

from __future__ import annotations

import logging
import os
import sys
from typing import Any, ClassVar
from typing import TYPE_CHECKING, Any, ClassVar

# Optional Sentry dependency
try:
# Optional Sentry dependency - only import for type hints when available
if TYPE_CHECKING:
import sentry_sdk
from sentry_sdk import capture_exception, capture_message
from sentry_sdk.integrations import (
Expand All @@ -38,30 +40,17 @@
)
from sentry_sdk.integrations.logging import ignore_logger
from sentry_sdk.tracing import Transaction
SENTRY_AVAILABLE = True
except ImportError:
SENTRY_AVAILABLE = False
# Mock classes and functions for when Sentry is not available
sentry_sdk = None # type: ignore
def capture_exception(*args, **kwargs): return None
def capture_message(*args, **kwargs): return None

class Transaction:
def __init__(self, *args, **kwargs): pass
def __enter__(self): return self
def __exit__(self, *args): pass

# Mock integration classes for type hints
class FastApiIntegration: # type: ignore
def __init__(self, *args, **kwargs): pass

class LoggingIntegration: # type: ignore
def __init__(self, *args, **kwargs): pass

class SqlalchemyIntegration: # type: ignore
def __init__(self, *args, **kwargs): pass

def ignore_logger(*args, **kwargs): pass
else:
sentry_sdk = None
capture_exception = None
capture_message = None
Transaction = None
FastApiIntegration = None
LoggingIntegration = None
SqlalchemyIntegration = None
ignore_logger = None

SENTRY_AVAILABLE = sentry_sdk is not None

from src.utils.logger import get_logger

Expand Down Expand Up @@ -279,10 +268,10 @@ def add_breadcrumb(
)


def capture_exception(
def capture_exception( # type: ignore[no-redef]
exc: BaseException | None = None,
extra: dict[str, Any] | None = None,
**tags,
**tags: Any,
) -> str | None:
"""Capture an exception with optional context.

Expand Down Expand Up @@ -318,11 +307,11 @@ def capture_exception(
return event_id


def capture_message(
def capture_message( # type: ignore[no-redef]
message: str,
level: str = "info",
extra: dict[str, Any] | None = None,
**tags,
**tags: Any,
) -> str | None:
"""Capture a message with optional context.

Expand Down
13 changes: 10 additions & 3 deletions src/utils/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from contextlib import suppress
from logging.handlers import RotatingFileHandler
from pathlib import Path
from typing import Any

# Import error tracking for automatic error capture in logs (Issue #230)
try:
Expand All @@ -31,9 +32,15 @@
except ImportError:
SENTRY_AVAILABLE = False
# Mock functions when error_tracking is not available
def add_breadcrumb(*args, **kwargs): pass
def capture_exception(*args, **kwargs): return None
def capture_message(*args, **kwargs): return None
def add_breadcrumb(
message: str,
category: str = "default",
level: str = "info",
**data: Any,
) -> None:
pass
def capture_exception(*args: Any, **kwargs: Any) -> None: pass
def capture_message(*args: Any, **kwargs: Any) -> None: pass


def setup_logging(
Expand Down
10 changes: 5 additions & 5 deletions tests/test_oauth_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"""

import pytest
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from unittest.mock import AsyncMock, patch, Mock
import httpx

Expand Down Expand Up @@ -84,7 +84,7 @@ def test_token_expired(self):
expires_in=1,
)
# Manually set expiration to past
token.expires_at = datetime.utcnow() - timedelta(seconds=10)
token.expires_at = datetime.now(timezone.utc) - timedelta(seconds=10)

assert token.is_expired() is True

Expand Down Expand Up @@ -117,7 +117,7 @@ def test_token_from_dict(self):

def test_token_from_dict_with_timestamps(self):
"""Test creating token from dictionary with timestamps."""
now = datetime.utcnow()
now = datetime.now(timezone.utc)
token_data = {
"access_token": "test",
"refresh_token": "refresh",
Expand Down Expand Up @@ -267,7 +267,7 @@ async def test_get_valid_token_auto_refresh(self, oauth_manager):
refresh_token="refresh",
expires_in=1,
)
expired_token.expires_at = datetime.utcnow() - timedelta(seconds=10)
expired_token.expires_at = datetime.now(timezone.utc) - timedelta(seconds=10)
oauth_manager.set_token(expired_token)

# Mock refresh response
Expand Down Expand Up @@ -430,7 +430,7 @@ async def test_refresh_all_tokens(self):
refresh_token="refresh",
expires_in=1,
)
expired_token.expires_at = datetime.utcnow() - timedelta(seconds=10)
expired_token.expires_at = datetime.now(timezone.utc) - timedelta(seconds=10)
manager.set_token(expired_token)

# Mock refresh response
Expand Down
7 changes: 7 additions & 0 deletions tests/test_performance_improvements.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,15 @@
@pytest.fixture
def test_db():
"""Create in-memory SQLite database for testing."""
from src.api.models import Base
from src.api.user_models import Base as UserBase

engine = create_engine("sqlite:///:memory:", echo=False)

# Create all tables from all model bases
Base.metadata.create_all(engine)
UserBase.metadata.create_all(engine)

SessionLocal = sessionmaker(bind=engine)
db = SessionLocal()
try:
Expand Down
7 changes: 7 additions & 0 deletions tests/test_training_mode_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ def reset_config():
"""Reset config before each test."""
reset_instance()
reset_simulation_engine()
# Clean up database to ensure test isolation
session = SessionLocal()
try:
session.query(SimulationBid).delete()
session.commit()
finally:
session.close()
yield


Expand Down
Loading