mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-25 08:00:59 +00:00
feat: Support .ducklake() and .datatable() in agent workers (#8697)
* Update clients to check for agent workers * fixes * typescript uses 127.0.0.1 * Refresh system prompts * fix: check both localhost and 127.0.0.1 in workerHasInternalServer detection Both Python and TypeScript clients now check for both hostnames to avoid silent breakage if BASE_INTERNAL_URL uses one or the other. Also adds return type annotation to the Python method. Co-authored-by: Diego Imbert <diegoimbert@users.noreply.github.com> * refresh system prompts * nit localhost regex boundary * fix: use provider.language instead of undefined bare language in sqlUtils The language variable was referenced as a bare identifier in the fetch calls, resolving to undefined at runtime instead of reading from provider.language. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Diego Imbert <diegoimbert@users.noreply.github.com> Co-authored-by: Ruben Fiszel <ruben@windmill.dev> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -262,6 +262,8 @@ const result: S3Object = await wmill.writeS3File(
|
||||
|
||||
Import: import * as wmill from 'windmill-client'
|
||||
|
||||
workerHasInternalServer(): boolean
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
@@ -925,6 +927,8 @@ const result: S3Object = await wmill.writeS3File(
|
||||
|
||||
Import: import * as wmill from 'windmill-client'
|
||||
|
||||
workerHasInternalServer(): boolean
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
@@ -1651,6 +1655,8 @@ const result: S3Object = await wmill.writeS3File(
|
||||
|
||||
Import: import * as wmill from 'windmill-client'
|
||||
|
||||
workerHasInternalServer(): boolean
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
@@ -2591,6 +2597,8 @@ export async function preprocessor(event: Event) {
|
||||
|
||||
Import: import * as wmill from 'windmill-client'
|
||||
|
||||
workerHasInternalServer(): boolean
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
@@ -3433,6 +3441,8 @@ result: S3Object = wmill.write_s3_file(
|
||||
|
||||
Import: import wmill
|
||||
|
||||
def worker_has_internal_server() -> bool
|
||||
|
||||
def get_mocked_api() -> Optional[dict]
|
||||
|
||||
# Get the HTTP client instance.
|
||||
@@ -3497,7 +3507,10 @@ def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int
|
||||
# Run script by hash synchronously and return its result.
|
||||
def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any
|
||||
|
||||
# Run a script on the current worker without creating a job
|
||||
# Run a script on the current worker without creating a job.
|
||||
#
|
||||
# On agent workers (no internal server), falls back to running a normal
|
||||
# preview job and waiting for the result.
|
||||
def run_inline_script_preview(content: str, language: str, args: dict = None) -> Any
|
||||
|
||||
# Wait for a job to complete and return its result.
|
||||
|
||||
@@ -66,6 +66,11 @@ class Windmill:
|
||||
f"workspace required as an argument or as WM_WORKSPACE environment variable"
|
||||
)
|
||||
|
||||
def worker_has_internal_server(self) -> bool:
|
||||
return bool(
|
||||
re.match(r"^https?://(localhost|127\.0\.0\.1)(:|/|$)", self.base_url or "")
|
||||
)
|
||||
|
||||
def get_mocked_api(self) -> Optional[dict]:
|
||||
mocked_path = os.environ.get("WM_MOCKED_API_FILE")
|
||||
if not mocked_path:
|
||||
@@ -326,8 +331,15 @@ class Windmill:
|
||||
language: str,
|
||||
args: dict = None,
|
||||
) -> Any:
|
||||
"""Run a script on the current worker without creating a job"""
|
||||
endpoint = f"/w/{self.workspace}/jobs/run_inline/preview"
|
||||
"""Run a script on the current worker without creating a job.
|
||||
|
||||
On agent workers (no internal server), falls back to running a normal
|
||||
preview job and waiting for the result.
|
||||
"""
|
||||
if self.worker_has_internal_server():
|
||||
endpoint = f"/w/{self.workspace}/jobs/run_inline/preview"
|
||||
else:
|
||||
endpoint = f"/w/{self.workspace}/jobs/run_wait_result/preview"
|
||||
body = {
|
||||
"content": content,
|
||||
"language": language,
|
||||
|
||||
@@ -153,6 +153,8 @@ export const SDK_TYPESCRIPT = `# TypeScript SDK (windmill-client)
|
||||
|
||||
Import: import * as wmill from 'windmill-client'
|
||||
|
||||
workerHasInternalServer(): boolean
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
@@ -690,6 +692,8 @@ export const SDK_PYTHON = `# Python SDK (wmill)
|
||||
|
||||
Import: import wmill
|
||||
|
||||
def worker_has_internal_server() -> bool
|
||||
|
||||
def get_mocked_api() -> Optional[dict]
|
||||
|
||||
# Get the HTTP client instance.
|
||||
@@ -754,7 +758,10 @@ def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int
|
||||
# Run script by hash synchronously and return its result.
|
||||
def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any
|
||||
|
||||
# Run a script on the current worker without creating a job
|
||||
# Run a script on the current worker without creating a job.
|
||||
#
|
||||
# On agent workers (no internal server), falls back to running a normal
|
||||
# preview job and waiting for the result.
|
||||
def run_inline_script_preview(content: str, language: str, args: dict = None) -> Any
|
||||
|
||||
# Wait for a job to complete and return its result.
|
||||
|
||||
@@ -1213,6 +1213,8 @@ SELECT * FROM users WHERE name = ? AND age > ?;
|
||||
|
||||
Import: import * as wmill from 'windmill-client'
|
||||
|
||||
workerHasInternalServer(): boolean
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
@@ -1750,6 +1752,8 @@ ducklake(name: string = "main"): SqlTemplateFunction
|
||||
|
||||
Import: import wmill
|
||||
|
||||
def worker_has_internal_server() -> bool
|
||||
|
||||
def get_mocked_api() -> Optional[dict]
|
||||
|
||||
# Get the HTTP client instance.
|
||||
@@ -1814,7 +1818,10 @@ def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int
|
||||
# Run script by hash synchronously and return its result.
|
||||
def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any
|
||||
|
||||
# Run a script on the current worker without creating a job
|
||||
# Run a script on the current worker without creating a job.
|
||||
#
|
||||
# On agent workers (no internal server), falls back to running a normal
|
||||
# preview job and waiting for the result.
|
||||
def run_inline_script_preview(content: str, language: str, args: dict = None) -> Any
|
||||
|
||||
# Wait for a job to complete and return its result.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
Import: import wmill
|
||||
|
||||
def worker_has_internal_server() -> bool
|
||||
|
||||
def get_mocked_api() -> Optional[dict]
|
||||
|
||||
# Get the HTTP client instance.
|
||||
@@ -66,7 +68,10 @@ def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int
|
||||
# Run script by hash synchronously and return its result.
|
||||
def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any
|
||||
|
||||
# Run a script on the current worker without creating a job
|
||||
# Run a script on the current worker without creating a job.
|
||||
#
|
||||
# On agent workers (no internal server), falls back to running a normal
|
||||
# preview job and waiting for the result.
|
||||
def run_inline_script_preview(content: str, language: str, args: dict = None) -> Any
|
||||
|
||||
# Wait for a job to complete and return its result.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
Import: import * as wmill from 'windmill-client'
|
||||
|
||||
workerHasInternalServer(): boolean
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
|
||||
@@ -131,6 +131,8 @@ const result: S3Object = await wmill.writeS3File(
|
||||
|
||||
Import: import * as wmill from 'windmill-client'
|
||||
|
||||
workerHasInternalServer(): boolean
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
|
||||
@@ -129,6 +129,8 @@ const result: S3Object = await wmill.writeS3File(
|
||||
|
||||
Import: import * as wmill from 'windmill-client'
|
||||
|
||||
workerHasInternalServer(): boolean
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
|
||||
@@ -135,6 +135,8 @@ const result: S3Object = await wmill.writeS3File(
|
||||
|
||||
Import: import * as wmill from 'windmill-client'
|
||||
|
||||
workerHasInternalServer(): boolean
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
|
||||
@@ -96,6 +96,8 @@ export async function preprocessor(event: Event) {
|
||||
|
||||
Import: import * as wmill from 'windmill-client'
|
||||
|
||||
workerHasInternalServer(): boolean
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
|
||||
@@ -137,6 +137,8 @@ result: S3Object = wmill.write_s3_file(
|
||||
|
||||
Import: import wmill
|
||||
|
||||
def worker_has_internal_server() -> bool
|
||||
|
||||
def get_mocked_api() -> Optional[dict]
|
||||
|
||||
# Get the HTTP client instance.
|
||||
@@ -201,7 +203,10 @@ def run_script_by_path(path: str, args: dict = None, timeout: dt.timedelta | int
|
||||
# Run script by hash synchronously and return its result.
|
||||
def run_script_by_hash(hash_: str, args: dict = None, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any
|
||||
|
||||
# Run a script on the current worker without creating a job
|
||||
# Run a script on the current worker without creating a job.
|
||||
#
|
||||
# On agent workers (no internal server), falls back to running a normal
|
||||
# preview job and waiting for the result.
|
||||
def run_inline_script_preview(content: str, language: str, args: dict = None) -> Any
|
||||
|
||||
# Wait for a job to complete and return its result.
|
||||
|
||||
@@ -43,6 +43,10 @@ export const SHARED_FOLDER = "/shared";
|
||||
|
||||
let mockedApi: MockedApi | undefined = undefined;
|
||||
|
||||
export function workerHasInternalServer(): boolean {
|
||||
return /^https?:\/\/(localhost|127\.0\.0\.1)(:|\/|$)/.test(OpenAPI.BASE ?? "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Windmill client with authentication token and base URL
|
||||
* @param token - Authentication token (defaults to WM_TOKEN env variable)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getWorkspace } from "./client";
|
||||
import { getWorkspace, workerHasInternalServer } from "./client";
|
||||
import { JobService } from "./services.gen";
|
||||
|
||||
type ResultCollection =
|
||||
@@ -223,10 +223,18 @@ function buildSqlTemplateFunction(provider: SqlProvider): SqlTemplateFunction {
|
||||
if (resultCollection)
|
||||
content = `-- result_collection=${resultCollection}\n${content}`;
|
||||
try {
|
||||
let result = await JobService.runScriptPreviewInline({
|
||||
workspace: getWorkspace(),
|
||||
requestBody: { args, content, language: provider.language },
|
||||
});
|
||||
let result;
|
||||
if (workerHasInternalServer()) {
|
||||
result = await JobService.runScriptPreviewInline({
|
||||
workspace: getWorkspace(),
|
||||
requestBody: { args, content, language: provider.language },
|
||||
});
|
||||
} else {
|
||||
result = await JobService.runScriptPreviewAndWaitResult({
|
||||
workspace: getWorkspace(),
|
||||
requestBody: { args, content, language: provider.language },
|
||||
});
|
||||
}
|
||||
return result as SqlResult<any, ResultCollectionT>;
|
||||
} catch (e: any) {
|
||||
let err = e;
|
||||
|
||||
Reference in New Issue
Block a user