11

Just started using Boto3 with Python so definitely new at this.

I'm trying to use a simple get_metric_statistics script to return information about CPUUtilization for an instance. Here is the script I'm looking to use:

import boto3
import datetime

cw = boto3.client('cloudwatch')

cw.get_metric_statistics(       
        300,
        datetime.datetime.utcnow() - datetime.timedelta(seconds=600),
        datetime.datetime.utcnow(),
        'CPUUtilization',
        'AWS/EC2',
        'Average',
        {'InstanceId':'i-11111111111'},
        )

but I keep getting the following message:

Traceback (most recent call last):
  File "C:..../CloudWatch_GetMetricStatistics.py", line 13, in <module>
    {'InstanceId':'i-0c996c11414476c7c'},
  File "C:\Program Files\Python27\lib\site-packages\botocore\client.py", line 251, in _api_call
    "%s() only accepts keyword arguments." % py_operation_name)
TypeError: get_metric_statistics() only accepts keyword arguments.

I have:

  1. Looked at the documentation on Boto3 and I believe I have got everything correctly written/included
  2. Set the correct region/output format/security credentials in the .aws folder
  3. Googled similar problems with put_metric_statistics, etc to try and figure it out

I'm still stuck as to what I'm missing?

Any guidance would be much appreciated.

Many thanks Ben

djvg
  • 11,722
  • 5
  • 72
  • 103
user7925487
  • 193
  • 2
  • 3
  • 14
  • 1
    Handy reference for future Python users with args/kwargs issues: https://realpython.com/python-kwargs-and-args/ – jarmod Oct 29 '20 at 18:13

3 Answers3

12

This works:

import boto3
import datetime

cw = boto3.client('cloudwatch')

cw.get_metric_statistics(
        Period=300,
        StartTime=datetime.datetime.utcnow() - datetime.timedelta(seconds=600),
        EndTime=datetime.datetime.utcnow(),
        MetricName='CPUUtilization',
        Namespace='AWS/EC2',
        Statistics=['Average'],
        Dimensions=[{'Name':'InstanceId', 'Value':'i-abcd1234'}]
        )

To find the right values, I use the AWS Command-Line Interface (CLI):

aws cloudwatch list-metrics --namespace AWS/EC2 --metric-name CPUUtilization --max-items 1

It returns information such as:

{
    "Metrics": [
        {
            "Namespace": "AWS/EC2", 
            "Dimensions": [
                {
                    "Name": "InstanceId", 
                    "Value": "i-abcd1234"
                }
            ], 
            "MetricName": "CPUUtilization"
        }
    ], 
    "NextToken": "xxx"
}

You can then use these values to populate your get_metric_statistics() requet (such as the Dimensions parameter).

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
  • Ah brilliant thank you! I had gone through a few iterations of the syntax (including adding the Name part of the KV pair) but clearly it wasn't quite right. Many thanks for this - the issue has gone now. – user7925487 Apr 27 '17 at 08:40
  • 1
    Great! If this or any answer has solved your question please consider [accepting it](http://meta.stackexchange.com/q/5234/179419) by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this. – John Rotenstein Apr 27 '17 at 11:54
  • Thanks. Is there a way I can pass region dynamically? When my instances are across region, get_metric_statistics retrieves datapoints only for instances belonging to the region I earlier used in aws configure. So is there a way region can be passed as a param? – Neo Mar 19 '21 at 15:26
  • @SelvaPrasad to address a specific region, use `cw = boto3.client('cloudwatch', region_name='xyz')`. – jarmod Oct 20 '21 at 11:29
8

Refer to the documentation, and your error message:

get_metric_statistics() only accepts keyword agruments

Named arguments must be passed to the function as is defined in the docs:

get_metric_statistics(**kwargs)
mickzer
  • 5,958
  • 5
  • 34
  • 57
  • 2
    correct, the root cause is, the args needs to be in name=value format! for example, `get_metric_statistics(Period=300,...` instead of `get_metric_statistics(300,...` – Jimson James Jun 01 '20 at 17:33
-3

have you used region_name when trying to get details. Can you share your github to know better, what you are doing.