langgraph-sdk 0.3.3__tar.gz → 0.3.4__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.
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/PKG-INFO +2 -2
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/langgraph_sdk/__init__.py +1 -1
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/langgraph_sdk/client.py +184 -4
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/langgraph_sdk/schema.py +30 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/pyproject.toml +2 -2
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/tests/test_crons_client.py +209 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/uv.lock +235 -239
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/.gitignore +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/LICENSE +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/Makefile +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/README.md +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/langgraph_sdk/auth/__init__.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/langgraph_sdk/auth/exceptions.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/langgraph_sdk/auth/types.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/langgraph_sdk/encryption/__init__.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/langgraph_sdk/encryption/types.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/langgraph_sdk/errors.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/langgraph_sdk/py.typed +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/langgraph_sdk/sse.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/tests/fixtures/response.txt +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/tests/test_api_parity.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/tests/test_assistants_client.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/tests/test_client_stream.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/tests/test_encryption.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/tests/test_errors.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/tests/test_serde.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/tests/test_serde_schema.py +0 -0
- {langgraph_sdk-0.3.3 → langgraph_sdk-0.3.4}/tests/test_skip_auto_load_api_key.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: langgraph-sdk
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: SDK for interacting with LangGraph API
|
|
5
5
|
Project-URL: Source, https://github.com/langchain-ai/langgraph/tree/main/libs/sdk-py
|
|
6
|
-
Project-URL: Twitter, https://x.com/
|
|
6
|
+
Project-URL: Twitter, https://x.com/LangChain
|
|
7
7
|
Project-URL: Slack, https://www.langchain.com/join-community
|
|
8
8
|
Project-URL: Reddit, https://www.reddit.com/r/LangChain/
|
|
9
9
|
License-Expression: MIT
|
|
@@ -3,6 +3,6 @@ from langgraph_sdk.client import get_client, get_sync_client
|
|
|
3
3
|
from langgraph_sdk.encryption import Encryption
|
|
4
4
|
from langgraph_sdk.encryption.types import EncryptionContext
|
|
5
5
|
|
|
6
|
-
__version__ = "0.3.
|
|
6
|
+
__version__ = "0.3.4"
|
|
7
7
|
|
|
8
8
|
__all__ = ["Auth", "Encryption", "EncryptionContext", "get_client", "get_sync_client"]
|
|
@@ -2984,6 +2984,7 @@ class CronClient:
|
|
|
2984
2984
|
webhook: str | None = None,
|
|
2985
2985
|
multitask_strategy: str | None = None,
|
|
2986
2986
|
end_time: datetime | None = None,
|
|
2987
|
+
enabled: bool | None = None,
|
|
2987
2988
|
headers: Mapping[str, str] | None = None,
|
|
2988
2989
|
params: QueryParamTypes | None = None,
|
|
2989
2990
|
) -> Run:
|
|
@@ -2994,6 +2995,7 @@ class CronClient:
|
|
|
2994
2995
|
assistant_id: The assistant ID or graph name to use for the cron job.
|
|
2995
2996
|
If using graph name, will default to first assistant created from that graph.
|
|
2996
2997
|
schedule: The cron schedule to execute this job on.
|
|
2998
|
+
Schedules are interpreted in UTC.
|
|
2997
2999
|
input: The input to the graph.
|
|
2998
3000
|
metadata: Metadata to assign to the cron job runs.
|
|
2999
3001
|
config: The configuration for the assistant.
|
|
@@ -3008,6 +3010,7 @@ class CronClient:
|
|
|
3008
3010
|
multitask_strategy: Multitask strategy to use.
|
|
3009
3011
|
Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
|
|
3010
3012
|
end_time: The time to stop running the cron job. If not provided, the cron job will run indefinitely.
|
|
3013
|
+
enabled: Whether the cron job is enabled or not.
|
|
3011
3014
|
headers: Optional custom headers to include with the request.
|
|
3012
3015
|
params: Optional query parameters to include with the request.
|
|
3013
3016
|
|
|
@@ -3028,7 +3031,8 @@ class CronClient:
|
|
|
3028
3031
|
interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
|
|
3029
3032
|
interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
|
|
3030
3033
|
webhook="https://my.fake.webhook.com",
|
|
3031
|
-
multitask_strategy="interrupt"
|
|
3034
|
+
multitask_strategy="interrupt",
|
|
3035
|
+
enabled=True,
|
|
3032
3036
|
)
|
|
3033
3037
|
```
|
|
3034
3038
|
"""
|
|
@@ -3044,6 +3048,7 @@ class CronClient:
|
|
|
3044
3048
|
"interrupt_after": interrupt_after,
|
|
3045
3049
|
"webhook": webhook,
|
|
3046
3050
|
"end_time": end_time.isoformat() if end_time else None,
|
|
3051
|
+
"enabled": enabled,
|
|
3047
3052
|
}
|
|
3048
3053
|
if multitask_strategy:
|
|
3049
3054
|
payload["multitask_strategy"] = multitask_strategy
|
|
@@ -3071,6 +3076,7 @@ class CronClient:
|
|
|
3071
3076
|
on_run_completed: OnCompletionBehavior | None = None,
|
|
3072
3077
|
multitask_strategy: str | None = None,
|
|
3073
3078
|
end_time: datetime | None = None,
|
|
3079
|
+
enabled: bool | None = None,
|
|
3074
3080
|
headers: Mapping[str, str] | None = None,
|
|
3075
3081
|
params: QueryParamTypes | None = None,
|
|
3076
3082
|
) -> Run:
|
|
@@ -3080,6 +3086,7 @@ class CronClient:
|
|
|
3080
3086
|
assistant_id: The assistant ID or graph name to use for the cron job.
|
|
3081
3087
|
If using graph name, will default to first assistant created from that graph.
|
|
3082
3088
|
schedule: The cron schedule to execute this job on.
|
|
3089
|
+
Schedules are interpreted in UTC.
|
|
3083
3090
|
input: The input to the graph.
|
|
3084
3091
|
metadata: Metadata to assign to the cron job runs.
|
|
3085
3092
|
config: The configuration for the assistant.
|
|
@@ -3096,6 +3103,7 @@ class CronClient:
|
|
|
3096
3103
|
multitask_strategy: Multitask strategy to use.
|
|
3097
3104
|
Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
|
|
3098
3105
|
end_time: The time to stop running the cron job. If not provided, the cron job will run indefinitely.
|
|
3106
|
+
enabled: Whether the cron job is enabled or not.
|
|
3099
3107
|
headers: Optional custom headers to include with the request.
|
|
3100
3108
|
params: Optional query parameters to include with the request.
|
|
3101
3109
|
|
|
@@ -3115,7 +3123,8 @@ class CronClient:
|
|
|
3115
3123
|
interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
|
|
3116
3124
|
interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
|
|
3117
3125
|
webhook="https://my.fake.webhook.com",
|
|
3118
|
-
multitask_strategy="interrupt"
|
|
3126
|
+
multitask_strategy="interrupt",
|
|
3127
|
+
enabled=True,
|
|
3119
3128
|
)
|
|
3120
3129
|
```
|
|
3121
3130
|
|
|
@@ -3133,6 +3142,7 @@ class CronClient:
|
|
|
3133
3142
|
"webhook": webhook,
|
|
3134
3143
|
"on_run_completed": on_run_completed,
|
|
3135
3144
|
"end_time": end_time.isoformat() if end_time else None,
|
|
3145
|
+
"enabled": enabled,
|
|
3136
3146
|
}
|
|
3137
3147
|
if multitask_strategy:
|
|
3138
3148
|
payload["multitask_strategy"] = multitask_strategy
|
|
@@ -3170,11 +3180,88 @@ class CronClient:
|
|
|
3170
3180
|
"""
|
|
3171
3181
|
await self.http.delete(f"/runs/crons/{cron_id}", headers=headers, params=params)
|
|
3172
3182
|
|
|
3183
|
+
async def update(
|
|
3184
|
+
self,
|
|
3185
|
+
cron_id: str,
|
|
3186
|
+
*,
|
|
3187
|
+
schedule: str | None = None,
|
|
3188
|
+
end_time: datetime | None = None,
|
|
3189
|
+
input: Input | None = None,
|
|
3190
|
+
metadata: Mapping[str, Any] | None = None,
|
|
3191
|
+
config: Config | None = None,
|
|
3192
|
+
context: Context | None = None,
|
|
3193
|
+
webhook: str | None = None,
|
|
3194
|
+
interrupt_before: All | list[str] | None = None,
|
|
3195
|
+
interrupt_after: All | list[str] | None = None,
|
|
3196
|
+
on_run_completed: OnCompletionBehavior | None = None,
|
|
3197
|
+
enabled: bool | None = None,
|
|
3198
|
+
headers: Mapping[str, str] | None = None,
|
|
3199
|
+
params: QueryParamTypes | None = None,
|
|
3200
|
+
) -> Cron:
|
|
3201
|
+
"""Update a cron job by ID.
|
|
3202
|
+
|
|
3203
|
+
Args:
|
|
3204
|
+
cron_id: The cron ID to update.
|
|
3205
|
+
schedule: The cron schedule to execute this job on.
|
|
3206
|
+
Schedules are interpreted in UTC.
|
|
3207
|
+
end_time: The end date to stop running the cron.
|
|
3208
|
+
input: The input to the graph.
|
|
3209
|
+
metadata: Metadata to assign to the cron job runs.
|
|
3210
|
+
config: The configuration for the assistant.
|
|
3211
|
+
context: Static context added to the assistant.
|
|
3212
|
+
webhook: Webhook to call after LangGraph API call is done.
|
|
3213
|
+
interrupt_before: Nodes to interrupt immediately before they get executed.
|
|
3214
|
+
interrupt_after: Nodes to interrupt immediately after they get executed.
|
|
3215
|
+
on_run_completed: What to do with the thread after the run completes.
|
|
3216
|
+
Must be one of 'delete' or 'keep'. 'delete' removes the thread
|
|
3217
|
+
after execution. 'keep' creates a new thread for each execution but does not
|
|
3218
|
+
clean them up.
|
|
3219
|
+
enabled: Enable or disable the cron job.
|
|
3220
|
+
headers: Optional custom headers to include with the request.
|
|
3221
|
+
params: Optional query parameters to include with the request.
|
|
3222
|
+
|
|
3223
|
+
Returns:
|
|
3224
|
+
The updated cron job.
|
|
3225
|
+
|
|
3226
|
+
???+ example "Example Usage"
|
|
3227
|
+
|
|
3228
|
+
```python
|
|
3229
|
+
client = get_client(url="http://localhost:2024")
|
|
3230
|
+
updated_cron = await client.crons.update(
|
|
3231
|
+
cron_id="1ef3cefa-4c09-6926-96d0-3dc97fd5e39b",
|
|
3232
|
+
schedule="0 10 * * *",
|
|
3233
|
+
enabled=False,
|
|
3234
|
+
)
|
|
3235
|
+
```
|
|
3236
|
+
|
|
3237
|
+
"""
|
|
3238
|
+
payload = {
|
|
3239
|
+
"schedule": schedule,
|
|
3240
|
+
"end_time": end_time.isoformat() if end_time else None,
|
|
3241
|
+
"input": input,
|
|
3242
|
+
"metadata": metadata,
|
|
3243
|
+
"config": config,
|
|
3244
|
+
"context": context,
|
|
3245
|
+
"webhook": webhook,
|
|
3246
|
+
"interrupt_before": interrupt_before,
|
|
3247
|
+
"interrupt_after": interrupt_after,
|
|
3248
|
+
"on_run_completed": on_run_completed,
|
|
3249
|
+
"enabled": enabled,
|
|
3250
|
+
}
|
|
3251
|
+
payload = {k: v for k, v in payload.items() if v is not None}
|
|
3252
|
+
return await self.http.patch(
|
|
3253
|
+
f"/runs/crons/{cron_id}",
|
|
3254
|
+
json=payload,
|
|
3255
|
+
headers=headers,
|
|
3256
|
+
params=params,
|
|
3257
|
+
)
|
|
3258
|
+
|
|
3173
3259
|
async def search(
|
|
3174
3260
|
self,
|
|
3175
3261
|
*,
|
|
3176
3262
|
assistant_id: str | None = None,
|
|
3177
3263
|
thread_id: str | None = None,
|
|
3264
|
+
enabled: bool | None = None,
|
|
3178
3265
|
limit: int = 10,
|
|
3179
3266
|
offset: int = 0,
|
|
3180
3267
|
sort_by: CronSortBy | None = None,
|
|
@@ -3188,6 +3275,7 @@ class CronClient:
|
|
|
3188
3275
|
Args:
|
|
3189
3276
|
assistant_id: The assistant ID or graph name to search for.
|
|
3190
3277
|
thread_id: the thread ID to search for.
|
|
3278
|
+
enabled: The enabled status to search for.
|
|
3191
3279
|
limit: The maximum number of results to return.
|
|
3192
3280
|
offset: The number of results to skip.
|
|
3193
3281
|
headers: Optional custom headers to include with the request.
|
|
@@ -3203,6 +3291,7 @@ class CronClient:
|
|
|
3203
3291
|
cron_jobs = await client.crons.search(
|
|
3204
3292
|
assistant_id="my_assistant_id",
|
|
3205
3293
|
thread_id="my_thread_id",
|
|
3294
|
+
enabled=True,
|
|
3206
3295
|
limit=5,
|
|
3207
3296
|
offset=5,
|
|
3208
3297
|
)
|
|
@@ -3237,6 +3326,7 @@ class CronClient:
|
|
|
3237
3326
|
payload = {
|
|
3238
3327
|
"assistant_id": assistant_id,
|
|
3239
3328
|
"thread_id": thread_id,
|
|
3329
|
+
"enabled": enabled,
|
|
3240
3330
|
"limit": limit,
|
|
3241
3331
|
"offset": offset,
|
|
3242
3332
|
}
|
|
@@ -6292,6 +6382,7 @@ class SyncCronClient:
|
|
|
6292
6382
|
webhook: str | None = None,
|
|
6293
6383
|
multitask_strategy: str | None = None,
|
|
6294
6384
|
end_time: datetime | None = None,
|
|
6385
|
+
enabled: bool | None = None,
|
|
6295
6386
|
headers: Mapping[str, str] | None = None,
|
|
6296
6387
|
params: QueryParamTypes | None = None,
|
|
6297
6388
|
) -> Run:
|
|
@@ -6302,6 +6393,7 @@ class SyncCronClient:
|
|
|
6302
6393
|
assistant_id: The assistant ID or graph name to use for the cron job.
|
|
6303
6394
|
If using graph name, will default to first assistant created from that graph.
|
|
6304
6395
|
schedule: The cron schedule to execute this job on.
|
|
6396
|
+
Schedules are interpreted in UTC.
|
|
6305
6397
|
input: The input to the graph.
|
|
6306
6398
|
metadata: Metadata to assign to the cron job runs.
|
|
6307
6399
|
config: The configuration for the assistant.
|
|
@@ -6314,6 +6406,7 @@ class SyncCronClient:
|
|
|
6314
6406
|
multitask_strategy: Multitask strategy to use.
|
|
6315
6407
|
Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
|
|
6316
6408
|
end_time: The time to stop running the cron job. If not provided, the cron job will run indefinitely.
|
|
6409
|
+
enabled: Whether the cron job is enabled. By default, it is considered enabled.
|
|
6317
6410
|
headers: Optional custom headers to include with the request.
|
|
6318
6411
|
|
|
6319
6412
|
Returns:
|
|
@@ -6333,7 +6426,8 @@ class SyncCronClient:
|
|
|
6333
6426
|
interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
|
|
6334
6427
|
interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
|
|
6335
6428
|
webhook="https://my.fake.webhook.com",
|
|
6336
|
-
multitask_strategy="interrupt"
|
|
6429
|
+
multitask_strategy="interrupt",
|
|
6430
|
+
enabled=True
|
|
6337
6431
|
)
|
|
6338
6432
|
```
|
|
6339
6433
|
"""
|
|
@@ -6350,6 +6444,7 @@ class SyncCronClient:
|
|
|
6350
6444
|
"webhook": webhook,
|
|
6351
6445
|
"multitask_strategy": multitask_strategy,
|
|
6352
6446
|
"end_time": end_time.isoformat() if end_time else None,
|
|
6447
|
+
"enabled": enabled,
|
|
6353
6448
|
}
|
|
6354
6449
|
payload = {k: v for k, v in payload.items() if v is not None}
|
|
6355
6450
|
return self.http.post(
|
|
@@ -6375,6 +6470,7 @@ class SyncCronClient:
|
|
|
6375
6470
|
on_run_completed: OnCompletionBehavior | None = None,
|
|
6376
6471
|
multitask_strategy: str | None = None,
|
|
6377
6472
|
end_time: datetime | None = None,
|
|
6473
|
+
enabled: bool | None = None,
|
|
6378
6474
|
headers: Mapping[str, str] | None = None,
|
|
6379
6475
|
params: QueryParamTypes | None = None,
|
|
6380
6476
|
) -> Run:
|
|
@@ -6384,6 +6480,7 @@ class SyncCronClient:
|
|
|
6384
6480
|
assistant_id: The assistant ID or graph name to use for the cron job.
|
|
6385
6481
|
If using graph name, will default to first assistant created from that graph.
|
|
6386
6482
|
schedule: The cron schedule to execute this job on.
|
|
6483
|
+
Schedules are interpreted in UTC.
|
|
6387
6484
|
input: The input to the graph.
|
|
6388
6485
|
metadata: Metadata to assign to the cron job runs.
|
|
6389
6486
|
config: The configuration for the assistant.
|
|
@@ -6400,6 +6497,7 @@ class SyncCronClient:
|
|
|
6400
6497
|
multitask_strategy: Multitask strategy to use.
|
|
6401
6498
|
Must be one of 'reject', 'interrupt', 'rollback', or 'enqueue'.
|
|
6402
6499
|
end_time: The time to stop running the cron job. If not provided, the cron job will run indefinitely.
|
|
6500
|
+
enabled: Whether the cron job is enabled. By default, it is considered enabled.
|
|
6403
6501
|
headers: Optional custom headers to include with the request.
|
|
6404
6502
|
|
|
6405
6503
|
Returns:
|
|
@@ -6419,7 +6517,8 @@ class SyncCronClient:
|
|
|
6419
6517
|
interrupt_before=["node_to_stop_before_1","node_to_stop_before_2"],
|
|
6420
6518
|
interrupt_after=["node_to_stop_after_1","node_to_stop_after_2"],
|
|
6421
6519
|
webhook="https://my.fake.webhook.com",
|
|
6422
|
-
multitask_strategy="interrupt"
|
|
6520
|
+
multitask_strategy="interrupt",
|
|
6521
|
+
enabled=True
|
|
6423
6522
|
)
|
|
6424
6523
|
```
|
|
6425
6524
|
|
|
@@ -6438,6 +6537,7 @@ class SyncCronClient:
|
|
|
6438
6537
|
"on_run_completed": on_run_completed,
|
|
6439
6538
|
"multitask_strategy": multitask_strategy,
|
|
6440
6539
|
"end_time": end_time.isoformat() if end_time else None,
|
|
6540
|
+
"enabled": enabled,
|
|
6441
6541
|
}
|
|
6442
6542
|
payload = {k: v for k, v in payload.items() if v is not None}
|
|
6443
6543
|
return self.http.post(
|
|
@@ -6473,11 +6573,88 @@ class SyncCronClient:
|
|
|
6473
6573
|
"""
|
|
6474
6574
|
self.http.delete(f"/runs/crons/{cron_id}", headers=headers, params=params)
|
|
6475
6575
|
|
|
6576
|
+
def update(
|
|
6577
|
+
self,
|
|
6578
|
+
cron_id: str,
|
|
6579
|
+
*,
|
|
6580
|
+
schedule: str | None = None,
|
|
6581
|
+
end_time: datetime | None = None,
|
|
6582
|
+
input: Input | None = None,
|
|
6583
|
+
metadata: Mapping[str, Any] | None = None,
|
|
6584
|
+
config: Config | None = None,
|
|
6585
|
+
context: Context | None = None,
|
|
6586
|
+
webhook: str | None = None,
|
|
6587
|
+
interrupt_before: All | list[str] | None = None,
|
|
6588
|
+
interrupt_after: All | list[str] | None = None,
|
|
6589
|
+
on_run_completed: OnCompletionBehavior | None = None,
|
|
6590
|
+
enabled: bool | None = None,
|
|
6591
|
+
headers: Mapping[str, str] | None = None,
|
|
6592
|
+
params: QueryParamTypes | None = None,
|
|
6593
|
+
) -> Cron:
|
|
6594
|
+
"""Update a cron job by ID.
|
|
6595
|
+
|
|
6596
|
+
Args:
|
|
6597
|
+
cron_id: The cron ID to update.
|
|
6598
|
+
schedule: The cron schedule to execute this job on.
|
|
6599
|
+
Schedules are interpreted in UTC.
|
|
6600
|
+
end_time: The end date to stop running the cron.
|
|
6601
|
+
input: The input to the graph.
|
|
6602
|
+
metadata: Metadata to assign to the cron job runs.
|
|
6603
|
+
config: The configuration for the assistant.
|
|
6604
|
+
context: Static context added to the assistant.
|
|
6605
|
+
webhook: Webhook to call after LangGraph API call is done.
|
|
6606
|
+
interrupt_before: Nodes to interrupt immediately before they get executed.
|
|
6607
|
+
interrupt_after: Nodes to interrupt immediately after they get executed.
|
|
6608
|
+
on_run_completed: What to do with the thread after the run completes.
|
|
6609
|
+
Must be one of 'delete' or 'keep'. 'delete' removes the thread
|
|
6610
|
+
after execution. 'keep' creates a new thread for each execution but does not
|
|
6611
|
+
clean them up.
|
|
6612
|
+
enabled: Enable or disable the cron job.
|
|
6613
|
+
headers: Optional custom headers to include with the request.
|
|
6614
|
+
params: Optional query parameters to include with the request.
|
|
6615
|
+
|
|
6616
|
+
Returns:
|
|
6617
|
+
The updated cron job.
|
|
6618
|
+
|
|
6619
|
+
???+ example "Example Usage"
|
|
6620
|
+
|
|
6621
|
+
```python
|
|
6622
|
+
client = get_sync_client(url="http://localhost:8123")
|
|
6623
|
+
updated_cron = client.crons.update(
|
|
6624
|
+
cron_id="1ef3cefa-4c09-6926-96d0-3dc97fd5e39b",
|
|
6625
|
+
schedule="0 10 * * *",
|
|
6626
|
+
enabled=False,
|
|
6627
|
+
)
|
|
6628
|
+
```
|
|
6629
|
+
|
|
6630
|
+
"""
|
|
6631
|
+
payload = {
|
|
6632
|
+
"schedule": schedule,
|
|
6633
|
+
"end_time": end_time.isoformat() if end_time else None,
|
|
6634
|
+
"input": input,
|
|
6635
|
+
"metadata": metadata,
|
|
6636
|
+
"config": config,
|
|
6637
|
+
"context": context,
|
|
6638
|
+
"webhook": webhook,
|
|
6639
|
+
"interrupt_before": interrupt_before,
|
|
6640
|
+
"interrupt_after": interrupt_after,
|
|
6641
|
+
"on_run_completed": on_run_completed,
|
|
6642
|
+
"enabled": enabled,
|
|
6643
|
+
}
|
|
6644
|
+
payload = {k: v for k, v in payload.items() if v is not None}
|
|
6645
|
+
return self.http.patch(
|
|
6646
|
+
f"/runs/crons/{cron_id}",
|
|
6647
|
+
json=payload,
|
|
6648
|
+
headers=headers,
|
|
6649
|
+
params=params,
|
|
6650
|
+
)
|
|
6651
|
+
|
|
6476
6652
|
def search(
|
|
6477
6653
|
self,
|
|
6478
6654
|
*,
|
|
6479
6655
|
assistant_id: str | None = None,
|
|
6480
6656
|
thread_id: str | None = None,
|
|
6657
|
+
enabled: bool | None = None,
|
|
6481
6658
|
limit: int = 10,
|
|
6482
6659
|
offset: int = 0,
|
|
6483
6660
|
sort_by: CronSortBy | None = None,
|
|
@@ -6491,6 +6668,7 @@ class SyncCronClient:
|
|
|
6491
6668
|
Args:
|
|
6492
6669
|
assistant_id: The assistant ID or graph name to search for.
|
|
6493
6670
|
thread_id: the thread ID to search for.
|
|
6671
|
+
enabled: Whether the cron job is enabled.
|
|
6494
6672
|
limit: The maximum number of results to return.
|
|
6495
6673
|
offset: The number of results to skip.
|
|
6496
6674
|
headers: Optional custom headers to include with the request.
|
|
@@ -6505,6 +6683,7 @@ class SyncCronClient:
|
|
|
6505
6683
|
cron_jobs = client.crons.search(
|
|
6506
6684
|
assistant_id="my_assistant_id",
|
|
6507
6685
|
thread_id="my_thread_id",
|
|
6686
|
+
enabled=True,
|
|
6508
6687
|
limit=5,
|
|
6509
6688
|
offset=5,
|
|
6510
6689
|
)
|
|
@@ -6538,6 +6717,7 @@ class SyncCronClient:
|
|
|
6538
6717
|
payload = {
|
|
6539
6718
|
"assistant_id": assistant_id,
|
|
6540
6719
|
"thread_id": thread_id,
|
|
6720
|
+
"enabled": enabled,
|
|
6541
6721
|
"limit": limit,
|
|
6542
6722
|
"offset": offset,
|
|
6543
6723
|
}
|
|
@@ -372,6 +372,35 @@ class Cron(TypedDict):
|
|
|
372
372
|
"""The next run date of the cron."""
|
|
373
373
|
metadata: dict
|
|
374
374
|
"""The metadata of the cron."""
|
|
375
|
+
enabled: bool
|
|
376
|
+
"""Whether the cron is enabled."""
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
class CronUpdate(TypedDict, total=False):
|
|
380
|
+
"""Payload for updating a cron job. All fields are optional."""
|
|
381
|
+
|
|
382
|
+
schedule: str
|
|
383
|
+
"""The cron schedule to execute this job on."""
|
|
384
|
+
end_time: datetime
|
|
385
|
+
"""The end date to stop running the cron."""
|
|
386
|
+
input: Input
|
|
387
|
+
"""The input to the graph."""
|
|
388
|
+
metadata: dict[str, Any]
|
|
389
|
+
"""Metadata to assign to the cron job runs."""
|
|
390
|
+
config: Config
|
|
391
|
+
"""The configuration for the assistant."""
|
|
392
|
+
context: Context
|
|
393
|
+
"""Static context added to the assistant."""
|
|
394
|
+
webhook: str
|
|
395
|
+
"""Webhook to call after LangGraph API call is done."""
|
|
396
|
+
interrupt_before: All | list[str]
|
|
397
|
+
"""Nodes to interrupt immediately before they get executed."""
|
|
398
|
+
interrupt_after: All | list[str]
|
|
399
|
+
"""Nodes to interrupt immediately after they get executed."""
|
|
400
|
+
on_run_completed: OnCompletionBehavior
|
|
401
|
+
"""What to do with the thread after the run completes."""
|
|
402
|
+
enabled: bool
|
|
403
|
+
"""Enable or disable the cron job."""
|
|
375
404
|
|
|
376
405
|
|
|
377
406
|
# Select field aliases for client-side typing of `select` parameters.
|
|
@@ -428,6 +457,7 @@ CronSelectField = Literal[
|
|
|
428
457
|
"metadata",
|
|
429
458
|
"now",
|
|
430
459
|
"on_run_completed",
|
|
460
|
+
"enabled",
|
|
431
461
|
]
|
|
432
462
|
|
|
433
463
|
PrimitiveData = str | int | float | bool | None
|
|
@@ -18,7 +18,7 @@ path = "langgraph_sdk/__init__.py"
|
|
|
18
18
|
|
|
19
19
|
[project.urls]
|
|
20
20
|
Source = "https://github.com/langchain-ai/langgraph/tree/main/libs/sdk-py"
|
|
21
|
-
Twitter = "https://x.com/
|
|
21
|
+
Twitter = "https://x.com/LangChain"
|
|
22
22
|
Slack = "https://www.langchain.com/join-community"
|
|
23
23
|
Reddit = "https://www.reddit.com/r/LangChain/"
|
|
24
24
|
|
|
@@ -30,7 +30,7 @@ test = [
|
|
|
30
30
|
"pytest-watch",
|
|
31
31
|
]
|
|
32
32
|
lint = [
|
|
33
|
-
"ruff==0.14.
|
|
33
|
+
"ruff==0.14.11",
|
|
34
34
|
"codespell",
|
|
35
35
|
"mypy==1.19.0",
|
|
36
36
|
"ty==0.0.1a27",
|
|
@@ -276,3 +276,212 @@ def test_sync_create_with_end_time():
|
|
|
276
276
|
)
|
|
277
277
|
|
|
278
278
|
assert result == cron
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
@pytest.mark.parametrize(
|
|
282
|
+
"enabled_value",
|
|
283
|
+
[True, False],
|
|
284
|
+
ids=["enabled", "disabled"],
|
|
285
|
+
)
|
|
286
|
+
def test_sync_create_with_enabled_parameter(enabled_value):
|
|
287
|
+
"""Test that SyncCronClient.create includes enabled parameter in the payload."""
|
|
288
|
+
cron = _cron_payload()
|
|
289
|
+
|
|
290
|
+
def handler(request: httpx.Request) -> httpx.Response:
|
|
291
|
+
assert request.method == "POST"
|
|
292
|
+
assert request.url.path == "/runs/crons"
|
|
293
|
+
|
|
294
|
+
body = json.loads(request.content)
|
|
295
|
+
assert body["schedule"] == "0 12 * * *"
|
|
296
|
+
assert body["assistant_id"] == "asst_456"
|
|
297
|
+
assert body["enabled"] == enabled_value
|
|
298
|
+
|
|
299
|
+
return httpx.Response(200, json=cron)
|
|
300
|
+
|
|
301
|
+
transport = httpx.MockTransport(handler)
|
|
302
|
+
with httpx.Client(transport=transport, base_url="https://example.com") as client:
|
|
303
|
+
http_client = SyncHttpClient(client)
|
|
304
|
+
cron_client = SyncCronClient(http_client)
|
|
305
|
+
result = cron_client.create(
|
|
306
|
+
assistant_id="asst_456",
|
|
307
|
+
schedule="0 12 * * *",
|
|
308
|
+
enabled=enabled_value,
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
assert result == cron
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def _cron_response() -> dict[str, object]:
|
|
315
|
+
"""Return a mock Cron object response."""
|
|
316
|
+
return {
|
|
317
|
+
"cron_id": "cron_123",
|
|
318
|
+
"assistant_id": "asst_123",
|
|
319
|
+
"thread_id": "thread_123",
|
|
320
|
+
"on_run_completed": None,
|
|
321
|
+
"end_time": "2025-12-31T23:59:59+00:00",
|
|
322
|
+
"schedule": "0 10 * * *",
|
|
323
|
+
"created_at": "2024-01-01T00:00:00Z",
|
|
324
|
+
"updated_at": "2024-01-02T00:00:00Z",
|
|
325
|
+
"payload": {},
|
|
326
|
+
"user_id": None,
|
|
327
|
+
"next_run_date": "2024-01-03T10:00:00Z",
|
|
328
|
+
"metadata": {},
|
|
329
|
+
"enabled": True,
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
@pytest.mark.asyncio
|
|
334
|
+
async def test_async_update():
|
|
335
|
+
"""Test that CronClient.update works with schedule and enabled parameters."""
|
|
336
|
+
cron = _cron_response()
|
|
337
|
+
|
|
338
|
+
async def handler(request: httpx.Request) -> httpx.Response:
|
|
339
|
+
assert request.method == "PATCH"
|
|
340
|
+
assert request.url.path == "/runs/crons/cron_123"
|
|
341
|
+
|
|
342
|
+
# Parse the request body
|
|
343
|
+
body = json.loads(request.content)
|
|
344
|
+
assert body["schedule"] == "0 10 * * *"
|
|
345
|
+
assert body["enabled"] is False
|
|
346
|
+
assert "end_time" not in body # Should be filtered out by the None check
|
|
347
|
+
|
|
348
|
+
return httpx.Response(200, json=cron)
|
|
349
|
+
|
|
350
|
+
transport = httpx.MockTransport(handler)
|
|
351
|
+
async with httpx.AsyncClient(
|
|
352
|
+
transport=transport, base_url="https://example.com"
|
|
353
|
+
) as client:
|
|
354
|
+
http_client = HttpClient(client)
|
|
355
|
+
cron_client = CronClient(http_client)
|
|
356
|
+
result = await cron_client.update(
|
|
357
|
+
cron_id="cron_123",
|
|
358
|
+
schedule="0 10 * * *",
|
|
359
|
+
enabled=False,
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
assert result == cron
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
@pytest.mark.asyncio
|
|
366
|
+
async def test_async_update_with_end_time():
|
|
367
|
+
"""Test that CronClient.update includes end_time in the payload."""
|
|
368
|
+
cron = _cron_response()
|
|
369
|
+
end_time = datetime(2025, 12, 31, 23, 59, 59, tzinfo=timezone.utc)
|
|
370
|
+
|
|
371
|
+
async def handler(request: httpx.Request) -> httpx.Response:
|
|
372
|
+
assert request.method == "PATCH"
|
|
373
|
+
assert request.url.path == "/runs/crons/cron_123"
|
|
374
|
+
|
|
375
|
+
# Parse the request body
|
|
376
|
+
body = json.loads(request.content)
|
|
377
|
+
assert body["schedule"] == "0 10 * * *"
|
|
378
|
+
assert body["end_time"] == "2025-12-31T23:59:59+00:00"
|
|
379
|
+
assert body["enabled"] is True
|
|
380
|
+
|
|
381
|
+
return httpx.Response(200, json=cron)
|
|
382
|
+
|
|
383
|
+
transport = httpx.MockTransport(handler)
|
|
384
|
+
async with httpx.AsyncClient(
|
|
385
|
+
transport=transport, base_url="https://example.com"
|
|
386
|
+
) as client:
|
|
387
|
+
http_client = HttpClient(client)
|
|
388
|
+
cron_client = CronClient(http_client)
|
|
389
|
+
result = await cron_client.update(
|
|
390
|
+
cron_id="cron_123",
|
|
391
|
+
schedule="0 10 * * *",
|
|
392
|
+
end_time=end_time,
|
|
393
|
+
enabled=True,
|
|
394
|
+
)
|
|
395
|
+
|
|
396
|
+
assert result == cron
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
def test_sync_update():
|
|
400
|
+
"""Test that SyncCronClient.update works with schedule and enabled parameters."""
|
|
401
|
+
cron = _cron_response()
|
|
402
|
+
|
|
403
|
+
def handler(request: httpx.Request) -> httpx.Response:
|
|
404
|
+
assert request.method == "PATCH"
|
|
405
|
+
assert request.url.path == "/runs/crons/cron_123"
|
|
406
|
+
|
|
407
|
+
# Parse the request body
|
|
408
|
+
body = json.loads(request.content)
|
|
409
|
+
assert body["schedule"] == "0 10 * * *"
|
|
410
|
+
assert body["enabled"] is False
|
|
411
|
+
assert "end_time" not in body # Should be filtered out by the None check
|
|
412
|
+
|
|
413
|
+
return httpx.Response(200, json=cron)
|
|
414
|
+
|
|
415
|
+
transport = httpx.MockTransport(handler)
|
|
416
|
+
with httpx.Client(transport=transport, base_url="https://example.com") as client:
|
|
417
|
+
http_client = SyncHttpClient(client)
|
|
418
|
+
cron_client = SyncCronClient(http_client)
|
|
419
|
+
result = cron_client.update(
|
|
420
|
+
cron_id="cron_123",
|
|
421
|
+
schedule="0 10 * * *",
|
|
422
|
+
enabled=False,
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
assert result == cron
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
def test_sync_update_with_end_time():
|
|
429
|
+
"""Test that SyncCronClient.update includes end_time in the payload."""
|
|
430
|
+
cron = _cron_response()
|
|
431
|
+
end_time = datetime(2025, 12, 31, 23, 59, 59, tzinfo=timezone.utc)
|
|
432
|
+
|
|
433
|
+
def handler(request: httpx.Request) -> httpx.Response:
|
|
434
|
+
assert request.method == "PATCH"
|
|
435
|
+
assert request.url.path == "/runs/crons/cron_123"
|
|
436
|
+
|
|
437
|
+
# Parse the request body
|
|
438
|
+
body = json.loads(request.content)
|
|
439
|
+
assert body["schedule"] == "0 10 * * *"
|
|
440
|
+
assert body["end_time"] == "2025-12-31T23:59:59+00:00"
|
|
441
|
+
assert body["enabled"] is True
|
|
442
|
+
|
|
443
|
+
return httpx.Response(200, json=cron)
|
|
444
|
+
|
|
445
|
+
transport = httpx.MockTransport(handler)
|
|
446
|
+
with httpx.Client(transport=transport, base_url="https://example.com") as client:
|
|
447
|
+
http_client = SyncHttpClient(client)
|
|
448
|
+
cron_client = SyncCronClient(http_client)
|
|
449
|
+
result = cron_client.update(
|
|
450
|
+
cron_id="cron_123",
|
|
451
|
+
schedule="0 10 * * *",
|
|
452
|
+
end_time=end_time,
|
|
453
|
+
enabled=True,
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
assert result == cron
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
@pytest.mark.parametrize(
|
|
460
|
+
"enabled_value",
|
|
461
|
+
[True, False],
|
|
462
|
+
ids=["enabled", "disabled"],
|
|
463
|
+
)
|
|
464
|
+
def test_sync_update_with_enabled_parameter(enabled_value):
|
|
465
|
+
"""Test that SyncCronClient.update includes enabled parameter in the payload."""
|
|
466
|
+
cron = _cron_response()
|
|
467
|
+
|
|
468
|
+
def handler(request: httpx.Request) -> httpx.Response:
|
|
469
|
+
assert request.method == "PATCH"
|
|
470
|
+
assert request.url.path == "/runs/crons/cron_456"
|
|
471
|
+
|
|
472
|
+
body = json.loads(request.content)
|
|
473
|
+
assert body["enabled"] == enabled_value
|
|
474
|
+
assert "schedule" not in body # Only enabled is set
|
|
475
|
+
|
|
476
|
+
return httpx.Response(200, json=cron)
|
|
477
|
+
|
|
478
|
+
transport = httpx.MockTransport(handler)
|
|
479
|
+
with httpx.Client(transport=transport, base_url="https://example.com") as client:
|
|
480
|
+
http_client = SyncHttpClient(client)
|
|
481
|
+
cron_client = SyncCronClient(http_client)
|
|
482
|
+
result = cron_client.update(
|
|
483
|
+
cron_id="cron_456",
|
|
484
|
+
enabled=enabled_value,
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
assert result == cron
|