Skip to content

Commit f11ade4

Browse files
committed
refactor(bay): replace deprecated datetime.utcnow() with utils.utcnow()
Mechanical migration across all models, managers, services, and tests. No logic changes — only import source changes. Files updated: - Models: cargo, sandbox, session, idempotency, skill - Managers: session, cargo, sandbox - Services: gc tasks, idempotency, skills - API: sandboxes - Tests: sandbox_containers, gc_tasks, idempotency, browser_learning_scheduler, cargo_manager, sandbox_manager
1 parent 700b9a2 commit f11ade4

File tree

20 files changed

+125
-104
lines changed

20 files changed

+125
-104
lines changed

pkgs/bay/app/api/v1/sandboxes.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from app.models.sandbox import Sandbox, SandboxStatus
2222
from app.models.session import Session
2323
from app.router.capability.adapter_pool import default_adapter_pool
24+
from app.utils.datetime import utcnow
2425

2526
router = APIRouter()
2627
_log = structlog.get_logger()
@@ -85,7 +86,7 @@ def _sandbox_to_response(
8586
containers: list[ContainerRuntimeResponse] | None = None,
8687
) -> SandboxResponse:
8788
"""Convert Sandbox model to API response."""
88-
now = datetime.utcnow()
89+
now = utcnow()
8990
return _sandbox_to_response_at_time(
9091
sandbox,
9192
now=now,
@@ -359,7 +360,7 @@ async def list_sandboxes(
359360
cursor=cursor,
360361
)
361362

362-
now = datetime.utcnow()
363+
now = utcnow()
363364
items = [
364365
_sandbox_to_response_at_time(
365366
item.sandbox,

pkgs/bay/app/managers/cargo/cargo.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from __future__ import annotations
77

88
import uuid
9-
from datetime import datetime
109

1110
import structlog
1211
from sqlalchemy.ext.asyncio import AsyncSession
@@ -15,8 +14,9 @@
1514
from app.config import get_settings
1615
from app.drivers.base import Driver
1716
from app.errors import ConflictError, NotFoundError
18-
from app.models.sandbox import Sandbox
1917
from app.models.cargo import Cargo
18+
from app.models.sandbox import Sandbox
19+
from app.utils.datetime import utcnow
2020

2121
logger = structlog.get_logger()
2222

@@ -78,8 +78,8 @@ async def create(
7878
managed=managed,
7979
managed_by_sandbox_id=managed_by_sandbox_id,
8080
size_limit_mb=size_limit_mb or self._settings.cargo.default_size_limit_mb,
81-
created_at=datetime.utcnow(),
82-
last_accessed_at=datetime.utcnow(),
81+
created_at=utcnow(),
82+
last_accessed_at=utcnow(),
8383
)
8484

8585
self._db.add(cargo)
@@ -131,7 +131,8 @@ async def list(
131131
132132
Args:
133133
owner: Owner identifier
134-
managed: Filter by managed status (None = all, True = managed only, False = external only)
134+
managed: Filter by managed status
135+
(None = all, True = managed only, False = external only)
135136
limit: Maximum number of results
136137
cursor: Pagination cursor
137138
@@ -247,7 +248,7 @@ async def touch(self, cargo_id: str) -> None:
247248
cargo = result.scalars().first()
248249

249250
if cargo:
250-
cargo.last_accessed_at = datetime.utcnow()
251+
cargo.last_accessed_at = utcnow()
251252
await self._db.commit()
252253

253254
async def delete_internal_by_id(self, cargo_id: str) -> None:

pkgs/bay/app/managers/sandbox/sandbox.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
from __future__ import annotations
1010

1111
import uuid
12-
from datetime import datetime, timedelta
1312
from dataclasses import dataclass
13+
from datetime import timedelta
1414
from typing import TYPE_CHECKING
1515

1616
import structlog
@@ -29,6 +29,7 @@
2929
from app.managers.session import SessionManager
3030
from app.models.sandbox import Sandbox, SandboxStatus
3131
from app.models.session import Session
32+
from app.utils.datetime import utcnow
3233

3334
if TYPE_CHECKING:
3435
from app.drivers.base import Driver
@@ -107,7 +108,7 @@ async def create(
107108
# Calculate expiry
108109
expires_at = None
109110
if ttl and ttl > 0:
110-
expires_at = datetime.utcnow() + timedelta(seconds=ttl)
111+
expires_at = utcnow() + timedelta(seconds=ttl)
111112

112113
# Create sandbox
113114
sandbox = Sandbox(
@@ -116,8 +117,8 @@ async def create(
116117
profile_id=profile_id,
117118
cargo_id=cargo.id,
118119
expires_at=expires_at,
119-
created_at=datetime.utcnow(),
120-
last_active_at=datetime.utcnow(),
120+
created_at=utcnow(),
121+
last_active_at=utcnow(),
121122
)
122123

123124
self._db.add(sandbox)
@@ -172,7 +173,7 @@ async def list(
172173
Returns:
173174
Tuple of (sandboxes, next_cursor)
174175
"""
175-
now = datetime.utcnow()
176+
now = utcnow()
176177
scan_cursor = cursor
177178

178179
# Limit per-call scanning so rare filters don't force unbounded work.
@@ -229,7 +230,8 @@ async def list(
229230
if len(returned) >= limit:
230231
# Cursor is the last scanned sandbox_id at the point we reached the limit.
231232
next_cursor = sandbox.id
232-
# Match CargoManager cursor semantics: only return cursor if there may be more.
233+
# Match CargoManager cursor semantics:
234+
# only return cursor if there may be more.
233235
has_more_result = await self._db.execute(
234236
select(Sandbox.id)
235237
.where(
@@ -318,10 +320,10 @@ async def ensure_running(self, sandbox: Sandbox) -> Session:
318320
)
319321

320322
# Update idle timeout
321-
locked_sandbox.idle_expires_at = datetime.utcnow() + timedelta(
323+
locked_sandbox.idle_expires_at = utcnow() + timedelta(
322324
seconds=profile.idle_timeout
323325
)
324-
locked_sandbox.last_active_at = datetime.utcnow()
326+
locked_sandbox.last_active_at = utcnow()
325327
await self._db.commit()
326328

327329
return session
@@ -377,7 +379,7 @@ async def extend_ttl(
377379
}
378380
)
379381

380-
now = datetime.utcnow()
382+
now = utcnow()
381383
if old < now:
382384
raise SandboxExpiredError(
383385
details={
@@ -410,9 +412,9 @@ async def keepalive(self, sandbox: Sandbox) -> None:
410412

411413
profile = self._settings.get_profile(sandbox.profile_id)
412414
if profile:
413-
sandbox.idle_expires_at = datetime.utcnow() + timedelta(seconds=profile.idle_timeout)
415+
sandbox.idle_expires_at = utcnow() + timedelta(seconds=profile.idle_timeout)
414416

415-
sandbox.last_active_at = datetime.utcnow()
417+
sandbox.last_active_at = utcnow()
416418
await self._db.commit()
417419

418420
async def stop(self, sandbox: Sandbox) -> None:
@@ -500,7 +502,7 @@ async def delete(self, sandbox: Sandbox) -> None:
500502
cargo = await self._cargo_mgr.get_by_id(cargo_id)
501503

502504
# Soft delete sandbox
503-
locked_sandbox.deleted_at = datetime.utcnow()
505+
locked_sandbox.deleted_at = utcnow()
504506
locked_sandbox.current_session_id = None
505507
await self._db.commit()
506508

pkgs/bay/app/managers/session/session.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
import asyncio
1616
import uuid
17-
from datetime import datetime
1817

1918
import httpx
2019
import structlog
@@ -27,6 +26,7 @@
2726
from app.models.cargo import Cargo
2827
from app.models.session import Session, SessionStatus
2928
from app.services.http import http_client_manager
29+
from app.utils.datetime import utcnow
3030

3131
logger = structlog.get_logger()
3232

@@ -79,8 +79,8 @@ async def create(
7979
profile_id=profile.id,
8080
desired_state=SessionStatus.PENDING,
8181
observed_state=SessionStatus.PENDING,
82-
created_at=datetime.utcnow(),
83-
last_active_at=datetime.utcnow(),
82+
created_at=utcnow(),
83+
last_active_at=utcnow(),
8484
)
8585

8686
self._db.add(session)
@@ -180,7 +180,7 @@ async def _ensure_running_single(
180180
error=str(e),
181181
)
182182
session.observed_state = SessionStatus.FAILED
183-
session.last_observed_at = datetime.utcnow()
183+
session.last_observed_at = utcnow()
184184
await self._db.commit()
185185
raise
186186

@@ -211,7 +211,7 @@ async def _ensure_running_single(
211211
# Only persist endpoint after readiness succeeds.
212212
session.endpoint = endpoint
213213
session.observed_state = SessionStatus.RUNNING
214-
session.last_observed_at = datetime.utcnow()
214+
session.last_observed_at = utcnow()
215215
await self._db.commit()
216216

217217
except Exception as e:
@@ -235,7 +235,7 @@ async def _ensure_running_single(
235235
session.container_id = None
236236
session.endpoint = None
237237
session.observed_state = SessionStatus.FAILED
238-
session.last_observed_at = datetime.utcnow()
238+
session.last_observed_at = utcnow()
239239
await self._db.commit()
240240
raise
241241

@@ -316,7 +316,7 @@ async def _ensure_running_multi(
316316
session.endpoint = primary_info.endpoint
317317
session.containers = [ci.to_dict() for ci in container_infos]
318318
session.observed_state = SessionStatus.RUNNING
319-
session.last_observed_at = datetime.utcnow()
319+
session.last_observed_at = utcnow()
320320
await self._db.commit()
321321

322322
self._log.info(
@@ -356,7 +356,7 @@ async def _ensure_running_multi(
356356
session.endpoint = None
357357
session.containers = None
358358
session.observed_state = SessionStatus.FAILED
359-
session.last_observed_at = datetime.utcnow()
359+
session.last_observed_at = utcnow()
360360
await self._db.commit()
361361
raise
362362

@@ -628,7 +628,7 @@ async def stop(self, session: Session) -> None:
628628
session.observed_state = SessionStatus.STOPPED
629629
session.endpoint = None
630630
session.containers = None
631-
session.last_observed_at = datetime.utcnow()
631+
session.last_observed_at = utcnow()
632632
await self._db.commit()
633633

634634
async def destroy(self, session: Session) -> None:
@@ -708,7 +708,7 @@ async def refresh_status(self, session: Session) -> Session:
708708
session.observed_state = SessionStatus.STOPPED
709709
session.container_id = None
710710

711-
session.last_observed_at = datetime.utcnow()
711+
session.last_observed_at = utcnow()
712712
await self._db.commit()
713713

714714
return session
@@ -719,7 +719,7 @@ async def touch(self, session_id: str) -> None:
719719
session = result.scalars().first()
720720

721721
if session:
722-
session.last_active_at = datetime.utcnow()
722+
session.last_active_at = utcnow()
723723
await self._db.commit()
724724

725725
async def _probe_and_recover_if_dead(
@@ -792,7 +792,7 @@ async def _probe_and_recover_if_dead(
792792
session.container_id = None
793793
session.endpoint = None
794794
session.observed_state = SessionStatus.PENDING
795-
session.last_observed_at = datetime.utcnow()
795+
session.last_observed_at = utcnow()
796796
await self._db.commit()
797797

798798
self._log.info(

pkgs/bay/app/models/cargo.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
from sqlmodel import Field, Relationship, SQLModel
1414

15+
from app.utils.datetime import utcnow
16+
1517
if TYPE_CHECKING:
1618
from app.models.sandbox import Sandbox
1719

@@ -36,8 +38,8 @@ class Cargo(SQLModel, table=True):
3638
size_limit_mb: int = Field(default=1024)
3739

3840
# Timestamps
39-
created_at: datetime = Field(default_factory=datetime.utcnow)
40-
last_accessed_at: datetime = Field(default_factory=datetime.utcnow)
41+
created_at: datetime = Field(default_factory=utcnow)
42+
last_accessed_at: datetime = Field(default_factory=utcnow)
4143

4244
# Relationships
4345
sandboxes: list["Sandbox"] = Relationship(back_populates="cargo")

pkgs/bay/app/models/idempotency.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
from sqlmodel import Field, SQLModel
1212

13+
from app.utils.datetime import utcnow
14+
1315

1416
class IdempotencyKey(SQLModel, table=True):
1517
"""Idempotency key for POST operations."""
@@ -28,9 +30,9 @@ class IdempotencyKey(SQLModel, table=True):
2830
status_code: int = Field(default=200)
2931

3032
# TTL
31-
created_at: datetime = Field(default_factory=datetime.utcnow)
33+
created_at: datetime = Field(default_factory=utcnow)
3234
expires_at: datetime = Field(index=True)
3335

3436
def is_expired(self) -> bool:
3537
"""Check if this idempotency key has expired."""
36-
return datetime.utcnow() > self.expires_at
38+
return utcnow() > self.expires_at

pkgs/bay/app/models/sandbox.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
from sqlmodel import Field, Relationship, SQLModel
1414

15+
from app.utils.datetime import utcnow
16+
1517
if TYPE_CHECKING:
1618
from app.models.cargo import Cargo
1719
from app.models.session import Session
@@ -59,8 +61,8 @@ class Sandbox(SQLModel, table=True):
5961
version: int = Field(default=1)
6062

6163
# Timestamps
62-
created_at: datetime = Field(default_factory=datetime.utcnow)
63-
last_active_at: datetime = Field(default_factory=datetime.utcnow)
64+
created_at: datetime = Field(default_factory=utcnow)
65+
last_active_at: datetime = Field(default_factory=utcnow)
6466

6567
# Relationships
6668
cargo: "Cargo" = Relationship(back_populates="sandboxes")
@@ -76,7 +78,7 @@ def is_expired(self) -> bool:
7678
"""Check if sandbox TTL has expired."""
7779
if self.expires_at is None:
7880
return False
79-
return datetime.utcnow() > self.expires_at
81+
return utcnow() > self.expires_at
8082

8183
def compute_status(
8284
self,

pkgs/bay/app/models/session.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from sqlalchemy import Column
1717
from sqlmodel import Field, Relationship, SQLModel
1818

19+
from app.utils.datetime import utcnow
20+
1921
try:
2022
from sqlalchemy import JSON
2123
except ImportError:
@@ -87,8 +89,8 @@ class Session(SQLModel, table=True):
8789
last_observed_at: Optional[datetime] = Field(default=None)
8890

8991
# Timestamps
90-
created_at: datetime = Field(default_factory=datetime.utcnow)
91-
last_active_at: datetime = Field(default_factory=datetime.utcnow)
92+
created_at: datetime = Field(default_factory=utcnow)
93+
last_active_at: datetime = Field(default_factory=utcnow)
9294

9395
# Relationships
9496
sandbox: "Sandbox" = Relationship(back_populates="sessions")

0 commit comments

Comments
 (0)