From wire
Production Python quality skill. Auto-activates when writing, reviewing, or refactoring Python code. Enforces modern type syntax, LBYL exception handling, pathlib for file operations, and clean module design. Particularly relevant for Dagster asset code, pipeline ingestion scripts, and utility code in Wire projects.
npx claudepluginhub rittmananalytics/wire-plugin --plugin wireThis skill uses the workspace's default tool permissions.
This skill ensures Python code written in Wire projects meets production quality standards. It activates proactively when creating or reviewing Python files to enforce consistent patterns around types, error handling, file operations, and module structure.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
This skill ensures Python code written in Wire projects meets production quality standards. It activates proactively when creating or reviewing Python files to enforce consistent patterns around types, error handling, file operations, and module structure.
Keywords: "python", "type hints", "pathlib", "exception", "LBYL", "EAFP", "click", "subprocess", "refactor this", "is this good python", "make this pythonic", "code review", "improve this code"
Self-triggered: when you are about to write or modify .py files in a Wire project, especially in dagster_orchestration/, pipeline/, or utility scripts.
Use Python 3.10+ union syntax (X | None not Optional[X]). Annotate all function signatures:
# ✅ Correct
def get_row_count(table: str, project_id: str | None = None) -> int:
...
# ❌ Old style
from typing import Optional
def get_row_count(table: str, project_id: Optional[str] = None) -> int:
...
Use list[str] not List[str], dict[str, int] not Dict[str, int].
Check conditions before acting. Never use exceptions for control flow:
# ✅ LBYL — check first
if "key" in data:
value = data["key"]
else:
value = default
# ❌ EAFP — exception as control flow
try:
value = data["key"]
except KeyError:
value = default
When exceptions ARE appropriate:
raise RuntimeError("...") from original_errorrequests.raise_for_status())# ✅ Exception at system boundary
def read_config(path: Path) -> dict:
if not path.exists():
raise FileNotFoundError(f"Config not found: {path}")
try:
return json.loads(path.read_text(encoding="utf-8"))
except json.JSONDecodeError as e:
raise ValueError(f"Invalid JSON in config {path}") from e
pathlib.Path# ✅ Correct
from pathlib import Path
config_path = Path("config") / "settings.json"
if config_path.exists():
content = config_path.read_text(encoding="utf-8")
# ❌ Avoid
import os
config_path = os.path.join("config", "settings.json")
if os.path.exists(config_path):
with open(config_path, "r") as f:
content = f.read()
Always:
.exists() before .resolve() (.resolve() raises on non-existent paths in strict mode)encoding="utf-8" explicitly on .read_text() / .write_text()/ operator for path joining, not os.path.join()Module-level absolute imports only. No relative imports except for TYPE_CHECKING:
# ✅ Correct
from dagster import asset, AssetExecutionContext
from pathlib import Path
# ❌ Avoid
from .utils import helper # relative import
from dagster import * # wildcard import
Import order: stdlib → third-party → local. One blank line between each group.
Never do I/O, database calls, or heavy computation in __init__, __repr__, @property, or __len__. These are called implicitly and must be cheap.
| Anti-pattern | Correct approach |
|---|---|
for i in range(len(items)): | for item in items: or for i, item in enumerate(items): |
| Destructuring into single-use locals | Use the expression directly |
| More than 4 levels of indentation | Extract inner logic to a function |
Backwards-compatibility __all__ exports | Delete unused code outright |
print() for logging | logging.getLogger(__name__) or context.log.info() in Dagster |
import sys
import click
@click.command()
@click.argument("project_path", type=click.Path(exists=True, path_type=Path))
@click.option("--verbose", is_flag=True)
def run(project_path: Path, verbose: bool) -> None:
"""Brief description of what the command does."""
if not (project_path / "dbt_project.yml").exists():
click.echo("Error: not a dbt project directory", err=True)
raise SystemExit(1)
click.echo(f"Running in {project_path}")
click.echo() not print()err=True for error messages (writes to stderr)raise SystemExit(1) for error exits, not sys.exit(1) inside click commandsclick.Path(path_type=Path) to get pathlib.Path objects directlyimport subprocess
from pathlib import Path
def run_dbt(project_dir: Path, *args: str) -> subprocess.CompletedProcess:
cmd = ["dbt", *args]
result = subprocess.run(
cmd,
cwd=project_dir,
capture_output=True,
text=True,
check=False, # handle returncode manually
)
if result.returncode != 0:
raise RuntimeError(
f"dbt command failed: {' '.join(cmd)}\n{result.stderr}"
)
return result
Always:
subprocess.run() not subprocess.call() or os.system()text=True for string output (not bytes)returncode explicitly — don't rely on check=True swallowing contextcwd= rather than os.chdir()