Skip to main content

rsgi-wsrpc: Reactive Full-Featured Python Framework

"Everything Django should have been, and everything FastAPI forgot."
High-performance asynchronous web framework built on Rust (Granian RSGI) with bidirectional WSRPC (JSON-RPC 2.0), built-in async database ORM, modern authentication, and transactional two-phase file uploading.


🧭 Table of Contents

  1. Core Philosophy & Manifesto
  2. Architecture: Core + Plugins + Application
  3. Comparison: rsgi-wsrpc vs Django vs FastAPI
  4. 🤖 AI-Native: Token-Efficient & Purpose-Built for LLMs
  5. Quickstart in 60 Seconds
  6. Core Network Engine
  7. Official System Plugins
  8. Creating Custom Plugins & Modules in the app Directory
  9. Client Library (TypeScript/JavaScript)
  10. License

💡 Core Philosophy & Manifesto

The modern web has changed: users no longer tolerate static web pages reloading for hundreds of milliseconds. Users expect instant interactions (1–5 ms), reactive real-time state synchronization, and live progress streaming.

Yet Python developers were forced to choose between two extremes:

  1. Django — a 20-year-old monolithic design from the Web 2.0 era. Adding websockets and reactivity requires bundling Django + DRF + Channels + Redis + Celery + Daphne, consuming hundreds of megabytes of RAM per worker.
  2. FastAPI — performant, but trapped in the flat HTTP/1.1 REST paradigm (Request-Response). Every user action opens a new TCP connection, exchanges kilobytes of redundant HTTP headers, and lacks built-in batteries (auth, sessions, file transactions) — forcing developers to stitch together 50 disparate third-party libraries.

rsgi-wsrpc combines the best of both worlds:

  • From Rust and Granian — blistering RSGI runtime performance without Python GIL overhead.
  • From WSRPC (JSON-RPC 2.0) — a single persistent, multiplexed channel for all operations, symmetric RPC invocation (server can call client), and native multi-return streaming.
  • From Django — production-grade batteries (Auth, DB, Two-Phase File uploads) delivered as decoupled, lightweight plugins.

🏛 Architecture: Core + Plugins + Application

The architecture enforces a strict unidirectional dependency hierarchy (Clean Architecture):

┌─────────────────────────────────────────────────────────────────────────┐
│                       1. YOUR APPLICATION (Application)                 │
│                                                                         │
│   Knows about all components: configures application in code (Code-First),
│   activates necessary system plugins, and executes domain business logic
│   Examples: Social Network, CRM, Forum, Customer Portal, IoT Server.    │
└────────────────────────────────────┬────────────────────────────────────┘
                                     │ consumes and aggregates
┌────────────────────────────────────▼────────────────────────────────────┐
│                    2. SYSTEM & APPLICATION PLUGINS                      │
│                                                                         │
│   [ Plugin: DB ]        [ Plugin: Auth ]       [ Plugin: Files ]        │
│   Async SQLAlchemy 2.0  Users, JWT,            2PC file streaming,      │
│   SQLite / PostgreSQL   roles and permissions  registry & Nginx offload │
│                                                                         │
│   [ Domain Plugins: Forum, Billing, Notifications, Analytics... ]       │
└────────────────────────────────────┬────────────────────────────────────┘
                                     │ registers into
┌────────────────────────────────────▼────────────────────────────────────┐
│                        3. NETWORK CORE (Core)                           │
│                                                                         │
│   Pure high-performance socket and RSGI runtime (Granian in Rust).      │
│   ZERO knowledge of databases or application domain models.             │
│   Responsible for: WSRPC (JSON-RPC 2.0), multi-return, sessions, 2PC.   │
└─────────────────────────────────────────────────────────────────────────┘

Core Architectural Rules:

  1. The Core is Autonomous: core/ contains zero imports from application domains or database models.
  2. Plugins are Modular: Each plugin tackles one concern and registers its handlers via core APIs (@rpc_method, @on_startup, session.register_on_close).
  3. Application Governs Composition: Need a lightweight microservice without a database? Simply omit the db plugin. Need a full-stack portal? Import the complete battery bundle.

Below is the production-tested repository layout, clearly demarcating the network engine (core/), official batteries (app/system/), and custom application modules (app/<modules>/):

my_project/
├── core/                           # ⚡ NETWORK CORE (RSGI + WSRPC)
│   ├── lib/
│   │   └── config.py               # Code-First configuration & configure()
│   ├── constants.py                # System constants and roles (UserRole)
│   ├── lifecycle.py                # Async hooks @on_startup and @on_shutdown
│   ├── logger.py                   # High-performance structured logging
│   ├── router.py                   # HTTP routing on top of RSGI (@http_route)
│   ├── security.py                 # Argon2id, JWT tokens, RSA cryptography
│   ├── session.py                  # JsonRpcSession, @rpc_method, ContextVars, Rate-Limiter
│   └── tabular.py                  # Deterministic tabular payload compression (RFC 0002, pack_tabular)
│
├── app/                            # 📦 APPLICATION & PLUGIN LAYER
│   ├── system/                     # 🔌 System Plugins (Official Batteries)
│   │   ├── db.py                   # Async SQLAlchemy 2.0 engine (async_session, Base)
│   │   ├── broadcast.py            # Event broadcaster across active sockets
│   │   ├── auth/                   # Users, scopes, and Row-Level Security (RLS)
│   │   │   ├── models.py           # Models: User, Role, Permit
│   │   │   ├── handlers.py         # RPC methods: auth.*
│   │   │   ├── permissions.py      # Scope and role verification logic
│   │   │   └── security.py         # Hashing & authorization rules
│   │   ├── login/                  # Authentication, RSA handshake, RefreshToken
│   │   │   ├── handlers.py         # RPC methods: login.submit, login.refresh, login.whoami
│   │   │   └── db.py               # Active sessions and token persistence
│   │   ├── files/                  # File metadata registry & storage service
│   │   │   ├── models.py           # FileMetadata ORM model
│   │   │   ├── service.py          # FileStorageService (quota, schema migration, deletion)
│   │   │   └── handlers.py         # HTTP route /upload and RPC methods: files.*
│   │   ├── admin/                  # Administration control plane (sessions, cache, users)
│   │   │   └── handlers.py
│   │   └── internal_api/           # Interactive RPC documentation generator
│   │       ├── api.html            # Built-in UI sandbox
│   │       ├── handlers.py         # API inspection endpoints
│   │       └── generate_docs.py    # Docstring and signature parser
│   │
│   └── <business_modules>/         # 🚀 Your application business domains
│       ├── forum/                  # Example: Community discussion module
│       │   ├── models.py           # Topic, Message, Tag models
│       │   └── handlers.py         # RPC methods: forum.get_topics, forum.create_topic
│       ├── billing/                # Example: Billing and invoicing module
│       │   ├── models.py           # Invoice, Transaction models
│       │   └── handlers.py         # RPC methods: billing.create_invoice, billing.pay
│       └── notifications/          # Example: Real-time notification service
│           └── handlers.py         # Push dispatching via broadcast
│
├── client/                         # 💻 CLIENT LIBRARIES
│   └── wsrpc.ts                    # Official TypeScript/JavaScript WSRPC client
│
├── docs/                           # 📚 Framework Documentation (EN)
│   ├── readme.md
│   ├── core.md                     # Comprehensive Core developer guide
│   └── files.md                    # Two-phase file upload guide (2PC)
│
├── docs_ru/                        # 📚 Framework Documentation (RU Twin)
│   ├── readme.md
│   ├── core.md                     # Comprehensive Core developer guide
│   └── files.md                    # Two-phase file upload guide (2PC)
│
├── main.py                         # 🚀 Entrypoint: plugin composition, RSGI application
└── pyproject.toml                  # 📦 Dependencies and package manifest

⚡ Comparison: rsgi-wsrpc vs Django vs FastAPI

1. Client-Server Interaction Model

Traditional REST (FastAPI / Django):

Every operation re-initiates a TCP/TLS handshake, transfers cookies/headers, and terminates:

