| name | scaffold-helpers |
| description | Scaffolds battle-tested helper modules — exception hierarchy, retry logic, date utilities, port management, FastAPI middleware, and async database layer. |
Scaffold Helpers
"Universal utilities, zero boilerplate."
Scaffolds battle-tested helper modules that every Python project needs. These are framework-agnostic — they work identically in FastAPI, Flask, CLI tools, or background workers.
How to Use
Fresh project (safe mode — only adds new files)
human-skills '{
"tool_name": "sethelpers",
"tool_args": {
"destination": "/path/to/your_project/src/helpers"
}
}'
Force overwrite matching files only
human-skills '{
"tool_name": "sethelpers",
"tool_args": {
"destination": "/path/to/your_project/src/helpers",
"override": "true"
}
}'
Helpers Structure
helpers/
├── __init__.py ← Single export point with graceful degradation
├── exceptions.py ← AppError → NotFoundError, ValidationError, etc.
├── date_utils.py ← ISO 8601, timezone-aware parsing, relative time
├── retry.py ← Tenacity-based exponential backoff (sync + async)
├── port_utils.py ← Auto-kill orphaned server processes
├── cors.py ← [Optional] CORS configuration (requires FastAPI)
├── middleware.py ← [Optional] Request logging middleware (requires FastAPI)
├── error_handlers.py ← [Optional] Global exception handlers (requires FastAPI)
├── connection.py ← [Optional] Async database engine (requires SQLAlchemy)
└── repository.py ← [Optional] Base CRUD repository (requires SQLAlchemy)
API Quick Reference
Exceptions (always available)
from src.helpers import NotFoundError, ValidationError, ExternalServiceError
raise NotFoundError("User", user_id)
raise ValidationError("Invalid email")
raise ExternalServiceError("Stripe", "declined")
raise PermissionDeniedError()
raise ConflictError("Duplicate entry")
raise RateLimitError(retry_after=60)
Date Utils (always available)
from src.helpers import time_now_iso, parse_iso, relative_time
timestamp = time_now_iso()
dt = parse_iso("2025-05-15T14:30:00")
ago = relative_time(some_datetime)
Retry Logic (requires tenacity)
from src.helpers import retry_on_failure, retry_async_on_failure
@retry_on_failure(max_attempts=3)
def call_api():
response = requests.get(url, timeout=10)
response.raise_for_status()
@retry_async_on_failure(max_attempts=5, retryable=(ConnectionError, TimeoutError))
async def fetch_data():
async with httpx.AsyncClient() as client:
resp = await client.get(url, timeout=10)
resp.raise_for_status()
Port Utils (always available)
from src.helpers import kill_pid, get_pid
kill_pid(8000)
get_pid(8000)
FastAPI Components (requires fastapi)
from src.helpers import register_cors, register_middleware, register_error_handlers
Database Layer (requires sqlalchemy[asyncio])
from src.helpers import init_db, get_session, shutdown_db, BaseRepository
class UserRepository(BaseRepository[User]):
def __init__(self, session):
super().__init__(User, session)
Graceful Degradation
helpers/__init__.py uses graceful degradation for optional dependencies:
- Core (exceptions, date_utils, retry, port_utils) — always available
- Web (cors, middleware, error_handlers) — only if FastAPI is installed
- DB (connection, repository) — only if SQLAlchemy is installed
[!IMPORTANT]
The try-except ImportError: pass blocks in __init__.py are intentional and are NOT linter violations.
Post-Scaffolding
- Rename
AppError → YourProjectError in exceptions.py (optional)
- Add
tenacity to dependencies: pip install tenacity
- Import:
from src.helpers import AppError, NotFoundError
Enforcement
See .agents/rules/helpers-usage-rules.md for strict usage patterns. Manual retry loops and raw exceptions are FORBIDDEN.