-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Support default millisecond timestamp precision for custom services #3568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,9 +67,22 @@ | |
| HOST_PREFIX_RE = re.compile(r"^[A-Za-z0-9\.\-]+$") | ||
|
|
||
|
|
||
| def create_serializer(protocol_name, include_validation=True): | ||
| def create_serializer( | ||
| protocol_name, include_validation=True, timestamp_precision='second' | ||
| ): | ||
| """Create a serializer for the given protocol. | ||
|
|
||
| :param protocol_name: The protocol name to create a serializer for. | ||
jonathan343 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| :param include_validation: Whether to include parameter validation. | ||
| :param timestamp_precision: Timestamp precision level. | ||
| - 'second': Standard second precision (default) | ||
| - 'millisecond': Millisecond precision for high-accuracy timestamps | ||
| :return: A serializer instance for the given protocol. | ||
| """ | ||
| # TODO: Unknown protocols. | ||
| serializer = SERIALIZERS[protocol_name]() | ||
| serializer = SERIALIZERS[protocol_name]( | ||
| timestamp_precision=timestamp_precision | ||
| ) | ||
| if include_validation: | ||
| validator = validate.ParamValidator() | ||
| serializer = validate.ParamValidationDecorator(validator, serializer) | ||
|
|
@@ -85,6 +98,11 @@ class Serializer: | |
| MAP_TYPE = dict | ||
| DEFAULT_ENCODING = 'utf-8' | ||
|
|
||
| def __init__(self, timestamp_precision='second'): | ||
|
||
| if timestamp_precision is None: | ||
| timestamp_precision = 'second' | ||
| self._timestamp_precision = timestamp_precision | ||
jonathan343 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| def serialize_to_request(self, parameters, operation_model): | ||
| """Serialize parameters into an HTTP request. | ||
|
|
||
|
|
@@ -139,18 +157,36 @@ def _create_default_request(self): | |
| # Some extra utility methods subclasses can use. | ||
|
|
||
| def _timestamp_iso8601(self, value): | ||
| if value.microsecond > 0: | ||
| timestamp_format = ISO8601_MICRO | ||
| """Return ISO8601 timestamp with precision based on timestamp_precision.""" | ||
| # Smithy's standard is milliseconds, so we truncate the timestamp if the millisecond flag is set to true | ||
| if self._timestamp_precision == 'millisecond': | ||
jonathan343 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| milliseconds = value.microsecond // 1000 | ||
| return ( | ||
| value.strftime('%Y-%m-%dT%H:%M:%S') + f'.{milliseconds:03d}Z' | ||
| ) | ||
| else: | ||
| timestamp_format = ISO8601 | ||
| return value.strftime(timestamp_format) | ||
| # Otherwise we continue supporting microseconds in iso8601 for legacy reasons | ||
| if value.microsecond > 0: | ||
| timestamp_format = ISO8601_MICRO | ||
| else: | ||
| timestamp_format = ISO8601 | ||
| return value.strftime(timestamp_format) | ||
|
|
||
| def _timestamp_unixtimestamp(self, value): | ||
| return int(calendar.timegm(value.timetuple())) | ||
| """Return unix timestamp with precision based on timestamp_precision.""" | ||
| # As of the addition of the precision flag, we support millisecond precision here as well | ||
| if self._timestamp_precision == 'millisecond': | ||
| base_timestamp = calendar.timegm(value.timetuple()) | ||
| milliseconds = (value.microsecond // 1000) / 1000.0 | ||
| return base_timestamp + milliseconds | ||
| else: | ||
| return int(calendar.timegm(value.timetuple())) | ||
|
|
||
| def _timestamp_rfc822(self, value): | ||
| """Return RFC822 timestamp (always second precision - RFC doesn't support sub-second).""" | ||
| # RFC 2822 doesn't support sub-second precision, so always use second precision format | ||
SamRemis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if isinstance(value, datetime.datetime): | ||
| value = self._timestamp_unixtimestamp(value) | ||
| value = int(calendar.timegm(value.timetuple())) | ||
| return formatdate(value, usegmt=True) | ||
|
|
||
| def _convert_timestamp_to_str(self, value, timestamp_format=None): | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.