[ Client ] ──── TCP + TLS Handshake (50-100 ms) ────► [ Server ]
[ Client ] ──── POST /api/items (Headers + Body) ───► [ Server ]
[ Client ] ◄─── 200 OK (Headers + Body) ──────────── [ Server ]  (connection closed)

[ Client ] ──── TCP + TLS Handshake (50-100 ms) ────► [ Server ]
[ Client ] ──── GET /api/user/profile ──────────────► [ Server ]
[ Client ] ◄─── 200 OK ───────────────────────────── [ Server ]

Reactive WSRPC (rsgi-wsrpc):

A single persistent, multiplexed WebSocket channel. Zero handshake latency, instant 1–3 ms roundtrips:

[ Client ] ═════════════════════════════════════════► [ Server ]
           (Persistent secure WSRPC socket)
           
           ─── id: 1, method: "items.create" ───────► (1 ms)
           ◄── id: 1, result: { id: 42 } ──────────── (1 ms)
           
           ─── id: 2, method: "user.get_profile" ───► (1 ms)
           ◄── id: 2, result: { name: "Alex" } ────── (1 ms)
           
           ◄── SERVER PUSH: method: "notify" ──────── (Server initiates RPC on client!)

2. Feature Matrix

Feature Django FastAPI rsgi-wsrpc
Network Engine Python WSGI / slow ASGI Uvicorn (ASGI) Granian (Rust RSGI) 🚀
Response Latency 80–250 ms 30–120 ms 1–5 ms
Symmetry ❌ Client ➔ Server only ❌ Client ➔ Server only ✅ Client ⇄ Server (Bidirectional)
Progress Streaming ❌ Requires Redis + Channels ❌ Heavy websocket boilerplate ✅ Native multi-return (stream: true)
RAM Footprint ~150–250 MB per worker ~80–120 MB per worker ~25–40 MB per worker
File Transfers Buffered in worker RAM Buffered in RAM / SpooledFile Streaming O(1) RAM + 2PC + Nginx Offload
Built-in Auth ✅ Included (Synchronous) ❌ None (Roll your own) ✅ Included (JWT + Refresh + Argon2)
Infrastructure Python + Postgres + Redis + Celery Python + Postgres + ... Single Granian binary + SQLite/Postgres
AI-Native Engineering ❌ Highly Inefficient ⚠️ Moderate (heavy boilerplate) 🚀 Maximum (AI-Native Architecture)
LLM Token Consumption ~3,000 – 5,000 tokens / feature ~2,000 – 3,500 tokens / feature ~300 – 600 tokens (5–10x savings!)
Files Touched per Feature 5–7 files 4–6 files 1–2 files (handlers.py + rpc.call)
Code Boilerplate Extreme (DTOs, URLs, views, redux) High (Pydantic schemas, Depends) Minimal (clean @rpc_method)

🤖 AI-Native: Token-Efficient & Purpose-Built for LLMs

rsgi-wsrpc is engineered from the ground up for modern AI-assisted engineering: code authored, reviewed, and refactored by LLMs and Autonomous AI Agents (Claude, Cursor, Gemini, GPT-4o, GitHub Copilot).

In conventional frameworks (FastAPI / Django), up to 80% of generated tokens are squandered on glue code, serialization boilerplate, and redundant plumbing. In rsgi-wsrpc, the unified contract yields massive savings on LLM context windows and developer token budgets.

TOKEN CONSUMPTION FOR IMPLEMENTING A FEATURE (E.G. ADD COMMENT WITH REAL-TIME PUSH)

Django REST:  ████████████████████████████████████████ (~4,200 tokens)
FastAPI:      █████████████████████████ (~2,600 tokens)
rsgi-wsrpc:   ███ (~350 tokens)  ──► UP TO 85% TOKEN REDUCTION!

Why AI Writes rsgi-wsrpc Code Faster, More Accurately, and Cheaper:

1. Zero-Boilerplate Simplicity

You no longer need to burn context asking models to generate Pydantic request DTOs, response DTOs, HTTP error handlers, route registration boilerplate, and mirrored frontend fetch() wrappers.

  • Backend: One decorator @rpc_method("domain.action"). User (current_user_ctx) and session context are accessible natively without intricate Depends() dependency graphs.
  • Frontend: One line: await rpc.call("domain.action", { ... }).

2. Unified Protocol vs Stack Sprawl

In traditional systems, developers must explain multiple disparate transport layers to the AI: REST for CRUD, WebSockets/SSE for notifications, Redis Pub/Sub for worker tasks, and Multipart for file uploads. Models exhaust their attention budgets and hallucinate. With rsgi-wsrpc, all communication adheres to one symmetrical protocol WSRPC (JSON-RPC 2.0): queries, mutations, progress streams (stream: true), server push notifications (rpc.on), and interactive server-to-client dialogs (rpc.registerMethod).

3. High Context Locality

Modules in app/<module>/ are strictly decoupled. When assigning an AI agent a feature or bug fix, you only need to provide 1 single file (handlers.py), rather than sprawling architectural files.

  • Fewer Input Tokens: Instant, near-zero latency generation from AI agents.
  • Higher Precision: Eliminates hallucinations caused by oversized, noisy context windows.
  • Direct Cost Reduction: Lowers operational API billing on commercial models.

🚀 Installation & Quickstart

📦 Installation via PIP

Install the minimal core (Granian RSGI, Orjson, WSRPC, Cryptography):

pip install rsgi-wsrpc

Or install with database support and drivers depending on your target stack:

pip install "rsgi-wsrpc[sqlite]"      # Async SQLite (aiosqlite + SQLAlchemy 2.0)
pip install "rsgi-wsrpc[postgres]"    # Async PostgreSQL (asyncpg + SQLAlchemy 2.0)
pip install "rsgi-wsrpc[mysql]"       # Async MySQL (asyncmy + SQLAlchemy 2.0)
pip install "rsgi-wsrpc[full]"        # All drivers and plugins included

⚡ Option A: Interactive Showcase Demo (1-Click)

The repository includes a ready-to-run interactive showcase (examples/showcase/):

# Linux / macOS:
./examples/showcase/run.sh

# macOS (without terminal):
# Double-click examples/showcase/run_mac.command directly in Finder!

# Windows (cmd):
examples\showcase\run.bat

# Windows (PowerShell):
.\examples\showcase\run.ps1

The launcher automatically provisions a .venv, installs dependencies, and boots the Granian server. Open http://127.0.0.1:8080 in your browser to inspect real-time WSRPC operations, the reactive database, Tabular payload compression, and streaming progress.


🛠 Option B: Minimal Server (main.py)

from core.session import rpc_method, JsonRpcSession
from core.lifecycle import on_startup

# Register RPC method
@rpc_method("math.add")
async def add_numbers(session: JsonRpcSession, params: dict):
    a = params.get("a", 0)
    b = params.get("b", 0)
    return {"result": a + b}

# Multi-return streaming progress method
@rpc_method("task.run_long")
async def run_task(session: JsonRpcSession, params: dict):
    rpc_id = params.get("rpc_id")
    for step in range(1, 4):
        # Transmit intermediate progress chunk to the socket
        await session.send_stream_chunk(rpc_id, {"progress": step * 33})
    return {"status": "completed"}

2. Launch Server via Granian

granian --interface rsgi --host 127.0.0.1 --port 8080 main:app

3. Invoke from Client (JavaScript / TypeScript)

import { BinaryWSRPC } from './wsrpc.js';

const client = new BinaryWSRPC('ws://127.0.0.1:8080');
await client.connect();

// Regular RPC call
const sum = await client.call('math.add', { a: 10, b: 25 });
console.log(sum.result); // 35

// Multi-return streaming call
await client.callStream('task.run_long', {}, (chunk) => {
    console.log(`Progress: ${chunk.progress}%`);
});

⚙️ Core Network Engine

📖 For the complete technical manual with code examples, see: docs/core.md.

