langgraph-api 0.2.113__py3-none-any.whl → 0.2.114__py3-none-any.whl

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.

Potentially problematic release.


This version of langgraph-api might be problematic. Click here for more details.

langgraph_api/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.2.113"
1
+ __version__ = "0.2.114"
@@ -17,7 +17,7 @@ from langgraph_api.graph import get_assistant_id, get_graph
17
17
  from langgraph_api.js.base import BaseRemotePregel
18
18
  from langgraph_api.route import ApiRequest, ApiResponse, ApiRoute
19
19
  from langgraph_api.serde import ajson_loads
20
- from langgraph_api.utils import fetchone, validate_uuid
20
+ from langgraph_api.utils import fetchone, get_pagination_headers, validate_uuid
21
21
  from langgraph_api.validation import (
22
22
  AssistantCreate,
23
23
  AssistantPatch,
@@ -172,20 +172,21 @@ async def search_assistants(
172
172
  ) -> ApiResponse:
173
173
  """List assistants."""
174
174
  payload = await request.json(AssistantSearchRequest)
175
+ offset = int(payload.get("offset") or 0)
175
176
  async with connect() as conn:
176
- assistants_iter, total = await Assistants.search(
177
+ assistants_iter, next_offset = await Assistants.search(
177
178
  conn,
178
179
  graph_id=payload.get("graph_id"),
179
180
  metadata=payload.get("metadata"),
180
181
  limit=int(payload.get("limit") or 10),
181
- offset=int(payload.get("offset") or 0),
182
+ offset=offset,
182
183
  sort_by=payload.get("sort_by"),
183
184
  sort_order=payload.get("sort_order"),
184
185
  )
185
- return ApiResponse(
186
- [assistant async for assistant in assistants_iter],
187
- headers={"X-Pagination-Total": str(total)},
186
+ assistants, response_headers = await get_pagination_headers(
187
+ assistants_iter, next_offset, offset
188
188
  )
189
+ return ApiResponse(assistants, headers=response_headers)
189
190
 
190
191
 
191
192
  @retry_db
langgraph_api/api/runs.py CHANGED
@@ -12,7 +12,7 @@ from langgraph_api.asyncio import ValueEvent, aclosing
12
12
  from langgraph_api.models.run import create_valid_run
13
13
  from langgraph_api.route import ApiRequest, ApiResponse, ApiRoute
14
14
  from langgraph_api.sse import EventSourceResponse
15
- from langgraph_api.utils import fetchone, validate_uuid
15
+ from langgraph_api.utils import fetchone, get_pagination_headers, validate_uuid
16
16
  from langgraph_api.validation import (
17
17
  CronCreate,
18
18
  CronSearch,
@@ -568,20 +568,21 @@ async def search_crons(request: ApiRequest):
568
568
  if thread_id := payload.get("thread_id"):
569
569
  validate_uuid(thread_id, "Invalid thread ID: must be a UUID")
570
570
 
571
+ offset = int(payload.get("offset", 0))
571
572
  async with connect() as conn:
572
- crons_iter, total = await Crons.search(
573
+ crons_iter, next_offset = await Crons.search(
573
574
  conn,
574
575
  assistant_id=assistant_id,
575
576
  thread_id=thread_id,
576
577
  limit=int(payload.get("limit", 10)),
577
- offset=int(payload.get("offset", 0)),
578
+ offset=offset,
578
579
  sort_by=payload.get("sort_by"),
579
580
  sort_order=payload.get("sort_order"),
580
581
  )
581
- return ApiResponse(
582
- [cron async for cron in crons_iter],
583
- headers={"X-Pagination-Total": str(total)},
582
+ crons, response_headers = await get_pagination_headers(
583
+ crons_iter, next_offset, offset
584
584
  )
585
+ return ApiResponse(crons, headers=response_headers)
585
586
 
586
587
 
587
588
  runs_routes = [
@@ -6,7 +6,7 @@ from starlette.routing import BaseRoute
6
6
 
7
7
  from langgraph_api.route import ApiRequest, ApiResponse, ApiRoute
8
8
  from langgraph_api.state import state_snapshot_to_thread_state
9
- from langgraph_api.utils import fetchone, validate_uuid
9
+ from langgraph_api.utils import fetchone, get_pagination_headers, validate_uuid
10
10
  from langgraph_api.validation import (
11
11
  ThreadCreate,
12
12
  ThreadPatch,
@@ -61,7 +61,7 @@ async def search_threads(
61
61
  limit = int(payload.get("limit") or 10)
62
62
  offset = int(payload.get("offset") or 0)
63
63
  async with connect() as conn:
64
- iter, next_offset = await Threads.search(
64
+ threads_iter, next_offset = await Threads.search(
65
65
  conn,
66
66
  status=payload.get("status"),
67
67
  values=payload.get("values"),
@@ -71,15 +71,9 @@ async def search_threads(
71
71
  sort_by=payload.get("sort_by"),
72
72
  sort_order=payload.get("sort_order"),
73
73
  )
74
- threads = [thread async for thread in iter]
75
- if next_offset is None:
76
- response_headers = {"X-Pagination-Total": str(len(threads) + offset)}
77
- else:
78
- cur = str(next_offset)
79
- response_headers = {
80
- "X-Pagination-Total": cur,
81
- "X-Pagination-Next": cur,
82
- }
74
+ threads, response_headers = await get_pagination_headers(
75
+ threads_iter, next_offset, offset
76
+ )
83
77
  return ApiResponse(threads, headers=response_headers)
84
78
 
85
79
 
langgraph_api/server.py CHANGED
@@ -71,7 +71,7 @@ middleware.extend(
71
71
  allow_credentials=True,
72
72
  allow_methods=["*"],
73
73
  allow_headers=["*"],
74
- expose_headers=["x-pagination-total"],
74
+ expose_headers=["x-pagination-total", "x-pagination-next"],
75
75
  )
76
76
  if config.CORS_CONFIG is None
77
77
  else Middleware(
@@ -1,6 +1,6 @@
1
1
  import contextvars
2
2
  import uuid
3
- from collections.abc import AsyncIterator
3
+ from collections.abc import AsyncGenerator, AsyncIterator
4
4
  from contextlib import asynccontextmanager
5
5
  from datetime import datetime
6
6
  from typing import Any, Protocol, TypeAlias, TypeVar
@@ -127,3 +127,19 @@ class SchemaGenerator(BaseSchemaGenerator):
127
127
  schema["paths"][endpoint.path][endpoint.http_method] = parsed
128
128
 
129
129
  return schema
130
+
131
+
132
+ async def get_pagination_headers(
133
+ resource: AsyncGenerator[T],
134
+ next_offset: int | None,
135
+ offset: int,
136
+ ) -> tuple[list[T], dict[str, str]]:
137
+ resources = [r async for r in resource]
138
+ if next_offset is None:
139
+ response_headers = {"X-Pagination-Total": str(len(resources) + offset)}
140
+ else:
141
+ response_headers = {
142
+ "X-Pagination-Total": str(next_offset + 1), # Next offset will be "n"
143
+ "X-Pagination-Next": str(next_offset),
144
+ }
145
+ return resources, response_headers
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-api
3
- Version: 0.2.113
3
+ Version: 0.2.114
4
4
  Author-email: Nuno Campos <nuno@langchain.dev>, Will Fu-Hinthorn <will@langchain.dev>
5
5
  License: Elastic-2.0
6
6
  License-File: LICENSE
@@ -11,7 +11,7 @@ Requires-Dist: httpx>=0.25.0
11
11
  Requires-Dist: jsonschema-rs<0.30,>=0.20.0
12
12
  Requires-Dist: langchain-core>=0.3.64
13
13
  Requires-Dist: langgraph-checkpoint>=2.0.23
14
- Requires-Dist: langgraph-runtime-inmem<0.7,>=0.6.7
14
+ Requires-Dist: langgraph-runtime-inmem<0.7,>=0.6.8
15
15
  Requires-Dist: langgraph-sdk>=0.2.0
16
16
  Requires-Dist: langgraph>=0.4.0
17
17
  Requires-Dist: langsmith>=0.3.45
@@ -1,4 +1,4 @@
1
- langgraph_api/__init__.py,sha256=YuoNAr2ZnhYxr-DSsTTZheKFrr_w-5RjlSY_cdQOZ2A,24
1
+ langgraph_api/__init__.py,sha256=FvhaSOAw0OQ1NvIUlXa-kO_z2gwtORe4nLr3ouqI-m8,24
2
2
  langgraph_api/asgi_transport.py,sha256=eqifhHxNnxvI7jJqrY1_8RjL4Fp9NdN4prEub2FWBt8,5091
3
3
  langgraph_api/asyncio.py,sha256=Wv4Rwm-a-Cf6JpfgJmVuVlXQ7SlwrjbTn0eq1ux8I2Q,9652
4
4
  langgraph_api/cli.py,sha256=xQojITwmmKSJw48Lr2regcnRPRq2FJqWlPpeyr5TgbU,16158
@@ -17,7 +17,7 @@ langgraph_api/queue_entrypoint.py,sha256=hC8j-A4cUxibusiiPJBlK0mkmChNZxNcXn5GVwL
17
17
  langgraph_api/route.py,sha256=4VBkJMeusfiZtLzyUaKm1HwLHTq0g15y2CRiRhM6xyA,4773
18
18
  langgraph_api/schema.py,sha256=WoA7uu1VA_ZRVSR4gpAnm1n7sKDfWUEojx7CFDiOH7Q,6341
19
19
  langgraph_api/serde.py,sha256=0ALETUn582vNF-m0l_WOZGF_scL1VPA39fDkwMJQPrg,5187
20
- langgraph_api/server.py,sha256=Z_VL-kIphybTRDWBIqHMfRhgCmAFyTRqAGlgnHQF0Zg,6973
20
+ langgraph_api/server.py,sha256=KBnMFt3f9RVLVu_NqyeRc13D_Lq62Rk_2czZKEUMU5E,6994
21
21
  langgraph_api/sse.py,sha256=SLdtZmTdh5D8fbWrQjuY9HYLd2dg8Rmi6ZMmFMVc2iE,4204
22
22
  langgraph_api/state.py,sha256=P2mCo-0bqPu2v9FSFGJtUCjPPNvv6wLUKQh8SdxAtc8,4387
23
23
  langgraph_api/store.py,sha256=srRI0fQXNFo_RSUs4apucr4BEp_KrIseJksZXs32MlQ,4635
@@ -29,13 +29,13 @@ langgraph_api/validation.py,sha256=zMuKmwUEBjBgFMwAaeLZmatwGVijKv2sOYtYg7gfRtc,4
29
29
  langgraph_api/webhook.py,sha256=VCJp4dI5E1oSJ15XP34cnPiOi8Ya8Q1BnBwVGadOpLI,1636
30
30
  langgraph_api/worker.py,sha256=LVvjvigurlDgpNjFcbAvRH7744fE01Lirrg2ZlHtORE,14245
31
31
  langgraph_api/api/__init__.py,sha256=WHy6oNLWtH1K7AxmmsU9RD-Vm6WP-Ov16xS8Ey9YCmQ,6090
32
- langgraph_api/api/assistants.py,sha256=e6da5aYMVAxj2rZG9RxZbBKFM0bP_f8Xbx0P5UhK8Y8,15924
32
+ langgraph_api/api/assistants.py,sha256=ecHaID71ReTAZF4qsJzDe5L-2T5iOL2v8p6kQVHLKFk,16009
33
33
  langgraph_api/api/mcp.py,sha256=qe10ZRMN3f-Hli-9TI8nbQyWvMeBb72YB1PZVbyqBQw,14418
34
34
  langgraph_api/api/meta.py,sha256=fmc7btbtl5KVlU_vQ3Bj4J861IjlqmjBKNtnxSV-S-Q,4198
35
35
  langgraph_api/api/openapi.py,sha256=KToI2glOEsvrhDpwdScdBnL9xoLOqkTxx5zKq2pMuKQ,11957
36
- langgraph_api/api/runs.py,sha256=whjpK5Kn3nQy9g9qQK94F_rTlX4oG65WODUyj5TSOwM,20877
36
+ langgraph_api/api/runs.py,sha256=iPzPen-_UMikGuRtg4xiageZC6eKwsmsMnqpnGdbucY,20962
37
37
  langgraph_api/api/store.py,sha256=TSeMiuMfrifmEnEbL0aObC2DPeseLlmZvAMaMzPgG3Y,5535
38
- langgraph_api/api/threads.py,sha256=NvWQ7j9XMJjOnist2XpNg3rheUhHCiqacC7MsSXFpEQ,9895
38
+ langgraph_api/api/threads.py,sha256=haV1VkROLhWz4NZpO28ncFog-tbv7_iWqE1I8ZrQiDs,9726
39
39
  langgraph_api/api/ui.py,sha256=17QrRy2XVzP7x_0RdRw7pmSv-n1lmnb54byHCGGeNhM,2490
40
40
  langgraph_api/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  langgraph_api/auth/custom.py,sha256=ZtNSQ4hIldbd2HvRsilwKzN_hjCWIiIOHClmYyPi8FM,22206
@@ -76,7 +76,7 @@ langgraph_api/middleware/request_id.py,sha256=SDj3Yi3WvTbFQ2ewrPQBjAV8sYReOJGeIi
76
76
  langgraph_api/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
77
  langgraph_api/models/run.py,sha256=RX2LaE1kmTruX8o8HgvqeEt5YpPGHILWByChjMZVJ58,15035
78
78
  langgraph_api/tunneling/cloudflare.py,sha256=iKb6tj-VWPlDchHFjuQyep2Dpb-w2NGfJKt-WJG9LH0,3650
79
- langgraph_api/utils/__init__.py,sha256=92mSti9GfGdMRRWyESKQW5yV-75Z9icGHnIrBYvdypU,3619
79
+ langgraph_api/utils/__init__.py,sha256=EQu0PShwHhxUI_9mDFgqlAf5_y5bX8TEk723P5iby24,4161
80
80
  langgraph_api/utils/cache.py,sha256=SrtIWYibbrNeZzLXLUGBFhJPkMVNQnVxR5giiYGHEfI,1810
81
81
  langgraph_api/utils/config.py,sha256=gONI0UsoSpuR72D9lSGAmpr-_iSMDFdD4M_tiXXjmNk,3936
82
82
  langgraph_api/utils/future.py,sha256=CGhUb_Ht4_CnTuXc2kI8evEn1gnMKYN0ce9ZyUkW5G4,7251
@@ -94,8 +94,8 @@ langgraph_runtime/store.py,sha256=7mowndlsIroGHv3NpTSOZDJR0lCuaYMBoTnTrewjslw,11
94
94
  LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
95
95
  logging.json,sha256=3RNjSADZmDq38eHePMm1CbP6qZ71AmpBtLwCmKU9Zgo,379
96
96
  openapi.json,sha256=jyQZW5U4V15zWciiIvaDPasYZd3k1iMiQ2vkPxf3zb4,145614
97
- langgraph_api-0.2.113.dist-info/METADATA,sha256=KYzCdutNJiyluoAZUY-ff1_tokxpTsMK-fK_KzDdkHA,3890
98
- langgraph_api-0.2.113.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
- langgraph_api-0.2.113.dist-info/entry_points.txt,sha256=hGedv8n7cgi41PypMfinwS_HfCwA7xJIfS0jAp8htV8,78
100
- langgraph_api-0.2.113.dist-info/licenses/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
101
- langgraph_api-0.2.113.dist-info/RECORD,,
97
+ langgraph_api-0.2.114.dist-info/METADATA,sha256=vUC4EP4w8Mv9FFd6hsoODoI0ofHfjNmQ677f6sYRYpI,3890
98
+ langgraph_api-0.2.114.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
+ langgraph_api-0.2.114.dist-info/entry_points.txt,sha256=hGedv8n7cgi41PypMfinwS_HfCwA7xJIfS0jAp8htV8,78
100
+ langgraph_api-0.2.114.dist-info/licenses/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
101
+ langgraph_api-0.2.114.dist-info/RECORD,,