Mock CloudWatch put_metric_data in Python

Simulate AWS CloudWatch put_metric_data with validation and formatted output for local testing without AWS.

Easy Python 3.9+ Aug 9, 2026 Cloud + Python 15 views 0 copies

Python code

29 lines
Python 3.9+
import json
from datetime import datetime, timezone


def put_metric_data(namespace, metric_data_list):
    """
    Mock AWS CloudWatch put_metric_data.
    Validates and prints the metrics that would be sent.
    """
    timestamp = datetime.now(timezone.utc).isoformat()
    print(f"[MockCloudWatch] Received request at {timestamp}")
    print(f"[MockCloudWatch] Namespace: {namespace}")
    print("[MockCloudWatch] Metric data:")
    for metric in metric_data_list:
        required = {"MetricName", "Value", "Unit"}
        missing = required - set(metric.keys())
        if missing:
            raise ValueError(f"Metric missing required fields: {missing}")
        print(f"  - {metric['MetricName']}: {metric['Value']} {metric['Unit']} (dimensions: {metric.get('Dimensions', [])})")
    return {"ResponseMetadata": {"HTTPStatusCode": 200}}


if __name__ == "__main__":
    sample_metrics = [
        {"MetricName": "CPUUtilization", "Value": 42.5, "Unit": "Percent", "Dimensions": [{"Name": "InstanceId", "Value": "i-12345"}]},
        {"MetricName": "MemoryFree", "Value": 1024, "Unit": "Megabytes"},
    ]
    response = put_metric_data("Custom/AppMetrics", sample_metrics)
    print(f"Response: {json.dumps(response)}")

Output

stdout
[MockCloudWatch] Received request at 2025-04-15T12:00:00.123456+00:00
[MockCloudWatch] Namespace: Custom/AppMetrics
[MockCloudWatch] Metric data:
  - CPUUtilization: 42.5 Percent (dimensions: [{'Name': 'InstanceId', 'Value': 'i-12345'}])
  - MemoryFree: 1024 Megabytes (dimensions: [])
Response: {"ResponseMetadata": {"HTTPStatusCode": 200}}

How it works

The function mimics the boto3 CloudWatch client's put_metric_data API, accepting a namespace and a list of metric dictionaries. It validates that each metric contains the required keys (MetricName, Value, Unit) before printing a formatted summary. Using datetime.now(timezone.utc) ensures an ISO timestamp with UTC timezone for realistic logging. The function returns a mock response dict similar to boto3's structure, allowing code that expects a response to work unchanged. This approach lets you test CloudWatch publishing logic locally without AWS credentials or network calls.

Common mistakes

  • Forgetting to include required keys like `Unit` in each metric, causing validation errors.
  • Using naive datetime without timezone, leading to inconsistent timestamps.
  • Assuming `Dimensions` is always present; using `.get()` avoids KeyError.

Variations

  1. Use a mock object with `unittest.mock.patch` to replace `boto3.client('cloudwatch').put_metric_data` for unit tests.

Real-world use cases

  • Local development of a service that publishes custom application metrics, verifying the data shape before wiring real AWS.
  • Unit testing code that sends metrics to CloudWatch without incurring AWS costs or needing internet access.
  • Writing a script to preview metric batches and catch missing fields before deploying to production.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Cloud + Python

Related tutorials and quizzes for this topic.