mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-26 17:42:24 +02:00
feat(sdk-py): add return_minimal to threads update (#7704)
Adds a first-class `return_minimal` option to the Python `threads.update` clients. When enabled, the SDK sends `Prefer: return=minimal` and returns `None` for the 204 response. Covers both async and sync clients with focused tests.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncIterator, Mapping, Sequence
|
||||
from typing import Any
|
||||
from typing import Any, Literal, overload
|
||||
|
||||
from langgraph_sdk._async.http import HttpClient
|
||||
from langgraph_sdk.schema import (
|
||||
@@ -172,15 +172,52 @@ class ThreadsClient:
|
||||
"/threads", json=payload, headers=headers, params=params
|
||||
)
|
||||
|
||||
@overload
|
||||
async def update(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
metadata: Mapping[str, Any],
|
||||
ttl: int | Mapping[str, Any] | None = None,
|
||||
return_minimal: Literal[False] = False,
|
||||
headers: Mapping[str, str] | None = None,
|
||||
params: QueryParamTypes | None = None,
|
||||
) -> Thread:
|
||||
) -> Thread: ...
|
||||
|
||||
@overload
|
||||
async def update(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
metadata: Mapping[str, Any],
|
||||
ttl: int | Mapping[str, Any] | None = None,
|
||||
return_minimal: Literal[True],
|
||||
headers: Mapping[str, str] | None = None,
|
||||
params: QueryParamTypes | None = None,
|
||||
) -> None: ...
|
||||
|
||||
@overload
|
||||
async def update(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
metadata: Mapping[str, Any],
|
||||
ttl: int | Mapping[str, Any] | None = None,
|
||||
return_minimal: bool,
|
||||
headers: Mapping[str, str] | None = None,
|
||||
params: QueryParamTypes | None = None,
|
||||
) -> Thread | None: ...
|
||||
|
||||
async def update(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
metadata: Mapping[str, Any],
|
||||
ttl: int | Mapping[str, Any] | None = None,
|
||||
return_minimal: bool = False,
|
||||
headers: Mapping[str, str] | None = None,
|
||||
params: QueryParamTypes | None = None,
|
||||
) -> Thread | None:
|
||||
"""Update a thread.
|
||||
|
||||
Args:
|
||||
@@ -189,11 +226,12 @@ class ThreadsClient:
|
||||
ttl: Optional time-to-live in minutes for the thread. You can pass an
|
||||
integer (minutes) or a mapping with keys `ttl` and optional
|
||||
`strategy` (defaults to "delete").
|
||||
return_minimal: If `True`, request a 204 response with no body.
|
||||
headers: Optional custom headers to include with the request.
|
||||
params: Optional query parameters to include with the request.
|
||||
|
||||
Returns:
|
||||
The created thread.
|
||||
The updated thread, or `None` when `return_minimal=True`.
|
||||
|
||||
???+ example "Example Usage"
|
||||
|
||||
@@ -212,10 +250,13 @@ class ThreadsClient:
|
||||
payload["ttl"] = {"ttl": ttl, "strategy": "delete"}
|
||||
else:
|
||||
payload["ttl"] = ttl
|
||||
request_headers = dict(headers or {})
|
||||
if return_minimal:
|
||||
request_headers["Prefer"] = "return=minimal"
|
||||
return await self.http.patch(
|
||||
f"/threads/{thread_id}",
|
||||
json=payload,
|
||||
headers=headers,
|
||||
headers=request_headers or None,
|
||||
params=params,
|
||||
)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Iterator, Mapping, Sequence
|
||||
from typing import Any
|
||||
from typing import Any, Literal, overload
|
||||
|
||||
from langgraph_sdk._sync.http import SyncHttpClient
|
||||
from langgraph_sdk.schema import (
|
||||
@@ -168,15 +168,52 @@ class SyncThreadsClient:
|
||||
|
||||
return self.http.post("/threads", json=payload, headers=headers, params=params)
|
||||
|
||||
@overload
|
||||
def update(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
metadata: Mapping[str, Any],
|
||||
ttl: int | Mapping[str, Any] | None = None,
|
||||
return_minimal: Literal[False] = False,
|
||||
headers: Mapping[str, str] | None = None,
|
||||
params: QueryParamTypes | None = None,
|
||||
) -> Thread:
|
||||
) -> Thread: ...
|
||||
|
||||
@overload
|
||||
def update(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
metadata: Mapping[str, Any],
|
||||
ttl: int | Mapping[str, Any] | None = None,
|
||||
return_minimal: Literal[True],
|
||||
headers: Mapping[str, str] | None = None,
|
||||
params: QueryParamTypes | None = None,
|
||||
) -> None: ...
|
||||
|
||||
@overload
|
||||
def update(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
metadata: Mapping[str, Any],
|
||||
ttl: int | Mapping[str, Any] | None = None,
|
||||
return_minimal: bool,
|
||||
headers: Mapping[str, str] | None = None,
|
||||
params: QueryParamTypes | None = None,
|
||||
) -> Thread | None: ...
|
||||
|
||||
def update(
|
||||
self,
|
||||
thread_id: str,
|
||||
*,
|
||||
metadata: Mapping[str, Any],
|
||||
ttl: int | Mapping[str, Any] | None = None,
|
||||
return_minimal: bool = False,
|
||||
headers: Mapping[str, str] | None = None,
|
||||
params: QueryParamTypes | None = None,
|
||||
) -> Thread | None:
|
||||
"""Update a thread.
|
||||
|
||||
Args:
|
||||
@@ -185,11 +222,12 @@ class SyncThreadsClient:
|
||||
ttl: Optional time-to-live in minutes for the thread. You can pass an
|
||||
integer (minutes) or a mapping with keys `ttl` and optional
|
||||
`strategy` (defaults to "delete").
|
||||
return_minimal: If `True`, request a 204 response with no body.
|
||||
headers: Optional custom headers to include with the request.
|
||||
params: Optional query parameters to include with the request.
|
||||
|
||||
Returns:
|
||||
The created `Thread`.
|
||||
The updated `Thread`, or `None` when `return_minimal=True`.
|
||||
|
||||
???+ example "Example Usage"
|
||||
|
||||
@@ -208,10 +246,13 @@ class SyncThreadsClient:
|
||||
payload["ttl"] = {"ttl": ttl, "strategy": "delete"}
|
||||
else:
|
||||
payload["ttl"] = ttl
|
||||
request_headers = dict(headers or {})
|
||||
if return_minimal:
|
||||
request_headers["Prefer"] = "return=minimal"
|
||||
return self.http.patch(
|
||||
f"/threads/{thread_id}",
|
||||
json=payload,
|
||||
headers=headers,
|
||||
headers=request_headers or None,
|
||||
params=params,
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
from langgraph_sdk.client import (
|
||||
HttpClient,
|
||||
SyncHttpClient,
|
||||
SyncThreadsClient,
|
||||
ThreadsClient,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_async_threads_update_return_minimal():
|
||||
async def handler(request: httpx.Request) -> httpx.Response:
|
||||
assert request.method == "PATCH"
|
||||
assert request.url.path == "/threads/thread_123"
|
||||
assert request.headers["Prefer"] == "return=minimal"
|
||||
assert json.loads(request.content) == {"metadata": {"foo": "bar"}}
|
||||
return httpx.Response(204)
|
||||
|
||||
transport = httpx.MockTransport(handler)
|
||||
async with httpx.AsyncClient(
|
||||
transport=transport, base_url="https://example.com"
|
||||
) as client:
|
||||
http_client = HttpClient(client)
|
||||
threads_client = ThreadsClient(http_client)
|
||||
result = await threads_client.update(
|
||||
"thread_123",
|
||||
metadata={"foo": "bar"},
|
||||
return_minimal=True,
|
||||
)
|
||||
|
||||
assert result is None
|
||||
|
||||
|
||||
def test_sync_threads_update_return_minimal():
|
||||
def handler(request: httpx.Request) -> httpx.Response:
|
||||
assert request.method == "PATCH"
|
||||
assert request.url.path == "/threads/thread_123"
|
||||
assert request.headers["Prefer"] == "return=minimal"
|
||||
assert json.loads(request.content) == {"metadata": {"foo": "bar"}}
|
||||
return httpx.Response(204)
|
||||
|
||||
transport = httpx.MockTransport(handler)
|
||||
with httpx.Client(transport=transport, base_url="https://example.com") as client:
|
||||
http_client = SyncHttpClient(client)
|
||||
threads_client = SyncThreadsClient(http_client)
|
||||
result = threads_client.update(
|
||||
"thread_123",
|
||||
metadata={"foo": "bar"},
|
||||
return_minimal=True,
|
||||
)
|
||||
|
||||
assert result is None
|
||||
Reference in New Issue
Block a user