David
01/23/2025, 9:23 PMMarvin
01/23/2025, 9:23 PMprefect deploy
command to configure this, but for a REST API call, you would construct a JSON payload.
Here's a conceptual example of what the JSON payload might look like for a cron schedule:
json
{
"schedule": {
"type": "cron",
"cron": "0 * * * *", // Runs every hour
"timezone": "UTC"
},
"deployment": {
"name": "my_flow_deployment",
"flow_name": "my_flow"
// Include other deployment-specific parameters here
}
}
This JSON object includes a schedule
key with a type
of "cron", a cron expression, and optionally a timezone. The deployment
key would contain the rest of your deployment configuration.
For more information on scheduling deployments, you can refer to the Prefect documentation on adding schedules.
If you need further details on how to structure the REST API request, you might need to explore the Prefect API documentation or reach out to the Prefect community for more specific REST API usage examples.David
01/23/2025, 9:25 PM{
"exception_message": "Invalid request received.",
"exception_detail": [
{
"type": "missing",
"loc": [
"body",
0,
"schedule",
"function-after[validate_timezone(), IntervalSchedule]",
"interval"
],
"msg": "Field required",
"input": {
"cron": "0 0 * * *",
"timezone": [
"America/New_York"
],
"type": "cron",
"day_or": true,
"valid": true
}
},
{
"type": "string_type",
"loc": [
"body",
0,
"schedule",
"function-after[validate_timezone(), IntervalSchedule]",
"timezone"
],
"msg": "Input should be a valid string",
"input": [
"America/New_York"
]
},
{
"type": "extra_forbidden",
"loc": [
"body",
0,
"schedule",
"function-after[validate_timezone(), IntervalSchedule]",
"cron"
],
"msg": "Extra inputs are not permitted",
"input": "0 0 * * *"
},
{
"type": "extra_forbidden",
"loc": [
"body",
0,
"schedule",
"function-after[validate_timezone(), IntervalSchedule]",
"type"
],
"msg": "Extra inputs are not permitted",
"input": "cron"
},
{
"type": "extra_forbidden",
"loc": [
"body",
0,
"schedule",
"function-after[validate_timezone(), IntervalSchedule]",
"day_or"
],
"msg": "Extra inputs are not permitted",
"input": true
},
{
"type": "extra_forbidden",
"loc": [
"body",
0,
"schedule",
"function-after[validate_timezone(), IntervalSchedule]",
"valid"
],
"msg": "Extra inputs are not permitted",
"input": true
},
{
"type": "string_type",
"loc": [
"body",
0,
"schedule",
"function-after[validate_timezone(), CronSchedule]",
"timezone"
],
"msg": "Input should be a valid string",
"input": [
"America/New_York"
]
},
{
"type": "extra_forbidden",
"loc": [
"body",
0,
"schedule",
"function-after[validate_timezone(), CronSchedule]",
"type"
],
"msg": "Extra inputs are not permitted",
"input": "cron"
},
{
"type": "extra_forbidden",
"loc": [
"body",
0,
"schedule",
"function-after[validate_timezone(), CronSchedule]",
"valid"
],
"msg": "Extra inputs are not permitted",
"input": true
},
{
"type": "missing",
"loc": [
"body",
0,
"schedule",
"RRuleSchedule",
"rrule"
],
"msg": "Field required",
"input": {
"cron": "0 0 * * *",
"timezone": [
"America/New_York"
],
"type": "cron",
"day_or": true,
"valid": true
}
},
{
"type": "string_type",
"loc": [
"body",
0,
"schedule",
"RRuleSchedule",
"timezone"
],
"msg": "Input should be a valid string",
"input": [
"America/New_York"
]
},
{
"type": "extra_forbidden",
"loc": [
"body",
0,
"schedule",
"RRuleSchedule",
"cron"
],
"msg": "Extra inputs are not permitted",
"input": "0 0 * * *"
},
{
"type": "extra_forbidden",
"loc": [
"body",
0,
"schedule",
"RRuleSchedule",
"type"
],
"msg": "Extra inputs are not permitted",
"input": "cron"
},
{
"type": "extra_forbidden",
"loc": [
"body",
0,
"schedule",
"RRuleSchedule",
"day_or"
],
"msg": "Extra inputs are not permitted",
"input": true
},
{
"type": "extra_forbidden",
"loc": [
"body",
0,
"schedule",
"RRuleSchedule",
"valid"
],
"msg": "Extra inputs are not permitted",
"input": true
},
{
"type": "extra_forbidden",
"loc": [
"body",
0,
"max_schedule_runs"
],
"msg": "Extra inputs are not permitted",
"input": 1
}
],
"request_body": [
{
"active": true,
"max_active_runs": 1,
"max_schedule_runs": 1,
"catchup": false,
"schedule": {
"cron": "0 0 * * *",
"timezone": [
"America/New_York"
],
"type": "cron",
"day_or": true,
"valid": true
}
}
]
}
Marvin
01/23/2025, 9:25 PMDavid
01/23/2025, 9:26 PM{"exception_message":"Invalid request received.","exception_detail":[{"type":"missing","loc":["body",0,"schedule","function-after[validate_timezone(), IntervalSchedule]","interval"],"msg":"Field required","input":{"cron":"0 0 * * *","timezone":["America/New_York"],"type":"cron","day_or":true,"valid":true}}...
Marvin
01/23/2025, 9:26 PM"cron": "0 0 * * *"
for running at midnight every day.
2. Timezone: Make sure the timezone is a string, like "timezone": "America/New_York"
, not a list.
3. Schedule Type: Confirm that the type is set to "cron"
.
4. Miscellaneous Fields: Ensure that there are no extra or misconfigured fields, such as day_or
, valid
, or function-after
.
Here's a corrected version of how the JSON payload might look:
json
{
"schedule": {
"type": "cron",
"cron": "0 0 * * *",
"timezone": "America/New_York"
},
"deployment": {
"name": "my_flow_deployment",
"flow_name": "my_flow"
// Include other deployment-specific parameters here
}
}
Make sure your JSON structure matches this format and that there are no extraneous fields or incorrect data types. For more detailed guidance, you can refer to the Prefect documentation on adding schedules.Nate
01/23/2025, 9:27 PMDavid
01/23/2025, 9:28 PM{
"active": true,
"catchup": false,
"max_active_runs": 1,
"max_schedule_runs": 1,
"schedule": {
"cron": "0 0 * * *",
"timezone": [
"America/New_York"
],
"day_or": true
}
}
im confused how im supposed to differentiate between the 3 schedule typesDavid
01/23/2025, 9:30 PMNate
01/23/2025, 9:33 PM» cat sandbox/schedule_payload.py
from prefect import flow
@flow
def foo(): ...
if __name__ == "__main__":
foo.serve(cron="* * * * *")
» git diff
diff --git a/src/prefect/deployments/runner.py b/src/prefect/deployments/runner.py
index db8c2dcf02..8071b5b41d 100644
--- a/src/prefect/deployments/runner.py
+++ b/src/prefect/deployments/runner.py
@@ -318,6 +318,8 @@ class RunnerDeployment(BaseModel):
enforce_parameter_schema=self.enforce_parameter_schema,
)
+ print(create_payload)
» python sandbox/schedule_payload.py
{'flow_id': UUID('95d588cf-f93c-4fb5-ad97-4fd1e44cb1ac'), 'name': 'foo', 'work_queue_name': None, 'work_pool_name': None, 'version': '2bf38ae7c5aba1fd02ab29f5b7ba35cb', 'paused': False, 'schedules': [DeploymentScheduleCreate(schedule=CronSchedule(cron='* * * * *', timezone=None, day_or=True), active=True, max_scheduled_runs=None)], 'concurrency_limit': None, 'concurrency_options': None, 'parameters': {}, 'description': None, 'tags': [], 'path': '.', 'entrypoint': 'sandbox/schedule_payload.py:foo', 'storage_document_id': None, 'infrastructure_document_id': None, 'parameter_openapi_schema': {'title': 'Parameters', 'type': 'object', 'properties': {}}, 'enforce_parameter_schema': True}
Your flow 'foo' is being served and polling for scheduled runs!
Nate
01/23/2025, 9:34 PMNate
01/23/2025, 9:35 PM» python sandbox/schedule_payload.py
{
"name": "foo",
"flow_id": "95d588cf-f93c-4fb5-ad97-4fd1e44cb1ac",
"paused": false,
"schedules": [
{
"schedule": {
"cron": "* * * * *",
"timezone": null,
"day_or": true
},
"active": true,
"max_scheduled_runs": null
}
],
"concurrency_limit": null,
"concurrency_options": null,
"enforce_parameter_schema": true,
"parameter_openapi_schema": {
"title": "Parameters",
"type": "object",
"properties": {}
},
"parameters": {},
"tags": [],
"labels": {},
"pull_steps": null,
"work_queue_name": null,
"work_pool_name": null,
"storage_document_id": null,
"infrastructure_document_id": null,
"description": "None",
"path": ".",
"version": "2bf38ae7c5aba1fd02ab29f5b7ba35cb",
"entrypoint": "sandbox/schedule_payload.py:foo",
"job_variables": {}
}
Your flow 'foo' is being served and polling for scheduled runs!
To trigger a run for this flow, use the following command:
$ prefect deployment run 'foo/foo'
You can also run your flow via the Prefect UI: <http://localhost:4200/deployments/deployment/36ff384f-4034-46c2-8605-77d16f2550ad>
^C15:35:02.242 | INFO | prefect.runner - Pausing all deployments...
15:35:02.282 | INFO | prefect.runner - All deployments have been paused!
15:35:02.283 | INFO | prefect.flows - Received KeyboardInterrupt, shutting down...
» git diff
diff --git a/src/prefect/client/orchestration/_deployments/client.py b/src/prefect/client/orchestration/_deployments/client.py
index 39dabd55ae..e51f79062a 100644
--- a/src/prefect/client/orchestration/_deployments/client.py
+++ b/src/prefect/client/orchestration/_deployments/client.py
@@ -658,6 +658,8 @@ class DeploymentAsyncClient(BaseAsyncClient):
enforce_parameter_schema=enforce_parameter_schema,
)
+ print(deployment_create.model_dump_json(indent=2))
+
David
01/24/2025, 2:43 PM{
"active": true,
"schedule": {
"cron": "0 0 * * *",
"timezone": "America/New_York",
"day_or": true
}
}
i removed the catchup
, max_active_etc
and my cron validator was adding a valid
key. simplification fixed it.