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.14.0.tar.gz (353.3 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.14.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.14.0-cp314-cp314-manylinux_2_24_aarch64.whl (7.6 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.24+ ARM64

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

Uploaded CPython 3.14macOS 11.0+ ARM64

pydynox-0.14.0-cp314-cp314-macosx_10_12_x86_64.whl (7.4 MB view details)

Uploaded CPython 3.14macOS 10.12+ x86-64

pydynox-0.14.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.14.0-cp313-cp313-manylinux_2_24_aarch64.whl (7.6 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.24+ ARM64

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

Uploaded CPython 3.13macOS 11.0+ ARM64

pydynox-0.14.0-cp313-cp313-macosx_10_12_x86_64.whl (7.4 MB view details)

Uploaded CPython 3.13macOS 10.12+ x86-64

pydynox-0.14.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.14.0-cp312-cp312-manylinux_2_24_aarch64.whl (7.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.24+ ARM64

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

Uploaded CPython 3.12macOS 11.0+ ARM64

pydynox-0.14.0-cp312-cp312-macosx_10_12_x86_64.whl (7.4 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

pydynox-0.14.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.14.0-cp311-cp311-manylinux_2_24_aarch64.whl (7.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.24+ ARM64

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

Uploaded CPython 3.11macOS 11.0+ ARM64

pydynox-0.14.0-cp311-cp311-macosx_10_12_x86_64.whl (7.4 MB view details)

Uploaded CPython 3.11macOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for pydynox-0.14.0.tar.gz
Algorithm Hash digest
SHA256 fe71204b03904dede7ff58aa3df26f6056dcc577e809dc330cc93c365fcec3c8
MD5 ee717e3ed3b97d54e3c96d31a4bc2c25
BLAKE2b-256 94783fb4685a61e9b22dee0299acacf1a2e9884a89299047369c24ea799e0400

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp314-cp314-manylinux_2_24_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp314-cp314-manylinux_2_24_x86_64.whl
Algorithm Hash digest
SHA256 89ba57c15864fa2f38f0a0f7be9a0d8040a3fb844ab4b7137d0b877492720cc7
MD5 c669629e2a614340bff85e85609a1806
BLAKE2b-256 3d0906299a657b98e10a63e883e6ce6747c12ce3799f0fe0844192a1f9aa5168

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp314-cp314-manylinux_2_24_aarch64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp314-cp314-manylinux_2_24_aarch64.whl
Algorithm Hash digest
SHA256 cdf82cebaf22a6d268cd0b9d75d6cdd4d95928d6bb9e5fc8e68aa4de8ae9c829
MD5 1213f2aaeb9639e673c11c98dc9e49bd
BLAKE2b-256 f57849c86ecb66bdb45954a99e4b1f71a56f0cbda1f449682e4c70357af949a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8822738a073239932bbfd8ab05102d0bb17e8e19b061d606614e026cd39df14b
MD5 f0063fa7bcaa137b6f7ff00815b6b17f
BLAKE2b-256 0873560bf9e66ec1f0d66dafa93727af5c7b70f20f493c2c5417340e7f1b44e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp314-cp314-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp314-cp314-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 833c7efd375a73e8091d07b0284c93ba7d4ce45957d536eb0ee27d18061fc20b
MD5 df19816cac1bb4c87d8c1acce2055b09
BLAKE2b-256 2fe99cd90b8f213961f00c90b2bd0fb777b854a21c0cbed237ba9dac9f13bdae

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp313-cp313-manylinux_2_24_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp313-cp313-manylinux_2_24_x86_64.whl
Algorithm Hash digest
SHA256 95f2e179d43f6ba873e0a6270b2ddfeeddd3362e90f34277e4897dd128dbda44
MD5 9092e2edbe628432f39bfea661ad6c9c
BLAKE2b-256 3dc1829c4f59550986625315da6c5171b77b69281bf30a128d1b27b9d83025ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp313-cp313-manylinux_2_24_aarch64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp313-cp313-manylinux_2_24_aarch64.whl
Algorithm Hash digest
SHA256 d716069ac23718c9b5833522e7e287447d4d6f08b24bdd00e45225bf7bf74fd5
MD5 488ce258c7cb9ecffa27bc6a9c0bcb18
BLAKE2b-256 37e43bd1d5a80b2a8ecc7d8a2b62d9f8fd5b60ae40b5bfe0111eef1818f2e2e7

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1dc94f92047674db5895dc404d4be0495e0232a9e9bfb0e2367ce50fea7eed30
MD5 04f58fe55b9c2b5bf4bf010c57d25a23
BLAKE2b-256 b46698282cc829a56df9de728ce21bbd6ce7296fcb6a5be873519fd85fb69535

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp313-cp313-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp313-cp313-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 5fdda2363881bb3a867406593a61c50ef636c3a80bef3cb3d9acab2ad0ada5cf
MD5 5bc50eb6815ea95ad0702694b6528777
BLAKE2b-256 fb11b40c22eb34bcc576862d65dc0598bd44877670c9763fc33fc4130bab116b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp312-cp312-manylinux_2_24_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp312-cp312-manylinux_2_24_x86_64.whl
Algorithm Hash digest
SHA256 a93190430cf0a0feead5bc87db3ecd92d8cea9538e777d041c889bb709136606
MD5 d472081beb65475cfcf57c3bb51235cc
BLAKE2b-256 e4efda48709514bf54fbaabdb31b9d2683ae8cd6ee0f58219ec1f0f20e891d84

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp312-cp312-manylinux_2_24_aarch64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp312-cp312-manylinux_2_24_aarch64.whl
Algorithm Hash digest
SHA256 48bfa2285689f18ca9cf70bf7d11f8d548830b900d5a8c3378fc3bab4926dd61
MD5 43aeb3de782fb0cd506e20a558747a47
BLAKE2b-256 9821ced368b08f60efb9a421873adccabc66ebc3e20b7fe81bce9dd67fd41178

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7fc1d8d811fb9dd1ba637de9be94c3ca6c1dae135edd610fa23173da87ed602c
MD5 211362618dd16faea8d301e321a30fca
BLAKE2b-256 88a502bba006b0fddfe9a3c16962cba1f4984ac07a4489a5c3cddb2535dc0549

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 e812d5e77db0343943bf6b58df080dfa0daac06e97e38315b27e6bb2a55af8da
MD5 6242398ae5d79684d3c4235d26edf612
BLAKE2b-256 7519e85ef7d4d8435c1a27d5bc4f2b7504ffd29d392bde3585881165f25366f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp311-cp311-manylinux_2_24_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp311-cp311-manylinux_2_24_x86_64.whl
Algorithm Hash digest
SHA256 1a41a2d92a50e7746aadd01db4192f437cc1657b16dc2f94264a8d45d887797e
MD5 fae9a131affca67cb594b930c6c42b27
BLAKE2b-256 8abe0b9cf43c976d30e2aa33ea8fb590a5b9664b062b337ac2617d0fc74d2f2d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp311-cp311-manylinux_2_24_aarch64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp311-cp311-manylinux_2_24_aarch64.whl
Algorithm Hash digest
SHA256 edda029d3a517e839276558d4781819803f174b05609ea601e463cdcbacb1279
MD5 aa0ce7fc8232cb4c11f5a88586a8aea9
BLAKE2b-256 5b17997104837b3a495682c04dcc6cc4e624b3d5367c233c1f8e775f534fd234

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d9470c01ce63db9d747dedf5f680c4494640e3b3e95234d0f080680ccb2cddb1
MD5 05a51172ab028953713fae7332b701b7
BLAKE2b-256 e346cff103e77c5e07da923779e1cfa47eecbb4b323bac5868532a13d4ef8fdf

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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.14.0-cp311-cp311-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for pydynox-0.14.0-cp311-cp311-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 ac4bf42fd903cb863884df45253de7681470f74c2af4d3e89bbbbcf408204ca5
MD5 a57d93e9f10f46d52a6ccafae0f059b9
BLAKE2b-256 8f6951ac7e3e92856f9ddee3d3fa42e329f698a8abff32c17a3f6a13768c4662

See more details on using hashes here.

Provenance

The following attestation bundles were made for pydynox-0.14.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