The network core resides in the core/ directory and exposes the following building blocks:

  • core/session.py:

    • JsonRpcSession: Manages persistent client sockets.
    • Multiplexes incoming and outgoing RPC requests by numeric id.
    • Built-in Rate-Limiter (Token Bucket) for protection against flooding (30 req/s) with zero runtime overhead.
    • Isolated Python ContextVar instances (current_user_ctx, current_session_ctx, current_rpc_id_ctx, current_transport_ctx), accessible anywhere in the async execution context.
    • Session termination hooks: session.register_on_close(callback) for clean resource teardown.
    • Symmetric client invocation from server: await session.send_request("client_method", params).
  • core/router.py:

    • @http_route(path, methods) decorator to register raw RSGI HTTP handlers.
    • High-throughput file streams, webhooks, and health checks.
  • core/tabular.py:

    • Deterministic tabular payload compression (RFC 0002, pack_tabular, @tabular_response).
    • Cuts 50–70% of network traffic by transmitting property schemas once and packing records into a 2D matrix.
    • Direct SQL tuple optimization bypasses dictionary allocations, minimizing Python GC overhead.
  • core/security.py:

    • Password hashing using Argon2id.
    • JWT access token issuance and validation.
    • Asymmetric RSA encryption for secure credential exchange.
  • core/lifecycle.py:

    • Application startup dispatcher @on_startup (runs migrations, cache warming, and background daemons before opening sockets).
  • core/lib/config.py:

    • Settings parser for settings.yaml supporting environment variable overrides.

🔌 Official System Plugins

The framework includes pre-built and tested system batteries in app/system/:

1. Database Plugin (plugins/db)

  • Stack: Async SQLAlchemy 2.0 + orjson for ultra-fast JSON serialization.
  • Engines: SQLite out-of-the-box (zero configuration). Seamless switch to PostgreSQL via settings.yaml.
  • Usage:
    from app.system.db import async_session, Base
    from sqlalchemy import select
    
    async with async_session() as db:
        users = (await db.execute(select(User))).scalars().all()
    

2. Authentication & User Plugin (plugins/auth)

  • Features:
    • User model, flexible role architecture (dynamic roles in auth_role DB table, custom UserRole subclasses, superadmin bypass).
    • Row-Level Security (RLS): base classes BasicSecureModel and RowSecureModel for tenant/owner scoping.
    • Reliable session extension via RefreshToken and multi-device tracking in ActiveSession.
    • Context-based user retrieval anywhere without passing parameters:
      from core.session import current_user_ctx
      user = current_user_ctx.get()
      

3. Two-Phase File Upload Plugin (plugins/files)

  • Comprehensive architecture: see docs/files.md.
  • Two-Phase Commit Workflow:
    1. Client initiates upload transaction: server provisions isolated /tmp/app_uploads/<folder_hash>/.
    2. Client streams files via POST /upload. Bytes stream directly to disk without memory buffering.
    3. If client disconnects — core triggers session.on_close and erases the temp folder immediately.
    4. On completion — folder moves atomically to production storage /files/<folder_hash>/ in 0 milliseconds.
    5. Files are indexed in unified file_metadata database table (quotas, original names, MIME types).
    6. Downloads are served directly by Nginx with zero Python overhead.

4. Smart Reactive Cache Plugin (plugins/smart_cache)

  • Comprehensive architecture: see docs/smart_cache.md and RFC 0001.
  • 0 ms Latency Principle & Push Invalidation:
    • Instant screen rendering from L1 RAM (or L2 IndexedDB/localStorage) with zero network wait.
    • Server automatically tracks mutations and pushes cache.invalidate impulses or targeted cache.patch via @invalidates(tags=...).
    • Zero blind polling — the WebSocket stays completely silent until data actually changes.
    • Version handshake (cache.sync_check) on reconnect syncs only tags that changed during offline state.

5. Modular Backend Test Framework (tests/)

  • Comprehensive guide: see docs/testing.md.
  • Client-Perspective Black-Box Testing:
    • Validates the backend exactly as a real frontend client interacts with it (over WebSocket WSRPC and HTTP).
    • PersonaManager: pre-authenticated sessions (admin, user, guest) with automatic local database seeding and RLS bypass.
    • Native verification of streaming (stream: true), push notification interception (cache.invalidate, cache.patch), and two-phase uploads.
    • Built-in stress & load testing (tests/suites/test_load.py): benchmarks RPS, latency percentiles (p50/p95/p99), and broadcast fan-out reliability.

🛠 Creating Custom Plugins & Modules in the app Directory

