Skip to content

Commit d0c334d

Browse files
authored
Merge pull request #165 from awslabs/refactor/arch-wave1-isolated
refactor: fix isolated mechanical violations (datetime, except-pass, stubs)
2 parents 2bd1c5b + 3e57bfd commit d0c334d

39 files changed

Lines changed: 185 additions & 151 deletions

src/orb/api/handlers/get_return_requests_handler.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""API handler for getting return requests."""
22

33
import time
4-
from datetime import datetime
4+
from datetime import datetime, timezone
55
from typing import TYPE_CHECKING, Any, Optional, cast
66

77
from orb.application.base.infrastructure_handlers import (
@@ -272,7 +272,7 @@ def _get_from_cache(self, cache_key: str) -> Optional[dict[str, Any]]:
272272
if cache_key in self._cache:
273273
cached_data = self._cache[cache_key]
274274
if (
275-
datetime.utcnow() - cached_data["timestamp"]
275+
datetime.now(timezone.utc) - cached_data["timestamp"]
276276
).total_seconds() < self._cache_duration:
277277
return cached_data["data"]
278278
else:
@@ -287,12 +287,12 @@ def _add_to_cache(self, cache_key: str, data: dict[str, Any]) -> None:
287287
cache_key: Cache key
288288
data: Data to cache
289289
"""
290-
self._cache[cache_key] = {"data": data, "timestamp": datetime.utcnow()}
290+
self._cache[cache_key] = {"data": data, "timestamp": datetime.now(timezone.utc)}
291291
self._cleanup_cache()
292292

293293
def _cleanup_cache(self) -> None:
294294
"""Clean up expired cache entries."""
295-
now = datetime.utcnow()
295+
now = datetime.now(timezone.utc)
296296
expired_keys = [
297297
key
298298
for key, value in self._cache.items()

src/orb/application/base/handlers.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import asyncio
1010
import time
1111
from abc import ABC, abstractmethod
12-
from datetime import datetime
12+
from datetime import datetime, timezone
1313
from functools import wraps
1414
from typing import Any, Callable, Optional, TypeVar
1515

@@ -136,7 +136,7 @@ async def async_wrapper(*args, **kwargs):
136136
self._metrics[operation_id] = {
137137
"duration": duration,
138138
"status": "success",
139-
"timestamp": datetime.utcnow(),
139+
"timestamp": datetime.now(timezone.utc),
140140
}
141141

142142
return result
@@ -156,7 +156,7 @@ async def async_wrapper(*args, **kwargs):
156156
"duration": duration,
157157
"status": "error",
158158
"error": str(e),
159-
"timestamp": datetime.utcnow(),
159+
"timestamp": datetime.now(timezone.utc),
160160
}
161161

162162
raise

src/orb/application/commands/cleanup_handlers.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from datetime import datetime, timedelta
5+
from datetime import datetime, timedelta, timezone
66

77
from orb.application.base.handlers import BaseCommandHandler
88
from orb.application.decorators import command_handler
@@ -51,7 +51,7 @@ async def execute_command(self, command: CleanupOldRequestsCommand) -> None:
5151
- command.request_ids_found: List of request IDs found (dry run)
5252
"""
5353
self.logger.info("Cleaning up requests older than %s days", command.older_than_days)
54-
cutoff_date = datetime.utcnow() - timedelta(days=command.older_than_days)
54+
cutoff_date = datetime.now(timezone.utc) - timedelta(days=command.older_than_days)
5555

5656
try:
5757
with self._uow_factory.create_unit_of_work() as uow:
@@ -139,7 +139,7 @@ async def execute_command(self, command: CleanupAllResourcesCommand) -> None:
139139
- command.total_cleaned: Total resources cleaned
140140
"""
141141
self.logger.info("Cleaning up all resources older than %s days", command.older_than_days)
142-
cutoff_date = datetime.utcnow() - timedelta(days=command.older_than_days)
142+
cutoff_date = datetime.now(timezone.utc) - timedelta(days=command.older_than_days)
143143

144144
try:
145145
with self._uow_factory.create_unit_of_work() as uow:

src/orb/application/dto/system.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
replacing Dict[str, Any] returns with appropriate type safety.
66
"""
77

8-
from datetime import datetime
8+
from datetime import datetime, timezone
99
from typing import Any, Optional
1010

1111
from pydantic import Field
@@ -128,7 +128,8 @@ class ConfigurationSectionResponse(BaseDTO):
128128
default_factory=list, description="List of providers that failed validation"
129129
)
130130
validation_timestamp: datetime = Field(
131-
default_factory=datetime.utcnow, description="When validation was performed"
131+
default_factory=lambda: datetime.now(timezone.utc),
132+
description="When validation was performed",
132133
)
133134

134135

@@ -146,7 +147,8 @@ class SystemStatusDTO(BaseDTO):
146147
cpu_usage_percent: float = Field(description="CPU usage percentage")
147148
disk_usage_percent: float = Field(description="Disk usage percentage")
148149
last_health_check: datetime = Field(
149-
default_factory=datetime.utcnow, description="Last health check timestamp"
150+
default_factory=lambda: datetime.now(timezone.utc),
151+
description="Last health check timestamp",
150152
)
151153
components: dict[str, str] = Field(
152154
default_factory=dict, description="Status of individual components"
@@ -167,7 +169,8 @@ class ProviderMetricsDTO(BaseDTO):
167169
uptime_percent: float = Field(description="Provider uptime percentage")
168170
health_status: str = Field(description="Current health status")
169171
metrics_timestamp: datetime = Field(
170-
default_factory=datetime.utcnow, description="When metrics were collected"
172+
default_factory=lambda: datetime.now(timezone.utc),
173+
description="When metrics were collected",
171174
)
172175

173176

@@ -196,7 +199,7 @@ class ProviderCapabilitiesDTO(BaseDTO):
196199
supports_auto_scaling: bool = Field(description="Whether auto scaling is supported")
197200
api_version: str = Field(description="API version")
198201
last_updated: datetime = Field(
199-
default_factory=datetime.utcnow, description="Last update timestamp"
202+
default_factory=lambda: datetime.now(timezone.utc), description="Last update timestamp"
200203
)
201204

202205

@@ -214,7 +217,8 @@ class ProviderStrategyConfigDTO(BaseDTO):
214217
retry_attempts: int = Field(description="Number of retry attempts")
215218
timeout_seconds: int = Field(description="Timeout in seconds")
216219
last_modified: datetime = Field(
217-
default_factory=datetime.utcnow, description="Last modification timestamp"
220+
default_factory=lambda: datetime.now(timezone.utc),
221+
description="Last modification timestamp",
218222
)
219223

220224

@@ -228,6 +232,7 @@ class ValidationDTO(BaseDTO):
228232
warnings: list[str] = Field(default_factory=list, description="List of validation warnings")
229233
template_id: str = Field(description="ID of the validated template")
230234
validation_timestamp: datetime = Field(
231-
default_factory=datetime.utcnow, description="When validation was performed"
235+
default_factory=lambda: datetime.now(timezone.utc),
236+
description="When validation was performed",
232237
)
233238
schema_version: str = Field(description="Schema version used for validation")

src/orb/application/queries/cleanup_query_handlers.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from datetime import datetime, timedelta
5+
from datetime import datetime, timedelta, timezone
66
from typing import Any
77

88
# Define query classes inline since they're not in dto/queries.py yet
@@ -49,7 +49,7 @@ async def execute_query(self, query: ListCleanableRequestsQuery) -> dict[str, An
4949
"Listing requests eligible for cleanup (older than %d days)", query.older_than_days
5050
)
5151

52-
cutoff_date = datetime.utcnow() - timedelta(days=query.older_than_days)
52+
cutoff_date = datetime.now(timezone.utc) - timedelta(days=query.older_than_days)
5353

5454
try:
5555
with self._uow_factory.create_unit_of_work() as uow:
@@ -66,7 +66,9 @@ async def execute_query(self, query: ListCleanableRequestsQuery) -> dict[str, An
6666
"request_id": str(request.request_id),
6767
"status": str(request.status),
6868
"created_at": request.created_at.isoformat(),
69-
"age_days": (datetime.utcnow() - request.created_at).days,
69+
"age_days": (
70+
datetime.now(timezone.utc) - request.created_at
71+
).days,
7072
}
7173
)
7274

src/orb/application/queries/specialized_handlers.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
from datetime import datetime, timezone
56
from typing import Any
67

78
from orb.application.base.handlers import BaseQueryHandler
@@ -208,15 +209,13 @@ async def execute_query(self, query: GetMachineHealthQuery) -> MachineHealthDTO:
208209
health_details = {"error": str(health_error)}
209210

210211
# Create health DTO
211-
from datetime import datetime
212-
213212
health_dto = MachineHealthDTO(
214213
machine_id=str(machine.machine_id),
215214
overall_status=health_status,
216215
system_status=health_status,
217216
instance_status=health_status,
218217
metrics=[health_details] if health_details else [],
219-
last_check=last_health_check or datetime.utcnow(),
218+
last_check=last_health_check or datetime.now(timezone.utc),
220219
)
221220

222221
self.logger.info(

src/orb/config/installation_detector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def get_scripts_location() -> Path:
118118
if scripts_dir is not None:
119119
return scripts_dir
120120
except Exception:
121-
pass
121+
pass # Best-effort: DI container may not be ready during installation detection
122122

123123
from orb.config.platform_dirs import get_config_location
124124

src/orb/domain/base/entity_pure.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Pure domain entities - foundation for all domain objects without infrastructure dependencies."""
22

33
from abc import ABC, abstractmethod
4-
from datetime import datetime
4+
from datetime import datetime, timezone
55
from typing import Any, Optional, TypeVar
66

77
T = TypeVar("T", bound="Entity")
@@ -26,8 +26,8 @@ def __init__(
2626
**kwargs: Additional attributes for subclasses
2727
"""
2828
self.id = id
29-
self.created_at = created_at or datetime.utcnow()
30-
self.updated_at = updated_at or datetime.utcnow()
29+
self.created_at = created_at or datetime.now(timezone.utc)
30+
self.updated_at = updated_at or datetime.now(timezone.utc)
3131

3232
# Store additional attributes for subclasses
3333
for key, value in kwargs.items():

src/orb/domain/base/error.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Domain error concepts - core error representation."""
22

33
from dataclasses import dataclass
4-
from datetime import datetime
4+
from datetime import datetime, timezone
55
from typing import Any, Optional
66

77

@@ -60,7 +60,7 @@ class ErrorContext:
6060
def create(cls, operation: str, layer: str, request_id: Optional[str] = None) -> "ErrorContext":
6161
"""Create error context with current timestamp."""
6262
return cls(
63-
timestamp=datetime.utcnow(),
63+
timestamp=datetime.now(timezone.utc),
6464
operation=operation,
6565
layer=layer,
6666
request_id=request_id,

src/orb/domain/machine/aggregate.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Machine aggregate - core machine domain logic."""
22

3-
from datetime import datetime
3+
from datetime import datetime, timezone
44
from typing import Any, Optional
55

66
from pydantic import ConfigDict, Field
@@ -83,10 +83,8 @@ def __init__(self, **data) -> None:
8383
data["id"] = data.get("machine_id", f"machine-{data.get('template_id', 'unknown')}")
8484

8585
# Set default timestamps if not provided
86-
from datetime import datetime
87-
8886
if "created_at" not in data:
89-
data["created_at"] = datetime.utcnow()
87+
data["created_at"] = datetime.now(timezone.utc)
9088

9189
super().__init__(**data)
9290

@@ -97,7 +95,7 @@ def start_launching(self) -> "Machine":
9795

9896
fields = self.model_dump()
9997
fields["status"] = MachineStatus.LAUNCHING
100-
fields["launched_at"] = datetime.utcnow()
98+
fields["launched_at"] = datetime.now(timezone.utc)
10199
fields["version"] = self.version + 1
102100

103101
updated_machine = Machine.model_validate(fields)
@@ -133,7 +131,7 @@ def update_status(self, new_status: MachineStatus, reason: Optional[str] = None)
133131
fields["version"] = self.version + 1
134132

135133
# Update timestamps based on status
136-
now = datetime.utcnow()
134+
now = datetime.now(timezone.utc)
137135
if new_status == MachineStatus.RUNNING and not self.launch_time:
138136
fields["launch_time"] = now
139137
elif new_status in [MachineStatus.TERMINATED, MachineStatus.FAILED]:
@@ -224,7 +222,7 @@ def is_healthy(self) -> bool:
224222
def uptime(self) -> Optional[int]:
225223
"""Get machine uptime in seconds."""
226224
if self.launch_time and self.status == MachineStatus.RUNNING:
227-
return int((datetime.utcnow() - self.launch_time).total_seconds())
225+
return int((datetime.now(timezone.utc) - self.launch_time).total_seconds())
228226
return None
229227

230228
def to_provider_format(self, provider_type: str) -> dict[str, Any]:

0 commit comments

Comments
 (0)