fix: add run_flow_sync to python client + few nits

This commit is contained in:
Ruben Fiszel
2023-12-05 19:49:18 +01:00
parent 925632ffd7
commit 49923331a4
6 changed files with 179 additions and 91 deletions
@@ -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>
+1 -1
View File
@@ -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}
+33 -3
View File
@@ -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(