langgraph-api 0.0.9__py3-none-any.whl → 0.0.10__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.

@@ -3,13 +3,13 @@ import copy
3
3
  import functools
4
4
  import importlib.util
5
5
  import inspect
6
- import logging
7
6
  import os
8
7
  import sys
9
8
  from collections.abc import Awaitable, Callable, Mapping
10
9
  from contextlib import AsyncExitStack
11
10
  from typing import Any, get_args
12
11
 
12
+ import structlog
13
13
  from langgraph_sdk import Auth
14
14
  from starlette.authentication import (
15
15
  AuthCredentials,
@@ -26,7 +26,7 @@ from starlette.responses import Response
26
26
  from langgraph_api.auth.langsmith.backend import LangsmithAuthBackend
27
27
  from langgraph_api.config import LANGGRAPH_AUTH
28
28
 
29
- logger = logging.getLogger(__name__)
29
+ logger = structlog.stdlib.get_logger(__name__)
30
30
 
31
31
  SUPPORTED_PARAMETERS = {
32
32
  "request": Request,
@@ -50,11 +50,15 @@ def get_custom_auth_middleware() -> AuthenticationBackend:
50
50
  "LANGGRAPH_AUTH must be set to a Python file path or a config dict"
51
51
  " to use custom authentication."
52
52
  )
53
+ logger.info("Using custom authentication", langgraph_auth=LANGGRAPH_AUTH)
53
54
  return _get_custom_auth_middleware(LANGGRAPH_AUTH)
54
55
 
55
56
 
56
57
  @functools.lru_cache(maxsize=1)
57
58
  def get_auth_instance() -> Auth | None:
59
+ logger.info(
60
+ f"Getting auth instance: {LANGGRAPH_AUTH}", langgraph_auth=str(LANGGRAPH_AUTH)
61
+ )
58
62
  if not LANGGRAPH_AUTH:
59
63
  return None
60
64
  path = LANGGRAPH_AUTH.get("path")
@@ -116,7 +120,6 @@ class CustomAuthBackend(AuthenticationBackend):
116
120
  ) = None,
117
121
  disable_studio_auth: bool = False,
118
122
  ):
119
- assert fn is not None
120
123
  if fn is None:
121
124
  self.fn = None
122
125
  elif not inspect.iscoroutinefunction(fn):
@@ -133,6 +136,14 @@ class CustomAuthBackend(AuthenticationBackend):
133
136
  else:
134
137
  self.ls_auth = None
135
138
 
139
+ def __str__(self):
140
+ return (
141
+ f"CustomAuthBackend(fn={self.fn}, "
142
+ f"ls_auth={self.ls_auth}, "
143
+ f"param_names={self._param_names}"
144
+ ")"
145
+ )
146
+
136
147
  async def authenticate(
137
148
  self, conn: HTTPConnection
138
149
  ) -> tuple[AuthCredentials, BaseUser] | None:
@@ -163,10 +174,12 @@ def _get_custom_auth_middleware(
163
174
  path = config.get("path")
164
175
  disable_studio_auth = config.get("disable_studio_auth", disable_studio_auth)
165
176
  auth_instance = _get_auth_instance(path)
166
- return CustomAuthBackend(
177
+ result = CustomAuthBackend(
167
178
  auth_instance._authenticate_handler if auth_instance else None,
168
179
  disable_studio_auth,
169
180
  )
181
+ logger.info(f"Loaded custom auth middleware: {str(result)}")
182
+ return result
170
183
 
171
184
 
172
185
  @functools.lru_cache(maxsize=1)
@@ -182,7 +195,7 @@ def _get_auth_instance(path: str | None = None) -> Auth | None:
182
195
  auth_instance._authenticate_handler = _solve_fastapi_dependencies(
183
196
  auth_instance._authenticate_handler, deps
184
197
  )
185
-
198
+ logger.info(f"Loaded auth instance from path {path}: {auth_instance}")
186
199
  return auth_instance
187
200
 
188
201
 
@@ -216,10 +229,11 @@ def _extract_arguments_from_scope(
216
229
  if "headers" in param_names:
217
230
  args["headers"] = dict(scope.get("headers", {}))
218
231
  if "authorization" in param_names:
219
- headers = scope.get("headers", {})
220
- args["authorization"] = headers.get("authorization") or headers.get(
221
- "Authorization"
222
- )
232
+ headers = dict(scope.get("headers", {}))
233
+ authorization = headers.get(b"authorization") or headers.get(b"Authorization")
234
+ if isinstance(authorization, bytes):
235
+ authorization = authorization.decode(encoding="utf-8")
236
+ args["authorization"] = authorization
223
237
  if "method" in param_names:
224
238
  args["method"] = scope.get("method")
225
239
 
@@ -254,6 +268,7 @@ def _solve_fastapi_dependencies(
254
268
  fn: Callable[..., Any], deps: Mapping[str, Any]
255
269
  ) -> Callable:
256
270
  """Solve FastAPI dependencies for a given function."""
271
+ logger.info("Solving FastAPI dependencies", fn=str(fn), deps=str(deps))
257
272
  from fastapi.dependencies.utils import (
258
273
  get_parameterless_sub_dependant,
259
274
  solve_dependencies,
@@ -1,3 +1,4 @@
1
+ import structlog
1
2
  from starlette.middleware import Middleware
2
3
  from starlette.middleware.authentication import (
3
4
  AuthenticationError,
@@ -9,8 +10,11 @@ from starlette.types import Receive, Scope, Send
9
10
 
10
11
  from langgraph_api.config import LANGGRAPH_AUTH_TYPE
11
12
 
13
+ logger = structlog.stdlib.get_logger(__name__)
14
+
12
15
 
13
16
  def get_auth_backend():
17
+ logger.info(f"Using auth of type={LANGGRAPH_AUTH_TYPE}")
14
18
  if LANGGRAPH_AUTH_TYPE == "langsmith":
15
19
  from langgraph_api.auth.langsmith.backend import LangsmithAuthBackend
16
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langgraph-api
3
- Version: 0.0.9
3
+ Version: 0.0.10
4
4
  Summary:
5
5
  License: Elastic-2.0
6
6
  Author: Nuno Campos
@@ -9,11 +9,11 @@ langgraph_api/api/store.py,sha256=y7VIejpsE7rpPF-tiMGBqqBwWPZ1wb3o48th6NUvb5I,38
9
9
  langgraph_api/api/threads.py,sha256=taU61XPcCEhBPCYPZcMDsgVDwwWUWJs8p-PrXFXWY48,8661
10
10
  langgraph_api/asyncio.py,sha256=XiFEllu-Kg4zAO084npHPYOPnLQRire3V75XrVQYMxE,6023
11
11
  langgraph_api/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- langgraph_api/auth/custom.py,sha256=zBJlCjHBr-yAP5Cw-9Q2wa2HVMSsm7BWCqYB8dni-R8,16785
12
+ langgraph_api/auth/custom.py,sha256=nE8dgtSuX4W8UoByEmr5aH0yK6H_rk0VOoETET9BqJQ,17528
13
13
  langgraph_api/auth/langsmith/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  langgraph_api/auth/langsmith/backend.py,sha256=uHeb5-h13NIjrX_LDAvfWYr3zpbJvlvbdUffch48hbM,2571
15
15
  langgraph_api/auth/langsmith/client.py,sha256=eKchvAom7hdkUXauD8vHNceBDDUijrFgdTV8bKd7x4Q,3998
16
- langgraph_api/auth/middleware.py,sha256=4RhtYv1eBA57irNUT3nXc5vpgBTKysaOKBnjyCMSuCY,1511
16
+ langgraph_api/auth/middleware.py,sha256=eHj4D2p2ASpMKzoTgMkEUXMhuubQdg9Jnq0gQS9qbvE,1637
17
17
  langgraph_api/auth/noop.py,sha256=vDJmzG2vArJxVzdHePvrJWahEa0dvGnhc2LEMMeiFz0,391
18
18
  langgraph_api/cli.py,sha256=7vQQiD3F50r-8KkbuFjwIz8LLbdKUTd4xZGUJPiO3yQ,11688
19
19
  langgraph_api/config.py,sha256=m3cf13AS9HVF84deJ3-9mmNTJ5GSVqcukES-FNbDbvo,2794
@@ -73,15 +73,15 @@ langgraph_license/validation.py,sha256=Uu_G8UGO_WTlLsBEY0gTVWjRR4czYGfw5YAD3HLZo
73
73
  langgraph_storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
74
74
  langgraph_storage/checkpoint.py,sha256=V4t2GwYEJdPCHbhq_4Udhlv0TWKDzlMu_rlNPdTDc50,3589
75
75
  langgraph_storage/database.py,sha256=Nr5zE9Fur3-tESkqe7xNXMf2QlBuw3H0CUie7jVa6Q4,6003
76
- langgraph_storage/ops.py,sha256=34zhzc1ISESlsfM-QlHaUlSNIvqSIgmN3aJHTQMb-xA,67670
76
+ langgraph_storage/ops.py,sha256=V0gnBlpzW3AE9kBNcT_uONYYEHEdgTR6a4mA9Owz6S4,67669
77
77
  langgraph_storage/queue.py,sha256=6cTZ0ubHu3S1T43yxHMVOwsQsDaJupByiU0sTUFFls8,3261
78
78
  langgraph_storage/retry.py,sha256=uvYFuXJ-T6S1QY1ZwkZHyZQbsvS-Ab68LSbzbUUSI2E,696
79
79
  langgraph_storage/store.py,sha256=D-p3cWc_umamkKp-6Cz3cAriSACpvM5nxUIvND6PuxE,2710
80
80
  langgraph_storage/ttl_dict.py,sha256=FlpEY8EANeXWKo_G5nmIotPquABZGyIJyk6HD9u6vqY,1533
81
81
  logging.json,sha256=3RNjSADZmDq38eHePMm1CbP6qZ71AmpBtLwCmKU9Zgo,379
82
82
  openapi.json,sha256=UxAGHZYM4PgNd48TSZt7f2lVuyPUkDadxBBhRy5jcmk,124512
83
- langgraph_api-0.0.9.dist-info/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
84
- langgraph_api-0.0.9.dist-info/METADATA,sha256=dfqbTUQL54HjgW4XZThB8H-bJALao6b5Fhi01JXQwE4,3993
85
- langgraph_api-0.0.9.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
86
- langgraph_api-0.0.9.dist-info/entry_points.txt,sha256=3EYLgj89DfzqJHHYGxPH4A_fEtClvlRbWRUHaXO7hj4,77
87
- langgraph_api-0.0.9.dist-info/RECORD,,
83
+ langgraph_api-0.0.10.dist-info/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
84
+ langgraph_api-0.0.10.dist-info/METADATA,sha256=VgLW5dnP15w_SuuNkgpgYVjDrBGxxuKGvvEaDOkxMhk,3994
85
+ langgraph_api-0.0.10.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
86
+ langgraph_api-0.0.10.dist-info/entry_points.txt,sha256=3EYLgj89DfzqJHHYGxPH4A_fEtClvlRbWRUHaXO7hj4,77
87
+ langgraph_api-0.0.10.dist-info/RECORD,,
langgraph_storage/ops.py CHANGED
@@ -846,7 +846,6 @@ class Threads(Authenticated):
846
846
  raise HTTPException(
847
847
  status_code=404, detail=f"Thread with ID {thread_id} not found"
848
848
  )
849
-
850
849
  # Delete the thread
851
850
  conn.locks.pop(thread_id, None)
852
851
  # Cascade delete all runs associated with this thread