Skip to content

Conversation

@achimnol
Copy link
Member

@achimnol achimnol commented Nov 10, 2025

This PR embraces:

by introducing a common Timeout configuration argument to the Docker instance constructor, which is converted to aiohttp.ClientTimeout internally.

Co-authored-by: Saulius Adamonis <saulius.adamonis@gmx.de>
Co-authored-by: Jonathan Carroll Otsuka <105506+djgoku@users.noreply.github.com>
Co-authored-by: Sanghun Lee <sanghun@lablup.com>

Changes

  • Add aiodocker.types.Timeout to have an independent interface to aiohttp.ClientTimeout.
    • It has to_aiohttp_client_timeout() method to separate from the underlying implementation.
    • But I think it would be better to expose aiohttp.ClientTimeout directly...
  • Make aiodocker.logs.DockerLog and aiodocker.stream.Stream to override total=None, sock_read=None after converting the session-level aiodocker.types.Timeout config to actual aiohttp.ClientTimeout instance via to_aiohttp_client_timeout().
    • Internally it uses attrs.evolve() as aiohttp.ClientTimeout is an immutable (frozen) dataclass. aiohttp also does the same.
    • For backward compatibility, it still accepts and merges the explicit aiohttp.ClientTimeout and/or float values if the method has an optional timeout argument.
  • Clean up, fix, and update missing pieces of the per-module documentation.

Impacts to Existing PRs

Warning

Trying to set a float value (total timeout) to the aiodocker APIs having legacy timeout arguments will now generate an explicit deprecation warning.

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt
  • Add a new news fragment into the changes folder

@codecov
Copy link

codecov bot commented Nov 10, 2025

Codecov Report

❌ Patch coverage is 83.63636% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.54%. Comparing base (490d4b5) to head (67749bd).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
aiodocker/docker.py 83.78% 2 Missing and 4 partials ⚠️
aiodocker/stream.py 60.00% 1 Missing and 1 partial ⚠️
aiodocker/logs.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #983      +/-   ##
==========================================
- Coverage   81.57%   81.54%   -0.03%     
==========================================
  Files          24       24              
  Lines        1422     1447      +25     
  Branches      190      194       +4     
==========================================
+ Hits         1160     1180      +20     
- Misses        186      189       +3     
- Partials       76       78       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- `aiodocker.docker.XXXX` -> `aiodocker.{appropriate-module-name}.XXXX`
- Reorganize too deeply nested headers in individual module pages
- Add missing ToC index refs
@achimnol achimnol changed the title Add timeout support Add timeout support with improved documentation Nov 11, 2025
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 adds timeout support to the aiodocker library by introducing a new Timeout configuration class that can be specified at the Docker client level. The changes standardize timeout handling across the library and deprecate per-API float timeout arguments in favor of using asyncio.timeout() for composable timeouts.

  • Introduces aiodocker.types.Timeout class with connect and total timeout fields
  • Updates the Docker client constructor to accept a timeout parameter
  • Modifies streaming APIs (DockerLog and Stream) to properly handle timeouts by overriding total and sock_read to None
  • Standardizes documentation formatting across all module RST files

Reviewed Changes

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

Show a summary per file
File Description
aiodocker/types.py Adds new Timeout dataclass with conversion to aiohttp.ClientTimeout
aiodocker/docker.py Updates Docker client to accept and use Timeout config, adds deprecation warning for float timeouts
aiodocker/stream.py Updates Stream to use client-level timeout with proper overrides for streaming
aiodocker/logs.py Updates DockerLog to use client-level timeout with proper overrides for streaming
aiodocker/containers.py Adds deprecation warning suppression for wait() API
aiodocker/utils.py Adds httpize() overloads for CIMultiDict support
docs/*.rst Standardizes documentation formatting and fixes module references
CHANGES/983.feature Documents the new timeout feature
CONTRIBUTORS.txt Adds contributors
Comments suppressed due to low confidence (2)

aiodocker/docker.py:480

  • The _query_chunked_post method passes the original headers parameter instead of the processed _headers to _query(). This causes the processed headers (including the default Content-Type) to be ignored. Change headers=headers to headers=_headers on line 480.
            headers=headers,

aiodocker/utils.py:155

  • The httpize() function implementation always returns a plain dict (converted = {}), but the overload signatures and return type annotation indicate it should return CIMultiDict[str] when input is CIMultiDict. The function should preserve the input type and return CIMultiDict when the input is CIMultiDict. Consider checking the input type and constructing the appropriate return type: CIMultiDict(converted) if isinstance(d, CIMultiDict) else converted.
def httpize(
    d: Optional[JSONObject | CIMultiDict[str | int | bool]],
) -> Optional[Mapping[str, str] | CIMultiDict[str | int | bool]]:
    if d is None:
        return None
    converted = {}
    for k, v in d.items():
        if isinstance(v, bool):
            v = "1" if v else "0"
        if not isinstance(v, str):
            v = json.dumps(v)
        converted[k] = v
    return converted

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

@achimnol achimnol requested review from asvetlov and bdraco November 12, 2025 05:19
@achimnol
Copy link
Member Author

@asvetlov @bdraco I followed the concept of separating timeout interface from the underlying aiohttp as discussed in #908 (comment), but still I'm in doutful on doing so because concealing aiohttp seems to have no meaning in aiodocker.

There are already many APIs like DockerContainer.{restart,wait}(), Stream, and Exec.start() which allows passing aiohttp.ClientTimeout directly, and the client constructor also accepts aiohttp.ClientSession and aiohttp.BaseConnector directly.

I'd like to modify the PR to use aiohttp.ClientTimeout directly but overriding the total and sock_read fields when it is used in the streaming/log APIs.

How about your thoughts?

@achimnol
Copy link
Member Author

Since there is no reponse, I'll rewrite it using aiohttp.ClientTimeout for consistency with existing APIs.

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.

2 participants