mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-21 23:22:27 +02:00
**Description:** This PR adds the Python SDK types necessary for langgraph platform users to inject their own custom encryption-at-rest functions. See [docs PR](https://github.com/langchain-ai/docs/pull/1715) for more details. note: this PR adds a starlette dev dependency so that custom encryption can access BaseUser information. **Issue:** required for LSD-172 **Dependencies:** - [depended upon by associated langgraph-api changes](https://github.com/langchain-ai/langgraph-api/pull/1773)(this PR must merge before that one) - [docs PR](https://github.com/langchain-ai/docs/pull/1715) **TODO:** - [x] move docs to docs repo - [x] bump package versions before merge --------- Signed-off-by: Connor Braa <cwlbraa@langchain.dev> Co-authored-by: Claude <noreply@anthropic.com>
93 lines
2.5 KiB
Python
93 lines
2.5 KiB
Python
import pytest
|
|
|
|
from langgraph_sdk.encryption import DuplicateHandlerError, Encryption
|
|
|
|
|
|
class TestHandlerValidation:
|
|
"""Test duplicate handler and signature validation."""
|
|
|
|
def test_duplicate_handlers_raise_error(self):
|
|
"""Registering the same handler type twice raises DuplicateHandlerError."""
|
|
encryption = Encryption()
|
|
|
|
@encryption.encrypt.blob
|
|
async def blob_enc(_ctx, data):
|
|
return data
|
|
|
|
@encryption.decrypt.blob
|
|
async def blob_dec(_ctx, data):
|
|
return data
|
|
|
|
@encryption.encrypt.json
|
|
async def json_enc(_ctx, data):
|
|
return data
|
|
|
|
@encryption.decrypt.json
|
|
async def json_dec(_ctx, data):
|
|
return data
|
|
|
|
@encryption.encrypt.json.thread
|
|
async def thread_enc(_ctx, data):
|
|
return data
|
|
|
|
@encryption.decrypt.json.custom
|
|
async def custom_dec(_ctx, data):
|
|
return data
|
|
|
|
# All duplicates should raise
|
|
with pytest.raises(DuplicateHandlerError):
|
|
|
|
@encryption.encrypt.blob
|
|
async def dup(_ctx, data):
|
|
return data
|
|
|
|
with pytest.raises(DuplicateHandlerError):
|
|
|
|
@encryption.decrypt.blob
|
|
async def dup(_ctx, data):
|
|
return data
|
|
|
|
with pytest.raises(DuplicateHandlerError):
|
|
|
|
@encryption.encrypt.json
|
|
async def dup(_ctx, data):
|
|
return data
|
|
|
|
with pytest.raises(DuplicateHandlerError):
|
|
|
|
@encryption.decrypt.json
|
|
async def dup(_ctx, data):
|
|
return data
|
|
|
|
with pytest.raises(DuplicateHandlerError):
|
|
|
|
@encryption.encrypt.json.thread
|
|
async def dup(_ctx, data):
|
|
return data
|
|
|
|
with pytest.raises(DuplicateHandlerError):
|
|
|
|
@encryption.decrypt.json.custom
|
|
async def dup(_ctx, data):
|
|
return data
|
|
|
|
def test_handlers_must_be_async(self):
|
|
"""Sync functions raise TypeError."""
|
|
encryption = Encryption()
|
|
|
|
with pytest.raises(TypeError, match="must be an async function"):
|
|
|
|
@encryption.encrypt.blob
|
|
def sync_handler(_ctx, data):
|
|
return data
|
|
|
|
def test_handlers_must_have_two_params(self):
|
|
"""Wrong parameter count raises TypeError."""
|
|
encryption = Encryption()
|
|
|
|
with pytest.raises(TypeError, match="must accept exactly 2 parameters"):
|
|
|
|
@encryption.encrypt.blob # type: ignore[arg-type]
|
|
async def wrong_params(ctx):
|
|
return ctx
|