Skip to content

Replace requests with httpx and make ClientProtocol async #28

@DaviddeBest-TNO

Description

@DaviddeBest-TNO

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

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions