write-script-python3

2
0
Source

MUST use when writing Python scripts.

Install

mkdir -p .claude/skills/write-script-python3 && curl -L -o skill.zip "https://mcp.directory/api/skills/download/3757" && unzip -o skill.zip -d .claude/skills/write-script-python3 && rm skill.zip

Installs to .claude/skills/write-script-python3

About this skill

CLI Commands

Place scripts in a folder. After writing, tell the user they can run:

  • wmill script generate-metadata - Generate .script.yaml and .lock files
  • wmill sync push - Deploy to Windmill

Do NOT run these commands yourself. Instead, inform the user that they should run them.

Use wmill resource-type list --schema to discover available resource types.

Python

Structure

The script must contain at least one function called main:

def main(param1: str, param2: int):
    # Your code here
    return {"result": param1, "count": param2}

Do not call the main function. Libraries are installed automatically.

Resource Types

On Windmill, credentials and configuration are stored in resources and passed as parameters to main.

You need to redefine the type of the resources that are needed before the main function as TypedDict:

from typing import TypedDict

class postgresql(TypedDict):
    host: str
    port: int
    user: str
    password: str
    dbname: str

def main(db: postgresql):
    # db contains the database connection details
    pass

Important rules:

  • The resource type name must be IN LOWERCASE
  • Only include resource types if they are actually needed
  • If an import conflicts with a resource type name, rename the imported object, not the type name
  • Make sure to import TypedDict from typing if you're using it

Imports

Libraries are installed automatically. Do not show installation instructions.

import requests
import pandas as pd
from datetime import datetime

If an import name conflicts with a resource type:

# Wrong - don't rename the type
import stripe as stripe_lib
class stripe_type(TypedDict): ...

# Correct - rename the import
import stripe as stripe_sdk
class stripe(TypedDict):
    api_key: str

Windmill Client

Import the windmill client for platform interactions:

import wmill

See the SDK documentation for available methods.

Preprocessor Scripts

For preprocessor scripts, the function should be named preprocessor and receives an event parameter:

from typing import TypedDict, Literal, Any

class Event(TypedDict):
    kind: Literal["webhook", "http", "websocket", "kafka", "email", "nats", "postgres", "sqs", "mqtt", "gcp"]
    body: Any
    headers: dict[str, str]
    query: dict[str, str]

def preprocessor(event: Event):
    # Transform the event into flow input parameters
    return {
        "param1": event["body"]["field1"],
        "param2": event["query"]["id"]
    }

S3 Object Operations

Windmill provides built-in support for S3-compatible storage operations.

import wmill

# Load file content from S3
content: bytes = wmill.load_s3_file(s3object)

# Load file as stream reader
reader: BufferedReader = wmill.load_s3_file_reader(s3object)

# Write file to S3
result: S3Object = wmill.write_s3_file(
    s3object,           # Target path (or None to auto-generate)
    file_content,       # bytes or BufferedReader
    s3_resource_path,   # Optional: specific S3 resource
    content_type,       # Optional: MIME type
    content_disposition # Optional: Content-Disposition header
)

Python SDK (wmill)

Import: import wmill

def get_mocked_api() -> Optional[dict]

Get the HTTP client instance.

Returns:

Configured httpx.Client for API requests

def get_client() -> httpx.Client

Make an HTTP GET request to the Windmill API.

Args:

endpoint: API endpoint path

raise_for_status: Whether to raise an exception on HTTP errors

**kwargs: Additional arguments passed to httpx.get

Returns:

HTTP response object

def get(endpoint, raise_for_status = True, **kwargs) -> httpx.Response

Make an HTTP POST request to the Windmill API.

Args:

endpoint: API endpoint path

raise_for_status: Whether to raise an exception on HTTP errors

**kwargs: Additional arguments passed to httpx.post

Returns:

HTTP response object

def post(endpoint, raise_for_status = True, **kwargs) -> httpx.Response

Create a new authentication token.

Args:

duration: Token validity duration (default: 1 day)

Returns:

New authentication token string

def create_token(duration = dt.timedelta(days=1)) -> str

Create a script job and return its job id.

.. deprecated:: Use run_script_by_path_async or run_script_by_hash_async instead.

def run_script_async(path: str = None, hash_: str = None, args: dict = None, scheduled_in_secs: int = None) -> str

Create a script job by path and return its job id.

def run_script_by_path_async(path: str, args: dict = None, scheduled_in_secs: int = None) -> str

Create a script job by hash and return its job id.

def run_script_by_hash_async(hash_: str, args: dict = None, scheduled_in_secs: int = None) -> str

Create a flow job and return its job id.

def run_flow_async(path: str, args: dict = None, scheduled_in_secs: int = None, do_not_track_in_parent: bool = True) -> str

Run script synchronously and return its result.

.. deprecated:: Use run_script_by_path or run_script_by_hash instead.

def run_script(path: str = None, hash_: str = None, 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 script by path synchronously and return its result.

def run_script_by_path(path: 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 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

def run_inline_script_preview(content: str, language: str, args: dict = None) -> Any

Wait for a job to complete and return its result.

Args:

job_id: ID of the job to wait for

timeout: Maximum time to wait (seconds or timedelta)

verbose: Enable verbose logging

cleanup: Register cleanup handler to cancel job on exit

assert_result_is_not_none: Raise exception if result is None

Returns:

Job result when completed

Raises:

TimeoutError: If timeout is reached

Exception: If job fails

def wait_job(job_id, timeout: dt.timedelta | int | float | None = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False)

Cancel a specific job by ID.

Args:

job_id: UUID of the job to cancel

reason: Optional reason for cancellation

Returns:

Response message from the cancel endpoint

def cancel_job(job_id: str, reason: str = None) -> str

Cancel currently running executions of the same script.

def cancel_running() -> dict

Get job details by ID.

Args:

job_id: UUID of the job

Returns:

Job details dictionary

def get_job(job_id: str) -> dict

Get the root job ID for a flow hierarchy.

Args:

job_id: Job ID (defaults to current WM_JOB_ID)

Returns:

Root job ID

def get_root_job_id(job_id: str | None = None) -> dict

Get an OIDC JWT token for authentication to external services.

Args:

audience: Token audience (e.g., "vault", "aws")

expires_in: Optional expiration time in seconds

Returns:

JWT token string

def get_id_token(audience: str, expires_in: int | None = None) -> str

Get the status of a job.

Args:

job_id: UUID of the job

Returns:

Job status: "RUNNING", "WAITING", or "COMPLETED"

def get_job_status(job_id: str) -> JobStatus

Get the result of a completed job.

Args:

job_id: UUID of the completed job

assert_result_is_not_none: Raise exception if result is None

Returns:

Job result

def get_result(job_id: str, assert_result_is_not_none: bool = True) -> Any

Get a variable value by path.

Args:

path: Variable path in Windmill

Returns:

Variable value as string

def get_variable(path: str) -> str

Set a variable value by path, creating it if it doesn't exist.

Args:

path: Variable path in Windmill

value: Variable value to set

is_secret: Whether the variable should be secret (default: False)

def set_variable(path: str, value: str, is_secret: bool = False) -> None

Get a resource value by path.

Args:

path: Resource path in Windmill

none_if_undefined: Return None instead of raising if not found

interpolated: if variables and resources are fully unrolled

Returns:

Resource value dictionary or None

def get_resource(path: str, none_if_undefined: bool = False, interpolated: bool = True) -> dict | None

Set a resource value by path, creating it if it doesn't exist.

Args:

value: Resource value to set

path: Resource path in Windmill

resource_type: Resource type for creation

def set_resource(value: Any, path: str, resource_type: str)

List resources from Windmill workspace.

Args:

resource_type: Optional resource type to filter by (e.g., "postgresql", "mysql", "s3")

page: Optional page number for pagination

per_page: Optional number of results per page

Returns:

List of resource dictionaries

def list_resources(resource_type: str = None, page: int = None, per_page: int = None) -> list[dict]

Set the workflow state.

Args:

value: State value to set

path: Optional state resource path override.

def set_state(value: Any, path: str | None = None) -> None

Get the workflow state.

Args:

path: Optional state resource path override.

Returns:

State value or None if not set

def get_state(path: str | None = None) -> Any

Set job progress percentage (0-99).

Args:

value: Progress percentage


Content truncated.

You might also like

flutter-development

aj-geddes

Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.

643969

drawio-diagrams-enhanced

jgtolentino

Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.

591705

ui-ux-pro-max

nextlevelbuilder

"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."

318399

godot

bfollington

This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.

340397

nano-banana-pro

garg-aayush

Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.

452339

fastapi-templates

wshobson

Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.

304231

Stay ahead of the MCP ecosystem

Get weekly updates on new skills and servers.