feat(backend): add GET endpoint to trigger scripts

This commit is contained in:
Ruben Fiszel
2023-04-04 13:56:55 +02:00
parent 096bf2022c
commit 15c75d9d00
3 changed files with 116 additions and 35 deletions
+29 -24
View File
@@ -2473,18 +2473,6 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/ScriptPath"
- name: scheduled_for
description: when to schedule this job (leave empty for immediate run)
in: query
schema:
type: string
format: date-time
- name: scheduled_in_secs
description:
schedule the script to execute in the number of seconds starting now
in: query
schema:
type: integer
- $ref: "#/components/parameters/ParentJob"
- $ref: "#/components/parameters/IncludeHeader"
- $ref: "#/components/parameters/QueueLimit"
@@ -2504,6 +2492,26 @@ paths:
application/json:
schema: {}
get:
summary: run script by path with get
operationId: runWaitResultScriptByPathGet
tags:
- job
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/ScriptPath"
- $ref: "#/components/parameters/ParentJob"
- $ref: "#/components/parameters/IncludeHeader"
- $ref: "#/components/parameters/QueueLimit"
- $ref: "#/components/parameters/Payload"
responses:
"200":
description: job result
content:
application/json:
schema: {}
/w/{workspace}/jobs/run_wait_result/f/{path}:
post:
summary: run flow by path and wait until completion
@@ -2513,18 +2521,6 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/ScriptPath"
- name: scheduled_for
description: when to schedule this job (leave empty for immediate run)
in: query
schema:
type: string
format: date-time
- name: scheduled_in_secs
description:
schedule the script to execute in the number of seconds starting now
in: query
schema:
type: integer
- $ref: "#/components/parameters/IncludeHeader"
- $ref: "#/components/parameters/QueueLimit"
@@ -3528,6 +3524,7 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/JobId"
- $ref: "#/components/parameters/Payload"
- name: resume_id
in: path
required: true
@@ -4649,6 +4646,14 @@ components:
in: query
schema:
type: string
Payload:
name: payload
description: |
The base64 encoded payload that has been encoded as a JSON. e.g how to encode such payload encodeURIComponent
`encodeURIComponent(btoa(JSON.stringify({a: 2})))`
in: query
schema:
type: string
ScriptStartPath:
name: script_path_start
+63 -5
View File
@@ -47,6 +47,10 @@ pub fn workspaced_service() -> Router {
"/run_wait_result/p/*script_path",
post(run_wait_result_job_by_path),
)
.route(
"/run_wait_result/p/*script_path",
get(run_wait_result_job_by_path_get),
)
.route(
"/run_wait_result/h/:hash",
post(run_wait_result_job_by_hash),
@@ -309,6 +313,7 @@ pub struct RunJobQuery {
include_header: Option<String>,
invisible_to_owner: Option<bool>,
queue_limit: Option<i64>,
payload: Option<String>,
}
lazy_static::lazy_static! {
@@ -1194,7 +1199,7 @@ where
}
}
fn decode_payload<D: DeserializeOwned, T: AsRef<[u8]>>(t: T) -> anyhow::Result<D> {
fn decode_payload<D: DeserializeOwned>(t: String) -> anyhow::Result<D> {
let vec = base64::engine::general_purpose::URL_SAFE
.decode(t)
.context("invalid base64")?;
@@ -1385,6 +1390,61 @@ lazy_static::lazy_static! {
.and_then(|x| x.parse().ok())
.unwrap_or(20);
}
pub async fn run_wait_result_job_by_path_get(
authed: Authed,
Extension(user_db): Extension<UserDB>,
Extension(db): Extension<DB>,
Path((w_id, script_path)): Path<(String, StripPath)>,
Query(run_query): Query<RunJobQuery>,
) -> error::JsonResult<serde_json::Value> {
tracing::error!("run_wait_result_job_by_path_get {:#?}", run_query.payload);
let payload_r = run_query
.payload
.map(decode_payload)
.map(|x| x.map_err(|e| Error::InternalErr(e.to_string())));
let args = if let Some(payload) = payload_r {
payload?
} else {
serde_json::Map::new()
};
check_queue_too_long(db, QUEUE_LIMIT_WAIT_RESULT.or(run_query.queue_limit)).await?;
let script_path = script_path.to_path();
let mut tx = user_db.clone().begin(&authed).await?;
let job_payload = script_path_to_payload(script_path, &mut tx, &w_id).await?;
let (uuid, tx) = push(
tx,
&w_id,
job_payload,
args,
&authed.username,
&authed.email,
username_to_permissioned_as(&authed.username),
None,
None,
run_query.parent_job,
run_query.parent_job,
false,
false,
None,
!run_query.invisible_to_owner.unwrap_or(false),
)
.await?;
tx.commit().await?;
run_wait_result(
authed,
Extension(user_db),
*TIMEOUT_WAIT_RESULT,
uuid,
Path((w_id, script_path)),
)
.await
}
pub async fn run_wait_result_job_by_path(
authed: Authed,
Extension(user_db): Extension<UserDB>,
@@ -1398,7 +1458,6 @@ pub async fn run_wait_result_job_by_path(
let script_path = script_path.to_path();
let mut tx = user_db.clone().begin(&authed).await?;
let job_payload = script_path_to_payload(script_path, &mut tx, &w_id).await?;
let scheduled_for = run_query.get_scheduled_for(&mut tx).await?;
let args = run_query.add_include_headers(headers, args.unwrap_or_default());
@@ -1410,7 +1469,7 @@ pub async fn run_wait_result_job_by_path(
&authed.username,
&authed.email,
username_to_permissioned_as(&authed.username),
scheduled_for,
None,
None,
run_query.parent_job,
run_query.parent_job,
@@ -1446,7 +1505,6 @@ pub async fn run_wait_result_job_by_hash(
let hash = script_hash.0;
let mut tx = user_db.clone().begin(&authed).await?;
let path = get_path_for_hash(&mut tx, &w_id, hash).await?;
let scheduled_for = run_query.get_scheduled_for(&mut tx).await?;
let args = run_query.add_include_headers(headers, args.unwrap_or_default());
let (uuid, tx) = push(
@@ -1457,7 +1515,7 @@ pub async fn run_wait_result_job_by_hash(
&authed.username,
&authed.email,
username_to_permissioned_as(&authed.username),
scheduled_for,
None,
None,
run_query.parent_job,
run_query.parent_job,
@@ -82,7 +82,8 @@
},
sync: {
hash: `${$page.url.hostname}/api/w/${$workspaceStore}/jobs/run_wait_result/h/${script?.hash}`,
path: `${$page.url.hostname}/api/w/${$workspaceStore}/jobs/run_wait_result/p/${script?.path}`
path: `${$page.url.hostname}/api/w/${$workspaceStore}/jobs/run_wait_result/p/${script?.path}`,
get_path: `${$page.url.hostname}/api/w/${$workspaceStore}/jobs/run_wait_result/p/${script?.path}`
}
}
@@ -452,8 +453,9 @@
<h3 bind:this={webhookElem} id="webhooks">
Webhooks
<Tooltip>
Pass the input as a json payload, the token as a Bearer token or as query arg
`?token=XXX` and pass as header: 'Content-Type: application/json'
Pass the input as a json payload, the token as a Bearer token (header: 'Authorization:
Bearer XXXX') or as query arg `?token=XXX`, and pass as header: 'Content-Type:
application/json'
<a href="https://docs.windmill.dev/docs/core_concepts/webhooks" class="text-blue-500">
See docs
</a>
@@ -484,9 +486,25 @@
<Icon data={faClipboard} />
</span>
</a>
<Badge color="dark-gray" capitalize>
{type}
</Badge>
{#if type == 'get_path'}
<div class="flex flex-row gap-1">
<Badge>GET</Badge>
<Tooltip
>This webhook unlike the others which are all POST takes in a GET
request. The payload must be passed as the query arg `payload` and
encoded in JSON first, then in an URL safe base64. e.g:
`encodeURIComponent(btoa(JSON.stringify({'{a: 2}'})))` `
</Tooltip>
</div>
{:else}
<div class="flex flex-row gap-1">
<Badge>POST</Badge>
<Badge color="dark-gray" capitalize>
{type}
</Badge>
</div>
{/if}
</li>
{/each}
</ul>