mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-22 07:32:25 +02:00
**Description:** The crons create endpoint supports an end-time field that is not currently supported in the client. Adding that parameter here. **Issue:** N/A **Dependencies:** N/A **Twitter handle:** N/A
279 lines
9.0 KiB
Python
279 lines
9.0 KiB
Python
"""Tests for the crons client."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from datetime import datetime, timezone
|
|
|
|
import httpx
|
|
import pytest
|
|
|
|
from langgraph_sdk.client import (
|
|
CronClient,
|
|
HttpClient,
|
|
SyncCronClient,
|
|
SyncHttpClient,
|
|
)
|
|
|
|
|
|
def _cron_payload() -> dict[str, object]:
|
|
"""Return a mock cron response payload."""
|
|
return {
|
|
"run_id": "run_123",
|
|
"thread_id": "thread_123",
|
|
"assistant_id": "asst_123",
|
|
"created_at": "2024-01-01T00:00:00Z",
|
|
"updated_at": "2024-01-02T00:00:00Z",
|
|
"status": "success",
|
|
"metadata": {},
|
|
"multitask_strategy": "reject",
|
|
}
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_async_create_for_thread():
|
|
"""Test that CronClient.create_for_thread works without end_time."""
|
|
cron = _cron_payload()
|
|
|
|
async def handler(request: httpx.Request) -> httpx.Response:
|
|
assert request.method == "POST"
|
|
assert request.url.path == "/threads/thread_123/runs/crons"
|
|
|
|
# Parse the request body
|
|
body = json.loads(request.content)
|
|
assert body["schedule"] == "0 0 * * *"
|
|
assert body["assistant_id"] == "asst_123"
|
|
assert "end_time" not in body # Should be filtered out by the None check
|
|
|
|
return httpx.Response(200, json=cron)
|
|
|
|
transport = httpx.MockTransport(handler)
|
|
async with httpx.AsyncClient(
|
|
transport=transport, base_url="https://example.com"
|
|
) as client:
|
|
http_client = HttpClient(client)
|
|
cron_client = CronClient(http_client)
|
|
result = await cron_client.create_for_thread(
|
|
thread_id="thread_123",
|
|
assistant_id="asst_123",
|
|
schedule="0 0 * * *",
|
|
)
|
|
|
|
assert result == cron
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_async_create_for_thread_with_end_time():
|
|
"""Test that CronClient.create_for_thread includes end_time in the payload."""
|
|
cron = _cron_payload()
|
|
end_time = datetime(2025, 12, 31, 23, 59, 59, tzinfo=timezone.utc)
|
|
|
|
async def handler(request: httpx.Request) -> httpx.Response:
|
|
assert request.method == "POST"
|
|
assert request.url.path == "/threads/thread_123/runs/crons"
|
|
|
|
# Parse the request body
|
|
body = json.loads(request.content)
|
|
assert body["schedule"] == "0 0 * * *"
|
|
assert body["assistant_id"] == "asst_123"
|
|
assert body["end_time"] == "2025-12-31T23:59:59+00:00"
|
|
|
|
return httpx.Response(200, json=cron)
|
|
|
|
transport = httpx.MockTransport(handler)
|
|
async with httpx.AsyncClient(
|
|
transport=transport, base_url="https://example.com"
|
|
) as client:
|
|
http_client = HttpClient(client)
|
|
cron_client = CronClient(http_client)
|
|
result = await cron_client.create_for_thread(
|
|
thread_id="thread_123",
|
|
assistant_id="asst_123",
|
|
schedule="0 0 * * *",
|
|
end_time=end_time,
|
|
)
|
|
|
|
assert result == cron
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_async_create():
|
|
"""Test that CronClient.create works without end_time."""
|
|
cron = _cron_payload()
|
|
|
|
async def handler(request: httpx.Request) -> httpx.Response:
|
|
assert request.method == "POST"
|
|
assert request.url.path == "/runs/crons"
|
|
|
|
# Parse the request body
|
|
body = json.loads(request.content)
|
|
assert body["schedule"] == "0 12 * * *"
|
|
assert body["assistant_id"] == "asst_456"
|
|
assert "end_time" not in body # Should be filtered out by the None check
|
|
|
|
return httpx.Response(200, json=cron)
|
|
|
|
transport = httpx.MockTransport(handler)
|
|
async with httpx.AsyncClient(
|
|
transport=transport, base_url="https://example.com"
|
|
) as client:
|
|
http_client = HttpClient(client)
|
|
cron_client = CronClient(http_client)
|
|
result = await cron_client.create(
|
|
assistant_id="asst_456",
|
|
schedule="0 12 * * *",
|
|
)
|
|
|
|
assert result == cron
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_async_create_with_end_time():
|
|
"""Test that CronClient.create includes end_time in the payload."""
|
|
cron = _cron_payload()
|
|
end_time = datetime(2025, 6, 15, 12, 0, 0, tzinfo=timezone.utc)
|
|
|
|
async def handler(request: httpx.Request) -> httpx.Response:
|
|
assert request.method == "POST"
|
|
assert request.url.path == "/runs/crons"
|
|
|
|
# Parse the request body
|
|
body = json.loads(request.content)
|
|
assert body["schedule"] == "0 12 * * *"
|
|
assert body["assistant_id"] == "asst_456"
|
|
assert body["end_time"] == "2025-06-15T12:00:00+00:00"
|
|
|
|
return httpx.Response(200, json=cron)
|
|
|
|
transport = httpx.MockTransport(handler)
|
|
async with httpx.AsyncClient(
|
|
transport=transport, base_url="https://example.com"
|
|
) as client:
|
|
http_client = HttpClient(client)
|
|
cron_client = CronClient(http_client)
|
|
result = await cron_client.create(
|
|
assistant_id="asst_456",
|
|
schedule="0 12 * * *",
|
|
end_time=end_time,
|
|
)
|
|
|
|
assert result == cron
|
|
|
|
|
|
def test_sync_create_for_thread():
|
|
"""Test that SyncCronClient.create_for_thread works without end_time."""
|
|
cron = _cron_payload()
|
|
|
|
def handler(request: httpx.Request) -> httpx.Response:
|
|
assert request.method == "POST"
|
|
assert request.url.path == "/threads/thread_123/runs/crons"
|
|
|
|
# Parse the request body
|
|
body = json.loads(request.content)
|
|
assert body["schedule"] == "0 0 * * *"
|
|
assert body["assistant_id"] == "asst_123"
|
|
assert "end_time" not in body # Should be filtered out by the None check
|
|
|
|
return httpx.Response(200, json=cron)
|
|
|
|
transport = httpx.MockTransport(handler)
|
|
with httpx.Client(transport=transport, base_url="https://example.com") as client:
|
|
http_client = SyncHttpClient(client)
|
|
cron_client = SyncCronClient(http_client)
|
|
result = cron_client.create_for_thread(
|
|
thread_id="thread_123",
|
|
assistant_id="asst_123",
|
|
schedule="0 0 * * *",
|
|
)
|
|
|
|
assert result == cron
|
|
|
|
|
|
def test_sync_create_for_thread_with_end_time():
|
|
"""Test that SyncCronClient.create_for_thread includes end_time in the payload."""
|
|
cron = _cron_payload()
|
|
end_time = datetime(2025, 12, 31, 23, 59, 59, tzinfo=timezone.utc)
|
|
|
|
def handler(request: httpx.Request) -> httpx.Response:
|
|
assert request.method == "POST"
|
|
assert request.url.path == "/threads/thread_123/runs/crons"
|
|
|
|
# Parse the request body
|
|
body = json.loads(request.content)
|
|
assert body["schedule"] == "0 0 * * *"
|
|
assert body["assistant_id"] == "asst_123"
|
|
assert body["end_time"] == "2025-12-31T23:59:59+00:00"
|
|
|
|
return httpx.Response(200, json=cron)
|
|
|
|
transport = httpx.MockTransport(handler)
|
|
with httpx.Client(transport=transport, base_url="https://example.com") as client:
|
|
http_client = SyncHttpClient(client)
|
|
cron_client = SyncCronClient(http_client)
|
|
result = cron_client.create_for_thread(
|
|
thread_id="thread_123",
|
|
assistant_id="asst_123",
|
|
schedule="0 0 * * *",
|
|
end_time=end_time,
|
|
)
|
|
|
|
assert result == cron
|
|
|
|
|
|
def test_sync_create():
|
|
"""Test that SyncCronClient.create works without end_time."""
|
|
cron = _cron_payload()
|
|
|
|
def handler(request: httpx.Request) -> httpx.Response:
|
|
assert request.method == "POST"
|
|
assert request.url.path == "/runs/crons"
|
|
|
|
# Parse the request body
|
|
body = json.loads(request.content)
|
|
assert body["schedule"] == "0 12 * * *"
|
|
assert body["assistant_id"] == "asst_456"
|
|
assert "end_time" not in body # Should be filtered out by the None check
|
|
|
|
return httpx.Response(200, json=cron)
|
|
|
|
transport = httpx.MockTransport(handler)
|
|
with httpx.Client(transport=transport, base_url="https://example.com") as client:
|
|
http_client = SyncHttpClient(client)
|
|
cron_client = SyncCronClient(http_client)
|
|
result = cron_client.create(
|
|
assistant_id="asst_456",
|
|
schedule="0 12 * * *",
|
|
)
|
|
|
|
assert result == cron
|
|
|
|
|
|
def test_sync_create_with_end_time():
|
|
"""Test that SyncCronClient.create includes end_time in the payload."""
|
|
cron = _cron_payload()
|
|
end_time = datetime(2025, 6, 15, 12, 0, 0, tzinfo=timezone.utc)
|
|
|
|
def handler(request: httpx.Request) -> httpx.Response:
|
|
assert request.method == "POST"
|
|
assert request.url.path == "/runs/crons"
|
|
|
|
# Parse the request body
|
|
body = json.loads(request.content)
|
|
assert body["schedule"] == "0 12 * * *"
|
|
assert body["assistant_id"] == "asst_456"
|
|
assert body["end_time"] == "2025-06-15T12:00:00+00:00"
|
|
|
|
return httpx.Response(200, json=cron)
|
|
|
|
transport = httpx.MockTransport(handler)
|
|
with httpx.Client(transport=transport, base_url="https://example.com") as client:
|
|
http_client = SyncHttpClient(client)
|
|
cron_client = SyncCronClient(http_client)
|
|
result = cron_client.create(
|
|
assistant_id="asst_456",
|
|
schedule="0 12 * * *",
|
|
end_time=end_time,
|
|
)
|
|
|
|
assert result == cron
|