langgraph-api 0.2.13__tar.gz → 0.2.15__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.

Potentially problematic release.


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

Files changed (103) hide show
  1. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/PKG-INFO +1 -1
  2. langgraph_api-0.2.15/langgraph_api/__init__.py +1 -0
  3. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/logging.py +25 -0
  4. langgraph_api-0.2.15/langgraph_api/middleware/request_id.py +30 -0
  5. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/models/run.py +3 -0
  6. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/server.py +2 -0
  7. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/worker.py +22 -16
  8. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/pyproject.toml +1 -1
  9. langgraph_api-0.2.13/langgraph_api/__init__.py +0 -1
  10. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/LICENSE +0 -0
  11. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/README.md +0 -0
  12. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/api/__init__.py +0 -0
  13. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/api/assistants.py +0 -0
  14. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/api/mcp.py +0 -0
  15. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/api/meta.py +0 -0
  16. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/api/openapi.py +0 -0
  17. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/api/runs.py +0 -0
  18. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/api/store.py +0 -0
  19. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/api/threads.py +0 -0
  20. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/api/ui.py +0 -0
  21. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/asyncio.py +0 -0
  22. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/auth/__init__.py +0 -0
  23. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/auth/custom.py +0 -0
  24. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/auth/langsmith/__init__.py +0 -0
  25. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/auth/langsmith/backend.py +0 -0
  26. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/auth/langsmith/client.py +0 -0
  27. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/auth/middleware.py +0 -0
  28. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/auth/noop.py +0 -0
  29. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/auth/studio_user.py +0 -0
  30. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/cli.py +0 -0
  31. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/command.py +0 -0
  32. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/config.py +0 -0
  33. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/cron_scheduler.py +0 -0
  34. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/errors.py +0 -0
  35. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/graph.py +0 -0
  36. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/http.py +0 -0
  37. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/.gitignore +0 -0
  38. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/.prettierrc +0 -0
  39. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/__init__.py +0 -0
  40. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/base.py +0 -0
  41. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/build.mts +0 -0
  42. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/client.http.mts +0 -0
  43. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/client.mts +0 -0
  44. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/errors.py +0 -0
  45. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/global.d.ts +0 -0
  46. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/package.json +0 -0
  47. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/remote.py +0 -0
  48. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/schema.py +0 -0
  49. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/src/graph.mts +0 -0
  50. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/src/load.hooks.mjs +0 -0
  51. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/src/preload.mjs +0 -0
  52. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/src/utils/files.mts +0 -0
  53. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/src/utils/importMap.mts +0 -0
  54. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/src/utils/pythonSchemas.mts +0 -0
  55. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/src/utils/serde.mts +0 -0
  56. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/sse.py +0 -0
  57. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/api.test.mts +0 -0
  58. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/auth.test.mts +0 -0
  59. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/compose-postgres.auth.yml +0 -0
  60. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/compose-postgres.yml +0 -0
  61. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/.gitignore +0 -0
  62. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/agent.css +0 -0
  63. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/agent.mts +0 -0
  64. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/agent.ui.tsx +0 -0
  65. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/agent_simple.mts +0 -0
  66. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/auth.mts +0 -0
  67. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/command.mts +0 -0
  68. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/delay.mts +0 -0
  69. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/dynamic.mts +0 -0
  70. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/error.mts +0 -0
  71. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/http.mts +0 -0
  72. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/langgraph.json +0 -0
  73. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/nested.mts +0 -0
  74. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/package.json +0 -0
  75. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/weather.mts +0 -0
  76. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/graphs/yarn.lock +0 -0
  77. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tests/utils.mts +0 -0
  78. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/tsconfig.json +0 -0
  79. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/ui.py +0 -0
  80. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/js/yarn.lock +0 -0
  81. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/metadata.py +0 -0
  82. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/middleware/__init__.py +0 -0
  83. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/middleware/http_logger.py +0 -0
  84. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/middleware/private_network.py +0 -0
  85. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/models/__init__.py +0 -0
  86. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/patch.py +0 -0
  87. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/queue_entrypoint.py +0 -0
  88. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/route.py +0 -0
  89. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/schema.py +0 -0
  90. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/serde.py +0 -0
  91. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/sse.py +0 -0
  92. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/state.py +0 -0
  93. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/stream.py +0 -0
  94. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/thread_ttl.py +0 -0
  95. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/tunneling/cloudflare.py +0 -0
  96. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/utils.py +0 -0
  97. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/validation.py +0 -0
  98. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_api/webhook.py +0 -0
  99. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_license/__init__.py +0 -0
  100. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_license/validation.py +0 -0
  101. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/langgraph_runtime/__init__.py +0 -0
  102. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/logging.json +0 -0
  103. {langgraph_api-0.2.13 → langgraph_api-0.2.15}/openapi.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: langgraph-api
