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:
Connor Braa
2026-05-04 15:46:13 -07:00
committed by GitHub
parent 125d10052c
commit 60e305596d
3 changed files with 148 additions and 8 deletions
+45 -4
View File
@@ -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,
)
+45 -4
View File
@@ -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,
)
+58
View File
@@ -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