Skip to content

Commit d70a020

Browse files
nficanoclaude
andcommitted
refactor: use import datetime as dt consistently
Replaces `from datetime import UTC, datetime, timedelta` with `import datetime as dt` across src/, tests/, examples/, and docs so datetime symbols are accessed via a single namespace. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c45330d commit d70a020

19 files changed

Lines changed: 79 additions & 74 deletions

docs/guides/leases.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ handle = await client.submit(
3939
## Absolute expiry timestamp
4040

4141
```python
42-
from datetime import datetime, timezone, timedelta
42+
import datetime as dt
4343

44-
expiry = datetime.now(timezone.utc) + timedelta(minutes=5)
44+
expiry = dt.datetime.now(dt.UTC) + dt.timedelta(minutes=5)
4545

4646
handle = await client.submit(
4747
agent="slow-agent",

examples/lease_expires_at/client.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
import asyncio
66
import contextlib
7+
import datetime as dt
78
import os
89
import sys
9-
from datetime import UTC, datetime, timedelta
1010

1111
from arcp import ClientInfo, LeaseConstraints, LeaseExpiredError, WebSocketTransport
1212
from arcp.client import ARCPClient
@@ -25,7 +25,9 @@ async def main() -> int:
2525
async with contextlib.aclosing(client):
2626
transport = await WebSocketTransport.connect(URL)
2727
await client.connect(transport)
28-
expires_at = (datetime.now(UTC) + timedelta(seconds=2)).isoformat().replace("+00:00", "Z")
28+
expires_at = (
29+
(dt.datetime.now(dt.UTC) + dt.timedelta(seconds=2)).isoformat().replace("+00:00", "Z")
30+
)
2931
handle = await client.submit(
3032
agent="slow",
3133
lease_constraints=LeaseConstraints(expires_at=expires_at),

src/arcp/_client/dispatch.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
from __future__ import annotations
66

77
import asyncio
8+
import datetime as dt
89
from collections.abc import Awaitable, Callable
9-
from datetime import UTC, datetime
1010
from typing import TYPE_CHECKING, Any
1111

1212
from .._envelope import Envelope
@@ -30,7 +30,7 @@
3030

3131

3232
def _now_iso() -> str:
33-
return datetime.now(UTC).isoformat().replace("+00:00", "Z")
33+
return dt.datetime.now(dt.UTC).isoformat().replace("+00:00", "Z")
3434

3535

3636
Handler = Callable[[Envelope], Awaitable[None]]

src/arcp/_client/ops.py

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

77
import asyncio
88
import contextlib
9-
from datetime import UTC, datetime
9+
import datetime as dt
1010
from typing import TYPE_CHECKING, Any
1111

1212
from .._envelope import Envelope
@@ -36,7 +36,7 @@
3636

3737

3838
def _now_iso() -> str:
39-
return datetime.now(UTC).isoformat().replace("+00:00", "Z")
39+
return dt.datetime.now(dt.UTC).isoformat().replace("+00:00", "Z")
4040

4141

4242
def _require_transport(client: ARCPClient) -> Transport:

src/arcp/_messages/execution.py

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

33
from __future__ import annotations
44

5+
import datetime as dt
56
import re
6-
from datetime import UTC, datetime
77
from decimal import Decimal, InvalidOperation
88
from typing import Any, Literal
99

@@ -73,19 +73,19 @@ def format_budget_amount(currency: str, value: Decimal) -> str:
7373
"""A lease maps capability namespace to a list of glob patterns."""
7474

7575

76-
def _ensure_utc_iso8601(value: str) -> datetime:
76+
def _ensure_utc_iso8601(value: str) -> dt.datetime:
7777
"""Parse a strict UTC ISO 8601 timestamp (`Z` or `+00:00` only).
7878
7979
Python 3.11+ `datetime.fromisoformat` accepts a trailing `Z` natively,
8080
so no `Z` → `+00:00` rewrite is required.
8181
"""
8282
try:
83-
dt = datetime.fromisoformat(value)
83+
parsed = dt.datetime.fromisoformat(value)
8484
except ValueError as e:
8585
raise ValueError(f"invalid ISO 8601 timestamp: {value!r}") from e
86-
if dt.tzinfo is None or dt.utcoffset() != UTC.utcoffset(dt):
86+
if parsed.tzinfo is None or parsed.utcoffset() != dt.UTC.utcoffset(parsed):
8787
raise ValueError(f"expires_at must be UTC: {value!r}")
88-
return dt
88+
return parsed
8989

9090

9191
class LeaseConstraints(BaseModel):

src/arcp/_runtime/_handler_list_jobs.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from __future__ import annotations
66

7-
from datetime import datetime
7+
import datetime as dt
88
from typing import TYPE_CHECKING
99

1010
from .._envelope import Envelope
@@ -28,10 +28,10 @@ async def handle_list_jobs(runtime: ARCPRuntime, ctx: SessionContext, env: Envel
2828
body = SessionListJobsPayload.model_validate(env.payload)
2929
limit = body.limit or 100
3030
offset = int(body.cursor) if body.cursor and body.cursor.isdigit() else 0
31-
created_after_dt: datetime | None = None
31+
created_after_dt: dt.datetime | None = None
3232
if body.filter is not None and body.filter.created_after:
3333
try:
34-
created_after_dt = datetime.fromisoformat(body.filter.created_after)
34+
created_after_dt = dt.datetime.fromisoformat(body.filter.created_after)
3535
except ValueError as exc:
3636
raise InvalidRequestError(
3737
f"filter.created_after is not a valid ISO 8601 timestamp: "
@@ -56,7 +56,7 @@ def _filter_jobs(
5656
ctx: SessionContext,
5757
body: SessionListJobsPayload,
5858
auth_cls: type[AuthorizationContext],
59-
created_after_dt: datetime | None,
59+
created_after_dt: dt.datetime | None,
6060
) -> list[Job]:
6161
# PLR0913: passes the pre-parsed created_after to avoid re-parsing
6262
# the ISO string for every job in the loop.
@@ -73,7 +73,7 @@ def _filter_jobs(
7373

7474

7575
def _matches_filter(
76-
job: Job, body: SessionListJobsPayload, created_after_dt: datetime | None
76+
job: Job, body: SessionListJobsPayload, created_after_dt: dt.datetime | None
7777
) -> bool:
7878
if body.filter is None:
7979
return True

src/arcp/_runtime/_handlers.py

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

77
import asyncio
88
import contextlib
9-
from datetime import UTC, datetime
9+
import datetime as dt
1010
from typing import TYPE_CHECKING
1111

1212
from .._envelope import Envelope
@@ -50,7 +50,7 @@
5050

5151

5252
def _now_iso() -> str:
53-
return datetime.now(UTC).isoformat().replace("+00:00", "Z")
53+
return dt.datetime.now(dt.UTC).isoformat().replace("+00:00", "Z")
5454

5555

5656
async def handle_ping(_runtime: ARCPRuntime, ctx: SessionContext, env: Envelope) -> None:

src/arcp/_runtime/_handshake.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
from __future__ import annotations
66

77
import asyncio
8+
import datetime as dt
89
import hmac
9-
from datetime import UTC, datetime
1010
from typing import TYPE_CHECKING, Any
1111

1212
from .._envelope import Envelope
@@ -26,7 +26,7 @@
2626

2727

2828
def _now_iso() -> str:
29-
return datetime.now(UTC).isoformat().replace("+00:00", "Z")
29+
return dt.datetime.now(dt.UTC).isoformat().replace("+00:00", "Z")
3030

3131

3232
async def perform_handshake(runtime: ARCPRuntime, transport: Any) -> SessionContext:
@@ -104,7 +104,7 @@ async def _perform_resume( # noqa: PLR0913
104104
runtime.heartbeat_interval_sec if "heartbeat" in negotiated else None
105105
),
106106
resume_window_sec=runtime.resume_window_sec,
107-
accepted_at=datetime.now(UTC),
107+
accepted_at=dt.datetime.now(dt.UTC),
108108
)
109109
send_queue: asyncio.Queue[Envelope | None] = asyncio.Queue()
110110
ctx = SessionContext(

src/arcp/_runtime/_job_runner.py

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

77
import asyncio
8-
from datetime import UTC, datetime
8+
import datetime as dt
99
from typing import TYPE_CHECKING, Any
1010

1111
from .._errors import ARCPError, InternalError, LeaseExpiredError
@@ -19,7 +19,7 @@
1919

2020

2121
def _now_iso() -> str:
22-
return datetime.now(UTC).isoformat().replace("+00:00", "Z")
22+
return dt.datetime.now(dt.UTC).isoformat().replace("+00:00", "Z")
2323

2424

2525
async def run_job(
@@ -181,7 +181,7 @@ async def _revoke_with_retry(runtime: ARCPRuntime, credential_id: str) -> bool:
181181

182182
async def _lease_watchdog(runtime: ARCPRuntime, job: Job, expires_at_iso: str) -> None:
183183
expiry = _parse_iso_utc(expires_at_iso)
184-
delay = (expiry - datetime.now(UTC)).total_seconds()
184+
delay = (expiry - dt.datetime.now(dt.UTC)).total_seconds()
185185
if delay > 0:
186186
try:
187187
await asyncio.sleep(delay)

src/arcp/_runtime/job.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
from __future__ import annotations
44

55
import asyncio
6+
import datetime as dt
67
from collections.abc import Awaitable, Callable
78
from dataclasses import dataclass, field, replace
8-
from datetime import UTC, datetime
99
from decimal import Decimal, InvalidOperation
1010
from typing import TYPE_CHECKING, Any, Literal
1111

@@ -36,7 +36,7 @@
3636

3737

3838
def _now_iso() -> str:
39-
return datetime.now(UTC).isoformat().replace("+00:00", "Z")
39+
return dt.datetime.now(dt.UTC).isoformat().replace("+00:00", "Z")
4040

4141

4242
@dataclass
@@ -59,7 +59,7 @@ class Job:
5959
state: JobStateName = "pending"
6060
chunked_result_started: bool = False
6161
inline_result_emitted: bool = False
62-
submitted_at: datetime = field(default_factory=lambda: datetime.now(UTC))
62+
submitted_at: dt.datetime = field(default_factory=lambda: dt.datetime.now(dt.UTC))
6363
idempotency_key: str | None = None
6464
# Wire dict of the most-recent terminal envelope (job.result / job.error)
6565
# this job emitted; used by the idempotency store to replay terminals on
@@ -302,7 +302,7 @@ def authorize(
302302
target: str,
303303
*,
304304
cost: dict[str, Decimal] | None = None,
305-
now: datetime | None = None,
305+
now: dt.datetime | None = None,
306306
) -> None:
307307
validate_lease_op(
308308
self.lease,
@@ -311,7 +311,7 @@ def authorize(
311311
budget=self.job.budget if "cost.budget" in self.lease else None,
312312
)
313313

314-
def authorize_model(self, model_id: str, *, now: datetime | None = None) -> None:
314+
def authorize_model(self, model_id: str, *, now: dt.datetime | None = None) -> None:
315315
"""Authorize an upstream model id against the job's `model.use` lease."""
316316
validate_lease_op(
317317
self.lease,

0 commit comments

Comments
 (0)