3
- Version: 0.2.13
3
+ Version: 0.2.15
4
4
  Summary:
5
5
  License: Elastic-2.0
6
6
  Author: Nuno Campos
@@ -0,0 +1 @@
1
+ __version__ = "0.2.15"
@@ -1,6 +1,8 @@
1
+ import contextvars
1
2
  import logging
2
3
  import os
3
4
  import threading
5
+ import typing
4
6
 
5
7
  import structlog
6
8
  from starlette.config import Config
@@ -17,6 +19,10 @@ LOG_LEVEL = log_env("LOG_LEVEL", cast=str, default="INFO")
17
19
  logging.getLogger().setLevel(LOG_LEVEL.upper())
18
20
  logging.getLogger("psycopg").setLevel(logging.WARNING)
19
21
 
22
+ worker_config: contextvars.ContextVar[dict[str, typing.Any] | None] = (
23
+ contextvars.ContextVar("worker_config", default=None)
24
+ )
25
+
20
26
  # custom processors
21
27
 
22
28
 
@@ -27,6 +33,15 @@ def add_thread_name(
27
33
  return event_dict
28
34
 
29
35
 
36
+ def set_logging_context(val: dict[str, typing.Any] | None) -> contextvars.Token:
37
+ if val is None:
38
+ return worker_config.set(None)
39
+ current = worker_config.get()
40
+ if current is None:
41
+ return worker_config.set(val)
42
+ return worker_config.set({**current, **val})
43
+
44
+
30
45
  class AddPrefixedEnvVars:
31
46
  def __init__(self, prefix: str) -> None:
32
47
  self.kv = {
@@ -42,6 +57,15 @@ class AddPrefixedEnvVars:
42
57
  return event_dict
43
58
 
44
59
 
60
+ class AddLoggingContext:
61
+ def __call__(
62
+ self, logger: logging.Logger, method_name: str, event_dict: EventDict
63
+ ) -> EventDict:
64
+ if (ctx := worker_config.get()) is not None:
65
+ event_dict.update(ctx)
66
+ return event_dict
67
+
68
+
45
69
  class JSONRenderer:
46
70
  def __call__(
47
71
  self, logger: logging.Logger, method_name: str, event_dict: EventDict
@@ -87,6 +111,7 @@ shared_processors = [
87
111
  structlog.processors.StackInfoRenderer(),
88
112
  structlog.processors.format_exc_info,
89
113
  structlog.processors.UnicodeDecoder(),
114
+ AddLoggingContext(),
90
115
  ]
91
116
 
92
117
 
@@ -0,0 +1,30 @@
1
+ """Middleware to handle setting request IDs for logging."""
2
+
3
+ import re
4
+ import uuid
5
+
6
+ from starlette.types import ASGIApp, Receive, Scope, Send
7
+
8
+ PATHS_INCLUDE = ("/runs", "/threads")
9
+
10
+
11
+ class RequestIdMiddleware:
12
+ def __init__(self, app: ASGIApp, mount_prefix: str = ""):
13
+ self.app = app
14
+ paths = (
15
+ (mount_prefix + p for p in ("/runs", "/threads"))
16
+ if mount_prefix
17
+ else ("/runs", "/threads")
18
+ )
19
+ self.pattern = re.compile(r"^(" + "|".join(paths) + r")(/.*)?$")
20
+
21
+ async def __call__(self, scope: Scope, receive: Receive, send: Send):
22
+ if scope["type"] == "http" and self.pattern.match(scope["path"]):
23
+ request_id = next(
24
+ (h[1] for h in scope["headers"] if h[0] == b"x-request-id"),
25
+ None,
26
+ )
27
+ if request_id is None:
28
+ request_id = str(uuid.uuid4()).encode()
29
+ scope["headers"].append((b"x-request-id", request_id))
30
+ await self.app(scope, receive, send)
@@ -248,6 +248,7 @@ async def create_valid_run(
248
248
  barrier: asyncio.Barrier | None = None,
249
249
  run_id: UUID | None = None,
250
250
  ) -> Run:
251
+ request_id = headers.get("x-request-id") # Will be null in the crons scheduler.
251
252
  (
252
253
  assistant_id,
253
254
  thread_id,
@@ -288,6 +289,8 @@ async def create_valid_run(
288
289
  configurable["langgraph_auth_permissions"] = ctx.permissions
289
290
  else:
290
291
  user_id = None
292
+ if not configurable.get("langgraph_request_id"):
293
+ configurable["langgraph_request_id"] = request_id
291
294
  run_coro = Runs.put(
292
295
  conn,
293
296
  assistant_id,
@@ -29,6 +29,7 @@ from langgraph_api.errors import (
29
29
  from langgraph_runtime.lifespan import lifespan
30
30
  from langgraph_api.middleware.http_logger import AccessLoggerMiddleware
31
31
  from langgraph_api.middleware.private_network import PrivateNetworkMiddleware
32
+ from langgraph_api.middleware.request_id import RequestIdMiddleware
32
33
  from langgraph_api.utils import SchemaGenerator
33
34
  from langgraph_runtime.retry import OVERLOADED_EXCEPTIONS
34
35
  from langgraph_api.js.base import is_js_path
@@ -69,6 +70,7 @@ middleware.extend(
69
70
  )
70
71
  ),
71
72
  Middleware(AccessLoggerMiddleware, logger=logger),
73
+ Middleware(RequestIdMiddleware, mount_prefix=config.MOUNT_PREFIX),
72
74
  ]
73
75
  )
74
76
  exception_handlers = {
@@ -8,23 +8,18 @@ import structlog
8
8
  from langgraph.pregel.debug import CheckpointPayload, TaskResultPayload
9
9
  from starlette.exceptions import HTTPException
10
10
 
11
+ import langgraph_api.logging as lg_logging
11
12
  from langgraph_api.auth.custom import SimpleUser, normalize_user
12
13
  from langgraph_api.config import (
13
14
  BG_JOB_ISOLATED_LOOPS,
14
15
  BG_JOB_MAX_RETRIES,
15
16
  BG_JOB_TIMEOUT_SECS,
16
17
  )
17
- from langgraph_api.errors import (
18
- UserInterrupt,
19
- UserRollback,
20
- )
18
+ from langgraph_api.errors import UserInterrupt, UserRollback
21
19
  from langgraph_api.js.errors import RemoteException
22
20
  from langgraph_api.metadata import incr_runs
23
21
  from langgraph_api.schema import Run
24
- from langgraph_api.stream import (
25
- astream_state,
26
- consume,
27
- )
22
+ from langgraph_api.stream import astream_state, consume
28
23
  from langgraph_api.utils import set_auth_ctx, with_user
29
24
  from langgraph_runtime.database import connect
30
25
  from langgraph_runtime.ops import Runs, Threads
@@ -89,11 +84,20 @@ async def worker(
89
84
  ):
90
85
  temporary = run["kwargs"].get("temporary", False)
91
86
  run_created_at = run["created_at"].isoformat()
87
+ run["kwargs"]
88
+ lg_logging.set_logging_context(
89
+ {
90
+ "run_id": str(run_id),
91
+ "run_attempt": attempt,
92
+ "thread_id": str(run.get("thread_id")),
93
+ "assistant_id": str(run.get("assistant_id")),
94
+ "graph_id": _get_graph_id(run),
95
+ "request_id": _get_request_id(run),
96
+ }
97
+ )
98
+
92
99
  await logger.ainfo(
93
100
  "Starting background run",
94
- run_id=str(run_id),
95
- run_attempt=attempt,
96
- run_created_at=run_created_at,
97
101
  run_started_at=run_started_at.isoformat(),
98
102
  run_queue_ms=ms(run_started_at, run["created_at"]),
99
103
  )
@@ -166,7 +170,6 @@ async def worker(
166
170
  run_started_at=run_started_at.isoformat(),
167
171
  run_ended_at=run_ended_at,
168
172
  run_exec_ms=ms(datetime.now(UTC), run_started_at),
169
- graph_id=_get_graph_id(run),
170
173
  )
171
174
  await Runs.set_status(conn, run_id, "timeout")
172
175
  except UserRollback as e:
@@ -183,7 +186,6 @@ async def worker(
183
186
  run_started_at=run_started_at.isoformat(),
184
187
  run_ended_at=run_ended_at,
185
188
  run_exec_ms=ms(datetime.now(UTC), run_started_at),
186
- graph_id=_get_graph_id(run),
187
189
  )
188
190
 
189
191
  except InFailedSqlTransaction as e:
@@ -221,7 +223,6 @@ async def worker(
221
223
  run_started_at=run_started_at.isoformat(),
222
224
  run_ended_at=run_ended_at,
223
225
  run_exec_ms=ms(datetime.now(UTC), run_started_at),
224
- graph_id=_get_graph_id(run),
225
226
  )
226
227
  await Runs.set_status(conn, run_id, "interrupted")
227
228
  except RETRIABLE_EXCEPTIONS as e:
@@ -237,7 +238,6 @@ async def worker(
237
238
  run_started_at=run_started_at.isoformat(),
238
239
  run_ended_at=run_ended_at,
239
240
  run_exec_ms=ms(datetime.now(UTC), run_started_at),
240
- graph_id=_get_graph_id(run),
241
241
  )
242
242
  await Runs.set_status(conn, run_id, "pending")
243
243
  raise
@@ -254,7 +254,6 @@ async def worker(
254
254
  run_started_at=run_started_at.isoformat(),
255
255
  run_ended_at=run_ended_at,
256
256
  run_exec_ms=ms(datetime.now(UTC), run_started_at),
257
- graph_id=_get_graph_id(run),
258
257
  )
259
258
  await Runs.set_status(conn, run_id, "error")
260
259
  set_auth_ctx(None, None)
@@ -311,6 +310,13 @@ def ms(after: datetime, before: datetime) -> int:
311
310
  return int((after - before).total_seconds() * 1000)
312
311
 
313
312
 
313
+ def _get_request_id(run: Run) -> str | None:
314
+ try:
315
+ return run["kwargs"]["config"]["configurable"]["langgraph_request_id"]
316
+ except Exception:
317
+ return None
318
+
319
+
314
320
  def _get_graph_id(run: Run) -> str | None:
315
321
  try:
316
322
  return run["kwargs"]["config"]["configurable"]["graph_id"]
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "langgraph-api"
3
- version = "0.2.13"
3
+ version = "0.2.15"
4
4
  description = ""
5
5
  authors = [
6
6
  "Nuno Campos <nuno@langchain.dev>",
@@ -1 +0,0 @@
1
- __version__ = "0.2.13"
File without changes
File without changes