Generate a Python REST publisher module for CloudSignal serverless messaging. Publishes MQTT messages via HTTP without persistent connections. Includes connection pooling, retry with backoff, and progress throttling. Use when implementing server-side notifications, job progress publishing, or backend-to-frontend real-time messaging with CloudSignal.
Generate a production-grade Python module for publishing real-time messages to CloudSignal's REST API. The generated code is suitable for serverless functions, FastAPI backends, or any Python async service — no persistent MQTT connections required.
cloudsignal.py — A self-contained async module with:
httpx.AsyncClient (thread-safe via asyncio.Lock)publish() and publish_with_retry() with exponential backoffAsk the user for these inputs (use defaults if not provided):
| Input | Example | Default |
|-------|---------|---------|
| Topic namespace | myapp | App name from project |
| Message types needed | notifications, jobs, transactions | All three |
| Python framework | FastAPI, Quart, Starlette, Django (async) | FastAPI |
| Target file path | app/services/cloudsignal.py | Ask based on project structure |
Important: The topic namespace MUST match the frontend's TOPIC_ROOT if the user has both a frontend and backend integration.
Read references/cloudsignal-publisher.py in this skill's directory. This is the canonical reference — a production-tested module extracted from a live SaaS. Use it as the base for all generated code.
Replace TOPIC_ROOT = "myapp" with the user's chosen namespace. This constant is used in all topic paths:
TOPIC_ROOT = "{user's namespace}"
The reference includes four domain functions. Keep, modify, or replace them based on what the user needs:
| Reference Function | Purpose | When to Keep |
|-------------------|---------|--------------|
| publish_job_progress() | Throttled progress updates | User has long-running jobs/tasks |
| publish_job_status() | Job lifecycle changes (retried) | User has jobs with start/complete/fail states |
| publish_transaction() | Balance/payment updates (retried) | User has financial transactions |
| publish_notification() | User alerts/toasts (retried) | Almost always — most apps need notifications |
For custom message types, follow the same patterns:
publish() with throttlingpublish_with_retry()The module's cleanup() function must be called on application shutdown. Generate the appropriate integration:
FastAPI (lifespan):
from contextlib import asynccontextmanager
from app.services import cloudsignal
@asynccontextmanager
async def lifespan(app: FastAPI):
yield
await cloudsignal.cleanup()
app = FastAPI(lifespan=lifespan)
Quart:
@app.after_serving
async def shutdown():
await cloudsignal.cleanup()
Starlette:
async def on_shutdown():
await cloudsignal.cleanup()
app = Starlette(on_shutdown=[on_shutdown])
Combine the adapted namespace, customized publish functions, and framework hook into the final cloudsignal.py. Preserve ALL of these production patterns from the reference:
asyncio.Lock prevents race conditions on startup_progress_timestamps: time.monotonic() for drift-free timingclear_progress_throttle(): Always called when an entity completes/fails to clean up tracking state0.5s * 2^attempt — keeps retries short (0.5s, 1s)publish() and publish_with_retry(): Callers choose the right one for their message criticalitysk_xxx Bearer auth: API key passed via Authorization: Bearer headerapplication/jsonAfter generating the module, show the user how to call it from their application code:
from app.services import cloudsignal
# In an API endpoint or background task:
await cloudsignal.publish_notification(
user_id="user_abc123",
notification_type="export_complete",
title="Export Ready",
message="Your data export is ready for download.",
action_url="/exports/download/file_xyz",
)
# For long-running jobs with progress:
for i, item in enumerate(items):
process(item)
await cloudsignal.publish_job_progress(
user_id=user_id,
job_id=job_id,
current=i + 1,
total=len(items),
)
# When the job completes:
await cloudsignal.publish_job_status(
user_id=user_id,
job_id=job_id,
status="completed",
file_url=download_url,
total_count=len(items),
)
Tell the user to add these to their environment (.env, secrets manager, etc.):
CLOUDSIGNAL_API_KEY=sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Optional — override the default REST Publisher URL:
# CLOUDSIGNAL_API_URL=https://rest-publisher.cloudsignal.app
Remind the user they need:
sk_xxx format) from the API Keys sectionThe user needs to install httpx:
pip install httpx
Read references/api-reference.md for the full REST API endpoint documentation if the user needs custom integration beyond the generated module.
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer