mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-09 15:19:10 +02:00
60 lines
1.8 KiB
Python
60 lines
1.8 KiB
Python
"""FastMCP must import without the legacy httpx/httpcore packages.
|
|
|
|
FastMCP depends on httpx2 exclusively; legacy httpx remains importable in the
|
|
test environment only as a transitive dependency of optional LLM SDKs. That
|
|
masks clean-install regressions: an accidental ``import httpx`` (directly or
|
|
via a third-party integration such as authlib's httpx client) passes CI but
|
|
breaks any install without those extras.
|
|
|
|
This test simulates the clean install by running a subprocess that blocks
|
|
legacy httpx imports at the meta-path level, then imports the modules that
|
|
have historically regressed. The defensive user-compat shim in
|
|
``fastmcp.server.server`` catches ImportError by design and must keep working
|
|
when httpx is absent.
|
|
"""
|
|
|
|
import subprocess
|
|
import sys
|
|
import textwrap
|
|
|
|
import pytest
|
|
|
|
_BLOCKER_SCRIPT = textwrap.dedent(
|
|
"""
|
|
import sys
|
|
|
|
class _LegacyHttpxBlocker:
|
|
blocked = {"httpx", "httpcore", "pytest_httpx"}
|
|
|
|
def find_spec(self, name, path=None, target=None):
|
|
if name.split(".")[0] in self.blocked:
|
|
raise ImportError(
|
|
f"{name} is blocked: FastMCP must not require legacy httpx"
|
|
)
|
|
return None
|
|
|
|
sys.meta_path.insert(0, _LegacyHttpxBlocker())
|
|
|
|
import fastmcp.cli.apps_dev
|
|
import fastmcp.client.client
|
|
import fastmcp.server.auth.oauth_proxy.proxy
|
|
import fastmcp.server.server
|
|
import fastmcp.utilities.openapi.director
|
|
|
|
print("OK")
|
|
"""
|
|
)
|
|
|
|
|
|
@pytest.mark.subprocess_heavy
|
|
def test_fastmcp_imports_without_legacy_httpx():
|
|
result = subprocess.run(
|
|
[sys.executable, "-c", _BLOCKER_SCRIPT],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=30,
|
|
)
|
|
assert result.returncode == 0, (
|
|
f"Import failed with legacy httpx blocked:\n{result.stderr}"
|
|
)
|
|
assert "OK" in result.stdout
|