[PR #26726] feat: migrate Python SDK to httpx with async/await support #31532

Closed
opened 2026-02-21 20:49:38 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/langgenius/dify/pull/26726

State: closed
Merged: Yes


Summary

This PR migrates the Dify Python SDK from the legacy requests library to the modern httpx library, adding full async/await support while maintaining 100% backward compatibility.

Changes

Core Migration

  • Migrated from requests to httpx: Replaced all HTTP client code with httpx for better performance and modern features
  • Added async/await support: Complete async client implementation with AsyncDifyClient and all async client classes
  • Context manager support: Added __enter__/__exit__ and __aenter__/__aexit__ for proper resource management
  • Connection pooling: Leverages httpx's built-in connection pooling for better performance

New Async Clients

  • AsyncDifyClient - Base async client with httpx.AsyncClient
  • AsyncChatClient - Async chat completion API
  • AsyncCompletionClient - Async text completion API
  • AsyncWorkflowClient - Async workflow execution API
  • AsyncWorkspaceClient - Async workspace management API
  • AsyncKnowledgeBaseClient - Async knowledge base operations API

Breaking Changes

  • Python requirement: Bumped from >=3.6 to >=3.10 (httpx requirement)
  • Dependency: Changed from requests to httpx>=0.27.0

Backward Compatibility

  • All existing sync APIs remain unchanged
  • httpx.Response is fully compatible with requests.Response for common methods (.json(), .text, .content, .status_code, .headers)
  • All 64 public methods available in both sync and async versions

API Completeness

100% API Parity

  • Sync clients: 64 public methods
  • Async clients: 64 public methods
  • All sync methods have corresponding async equivalents

Usage Examples

Synchronous (backward compatible)

from dify_client import ChatClient

# Context manager (recommended)
with ChatClient(api_key="your-key") as client:
    response = client.create_chat_message(
        inputs={}, query="Hello", user="user-123"
    )
    print(response.json())

# Traditional usage (still works)
client = ChatClient(api_key="your-key")
response = client.create_chat_message(...)
client.close()  # Remember to close

Asynchronous (new)

import asyncio
from dify_client import AsyncChatClient

async def main():
    async with AsyncChatClient(api_key="your-key") as client:
        response = await client.create_chat_message(
            inputs={}, query="Hello", user="user-123"
        )
        print(response.json())

asyncio.run(main())

Testing

  • All existing tests pass with httpx (backward compatible)
  • Verified API method parity (64/64 methods in both sync/async)
  • Confirmed httpx.Response compatibility with requests.Response

Migration Guide

For existing users, no code changes are required unless you want to use async features:

  1. Sync users: Code works as-is, just update the dependency
  2. Async users: Import from dify_client.async_client and use await with async methods
  3. Best practice: Use context managers (with/async with) for automatic resource cleanup

Performance Benefits

  • Connection pooling by default
  • HTTP/2 support (when available)
  • Better timeout control (separate connect/read timeouts)
  • Async support for high-concurrency scenarios

Related Issues

Part of Python SDK modernization effort.

**Original Pull Request:** https://github.com/langgenius/dify/pull/26726 **State:** closed **Merged:** Yes --- ## Summary This PR migrates the Dify Python SDK from the legacy `requests` library to the modern `httpx` library, adding full async/await support while maintaining 100% backward compatibility. ## Changes ### Core Migration - **Migrated from `requests` to `httpx`**: Replaced all HTTP client code with httpx for better performance and modern features - **Added async/await support**: Complete async client implementation with `AsyncDifyClient` and all async client classes - **Context manager support**: Added `__enter__`/`__exit__` and `__aenter__`/`__aexit__` for proper resource management - **Connection pooling**: Leverages httpx's built-in connection pooling for better performance ### New Async Clients - `AsyncDifyClient` - Base async client with httpx.AsyncClient - `AsyncChatClient` - Async chat completion API - `AsyncCompletionClient` - Async text completion API - `AsyncWorkflowClient` - Async workflow execution API - `AsyncWorkspaceClient` - Async workspace management API - `AsyncKnowledgeBaseClient` - Async knowledge base operations API ### Breaking Changes - **Python requirement**: Bumped from `>=3.6` to `>=3.10` (httpx requirement) - **Dependency**: Changed from `requests` to `httpx>=0.27.0` ### Backward Compatibility - All existing sync APIs remain unchanged - `httpx.Response` is fully compatible with `requests.Response` for common methods (`.json()`, `.text`, `.content`, `.status_code`, `.headers`) - All 64 public methods available in both sync and async versions ## API Completeness ✅ **100% API Parity** - Sync clients: 64 public methods - Async clients: 64 public methods - All sync methods have corresponding async equivalents ## Usage Examples ### Synchronous (backward compatible) ```python from dify_client import ChatClient # Context manager (recommended) with ChatClient(api_key="your-key") as client: response = client.create_chat_message( inputs={}, query="Hello", user="user-123" ) print(response.json()) # Traditional usage (still works) client = ChatClient(api_key="your-key") response = client.create_chat_message(...) client.close() # Remember to close ``` ### Asynchronous (new) ```python import asyncio from dify_client import AsyncChatClient async def main(): async with AsyncChatClient(api_key="your-key") as client: response = await client.create_chat_message( inputs={}, query="Hello", user="user-123" ) print(response.json()) asyncio.run(main()) ``` ## Testing - ✅ All existing tests pass with httpx (backward compatible) - ✅ Verified API method parity (64/64 methods in both sync/async) - ✅ Confirmed httpx.Response compatibility with requests.Response ## Migration Guide For existing users, no code changes are required unless you want to use async features: 1. **Sync users**: Code works as-is, just update the dependency 2. **Async users**: Import from `dify_client.async_client` and use `await` with async methods 3. **Best practice**: Use context managers (`with`/`async with`) for automatic resource cleanup ## Performance Benefits - ✅ Connection pooling by default - ✅ HTTP/2 support (when available) - ✅ Better timeout control (separate connect/read timeouts) - ✅ Async support for high-concurrency scenarios ## Related Issues Part of Python SDK modernization effort.
yindo added the pull-request label 2026-02-21 20:49:38 -05:00
yindo closed this issue 2026-02-21 20:49:39 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langgenius/dify#31532