diff --git a/packages/aws-sdk-signers/src/aws_sdk_signers/interfaces/io.py b/packages/aws-sdk-signers/src/aws_sdk_signers/interfaces/io.py index 491d21a50..ea0c84496 100644 --- a/packages/aws-sdk-signers/src/aws_sdk_signers/interfaces/io.py +++ b/packages/aws-sdk-signers/src/aws_sdk_signers/interfaces/io.py @@ -25,3 +25,12 @@ class Seekable(Protocol): def seek(self, offset: int, whence: int = 0, /) -> int: ... def tell(self) -> int: ... + + +@runtime_checkable +class AsyncSeekable(Protocol): + """An async file-like object with seek and tell implemented.""" + + async def seek(self, offset: int, whence: int = 0, /) -> int: ... + + def tell(self) -> int: ... diff --git a/packages/aws-sdk-signers/src/aws_sdk_signers/signers.py b/packages/aws-sdk-signers/src/aws_sdk_signers/signers.py index 8e96d04ea..279528ea4 100644 --- a/packages/aws-sdk-signers/src/aws_sdk_signers/signers.py +++ b/packages/aws-sdk-signers/src/aws_sdk_signers/signers.py @@ -5,13 +5,14 @@ import hmac import io import warnings +from asyncio import iscoroutinefunction from collections.abc import AsyncIterable, Iterable from copy import deepcopy from hashlib import sha256 from typing import Required, TypedDict from urllib.parse import parse_qsl, quote -from .interfaces.io import Seekable +from .interfaces.io import AsyncSeekable, Seekable from ._http import URI, AWSRequest, Field from ._identity import AWSCredentialIdentity from ._io import AsyncBytesReader @@ -757,11 +758,11 @@ async def _compute_payload_hash( ) checksum = sha256() - if isinstance(body, Seekable): + if isinstance(body, AsyncSeekable) and iscoroutinefunction(body.seek): position = body.tell() async for chunk in body: checksum.update(chunk) - body.seek(position) + await body.seek(position) else: buffer = io.BytesIO() async for chunk in body: