Skip to main content

A fast DynamoDB ORM for Python with a Rust core

Project description

pydynox 🐍⚙️

CI PyPI version Python versions License Downloads OpenSSF Scorecard

A fast DynamoDB ORM for Python with a Rust core.

Pre-release: The core features are working and tested. We're adding features, polishing the API, receiving ideas, and testing performance and edge cases before v1.0. Feel free to try it out and share feedback!

Why "pydynox"?

Py(thon) + Dyn(amoDB) + Ox(ide/Rust)

GenAI Contributions 🤖

I believe GenAI is transforming how we build software. It's a powerful tool that accelerates development when used by developers who understand what they're doing.

To support both humans and AI agents, I created:

  • .ai/ folder - Guidelines for agentic IDEs (Cursor, Windsurf, Kiro, etc.)
  • ADR/ folder - Architecture Decision Records for humans to understand the "why" behind decisions

If you're contributing with AI help:

  • Understand what the AI generated before submitting
  • Make sure the code follows the project patterns
  • Test your changes

I reserve the right to reject low-quality PRs where project patterns are not followed and it's clear that GenAI was driving instead of the developer.

Features

  • Simple class-based API like PynamoDB
  • Fast serialization with Rust
  • Batch operations with auto-splitting
  • Transactions
  • Global Secondary Indexes
  • Async support
  • Pydantic integration
  • TTL (auto-expiring items)
  • Lifecycle hooks
  • Auto-generate IDs and timestamps
  • Optimistic locking
  • Rate limiting
  • Field encryption (KMS)
  • Compression (zstd, lz4, gzip)
  • S3 attribute for large files
  • PartiQL support
  • Observability (logging, metrics)

Installation

pip install pydynox

For Pydantic support:

pip install pydynox[pydantic]

Quick Start

Define a Model

from pydynox import Model, ModelConfig, String, Number, Boolean, List

class User(Model):
    model_config = ModelConfig(table="users")
    
    pk = String(hash_key=True)
    sk = String(range_key=True)
    name = String()
    email = String()
    age = Number(default=0)
    active = Boolean(default=True)
    tags = List(String)

CRUD Operations

# Create
user = User(pk="USER#123", sk="PROFILE", name="John", email="john@test.com")
user.save()

# Read
user = User.get(pk="USER#123", sk="PROFILE")

# Update
user.name = "John Doe"
user.save()

# Delete
user.delete()

Query

from pydynox import Condition

# Simple query
users = User.query(pk="USER#123")

# With filters
users = User.query(pk="USER#123") \
    .where(Condition.begins_with("sk", "ORDER#")) \
    .where(Condition.gt("age", 18)) \
    .exec()

# Iterate (auto pagination)
for user in users:
    print(user.name)

Conditions

from pydynox import Condition

# Save with condition
user.save(condition=Condition.not_exists("pk"))

# Delete with condition
user.delete(condition=Condition.eq("version", 5))

# Combine conditions
user.save(
    condition=Condition.not_exists("pk") | Condition.eq("version", 1)
)

Available conditions:

  • Condition.eq(field, value) - equals
  • Condition.ne(field, value) - not equals
  • Condition.gt(field, value) - greater than
  • Condition.gte(field, value) - greater than or equal
  • Condition.lt(field, value) - less than
  • Condition.lte(field, value) - less than or equal
  • Condition.exists(field) - attribute exists
  • Condition.not_exists(field) - attribute does not exist
  • Condition.begins_with(field, prefix) - string starts with
  • Condition.contains(field, value) - string or list contains
  • Condition.between(field, low, high) - value in range

Atomic Updates

from pydynox import Action

# Simple set
user.update(name="New Name", email="new@test.com")

# Increment a number
user.update(Action.increment("age", 1))

# Append to list
user.update(Action.append("tags", ["verified"]))

# Remove field
user.update(Action.remove("temp_field"))

# Combine with condition
user.update(
    Action.increment("age", 1),
    condition=Condition.eq("status", "active")
)

Batch Operations

# Batch write
with User.batch_write() as batch:
    batch.save(user1)
    batch.save(user2)
    batch.delete(user3)

# Batch get
users = User.batch_get([
    ("USER#1", "PROFILE"),
    ("USER#2", "PROFILE"),
])

Global Secondary Index

from pydynox import GlobalIndex, ModelConfig

class User(Model):
    model_config = ModelConfig(table="users")
    
    pk = String(hash_key=True)
    sk = String(range_key=True)
    email = String()
    
    email_index = GlobalIndex(hash_key="email")

# Query on index
users = User.email_index.query(email="john@test.com")

Transactions

with User.transaction() as tx:
    tx.save(user1)
    tx.delete(user2)
    tx.update(user3, Action.increment("age", 1))

Async Support

# All methods work with await
user = await User.get(pk="USER#123", sk="PROFILE")
await user.save()

async for user in User.query(pk="USER#123"):
    print(user.name)

Pydantic Integration

from pydynox import dynamodb_model
from pydantic import BaseModel, EmailStr

@dynamodb_model(table="users", hash_key="pk", range_key="sk")
class User(BaseModel):
    pk: str
    sk: str
    name: str
    email: EmailStr
    age: int = 0

# All pydynox methods available
user = User(pk="USER#123", sk="PROFILE", name="John", email="john@test.com")
user.save()

S3 Attribute (Large Files)

DynamoDB has a 400KB item limit. S3Attribute stores files in S3 and keeps metadata in DynamoDB. Upload on save, download on demand, delete when the item is deleted.

from pydynox.attributes import S3Attribute
from pydynox._internal._s3 import S3File

class Document(Model):
    model_config = ModelConfig(table="documents")
    
    pk = StringAttribute(hash_key=True)
    content = S3Attribute(bucket="my-bucket", prefix="docs/")

# Upload
doc = Document(pk="DOC#1")
doc.content = S3File(b"...", name="report.pdf", content_type="application/pdf")
doc.save()

# Download
doc = Document.get(pk="DOC#1")
data = doc.content.get_bytes()           # Load to memory
doc.content.save_to("/path/to/file.pdf") # Stream to file
url = doc.content.presigned_url(3600)    # Share via URL

# Metadata (no S3 call)
print(doc.content.size)
print(doc.content.content_type)

# Delete - removes from both DynamoDB and S3
doc.delete()

Table Management

# Create table
User.create_table()

# Create with custom capacity
User.create_table(read_capacity=10, write_capacity=5)

# Create with on-demand billing
User.create_table(billing_mode="PAY_PER_REQUEST")

# Check if table exists
if not User.table_exists():
    User.create_table()

# Delete table
User.delete_table()

Documentation

Full documentation: https://leandrodamascena.github.io/pydynox

License

MIT License

Inspirations

This project was inspired by:

  • PynamoDB - The ORM-style API and model design
  • Pydantic - Data validation patterns and integration approach
  • dynarust - Rust DynamoDB client patterns
  • dyntastic - Pydantic + DynamoDB integration ideas

Building from Source

Requirements

  • Python 3.11+
  • Rust 1.70+
  • maturin

Setup

# Clone the repo
git clone https://github.com/leandrodamascena/pydynox.git
cd pydynox

# Install maturin
pip install maturin

# Build and install locally
maturin develop

# Or with uv
uv run maturin develop

Running Tests

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydynox-0.13.0.tar.gz (327.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pydynox-0.13.0-cp314-cp314-manylinux_2_24_x86_64.whl (7.6 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.24+ x86-64

pydynox-0.13.0-cp314-cp314-manylinux_2_24_aarch64.whl (7.6 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.24+ ARM64

pydynox-0.13.0-cp314-cp314-macosx_11_0_arm64.whl (6.9 MB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

pydynox-0.13.0-cp314-cp314-macosx_10_12_x86_64.whl (7.3 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

pydynox-0.13.0-cp313-cp313-manylinux_2_24_x86_64.whl (7.6 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.24+ x86-64

pydynox-0.13.0-cp313-cp313-manylinux_2_24_aarch64.whl (7.6 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.24+ ARM64

pydynox-0.13.0-cp313-cp313-macosx_11_0_arm64.whl (6.9 MB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

pydynox-0.13.0-cp313-cp313-macosx_10_12_x86_64.whl (7.3 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

pydynox-0.13.0-cp312-cp312-manylinux_2_24_x86_64.whl (7.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.24+ x86-64

pydynox-0.13.0-cp312-cp312-manylinux_2_24_aarch64.whl (7.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.24+ ARM64

pydynox-0.13.0-cp312-cp312-macosx_11_0_arm64.whl (6.9 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

pydynox-0.13.0-cp312-cp312-macosx_10_12_x86_64.whl (7.3 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

pydynox-0.13.0-cp311-cp311-manylinux_2_24_x86_64.whl (7.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.24+ x86-64

pydynox-0.13.0-cp311-cp311-manylinux_2_24_aarch64.whl (7.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.24+ ARM64

pydynox-0.13.0-cp311-cp311-macosx_11_0_arm64.whl (6.9 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

pydynox-0.13.0-cp311-cp311-macosx_10_12_x86_64.whl (7.3 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

File details

Details for the file pydynox-0.13.0.tar.gz.

File metadata

  • Download URL: pydynox-0.13.0.tar.gz
  • Upload date:
  • Size: 327.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pydynox-0.13.0.tar.gz
Algorithm Hash digest
SHA256 7b888b0f5ec7cb9ba7335091fed6da4b85a98d4278687ffcbfb1484ace3476a3
MD5 7cb005a7d8d724b7c22b453cdb00cdcd
BLAKE2b-256 d3ba3d53a4e910f4aa69e53c5d8a4479b61b5a2af3f4e470c980d2df2dc2eb7a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0.tar.gz:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp314-cp314-manylinux_2_24_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp314-cp314-manylinux_2_24_x86_64.whl
Algorithm Hash digest
SHA256 6b5d52cad42d401d90ccc72c8449c40d010393d0f79af1afb6175c626277879f
MD5 2bf2eabf0032592faf6eae62ead3256a
BLAKE2b-256 d33ce9177083ebb16874ba48a91ad0c308bf43396885018cdcbe648b15e6023f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp314-cp314-manylinux_2_24_x86_64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp314-cp314-manylinux_2_24_aarch64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp314-cp314-manylinux_2_24_aarch64.whl
Algorithm Hash digest
SHA256 46a8c085fbeb6acd007f15b6973b58aa2cb897e720beee32b35b4c36f23370c2
MD5 7ac581418e6c4478da525d8ecefbe481
BLAKE2b-256 4ed48e056ab85c5445a302613ab723429873ab4f33d7f34601582c9ed898b52d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp314-cp314-manylinux_2_24_aarch64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8deb207c0517266ee9b1d3e284d6e67a5d1fe820fe1d5b4dea82be25f01bc3f5
MD5 8b43bb3d7b728891e660d04dcfe65112
BLAKE2b-256 c82a563e00d751d885099b4fb68880a7cf9f479357f7e2e3eb0f040a3fa76993

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp314-cp314-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 abfa9b7e22d6624d5f5ad7ba600e4c93cfe936177f397e0738bb2010c6e54c93
MD5 3e6e0f4c55e0bc9e78e1f9f132df2750
BLAKE2b-256 64e38af622971652b81b23bba69d0bdf04b77acad3e849e1b800d72dc58735fb

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp314-cp314-macosx_10_12_x86_64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp313-cp313-manylinux_2_24_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp313-cp313-manylinux_2_24_x86_64.whl
Algorithm Hash digest
SHA256 5aa5e6d8622c1615d7aedd519a0076eda18e2397bf254db767c6851904b0c2a6
MD5 5ede99ea2be1bf7f3940404e5be77a51
BLAKE2b-256 42419a5d9dcbf5df8a5420b9fc46738dc36fc2b4328d623bb6860030ebfad781

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp313-cp313-manylinux_2_24_x86_64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp313-cp313-manylinux_2_24_aarch64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp313-cp313-manylinux_2_24_aarch64.whl
Algorithm Hash digest
SHA256 0b6fe85c3edf5dd380daba2afa075239797b8c07378fe6576ee9a4df02ba0589
MD5 1f4f0ea7f198ccd04c728edbedab9645
BLAKE2b-256 5ddc0f565df93f237515856c7ee11b4b319aa30dd880061a183a0ff7c7454eda

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp313-cp313-manylinux_2_24_aarch64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9b266a4cde77a7e1f715b02aac4f430953aa141687bfa9b2822fe64660d60e0e
MD5 c96b2684695362c48d2f2f9583187df9
BLAKE2b-256 a0529b10b6fdca79810bb1268e88a8eaa02711c83c6fb799b4ba548b5735b3d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 9f7105c89624c9e14d22f65d598d007a0703677eb60c23366cf0a1f97ddf91d8
MD5 83b4b40e9603ffc74d06c274f379c19f
BLAKE2b-256 9d993e7233276ffe0303f6bee4b95c0fbfd9b13a3677947d365ff64e014785ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp313-cp313-macosx_10_12_x86_64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp312-cp312-manylinux_2_24_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp312-cp312-manylinux_2_24_x86_64.whl
Algorithm Hash digest
SHA256 aae7923e3103f3f9e58c5ed9f4b3f4904ff291260baefb7644ccba561a55f749
MD5 3aecf1ce0dda4f2e030dae67e98636f1
BLAKE2b-256 14aeeed8aa9be9c94a3a7073ca2904c7cbaf92a9c1c5685d3a52b4132aa7399f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp312-cp312-manylinux_2_24_x86_64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp312-cp312-manylinux_2_24_aarch64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp312-cp312-manylinux_2_24_aarch64.whl
Algorithm Hash digest
SHA256 4644d67df01ba77fa344fa3d3d433ac47e403c698d977059d8d4e79fb984f32e
MD5 bea3f8d7535e343c246191ca6bd69f39
BLAKE2b-256 8cb252102d6d9058a26856adc9f48b921b2efc203b3f65731bdc3ec607845f87

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp312-cp312-manylinux_2_24_aarch64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f5687fff3c29d863f7ed1a6de34066c11da00ffe75f369a679920c6a94e3532f
MD5 c5b9cde656293b6968969018216566d1
BLAKE2b-256 c8a5266df3212d80d30468fa723286d6bb893cf31be90d2a6721ce5943344988

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 ce7528f3e98be8e278811a0adacffe91392ed627a2e403b02c628e92be4d0bc4
MD5 5fae515b26f1decf64f818c97e8aa08b
BLAKE2b-256 bcfa6daa2418c682579635468c4d12bc6bc1859d0887f713b9cc6f926842cc17

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp312-cp312-macosx_10_12_x86_64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp311-cp311-manylinux_2_24_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp311-cp311-manylinux_2_24_x86_64.whl
Algorithm Hash digest
SHA256 4b424a55af1a0d35dd22333c846755f3dd609d1512339fe939fdcc82b8eefe4e
MD5 b3ff463a10acccef38a9c00d73469b9c
BLAKE2b-256 27d75173e207a92ddafbee9f1b8be9a8643f33cd6e3e0126c94daacda68c8654

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp311-cp311-manylinux_2_24_x86_64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp311-cp311-manylinux_2_24_aarch64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp311-cp311-manylinux_2_24_aarch64.whl
Algorithm Hash digest
SHA256 fe725536bc8ae136b6eacba3051f582472071cbdd9c2e7b24503fce0cc13b818
MD5 fd87b852a5b59c91d64a8e06773716f3
BLAKE2b-256 c300d5a3f088cc3a3185ccecbfb021e8d7867dfac2fd9421c80c93d58cb12644

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp311-cp311-manylinux_2_24_aarch64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6046e693940fb26f388709552e129be0bee807a207a8768d6ccc72c17534282e
MD5 ec5e1a757a7aa50ee46eb91f972d2695
BLAKE2b-256 1dad4e8f3578247393fb0786ad40fda31edc575cff2d92e41536b1fd65330efb

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pydynox-0.13.0-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.13.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 e609a615c6f09a31623185e5d3ea41a6cd572217bcf663be947bab7c13aa2729
MD5 c7649fce06d7458a9c4b63230ee64657
BLAKE2b-256 cc57a440f1559c0b858f8f7bfd6d21df4ae346d644fb51c6ea622dd4b5e90d21

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.13.0-cp311-cp311-macosx_10_12_x86_64.whl:

Publisher: release.yml on leandrodamascena/pydynox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page