Skip to content

refactor(llm): extract shared http_client sync/async split helper#567

Open
matteomedioli wants to merge 1 commit into
matteo/anthropic-kwargs-bugfixfrom
matteo/split-http-client-helper
Open

refactor(llm): extract shared http_client sync/async split helper#567
matteomedioli wants to merge 1 commit into
matteo/anthropic-kwargs-bugfixfrom
matteo/split-http-client-helper

Conversation

@matteomedioli

@matteomedioli matteomedioli commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Description

Stacked on top of #565. While working on that fix, we noticed the http_client sync/async type-routing logic — pop http_client from kwargs, route an httpx.Client to the sync SDK client, an httpx.AsyncClient to the async one, warn and drop anything else — is copy-pasted verbatim three times: AnthropicLLM.__init__, OpenAILLM.__init__, and AzureOpenAILLM.__init__.

Since BaseAnthropicLLM/BaseOpenAILLM don't do any SDK client construction themselves (by design — that's left entirely to subclasses), any future subclass built to reach a custom endpoint would otherwise become a 4th/5th copy of this exact logic. Extracting it into one shared helper now means new subclasses inherit the fix instead of copying it.

Changes:

  • Added neo4j_graphrag.llm.utils.split_http_client_kwargs(kwargs) -> (sync_kwargs, async_kwargs), a single implementation of the pop/route/warn logic.
  • AnthropicLLM.__init__, OpenAILLM.__init__, and AzureOpenAILLM.__init__ now all call this helper instead of repeating the isinstance checks and warning inline.
  • Removed the now-unused httpx/warnings imports from anthropic_llm.py/openai_llm.py where they were only present for this logic.
  • Added direct unit tests for split_http_client_kwargs in tests/unit/llm/test_llm_utils.py (no-client passthrough, sync routing, async routing, invalid-type warn-and-drop, and non-mutation of the caller's input dict) — previously this logic only had indirect coverage through each provider class's own constructor tests.

Pure refactor: no behavior change for any existing caller.

Type of Change

  • New feature
  • Bug fix
  • Breaking change
  • Documentation update
  • Project configuration change

(Refactor, no behavior change — none of the boxes above are an exact fit; flagging explicitly since the template has no "refactor" option.)

Complexity

Complexity: Low

How Has This Been Tested?

  • Unit tests
  • E2E tests
  • Manual tests

New tests/unit/llm/test_llm_utils.py cases directly exercise split_http_client_kwargs: no http_client passed, httpx.Client routed to sync only, httpx.AsyncClient routed to async only, invalid type warns and is dropped from both, input dict is not mutated. Full existing tests/unit/llm/ suite passes unchanged. mypy/ruff check/ruff format --check all clean.

Checklist

The following requirements should have been met (depending on the changes in the branch):

  • Documentation has been updated
  • Unit tests have been updated
  • E2E tests have been updated
  • Examples have been updated
  • New files have copyright header
  • CLA (https://neo4j.com/developer/cla/) has been signed
  • CHANGELOG.md updated if appropriate

AnthropicLLM, OpenAILLM, and AzureOpenAILLM each carried an identical
~10-line dance to route an httpx.Client/httpx.AsyncClient http_client
kwarg to the matching SDK client, warning and dropping it otherwise.
Factored into one split_http_client_kwargs helper in llm/utils.py, used
by all three, so any future subclass needing a custom endpoint doesn't
need a fourth/fifth copy of the same logic. Pure refactor, no behavior
change.
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.

1 participant