Skip to content

Replace requests with httpx and make ClientProtocol async #28

Description

@david-debest

Parent

#27

What to build

Migrate the HTTP layer from requests to httpx and make the entire ClientProtocol async. This is the foundational slice — everything else depends on it.

Client protocol: Every method in ClientProtocol becomes async def (coroutine). The protocol remains a single interface — no sync/async split.

Real client: Client switches from requests to httpx.AsyncClient. The AsyncClient is created in Client.__init__() (httpx does not require an active event loop at construction time). Add a close() method to both the protocol and the implementation that closes the underlying httpx.AsyncClient.

Test client: TestClient methods become async def to satisfy the updated protocol. Replace collections.deque for _incoming_calls with asyncio.Queue. poll_ki_call() uses await self._incoming_calls.get() so it blocks (async) until a request is enqueued — simulating the SC long-polling behavior. Test helper methods (enqueue_handle_request, mock_result_binding_set, enqueue_exit) stay synchronous, using queue.put_nowait().

Dependencies: Replace requests with httpx in pyproject.toml. Add pytest-asyncio as a dev dependency.

Tests: Migrate ALL existing tests to async def + @pytest.mark.asyncio so the test suite passes against the new async protocol. Existing test patterns (TestClient injection, enqueue/mock/assert) should be preserved — only the async wrapping changes.

Acceptance criteria

  • requests removed from pyproject.toml dependencies; httpx added
  • pytest-asyncio added as dev dependency
  • All ClientProtocol methods are async def
  • Client uses httpx.AsyncClient internally for all HTTP calls
  • Client has a close() method that closes the httpx.AsyncClient
  • TestClient implements the async ClientProtocol
  • TestClient.poll_ki_call() uses asyncio.Queue and blocks until items are available
  • TestClient test helpers (enqueue_handle_request, mock_result_binding_set, enqueue_exit) remain synchronous
  • All existing tests migrated to async and passing
  • uv run ruff check . passes

Blocked by

None — can start immediately

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentIssue is ready for agent implementation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions