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.zipInstalls 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 fileswmill 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.
More by windmill-labs
View all skills by windmill-labs →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.
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.
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."
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.
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.
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.
Related MCP Servers
Browse all serversRtfmbro is an MCP server for config management tools—get real-time, version-specific docs from GitHub for Python, Node.j
Control a running Abaqus/CAE GUI via MCP: run Python scripts, fetch message logs, and automate Abaqus GUI scripting for
any-script-mcp: Run shell scripts and execute CLI tools defined in YAML, with custom shells (bash, Python, Node.js, Deno
Fast PyAirbyte auto-generates complete Python ETL pipeline scripts with Airbyte, featuring error handling and rapid envi
Learn how to use Python to read a file and manipulate local files safely through the Filesystem API.
Connect Blender to Claude AI for seamless 3D modeling. Use AI 3D model generator tools for faster, intuitive, interactiv
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.