langgraph-sdk 0.2.5__tar.gz → 0.2.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-sdk
3
- Version: 0.2.5
3
+ Version: 0.2.7
4
4
  Summary: SDK for interacting with LangGraph API
5
5
  Project-URL: Repository, https://www.github.com/langchain-ai/langgraph
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  from langgraph_sdk.auth import Auth
2
2
  from langgraph_sdk.client import get_client, get_sync_client
3
3
 
4
- __version__ = "0.2.5"
4
+ __version__ = "0.2.7"
5
5
 
6
6
  __all__ = ["Auth", "get_client", "get_sync_client"]
@@ -400,6 +400,20 @@ class AuthContext(BaseAuthContext):
400
400
  """
401
401
 
402
402
 
403
+ class ThreadTTL(typing.TypedDict, total=False):
404
+ """Time-to-live configuration for a thread.
405
+
406
+ Matches the OpenAPI schema where TTL is represented as an object with
407
+ an optional strategy and a time value in minutes.
408
+ """
409
+
410
+ strategy: typing.Literal["delete"]
411
+ """TTL strategy. Currently only 'delete' is supported."""
412
+
413
+ ttl: int
414
+ """Time-to-live in minutes from now until the thread should be swept."""
415
+
416
+
403
417
  class ThreadsCreate(typing.TypedDict, total=False):
404
418
  """Parameters for creating a new thread.
405
419
 
@@ -422,6 +436,9 @@ class ThreadsCreate(typing.TypedDict, total=False):
422
436
  if_exists: OnConflictBehavior
423
437
  """Behavior when a thread with the same ID already exists."""
424
438
 
439
+ ttl: ThreadTTL
440
+ """Optional TTL configuration for the thread."""
441
+
425
442
 
426
443
  class ThreadsRead(typing.TypedDict, total=False):
427
444
  """Parameters for reading thread state or run information.
@@ -157,27 +157,38 @@ def get_client(
157
157
  headers: Mapping[str, str] | None = None,
158
158
  timeout: TimeoutTypes | None = None,
159
159
  ) -> LangGraphClient:
160
- """Get a LangGraphClient instance.
160
+ """Create and configure a LangGraphClient.
161
+
162
+ The client provides programmatic access to a LangGraph Platform deployment. It supports
163
+ both remote servers and local in-process connections (when running inside a LangGraph server).
161
164
 
162
165
  Args:
163
- url: The URL of the LangGraph API.
164
- api_key: The API key. If not provided, it will be read from the environment.
165
- Precedence:
166
- 1. explicit argument
167
- 2. LANGGRAPH_API_KEY
168
- 3. LANGSMITH_API_KEY
169
- 4. LANGCHAIN_API_KEY
170
- headers: Optional custom headers
171
- timeout: Optional timeout configuration for the HTTP client.
172
- Accepts an httpx.Timeout instance, a float (seconds), or a tuple of timeouts.
173
- Tuple format is (connect, read, write, pool)
174
- If not provided, defaults to connect=5s, read=300s, write=300s, and pool=5s.
166
+ url:
167
+ Base URL of the LangGraph API.
168
+ – If `None`, the client first attempts an in-process connection via ASGI transport.
169
+ If that fails, it falls back to `http://localhost:8123`.
170
+ api_key:
171
+ API key for authentication. If omitted, the client reads from environment
172
+ variables in the following order:
173
+ 1. Function argument
174
+ 2. `LANGGRAPH_API_KEY`
175
+ 3. `LANGSMITH_API_KEY`
176
+ 4. `LANGCHAIN_API_KEY`
177
+ headers:
178
+ Additional HTTP headers to include in requests. Merged with authentication headers.
179
+ timeout:
180
+ HTTP timeout configuration. May be:
181
+ – `httpx.Timeout` instance
182
+ – float (total seconds)
183
+ – tuple `(connect, read, write, pool)` in seconds
184
+ Defaults: connect=5, read=300, write=300, pool=5.
175
185
 
176
186
  Returns:
177
- LangGraphClient: The top-level client for accessing AssistantsClient,
178
- ThreadsClient, RunsClient, and CronClient.
187
+ LangGraphClient:
188
+ A top-level client exposing sub-clients for assistants, threads,
189
+ runs, and cron operations.
179
190
 
180
- ???+ example "Example"
191
+ ???+ example "Connect to a remote server:"
181
192
 
182
193
  ```python
183
194
  from langgraph_sdk import get_client
@@ -188,6 +199,21 @@ def get_client(
188
199
  # example usage: client.<model>.<method_name>()
189
200
  assistants = await client.assistants.get(assistant_id="some_uuid")
190
201
  ```
202
+
203
+ ???+ example "Connect in-process to a running LangGraph server:"
204
+
205
+ ```python
206
+ from langgraph_sdk import get_client
207
+
208
+ client = get_client(url=None)
209
+
210
+ async def my_node(...):
211
+ subagent_result = await client.runs.wait(
212
+ thread_id=None,
213
+ assistant_id="agent",
214
+ input={"messages": [{"role": "user", "content": "Foo"}]},
215
+ )
216
+ ```
191
217
  """
192
218
 
193
219
  transport: httpx.AsyncBaseTransport | None = None
@@ -457,6 +483,8 @@ class HttpClient:
457
483
  sse = decoder.decode(line=line.rstrip(b"\n"))
458
484
  if sse is not None:
459
485
  yield sse
486
+ if sse := decoder.decode(b""):
487
+ yield sse
460
488
 
461
489
 
462
490
  async def _aencode_json(json: Any) -> tuple[dict[str, str], bytes | None]:
@@ -1179,6 +1207,7 @@ class ThreadsClient:
1179
1207
  if_exists: OnConflictBehavior | None = None,
1180
1208
  supersteps: Sequence[dict[str, Sequence[dict[str, Any]]]] | None = None,
1181
1209
  graph_id: str | None = None,
1210
+ ttl: int | Mapping[str, Any] | None = None,
1182
1211
  headers: Mapping[str, str] | None = None,
1183
1212
  params: QueryParamTypes | None = None,
1184
1213
  ) -> Thread:
@@ -1193,6 +1222,9 @@ class ThreadsClient:
1193
1222
  supersteps: Apply a list of supersteps when creating a thread, each containing a sequence of updates.
1194
1223
  Each update has `values` or `command` and `as_node`. Used for copying a thread between deployments.
1195
1224
  graph_id: Optional graph ID to associate with the thread.
1225
+ ttl: Optional time-to-live in minutes for the thread. You can pass an
1226
+ integer (minutes) or a mapping with keys `ttl` and optional
1227
+ `strategy` (defaults to "delete").
1196
1228
  headers: Optional custom headers to include with the request.
1197
1229
  params: Optional query parameters to include with the request.
1198
1230
 
@@ -1234,6 +1266,11 @@ class ThreadsClient:
1234
1266
  }
1235
1267
  for s in supersteps
1236
1268
  ]
1269
+ if ttl is not None:
1270
+ if isinstance(ttl, (int, float)):
1271
+ payload["ttl"] = {"ttl": ttl, "strategy": "delete"}
1272
+ else:
1273
+ payload["ttl"] = ttl
1237
1274
 
1238
1275
  return await self.http.post(
1239
1276
  "/threads", json=payload, headers=headers, params=params
@@ -1244,6 +1281,7 @@ class ThreadsClient:
1244
1281
  thread_id: str,
1245
1282
  *,
1246
1283
  metadata: Mapping[str, Any],
1284
+ ttl: int | Mapping[str, Any] | None = None,
1247
1285
  headers: Mapping[str, str] | None = None,
1248
1286
  params: QueryParamTypes | None = None,
1249
1287
  ) -> Thread:
@@ -1252,6 +1290,9 @@ class ThreadsClient:
1252
1290
  Args:
1253
1291
  thread_id: ID of thread to update.
1254
1292
  metadata: Metadata to merge with existing thread metadata.
1293
+ ttl: Optional time-to-live in minutes for the thread. You can pass an
1294
+ integer (minutes) or a mapping with keys `ttl` and optional
1295
+ `strategy` (defaults to "delete").
1255
1296
  headers: Optional custom headers to include with the request.
1256
1297
  params: Optional query parameters to include with the request.
1257
1298
 
@@ -1265,12 +1306,19 @@ class ThreadsClient:
1265
1306
  thread = await client.threads.update(
1266
1307
  thread_id="my-thread-id",
1267
1308
  metadata={"number":1},
1309
+ ttl=43_200,
1268
1310
  )
1269
1311
  ```
1270
1312
  """ # noqa: E501
1313
+ payload: dict[str, Any] = {"metadata": metadata}
1314
+ if ttl is not None:
1315
+ if isinstance(ttl, (int, float)):
1316
+ payload["ttl"] = {"ttl": ttl, "strategy": "delete"}
1317
+ else:
1318
+ payload["ttl"] = ttl
1271
1319
  return await self.http.patch(
1272
1320
  f"/threads/{thread_id}",
1273
- json={"metadata": metadata},
1321
+ json=payload,
1274
1322
  headers=headers,
1275
1323
  params=params,
1276
1324
  )
@@ -3627,6 +3675,8 @@ class SyncHttpClient:
3627
3675
  sse = decoder.decode(line.rstrip(b"\n"))
3628
3676
  if sse is not None:
3629
3677
  yield sse
3678
+ if sse := decoder.decode(b""):
3679
+ yield sse
3630
3680
 
3631
3681
 
3632
3682
  def _encode_json(json: Any) -> tuple[dict[str, str], bytes]:
@@ -4332,6 +4382,7 @@ class SyncThreadsClient:
4332
4382
  if_exists: OnConflictBehavior | None = None,
4333
4383
  supersteps: Sequence[dict[str, Sequence[dict[str, Any]]]] | None = None,
4334
4384
  graph_id: str | None = None,
4385
+ ttl: int | Mapping[str, Any] | None = None,
4335
4386
  headers: Mapping[str, str] | None = None,
4336
4387
  params: QueryParamTypes | None = None,
4337
4388
  ) -> Thread:
@@ -4346,6 +4397,9 @@ class SyncThreadsClient:
4346
4397
  supersteps: Apply a list of supersteps when creating a thread, each containing a sequence of updates.
4347
4398
  Each update has `values` or `command` and `as_node`. Used for copying a thread between deployments.
4348
4399
  graph_id: Optional graph ID to associate with the thread.
4400
+ ttl: Optional time-to-live in minutes for the thread. You can pass an
4401
+ integer (minutes) or a mapping with keys `ttl` and optional
4402
+ `strategy` (defaults to "delete").
4349
4403
  headers: Optional custom headers to include with the request.
4350
4404
 
4351
4405
  Returns:
@@ -4387,6 +4441,11 @@ class SyncThreadsClient:
4387
4441
  }
4388
4442
  for s in supersteps
4389
4443
  ]
4444
+ if ttl is not None:
4445
+ if isinstance(ttl, (int, float)):
4446
+ payload["ttl"] = {"ttl": ttl, "strategy": "delete"}
4447
+ else:
4448
+ payload["ttl"] = ttl
4390
4449
 
4391
4450
  return self.http.post("/threads", json=payload, headers=headers, params=params)
4392
4451
 
@@ -4395,6 +4454,7 @@ class SyncThreadsClient:
4395
4454
  thread_id: str,
4396
4455
  *,
4397
4456
  metadata: Mapping[str, Any],
4457
+ ttl: int | Mapping[str, Any] | None = None,
4398
4458
  headers: Mapping[str, str] | None = None,
4399
4459
  params: QueryParamTypes | None = None,
4400
4460
  ) -> Thread:
@@ -4403,7 +4463,11 @@ class SyncThreadsClient:
4403
4463
  Args:
4404
4464
  thread_id: ID of thread to update.
4405
4465
  metadata: Metadata to merge with existing thread metadata.
4466
+ ttl: Optional time-to-live in minutes for the thread. You can pass an
4467
+ integer (minutes) or a mapping with keys `ttl` and optional
4468
+ `strategy` (defaults to "delete").
4406
4469
  headers: Optional custom headers to include with the request.
4470
+ params: Optional query parameters to include with the request.
4407
4471
 
4408
4472
  Returns:
4409
4473
  Thread: The created thread.
@@ -4415,12 +4479,19 @@ class SyncThreadsClient:
4415
4479
  thread = client.threads.update(
4416
4480
  thread_id="my-thread-id",
4417
4481
  metadata={"number":1},
4482
+ ttl=43_200,
4418
4483
  )
4419
4484
  ```
4420
4485
  """ # noqa: E501
4486
+ payload: dict[str, Any] = {"metadata": metadata}
4487
+ if ttl is not None:
4488
+ if isinstance(ttl, (int, float)):
4489
+ payload["ttl"] = {"ttl": ttl, "strategy": "delete"}
4490
+ else:
4491
+ payload["ttl"] = ttl
4421
4492
  return self.http.patch(
4422
4493
  f"/threads/{thread_id}",
4423
- json={"metadata": metadata},
4494
+ json=payload,
4424
4495
  headers=headers,
4425
4496
  params=params,
4426
4497
  )