Internalize http client management to decouple consumers from httpx #14

Closed
opened 2026-06-08 03:16:13 +00:00 by coding-agent-marvin8 · 1 comment
coding-agent-marvin8 commented 2026-06-08 03:16:13 +00:00 (Migrated from codeberg.org)

Currently consumers must construct and pass an httpx.AsyncClient to APClient.
This leaks the HTTP implementation into longwei's public API, making any future
library change (httpx → httpx2) a consumer-breaking event.

Move client creation inside APClient. Consumers pass configuration
(timeout, http2) not a client object. APClient becomes an optional async
context manager for clean resource management.

This is the implementation of the direction noted in #6.

Currently consumers must construct and pass an httpx.AsyncClient to APClient. This leaks the HTTP implementation into longwei's public API, making any future library change (httpx → httpx2) a consumer-breaking event. Move client creation inside APClient. Consumers pass configuration (timeout, http2) not a client object. APClient becomes an optional async context manager for clean resource management. This is the implementation of the direction noted in #6.
coding-agent-marvin8 commented 2026-06-08 03:16:32 +00:00 (Migrated from codeberg.org)

Implements the direction recorded in #6.

Research findings:

  • All tests create AsyncClient() with zero args inline per test; no conftest.py; pytest-httpx intercepts at transport level globally, so internal client creation does not break mocking.
  • _mixin_request_helpers._request() passes timeout=self.timeout per request (line 92); the consumer's client-level timeout is already overridden. Only http2 needs to be set at construction time.
  • Known consumers: feed2fedi and zhongli share one AsyncClient between longwei and their own HTTP calls (image downloads, ReblogService). They will need a separate client for their own use after this change. taibai and fenliu dedicate the client to longwei — trivially compatible.

Plan of attack:

  1. Write failing tests (TDD RED) for: no-client constructor, http2 param, close(), aenter/aexit.
  2. Modify APClient.init and APClient.create() — remove client param, add http2, create self.client = AsyncClient(http2=http2) internally.
  3. Add close() + context manager methods.
  4. Update all tests — remove client = AsyncClient() and client=client arg.
  5. Update docs.
Implements the direction recorded in #6. Research findings: - All tests create AsyncClient() with zero args inline per test; no conftest.py; pytest-httpx intercepts at transport level globally, so internal client creation does not break mocking. - _mixin_request_helpers._request() passes timeout=self.timeout per request (line 92); the consumer's client-level timeout is already overridden. Only http2 needs to be set at construction time. - Known consumers: feed2fedi and zhongli share one AsyncClient between longwei and their own HTTP calls (image downloads, ReblogService). They will need a separate client for their own use after this change. taibai and fenliu dedicate the client to longwei — trivially compatible. Plan of attack: 1. Write failing tests (TDD RED) for: no-client constructor, http2 param, close(), __aenter__/__aexit__. 2. Modify APClient.__init__ and APClient.create() — remove client param, add http2, create self.client = AsyncClient(http2=http2) internally. 3. Add close() + context manager methods. 4. Update all tests — remove client = AsyncClient() and client=client arg. 5. Update docs.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
marvin8/longwei#14
No description provided.