Skip to content

Use datetime for ConsumerConfig timestamps#826

Open
caspervonb wants to merge 1 commit intomainfrom
change-jetstream-datetime-fields
Open

Use datetime for ConsumerConfig timestamps#826
caspervonb wants to merge 1 commit intomainfrom
change-jetstream-datetime-fields

Conversation

@caspervonb
Copy link
Collaborator

@caspervonb caspervonb commented Feb 12, 2026

  • Parse ISO 8601 timestamps from the server into datetime objects in from_response
  • Serialize back to ISO 8601 with Z suffix in to_request
  • Add tests for opt_start_time round-trip and datetime types on created/timestamp fields

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates JetStream consumer timestamp configuration fields to use datetime objects (instead of raw numeric values) and adds tests asserting that various timestamps returned by the API are timezone-aware datetime instances.

Changes:

  • Change ConsumerConfig.opt_start_time / pause_until to datetime | None, including request serialization and response parsing.
  • Add tests for timezone-aware datetime timestamps on StreamInfo (created, timestamp, state.first_ts, state.last_ts).
  • Add tests for consumer timestamps (ConsumerInfo.created, ConsumerInfo.timestamp) and opt_start_time round-tripping.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
nats-jetstream/src/nats/jetstream/consumer/init.py Switch ConsumerConfig timestamp fields to datetime, serialize to RFC3339, parse from API responses.
nats-jetstream/tests/test_stream.py Add assertions that stream timestamps are timezone-aware datetime values.
nats-jetstream/tests/test_consumer.py Add coverage for opt_start_time round-trip and timezone-aware consumer info timestamps.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +176 to +178
opt_start_time = datetime.fromisoformat(opt_start_time_str) if opt_start_time_str is not None else None
pause_until_str = config.pop("pause_until", None)
pause_until = datetime.fromisoformat(pause_until_str) if pause_until_str is not None else None
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConsumerConfig.from_response() parses opt_start_time/pause_until with datetime.fromisoformat() without normalizing RFC3339 'Z' suffix. Elsewhere in the codebase (e.g., ConsumerInfo/StreamInfo parsing) timestamps first replace 'Z' with '+00:00'; doing the same here avoids ValueError and keeps parsing consistent.

Suggested change
opt_start_time = datetime.fromisoformat(opt_start_time_str) if opt_start_time_str is not None else None
pause_until_str = config.pop("pause_until", None)
pause_until = datetime.fromisoformat(pause_until_str) if pause_until_str is not None else None
opt_start_time = (
datetime.fromisoformat(opt_start_time_str.replace("Z", "+00:00"))
if opt_start_time_str is not None
else None
)
pause_until_str = config.pop("pause_until", None)
pause_until = (
datetime.fromisoformat(pause_until_str.replace("Z", "+00:00"))
if pause_until_str is not None
else None
)

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@caspervonb I think we should address this?

Comment on lines +1026 to +1039
start_time = datetime(2025, 6, 1, 12, 0, 0, tzinfo=timezone.utc)
await stream.create_consumer(
name="ost_consumer",
deliver_policy="by_start_time",
ack_policy="none",
opt_start_time=start_time,
)

info = await stream.get_consumer_info("ost_consumer")
assert isinstance(info.config.opt_start_time, datetime)
assert info.config.opt_start_time.year == 2025
assert info.config.opt_start_time.month == 6
assert info.config.opt_start_time.day == 1
assert info.config.opt_start_time.hour == 12
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test hard-codes a specific calendar date and only asserts individual fields (year/month/day/hour), which can miss a lost/changed timezone and makes the test less robust than asserting full round-trip equality. Consider asserting tzinfo is preserved (and/or comparing the resulting datetime to the original within an acceptable precision).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants