Skip to content

Commit

Permalink
feat: Add sentinel value to allow per-request infinite timeout in API…
Browse files Browse the repository at this point in the history
… queries (#900)

Co-authored-by: Joongi Kim <[email protected]>
  • Loading branch information
fregataa and achimnol authored Sep 23, 2024
1 parent 5148c63 commit a0a30c2
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGES/900.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Introduce a sentinel value to `_do_query()` and its friend methods to allow configuring per-request infinite timeouts instead of always falling back to the session-level default timeout when setting the timeout argument to `None`, and add the timeout arguments to image-related API wrappers
14 changes: 9 additions & 5 deletions aiodocker/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from .swarm import DockerSwarm
from .system import DockerSystem
from .tasks import DockerTasks
from .types import SENTINEL, Sentinel
from .utils import httpize, parse_result
from .volumes import DockerVolume, DockerVolumes

Expand Down Expand Up @@ -218,7 +219,7 @@ async def _query(
params: Optional[JSONObject] = None,
data: Optional[Any] = None,
headers=None,
timeout=None,
timeout: Union[float, aiohttp.ClientTimeout, Sentinel, None] = SENTINEL,
chunked=None,
read_until_eof: bool = True,
versioned_api: bool = True,
Expand Down Expand Up @@ -248,7 +249,7 @@ async def _do_query(
params: Optional[JSONObject],
data: Any,
headers,
timeout,
timeout: Union[float, aiohttp.ClientTimeout, Sentinel, None] = SENTINEL,
chunked,
read_until_eof: bool,
versioned_api: bool,
Expand All @@ -260,8 +261,11 @@ async def _do_query(
headers = CIMultiDict(headers)
if "Content-Type" not in headers:
headers["Content-Type"] = "application/json"
if timeout is None:
if timeout is SENTINEL:
timeout = self.session.timeout
assert not isinstance(timeout, Sentinel)
if not isinstance(timeout, aiohttp.ClientTimeout):
timeout = aiohttp.ClientTimeout(timeout)
try:
real_params = httpize(params)
response = await self.session.request(
Expand Down Expand Up @@ -304,7 +308,7 @@ async def _query_json(
params: Optional[JSONObject] = None,
data: Optional[Any] = None,
headers=None,
timeout=None,
timeout: Union[float, aiohttp.ClientTimeout, Sentinel, None] = SENTINEL,
read_until_eof: bool = True,
versioned_api: bool = True,
) -> Any:
Expand Down Expand Up @@ -337,7 +341,7 @@ def _query_chunked_post(
params: Optional[JSONObject] = None,
data: Optional[Any] = None,
headers=None,
timeout=None,
timeout: Union[float, aiohttp.ClientTimeout, Sentinel, None] = SENTINEL,
read_until_eof: bool = True,
versioned_api: bool = True,
) -> AbstractAsyncContextManager[aiohttp.ClientResponse]:
Expand Down
13 changes: 11 additions & 2 deletions aiodocker/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
)

from .jsonstream import json_stream_list, json_stream_stream
from .types import JSONObject, SupportsRead
from .types import SENTINEL, JSONObject, Sentinel, SupportsRead
from .utils import clean_map, compose_auth_header


Expand Down Expand Up @@ -69,6 +69,7 @@ async def pull(
repo: Optional[str] = None,
platform: Optional[str] = None,
stream: Literal[False] = False,
timeout: Union[float, Sentinel, None] = SENTINEL,
) -> Dict[str, Any]: ...

@overload
Expand All @@ -81,6 +82,7 @@ def pull(
repo: Optional[str] = None,
platform: Optional[str] = None,
stream: Literal[True],
timeout: Union[float, Sentinel, None] = SENTINEL,
) -> AsyncIterator[Dict[str, Any]]: ...

def pull(
Expand All @@ -92,6 +94,7 @@ def pull(
repo: Optional[str] = None,
platform: Optional[str] = None,
stream: bool = False,
timeout: Union[float, Sentinel, None] = SENTINEL,
) -> Any:
"""
Similar to `docker pull`, pull an image locally
Expand Down Expand Up @@ -122,7 +125,13 @@ def pull(
)
# TODO: assert registry == repo?
headers["X-Registry-Auth"] = compose_auth_header(auth, registry)
cm = self.docker._query("images/create", "POST", params=params, headers=headers)
cm = self.docker._query(
"images/create",
"POST",
params=params,
headers=headers,
timeout=timeout,
)
return self._handle_response(cm, stream)

def _handle_response(self, cm, stream):
Expand Down
8 changes: 8 additions & 0 deletions aiodocker/types.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import enum
import sys
from typing import (
TYPE_CHECKING,
Expand Down Expand Up @@ -45,3 +46,10 @@ def read(self, length: int = ..., /) -> _T_co: ...
class PortInfo(TypedDict):
HostIp: str
HostPort: str


class Sentinel(enum.Enum):
TOKEN = enum.auto()


SENTINEL = Sentinel.TOKEN

0 comments on commit a0a30c2

Please sign in to comment.