Creating a custom feature module (e.g. support ticket system app/tickets/) is straightforward:

# app/tickets/handlers.py
from core.session import rpc_method, RPCError, current_user_ctx
from app.system.db import async_session
from app.system.files.service import FileStorageService

@rpc_method("tickets.create")
async def create_ticket(session, params):
    user = current_user_ctx.get()
    if not user:
        raise RPCError("Authentication required")

    title = params.get("title")
    text = params.get("text")
    folder_hash = params.get("folder_hash") # If files were attached

    # Persist ticket in database
    async with async_session() as db:
        async with db.begin():
            ticket = Ticket(title=title, text=text, author_id=user.id, folder=folder_hash)
            db.add(ticket)

    return {"status": "ok", "ticket_id": ticket.id}

@rpc_method("tickets.delete")
async def delete_ticket(session, params):
    ticket_id = params.get("ticket_id")
    
    async with async_session() as db:
        ticket = await db.get(Ticket, ticket_id)
        if ticket and ticket.folder:
            # Atomically delete all bundled files from disk and registry
            await FileStorageService.delete_bundle(ticket.folder)
        await db.delete(ticket)
        await db.commit()

    return {"deleted": True}

To enable the module, import its handlers in main.py:

# main.py
import app.tickets.handlers  # noqa: F401

💻 Client Library (TypeScript/JavaScript)

The framework includes the official zero-dependency client client/wsrpc.ts:

import { BinaryWSRPC, wsConnected, wsStatus } from './wsrpc';

const rpc = new BinaryWSRPC('wss://api.example.com/ws');
await rpc.connect();

// 1. Standard typed RPC call
const profile = await rpc.call<UserProfile>('user.get_profile', { user_id: 42 });
console.log('User profile:', profile.name);

// 2. Multi-return: Progress streaming for long-running workloads
const report = await rpc.callStream<ReportResult>(
    'reports.generate', 
    { period: '2026-Q3' }, 
    (chunk) => {
        console.log(`[${chunk.percent}%] Progress: ${chunk.message}`);
        updateProgressBar(chunk.percent); // Real-time UI progress update!
    }
);
console.log('Report ready:', report.download_url);

// 3. Receive unsolicited Server Push notifications
const unsubscribe = rpc.on('chat.new_message', (msg) => {
    console.log(`[${msg.author}]: ${msg.text}`);
    messagesList.update(items => [...items, msg]);
});

// 4. Symmetric RPC: Server initiates an interactive prompt on the client
rpc.registerMethod('ui.confirm', async (params) => {
    const isApproved = await showConfirmationModal(params.title, params.message);
    return { confirmed: isApproved }; // Transmitted back to the server!
});

📖 For in-depth UI framework integrations (Svelte, React, Vue), error handling, and unsubscription patterns, see: docs/core.md.


📄 License

This project is licensed under the MIT License.
Free for commercial use, modification, and distribution.

Release files for rsgi-wsrpc 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rsgi-wsrpc 0.2.0
File Size Uploaded
rsgi_wsrpc-0.2.0.tar.gz 74.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rsgi-wsrpc 0.2.0
File Interpreter ABI Platform
rsgi_wsrpc-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 154.5 kB

Release files / rsgi_wsrpc-0.2.0.tar.gz

Download URL rsgi_wsrpc-0.2.0.tar.gz
Size 74.5 kB
Tags Source
SHA-256 checksum
How to use checksums
7f2070b33c0d80da1f1bb4cc20b914383bfc5305627518b54f5ed9653537b68b
BLAKE2b-256 checksum
How to use checksums
f58af7546f9feefff7d423a806c1b8c46463d0c72dd9153ff465713befdd8139
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release files / rsgi_wsrpc-0.2.0-py3-none-any.whl

Download URL rsgi_wsrpc-0.2.0-py3-none-any.whl
Size 80.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ba734143bda08c5c117cefd901732d49613a24f4a0ac7199a6865080fb69c297
BLAKE2b-256 checksum
How to use checksums
4fa0ae8abec24b57aa0689208a5fb7e83fbab2522a36b9f6e8586a9a98204c47
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page