Skip to content

Instantly share code, notes, and snippets.

@odysseus0
Created June 19, 2025 20:16
Show Gist options
  • Save odysseus0/c266b0dfc833f02d2bc0e99aa9cee22c to your computer and use it in GitHub Desktop.
Save odysseus0/c266b0dfc833f02d2bc0e99aa9cee22c to your computer and use it in GitHub Desktop.
Investigation Memo: TikAPI httpx AsyncClient Issue

Investigation Memo: TikAPI httpx AsyncClient Issue

Date: June 19, 2025
Platform: MacOS
Project: TikAPI_MCP
Environment: /Users/tengjizhang/projects/flashbots_x/TikAPI_MCP

Problem Statement

The TikAPI MCP server was experiencing failures when making requests to the TikAPI service, with empty error messages: "An error occurred while requesting TikAPI: ". This prevented the /resources/read and search functionality from working properly.

Investigation Process

1. Initial Setup Verification βœ…

  • Confirmed server was running on port 8000
  • Verified basic endpoints (/resources/list, /tools/list) were functional
  • Checked .env configuration and TikAPI keys were present
  • Confirmed Redis was running properly

2. Root Cause Analysis πŸ”

Direct API Testing

  • curl: βœ… Works perfectly

    curl -H "X-API-KEY: ..." "https://api.tikapi.io/public/video?id=7003402629929913605"
  • urllib: βœ… Works perfectly

  • aiohttp: βœ… Works perfectly

  • httpx.Client (sync): βœ… Works perfectly

  • httpx.AsyncClient (async): ❌ FAILS with ConnectError

Key Discovery

The issue is specifically with httpx's AsyncClient - not TikAPI, not the network, not SSL/TLS, but the async implementation.

# βœ… This works
with httpx.Client() as client:
    response = client.get("https://api.tikapi.io/...")

# ❌ This fails
async with httpx.AsyncClient() as client:
    response = await client.get("https://api.tikapi.io/...")  # ConnectError

3. Technical Analysis

Error Pattern

  • Error Location: httpcore/_backends/anyio.py during TLS handshake
  • Error Type: ConnectError with empty message
  • Consistency: 100% reproducible with AsyncClient, 0% failure with sync Client

Attempted Solutions (All Failed)

  • Different httpx configurations (HTTP/1.1 only, no verification, custom timeouts)
  • Multiple anyio versions (3.7.1, 4.9.0)
  • Different SSL contexts and verification settings
  • Various connection pool settings
  • Alternative event loop (uvloop)

4. Library Version Updates πŸ“¦

Updated all dependencies to latest versions:

  • httpx: 0.27.2 β†’ 0.28.1
  • httpcore: 1.0.9 (latest)
  • anyio: 3.7.1 β†’ 4.9.0
  • aiohttp: 3.12.13 (latest)
  • fastapi: 0.115.13 (latest)
  • pydantic: 2.11.7 (latest)
  • uvicorn: 0.34.3 (latest)

Result: Issue persists even with latest versions.

Findings & Conclusions

Core Issue

This appears to be a rare edge case involving:

  1. TikAPI's specific server configuration
  2. httpx AsyncClient's anyio backend
  3. macOS environment SSL/TLS handling

Evidence Summary

Method Status Notes
curl βœ… Works Standard HTTP client
urllib βœ… Works Python built-in
aiohttp βœ… Works Alternative async HTTP client
httpx.Client (sync) βœ… Works Same library, sync version
httpx.AsyncClient ❌ Fails TLS handshake failure in anyio

Impact Assessment

  • Severity: High (blocks core functionality)
  • Scope: Specific to httpx AsyncClient + TikAPI combination
  • Reproducibility: 100% consistent

Potential Solutions Identified

During investigation, several working alternatives were discovered:

Working HTTP Clients

  1. httpx.Client (synchronous) - Same library, but sync version works perfectly
  2. aiohttp - Alternative async HTTP client, fully functional
  3. urllib - Python built-in library, works when wrapped in asyncio.to_thread

Workaround Approaches

  • Using sync httpx.Client with asyncio.to_thread for async compatibility
  • Replacing httpx.AsyncClient with aiohttp
  • Using urllib in threaded async context

All approaches maintain the async interface while avoiding the httpx AsyncClient issue.

Files Created During Investigation

  • debug_httpx_backends.py - httpx configuration testing
  • debug_async_vs_sync.py - Async vs sync comparison
  • test_aiohttp.py - Alternative HTTP client verification
  • tikapi_urllib_test.py - urllib verification
  • Various other debugging scripts

Investigation Duration: ~2 hours
Confidence Level: High (extensively tested and reproduced)
Risk Level: Low (workaround is reliable and well-tested)

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