← Back to Skills Marketplace
iliaal

ia-python-services

by Ilia Alshanetsky · GitHub ↗ · v3.0.4 · MIT-0
cross-platform ✓ Security Clean
296
Downloads
0
Stars
0
Active Installs
11
Versions
Install in OpenClaw
/install compound-eng-python-services
Description
Python patterns for CLI tools, async concurrency, and backend services. Use when working with Python code, building CLI apps, FastAPI services, async with as...
README (SKILL.md)

Python Services & CLI

Modern Tooling

Tool Replaces Purpose
uv pip, virtualenv, pyenv, pipx Package/dependency management
ruff flake8, black, isort Linting + formatting
ty mypy, pyright Type checking (Astral, faster)
  • uv init --package myproject for distributable packages, uv init for apps
  • uv add \x3Cpkg>, uv add --group dev \x3Cpkg>, never edit pyproject.toml deps manually
  • uv run \x3Ccmd> instead of activating venvs -- auto-activates the venv without explicit activation
  • uv add --upgrade \x3Cpkg> to upgrade a single package without touching others
  • uv tree --outdated to preview what would be upgraded before committing
  • uv.lock goes in version control
  • Use [dependency-groups] (PEP 735) for dev/test/docs, not [project.optional-dependencies]
  • PEP 723 inline metadata for standalone scripts with deps
  • ruff check --fix . && ruff format . for lint+format in one pass

Standard project layout:

src/mypackage/
    __init__.py
    main.py
    services/
    models/
tests/
    conftest.py
    test_main.py
pyproject.toml

See cli-tools.md for Click patterns, argparse, and CLI project layout.

Parallelism

Workload Approach
Many concurrent I/O calls asyncio (gather, create_task)
CPU-bound computation multiprocessing.Pool or concurrent.futures.ProcessPoolExecutor
Mixed I/O + CPU asyncio.to_thread() to offload blocking work
Simple scripts, few connections Stay synchronous

Sync vs Async Decision

Use async (asyncio) when:

  • I/O-bound work has multiple concurrent operations (HTTP calls, database queries, file I/O happening in parallel)
  • WebSocket servers or long-lived connections require it
  • The framework requires it (FastAPI async endpoints, aiohttp)

Stay synchronous when:

  • Work is CPU-bound (computation, data transformation) -- async adds nothing, use multiprocessing instead
  • Building simple scripts and CLI tools with sequential I/O
  • All I/O is sequential anyway (one DB query, process result, one API call)
  • The team lacks async debugging experience (asyncio stack traces are harder to read)

Rule of thumb: if the code is not waiting on multiple I/O operations concurrently, sync is simpler and correct. Do not add async complexity for a single sequential pipeline.

Key rule: Stay fully sync or fully async within a call path.

asyncio patterns:

  • asyncio.gather(*tasks) for concurrent I/O -- use return_exceptions=True for partial failure tolerance
  • asyncio.TaskGroup (3.11+) for structured concurrency -- automatic cancellation of sibling tasks on failure; prefer over gather when all tasks must succeed
  • asyncio.Semaphore(n) to limit concurrency (rate limiting external APIs)
  • asyncio.wait_for(coro, timeout=N) for timeouts
  • asyncio.Queue for producer-consumer
  • asyncio.Lock when coroutines share mutable state
  • Never block the event loop: asyncio.to_thread(sync_fn) for sync libs, aiohttp/httpx.AsyncClient for HTTP
  • Handle CancelledError -- always re-raise after cleanup
  • Async generators (async for) for streaming/pagination

multiprocessing for CPU-bound:

from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor(max_workers=4) as pool:
    results = list(pool.map(cpu_task, items))

See fastapi.md for project structure, lifespan, config, DI, async DB, and repository pattern.

Background Jobs

  • Return job ID immediately, process async. Client polls /jobs/{id} for status
  • Celery: @app.task(bind=True, max_retries=3, autoretry_for=(ConnectionError,)) -- exponential backoff: raise self.retry(countdown=2**self.request.retries * 60)
  • Alternatives: Dramatiq (modern Celery), RQ (simple Redis), cloud-native (SQS+Lambda, Cloud Tasks)
  • Idempotency is mandatory -- tasks may retry. Use idempotency keys for external calls, check-before-write, upsert patterns
  • Dead letter queue for permanently failed tasks after max retries
  • Task workflows: chain(a.s(), b.s()) for sequential, group(...) for parallel, chord(group, callback) for fan-out/fan-in

Resilience

Retries with tenacity:

from tenacity import retry, stop_after_attempt, wait_exponential_jitter, retry_if_exception_type

@retry(
    retry=retry_if_exception_type((ConnectionError, TimeoutError)),
    stop=stop_after_attempt(5) | stop_after_delay(60),
    wait=wait_exponential_jitter(initial=1, max=30),
    before_sleep=log_retry_attempt,
)
def call_api(url: str) -> dict: ...
  • Retry only transient errors: network, 429/502/503/504. Never retry 4xx (except 429), auth errors, validation errors
  • Every network call needs a timeout
  • @fail_safe(default=[]) decorator for non-critical paths -- return cached/default on failure
  • functools.lru_cache(maxsize=N) for pure-function memoization; functools.cache (unbounded) for small domains
  • Stack decorators: @traced @with_timeout(30) @retry(...) -- separate infra from business logic

Connection pooling is mandatory for production: reuse httpx.AsyncClient() across requests, configure SQLAlchemy pool_size/max_overflow, use aiohttp.TCPConnector(limit=N).

Production Resilience

  • Fail-fast config validation: use a Pydantic BaseSettings model with model_validator to parse and validate all environment variables at startup. If invalid, crash before serving traffic. Never discover a missing secret on the first request that needs it.
  • Health endpoints: expose /health (shallow liveness -- returns 200 if the process responds) and /ready (deep readiness -- verifies database, Redis, and critical dependencies are reachable). Load balancers route traffic based on /ready; orchestrators restart based on /health.

Observability

  • structlog for JSON structured logging. Configure once at startup with JSONRenderer, TimeStamper, merge_contextvars
  • Correlation IDs -- generate at ingress (X-Correlation-ID header), bind to contextvars, propagate to downstream calls
  • Log levels: DEBUG=diagnostics, INFO=operations, WARNING=anomalies handled, ERROR=failures needing attention. Never log expected behavior at ERROR
  • Prometheus metrics -- track latency (Histogram), traffic (Counter), errors (Counter), saturation (Gauge). Keep label cardinality bounded (no user IDs)
  • OpenTelemetry for distributed tracing across services

Discipline

  • Simplicity first -- every change as simple as possible, impact minimal code
  • Only touch what's necessary -- avoid introducing unrelated changes
  • No hacky workarounds -- if a fix feels wrong, step back and implement the clean solution
  • Before adding a new abstraction, verify it appears in 3+ places. If not, inline it.
  • Verify: see Verify section below -- pass all checks with zero warnings before declaring done
  • Coverage target: 80%+ (uv run pytest --cov --cov-report=html)

Testing Patterns

  • pytest flags: --lf (last failed), -x (stop on first failure), -k "pattern" (filter), --pdb (debugger on failure)
  • Fixtures: use conftest.py for shared fixtures. Scope wisely: @pytest.fixture(scope="session") for expensive setup (DB connections), scope="function" (default) for test isolation
  • tmp_path: built-in fixture for temp files -- no manual cleanup needed
  • Parametrize with IDs: @pytest.mark.parametrize("input,expected", [...], ids=["empty", "single", "overflow"]) for readable test names
  • Mock discipline: always autospec=True on mocks to catch API drift. assert_awaited_once() for async mocks.
  • Test markers: register in pyproject.toml under [tool.pytest.ini_options] with markers = ["slow", "integration"]. Run fast tests with -m "not slow".
  • Protocol duck typing: use class Renderable(Protocol) for structural typing at service boundaries -- enables testing with plain objects instead of mocks
  • Context managers: @contextmanager for connection/transaction lifecycle. Always implement __exit__ cleanup.

Error Handling

  • Validate inputs at boundaries before expensive ops. Report all errors at once when possible
  • Use specific exceptions: ValueError, TypeError, KeyError, not bare Exception
  • raise ServiceError("upload failed") from e -- always chain to preserve debug trail
  • Convert external data to domain types (enums, Pydantic models) at system boundaries
  • Batch processing: BatchResult(succeeded={}, failed={}) -- don't let one item abort the batch
  • Pydantic BaseModel with field_validator for complex input validation

Migrations

  • Separate schema and data migrations -- data backfills in their own migration file
  • Renames/removals use expand-contract: add new column → backfill → switch reads → drop old (see ia-postgresql skill for the full pattern)
  • Never edit a migration that has already run in a shared environment
  • Alembic: use --autogenerate as a starting point, always review generated SQL before committing
  • Test migrations against production-sized data -- a migration that takes 2ms on dev can lock a table for minutes in production

API Design

  • Contract-first: define Pydantic BaseModel request/response schemas and FastAPI response_model before writing endpoint logic. The schema is the contract -- implementation follows. Generate OpenAPI docs from these models automatically.
  • Hyrum's Law awareness: every observable response field, ordering, or timing becomes a dependency for callers. Use explicit response_model and model_config = ConfigDict(extra="forbid") to control exactly what's serialized -- never return raw dicts or ORM objects from endpoints.
  • Addition over modification: add new optional fields (field: str | None = None) rather than changing or removing existing ones. Removing a Pydantic field from a response model breaks callers silently. Deprecate first (Field(deprecated=True)), remove in a later version.
  • Consistent error structure: all exceptions should produce the same envelope: {"error": {"code": "...", "message": "...", "details": ...}}. Register @app.exception_handler for RequestValidationError, HTTPException, and application-specific exceptions to normalize into one format. Callers build error handling once.
  • Boundary validation via Pydantic: validate at the endpoint/handler level with Pydantic models and FastAPI's automatic request parsing. Internal services and repositories trust that input was validated at entry -- no redundant validation scattered through business logic.
  • Third-party responses are untrusted data: validate shape and content of external API responses before using them in logic, rendering, or decision-making. A compromised or misbehaving service can return unexpected types, malicious content, or missing fields. Parse through a Pydantic model before use.

Verify

  • uv run pytest passes with zero failures
  • uv run ruff check . passes with zero warnings
  • uv run ty check . passes with zero errors
  • Coverage target: 80%+ (uv run pytest --cov)
Usage Guidance
This skill is instruction-only guidance for Python projects and appears internally consistent and low-risk. Before installing/using, confirm you trust the skill author (source unknown) and be aware that the SKILL.md recommends third-party tools (example: 'uv'); verify those tool names and their ecosystem independently. Because it can be invoked by the agent normally, monitor outputs for unexpected behavior and only grant secrets/credentials to separate services you explicitly integrate (the skill itself does not ask for them). If you need higher assurance, ask the maintainer for a known homepage or repository link and review any linked tooling before adopting it in production.
Capability Analysis
Type: OpenClaw Skill Name: compound-eng-python-services Version: 3.0.4 The skill bundle provides standard, high-quality guidelines and patterns for modern Python development, including FastAPI, CLI tools, and asynchronous programming. It recommends reputable tools like uv, ruff, and Pydantic, and emphasizes resilience, observability, and testing best practices. No malicious code, data exfiltration, or harmful prompt injection attempts were found across SKILL.md or the reference files.
Capability Assessment
Purpose & Capability
The name/description (patterns for CLI, async, FastAPI) align with the SKILL.md and reference content. The guidance focuses on project layout, concurrency, background jobs, and resilience — all appropriate for a Python services guidance skill. There are no declared env vars, binaries, or unrelated permissions requested.
Instruction Scope
SKILL.md contains only coding patterns, example snippets, and tool recommendations. It does not instruct the agent to read arbitrary host files, harvest environment variables, send data to external endpoints, or execute shell commands beyond normal developer tooling examples. References to configuration patterns (e.g., Pydantic BaseSettings) are prescriptive, not actions that exfiltrate data.
Install Mechanism
There is no install spec and no code files to write/execute. Being instruction-only means nothing is downloaded or installed by default, minimizing disk/write risk.
Credentials
The skill declares no required environment variables or credentials. While SKILL.md advises using env-based config in projects (Pydantic BaseSettings), that is expected for a backend guidance skill and does not imply the skill itself needs secrets.
Persistence & Privilege
always is false and the skill is user-invocable with normal autonomous invocation allowed. It does not request elevated persistence or to modify other skills or system-wide settings.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install compound-eng-python-services
  3. After installation, invoke the skill by name or use /compound-eng-python-services
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v3.0.4
v3.0.4
v3.0.3
v3.0.3
v3.0.2
v3.0.2
v3.0.1
v3.0.1
v3.0.0
v3.0.0
v2.56.1
v2.56.1
v2.56.0
v2.56.0
v2.55.1
v2.55.1
v2.55.0
v2.55.0
v2.53.2
v2.53.2
v2.53.0
v2.53.0
Metadata
Slug compound-eng-python-services
Version 3.0.4
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 11
Frequently Asked Questions

What is ia-python-services?

Python patterns for CLI tools, async concurrency, and backend services. Use when working with Python code, building CLI apps, FastAPI services, async with as... It is an AI Agent Skill for Claude Code / OpenClaw, with 296 downloads so far.

How do I install ia-python-services?

Run "/install compound-eng-python-services" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is ia-python-services free?

Yes, ia-python-services is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does ia-python-services support?

ia-python-services is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created ia-python-services?

It is built and maintained by Ilia Alshanetsky (@iliaal); the current version is v3.0.4.

💬 Comments