mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-12 00:06:14 +00:00
fix: add run_flow_sync to python client + few nits
This commit is contained in:
@@ -1,64 +1,64 @@
|
||||
<script lang="ts">
|
||||
import IconedResourceType from './IconedResourceType.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import IconedResourceType from './IconedResourceType.svelte'
|
||||
import Toggle from './Toggle.svelte'
|
||||
|
||||
export let value: any
|
||||
export let value: any
|
||||
|
||||
$: enabled = value != undefined
|
||||
$: enabled = value != undefined
|
||||
|
||||
let org = ''
|
||||
let org = ''
|
||||
|
||||
$: changeOrg(org)
|
||||
$: changeOrg(org)
|
||||
|
||||
function changeOrg(org) {
|
||||
if (value) {
|
||||
value = {
|
||||
...value,
|
||||
connect_config: {
|
||||
auth_url: `${org}/application/o/authorize/`,
|
||||
token_url: `${org}/application/o/token/`,
|
||||
scopes: ['openid', 'offline_access']
|
||||
},
|
||||
login_config: {
|
||||
auth_url: `${org}/application/o/authorize/`,
|
||||
token_url: `${org}/application/o/token/`,
|
||||
userinfo_url: `${org}/application/o/userinfo/`,
|
||||
scopes: ['openid', 'offline_access']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function changeOrg(org) {
|
||||
if (value) {
|
||||
value = {
|
||||
...value,
|
||||
connect_config: {
|
||||
auth_url: `${org}/application/o/authorize/`,
|
||||
token_url: `${org}/application/o/token/`,
|
||||
scopes: ['openid', 'offline_access']
|
||||
},
|
||||
login_config: {
|
||||
auth_url: `${org}/application/o/authorize/`,
|
||||
token_url: `${org}/application/o/token/`,
|
||||
userinfo_url: `${org}/application/o/userinfo/`,
|
||||
scopes: ['openid', 'offline_access', 'email']
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col gap-1">
|
||||
<label class="text-sm font-medium text-primary flex gap-4 items-center"
|
||||
><div class="w-[120px]"><IconedResourceType name={'authentik'} after={true} /></div><Toggle
|
||||
checked={enabled}
|
||||
on:change={(e) => {
|
||||
<label class="text-sm font-medium text-primary flex gap-4 items-center"
|
||||
><div class="w-[120px]"><IconedResourceType name={'authentik'} after={true} /></div><Toggle
|
||||
checked={enabled}
|
||||
on:change={(e) => {
|
||||
if (e.detail) {
|
||||
value = { id: '', secret: '' }
|
||||
} else {
|
||||
value = undefined
|
||||
}
|
||||
}}
|
||||
/></label
|
||||
>
|
||||
{#if enabled}
|
||||
<div class="border rounded p-2">
|
||||
<label class="block pb-2">
|
||||
/></label
|
||||
>
|
||||
{#if enabled}
|
||||
<div class="border rounded p-2">
|
||||
<label class="block pb-2">
|
||||
<span class="text-primary font-semibold text-sm"
|
||||
>Authentik Url ({'AUTHENTIK_HOST/application/o/authorize/'})</span
|
||||
>
|
||||
<input type="text" placeholder="yourorg" bind:value={org} />
|
||||
</label>
|
||||
<label class="block pb-2">
|
||||
<span class="text-primary font-semibold text-sm">Client Id</span>
|
||||
<input type="text" placeholder="Client Id" bind:value={value['id']} />
|
||||
</label>
|
||||
<label class="block pb-2">
|
||||
<span class="text-primary font-semibold text-sm">Client Secret </span>
|
||||
<input type="text" placeholder="Client Secret" bind:value={value['secret']} />
|
||||
</label>
|
||||
</div>
|
||||
{/if}
|
||||
>Authentik Url ({'AUTHENTIK_HOST/application/o/authorize/'})</span
|
||||
>
|
||||
<input type="text" placeholder="yourorg" bind:value={org} />
|
||||
</label>
|
||||
<label class="block pb-2">
|
||||
<span class="text-primary font-semibold text-sm">Client Id</span>
|
||||
<input type="text" placeholder="Client Id" bind:value={value['id']} />
|
||||
</label>
|
||||
<label class="block pb-2">
|
||||
<span class="text-primary font-semibold text-sm">Client Secret </span>
|
||||
<input type="text" placeholder="Client Secret" bind:value={value['secret']} />
|
||||
</label>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<div class="absolute inset-y-0 right-0 flex items-center px-2">
|
||||
<input class="!hidden js-password-toggle" id="toggle" type="checkbox" />
|
||||
<label
|
||||
class="bg-gray-300 hover:bg-gray-400 rounded px-2 py-1 text-sm text-tertiary font-mono cursor-pointer js-password-label"
|
||||
class="bg-surface-secondary hover:bg-gray-400 rounded px-2 py-1 text-sm text-tertiary font-mono cursor-pointer js-password-label"
|
||||
for="toggle">show</label
|
||||
>
|
||||
</div>
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
import { userStore, workspaceStore } from '$lib/stores'
|
||||
import type uFuzzy from '@leeoniya/ufuzzy'
|
||||
import { Code2, LayoutDashboard, SearchCode } from 'lucide-svelte'
|
||||
import TreeView from './TreeView.svelte'
|
||||
|
||||
export let filter = ''
|
||||
export let subtab: 'flow' | 'script' | 'app' = 'script'
|
||||
@@ -35,8 +34,8 @@
|
||||
import Drawer from '../common/drawer/Drawer.svelte'
|
||||
import HighlightCode from '../HighlightCode.svelte'
|
||||
import DrawerContent from '../common/drawer/DrawerContent.svelte'
|
||||
import { groupItems } from './treeViewUtils'
|
||||
import Item from './Item.svelte'
|
||||
import TreeViewRoot from './TreeViewRoot.svelte'
|
||||
|
||||
type TableItem<T, U extends 'script' | 'flow' | 'app' | 'raw_app'> = T & {
|
||||
canWrite: boolean
|
||||
@@ -246,8 +245,25 @@
|
||||
$: items && resetScroll()
|
||||
|
||||
let archived = false
|
||||
let treeView = false
|
||||
let treeView = getTreeView()
|
||||
|
||||
$: storeTreeView(treeView)
|
||||
|
||||
function storeTreeView(treeView: boolean) {
|
||||
if (treeView) {
|
||||
localStorage.setItem('treeView', 'true')
|
||||
} else {
|
||||
localStorage.removeItem('treeView')
|
||||
}
|
||||
}
|
||||
|
||||
function getTreeView() {
|
||||
try {
|
||||
return localStorage.getItem('treeView') == 'true'
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
let contentSearch: ContentSearch
|
||||
|
||||
let viewCodeDrawer: Drawer
|
||||
@@ -262,7 +278,7 @@
|
||||
})
|
||||
}
|
||||
|
||||
let collapseAll = false
|
||||
let collapseAll = true
|
||||
</script>
|
||||
|
||||
<SearchItems
|
||||
@@ -405,34 +421,22 @@
|
||||
{:else if filteredItems.length === 0}
|
||||
<NoItemFound />
|
||||
{:else if treeView}
|
||||
{@const groupedItems = groupItems(items)}
|
||||
<div class="border rounded-md">
|
||||
{#each groupedItems.slice(0, nbDisplayed) as item (item['folderName'] ?? 'user__' + item['username'])}
|
||||
{#if item}
|
||||
<TreeView
|
||||
{collapseAll}
|
||||
{item}
|
||||
on:scriptChanged={loadScripts}
|
||||
on:flowChanged={loadFlows}
|
||||
on:appChanged={loadApps}
|
||||
on:rawAppChanged={loadRawApps}
|
||||
on:reload={() => {
|
||||
loadScripts()
|
||||
loadFlows()
|
||||
loadApps()
|
||||
loadRawApps()
|
||||
}}
|
||||
{showCode}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{#if groupedItems.length > 30 && nbDisplayed < groupedItems.length}
|
||||
<span class="text-xs"
|
||||
>{nbDisplayed} root nodes out of {groupedItems.length}
|
||||
<button class="ml-4" on:click={() => (nbDisplayed += 30)}>load 30 more</button></span
|
||||
>
|
||||
{/if}
|
||||
<TreeViewRoot
|
||||
{items}
|
||||
{nbDisplayed}
|
||||
{collapseAll}
|
||||
on:scriptChanged={loadScripts}
|
||||
on:flowChanged={loadFlows}
|
||||
on:appChanged={loadApps}
|
||||
on:rawAppChanged={loadRawApps}
|
||||
on:reload={() => {
|
||||
loadScripts()
|
||||
loadFlows()
|
||||
loadApps()
|
||||
loadRawApps()
|
||||
}}
|
||||
{showCode}
|
||||
/>
|
||||
{:else}
|
||||
<div class="border rounded-md">
|
||||
{#each (items ?? []).slice(0, nbDisplayed) as item (item.type + '/' + item.path)}
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
import Item from './Item.svelte'
|
||||
import type { FolderItem, ItemType, UserItem } from './treeViewUtils'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { slide } from 'svelte/transition'
|
||||
import { pluralize } from '$lib/utils'
|
||||
|
||||
export let item: ItemType | FolderItem | UserItem
|
||||
|
||||
export let collapseAll: boolean
|
||||
export let depth: number = 0
|
||||
export let showCode: (path: string, summary: string) => void
|
||||
|
||||
const isFolder = (i: any): i is FolderItem => i && 'folderName' in i
|
||||
const isUser = (i: any): i is UserItem => i && 'username' in i
|
||||
@@ -24,8 +24,6 @@
|
||||
opened = !collapseAll
|
||||
}
|
||||
|
||||
export let showCode: (path: string, summary: string) => void
|
||||
|
||||
let showMax = 30
|
||||
</script>
|
||||
|
||||
@@ -57,7 +55,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button on:click={() => (opened = !opened)}>
|
||||
<button class="w-full flex flex-row-reverse" on:click={() => (opened = !opened)}>
|
||||
{#if opened}
|
||||
<ChevronUp size={20} />
|
||||
{:else}
|
||||
@@ -66,7 +64,7 @@
|
||||
</button>
|
||||
</div>
|
||||
{#if opened}
|
||||
<div transition:slide>
|
||||
<div>
|
||||
{#each item.items.slice(0, showMax) as subItem ((subItem['path'] ? subItem['type'] + '__' + subItem['path'] : undefined) ?? 'folder__' + subItem['folderName'])}
|
||||
<svelte:self
|
||||
{collapseAll}
|
||||
@@ -88,7 +86,6 @@
|
||||
if (isFolder(item)) {
|
||||
showMax += Math.min(30, item.items.length - showMax)
|
||||
showMax = showMax
|
||||
console.log(showMax)
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -118,7 +115,7 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<button on:click={() => (opened = !opened)}>
|
||||
<button class="w-full flex flex-row-reverse" on:click={() => (opened = !opened)}>
|
||||
{#if opened}
|
||||
<ChevronUp size={20} />
|
||||
{:else}
|
||||
@@ -127,7 +124,7 @@
|
||||
</button>
|
||||
</div>
|
||||
{#if opened}
|
||||
<div transition:slide>
|
||||
<div>
|
||||
{#each item.items.slice(0, showMax) as subItem ((subItem['path'] ? subItem['type'] + '__' + subItem['path'] : undefined) ?? 'folder__' + subItem['folderName'])}
|
||||
<svelte:self
|
||||
{collapseAll}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
<script lang="ts">
|
||||
import TreeView from './TreeView.svelte'
|
||||
import { groupItems } from './treeViewUtils'
|
||||
|
||||
export let collapseAll: boolean
|
||||
export let showCode: (path: string, summary: string) => void
|
||||
export let nbDisplayed: number
|
||||
export let items: any[] | undefined
|
||||
let treeLoading = false
|
||||
|
||||
$: groupedItems = grpItems(items)
|
||||
function grpItems(items: any[] | undefined): any[] {
|
||||
treeLoading = true
|
||||
let r
|
||||
try {
|
||||
r = groupItems(items)
|
||||
} finally {
|
||||
treeLoading = false
|
||||
}
|
||||
return r
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if treeLoading}
|
||||
<div class="flex flex-row items-center justify-center">
|
||||
<div
|
||||
class="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 dark:border-gray-100"
|
||||
/>
|
||||
</div>
|
||||
{:else if groupedItems.length === 0}
|
||||
<div class="flex flex-row items-center justify-center">
|
||||
<div class="text-gray-500 dark:text-gray-400">No items</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="border rounded-md">
|
||||
{#each groupedItems.slice(0, nbDisplayed) as item (item['folderName'] ?? 'user__' + item['username'])}
|
||||
{#if item}
|
||||
<TreeView
|
||||
{collapseAll}
|
||||
{item}
|
||||
on:scriptChanged
|
||||
on:flowChanged
|
||||
on:appChanged
|
||||
on:rawAppChanged
|
||||
on:reload
|
||||
{showCode}
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{#if groupedItems.length > 30 && nbDisplayed < groupedItems.length}
|
||||
<span class="text-xs"
|
||||
>{nbDisplayed} root nodes out of {groupedItems.length}
|
||||
<button class="ml-4" on:click={() => (nbDisplayed += 30)}>load 30 more</button></span
|
||||
>
|
||||
{/if}
|
||||
{/if}
|
||||
@@ -79,7 +79,7 @@ class Windmill:
|
||||
args: dict = None,
|
||||
scheduled_in_secs: int = None,
|
||||
) -> str:
|
||||
"""Create a job and return its job id."""
|
||||
"""Create a script job and return its job id."""
|
||||
assert not (path and hash_), "path and hash_ are mutually exclusive"
|
||||
args = args or {}
|
||||
params = {"scheduled_in_secs": scheduled_in_secs} if scheduled_in_secs else {}
|
||||
@@ -91,6 +91,21 @@ class Windmill:
|
||||
raise Exception("path or hash_ must be provided")
|
||||
return self.post(endpoint, json=args, params=params).text
|
||||
|
||||
def run_flow_async(
|
||||
self,
|
||||
path: str,
|
||||
args: dict = None,
|
||||
scheduled_in_secs: int = None,
|
||||
) -> str:
|
||||
"""Create a flow job and return its job id."""
|
||||
args = args or {}
|
||||
params = {"scheduled_in_secs": scheduled_in_secs} if scheduled_in_secs else {}
|
||||
if path:
|
||||
endpoint = f"/w/{self.workspace}/jobs/run/f/{path}"
|
||||
else:
|
||||
raise Exception("path must be provided")
|
||||
return self.post(endpoint, json=args, params=params).text
|
||||
|
||||
def run_script(
|
||||
self,
|
||||
path: str = None,
|
||||
@@ -448,16 +463,31 @@ def get_version() -> str:
|
||||
|
||||
@init_global_client
|
||||
def run_script_async(
|
||||
hash: str,
|
||||
hash_or_path: str,
|
||||
args: Dict[str, Any] = None,
|
||||
scheduled_in_secs: int = None,
|
||||
) -> str:
|
||||
is_path = "/" in hash_or_path
|
||||
hash_ = None if is_path else hash_or_path
|
||||
path = hash_or_path if is_path else None
|
||||
return _client.run_script_async(
|
||||
hash_=hash,
|
||||
hash_=hash_,
|
||||
path=path,
|
||||
args=args,
|
||||
scheduled_in_secs=scheduled_in_secs,
|
||||
)
|
||||
|
||||
@init_global_client
|
||||
def run_flow_async(
|
||||
path: str,
|
||||
args: Dict[str, Any] = None,
|
||||
scheduled_in_secs: int = None,
|
||||
) -> str:
|
||||
return _client.run_flow_async(
|
||||
path=path,
|
||||
args=args,
|
||||
scheduled_in_secs=scheduled_in_secs,
|
||||
)
|
||||
|
||||
@init_global_client
|
||||
def run_script_sync(
|
||||
|
||||
Reference in New Issue
Block a user