Skip to content

fix: align OpenAI http_client with SDK httpx#7773

Open
bugkeep wants to merge 3 commits intoAstrBotDevs:masterfrom
bugkeep:bugfix/7770-openai-http-client
Open

fix: align OpenAI http_client with SDK httpx#7773
bugkeep wants to merge 3 commits intoAstrBotDevs:masterfrom
bugkeep:bugfix/7770-openai-http-client

Conversation

@bugkeep
Copy link
Copy Markdown
Contributor

@bugkeep bugkeep commented Apr 24, 2026

Fixes #7770.

The OpenAI SDK validates http_client with isinstance(..., httpx.AsyncClient) using the SDK's own httpx import. In some packaged/Docker environments multiple httpx installations can be present, causing this check to fail even when passing a real AsyncClient instance.

This change lets create_proxy_client build the client from a caller-provided httpx module, and updates the OpenAI provider to construct the client using openai._base_client.httpx (falling back to the regular httpx import if unavailable).

Tests:

  • uv run ruff format .
  • uv run ruff check .
  • uv run pytest -q tests/test_openai_source.py::test_create_http_client_uses_openai_httpx_module

Summary by Sourcery

Align OpenAI HTTP client construction with the OpenAI SDK’s own httpx import to avoid type mismatches in certain environments.

Bug Fixes:

  • Ensure the OpenAI provider’s HTTP client is built using the OpenAI SDK’s internal httpx module to prevent isinstance checks from failing when multiple httpx installations exist.

Enhancements:

  • Allow create_proxy_client to accept an injectable httpx module so callers can control which httpx implementation is used.

Tests:

  • Add a test verifying that the OpenAI provider passes the OpenAI SDK’s httpx module into create_proxy_client when creating its HTTP client.

@auto-assign auto-assign Bot requested review from Fridemn and advent259141 April 24, 2026 12:52
@dosubot dosubot Bot added size:S This PR changes 10-29 lines, ignoring generated files. area:provider The bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner. labels Apr 24, 2026
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • In _create_http_client, consider catching a narrower exception (e.g., ImportError and AttributeError) instead of a bare Exception when importing openai._base_client and accessing httpx to avoid masking unrelated errors.
  • create_proxy_client now accepts a generic httpx_module: Any but still advertises httpx.AsyncClient as its return type; consider updating the type hints (e.g., to a protocol or a type variable tied to httpx_module.AsyncClient) so that callers and static analysis tools get an accurate client type.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `_create_http_client`, consider catching a narrower exception (e.g., `ImportError` and `AttributeError`) instead of a bare `Exception` when importing `openai._base_client` and accessing `httpx` to avoid masking unrelated errors.
- `create_proxy_client` now accepts a generic `httpx_module: Any` but still advertises `httpx.AsyncClient` as its return type; consider updating the type hints (e.g., to a protocol or a type variable tied to `httpx_module.AsyncClient`) so that callers and static analysis tools get an accurate client type.

## Individual Comments

### Comment 1
<location path="astrbot/core/provider/sources/openai_source.py" line_range="445-450" />
<code_context>
+            from openai import _base_client as openai_base_client
+
+            httpx_module = openai_base_client.httpx
+        except Exception:
+            httpx_module = httpx
+        return create_proxy_client("OpenAI", proxy, httpx_module=httpx_module)
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Catch narrower exceptions instead of a blanket `Exception` when importing the OpenAI httpx module.

This block only wraps the import of `openai._base_client` and access to `openai_base_client.httpx`. Catching a blanket `Exception` can hide real runtime errors in the OpenAI SDK and cause an unexpected fallback to the global `httpx`. Please narrow this to `ImportError` and `AttributeError`, which are the expected failures when the module or attribute is missing.

```suggestion
        try:
            from openai import _base_client as openai_base_client

            httpx_module = openai_base_client.httpx
        except (ImportError, AttributeError):
            httpx_module = httpx
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread astrbot/core/provider/sources/openai_source.py Outdated
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the OpenAI source provider to use the httpx module from the openai SDK when creating HTTP clients, ensuring compatibility with the SDK's internal type checks. The create_proxy_client utility has been generalized to support an optional httpx_module argument, and a unit test was added to verify the implementation. A review comment suggests refining the exception handling during the openai module import to be more specific and to remove redundant variable assignments.

Comment on lines +444 to +450
httpx_module: Any = httpx
try:
from openai import _base_client as openai_base_client

httpx_module = openai_base_client.httpx
except Exception:
httpx_module = httpx
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The assignment httpx_module = httpx in the except block is redundant because httpx_module is already initialized to httpx on line 444. Additionally, catching a broad Exception is generally discouraged; using getattr with a default value and catching only ImportError results in a cleaner and more robust implementation.

Suggested change
httpx_module: Any = httpx
try:
from openai import _base_client as openai_base_client
httpx_module = openai_base_client.httpx
except Exception:
httpx_module = httpx
httpx_module = httpx
try:
from openai import _base_client as openai_base_client
httpx_module = getattr(openai_base_client, "httpx", httpx)
except ImportError:
pass
References
  1. PEP 8: Programming Recommendations - When catching exceptions, mention specific exceptions whenever possible instead of using a bare except: clause. Catching Exception can hide other errors. (link)

@bugkeep bugkeep force-pushed the bugfix/7770-openai-http-client branch from d5f3315 to a0d40f1 Compare April 25, 2026 04:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:provider The bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner. size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 獲取模型列表失敗: Invalid http_client argument (Missing parentheses on httpx.AsyncClient)

1 participant