youtype / mypy_boto3_builder

Type annotations builder for boto3 compatible with VSCode, PyCharm, Emacs, Sublime Text, pyright and mypy.
https://youtype.github.io/mypy_boto3_builder/
MIT License
544 stars 36 forks source link

Include TypeDef for Cloudwatch Alarms Events from EventBridge #220

Closed xquek closed 10 months ago

xquek commented 1 year ago

Describe your idea

Currently there are no typedef defined for cloudwatch alarms (or at least i cant seem to find it). https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-and-eventbridge.ht

Code sample I am hoping that there will be stubs so we we know what keys to look up for during development

Additional context When cloudwatch alarms are triggered, we can create cloudwatch event rules to trigger a lambda. When working with the lambda, it will be awesome to have typedef for the event object.

vemel commented 1 year ago

Hello! Thank you for the feature request.

Unfortunately, botocore shapes use String type for Event shape, so event structure cannot be parsed from botocore shapes. However, event TypeDef can always be hardcoded manually. I will take a look at how to implement it properly.

xquek commented 1 year ago

thank @vemel, let me know if there is anything you need help with ! happy to contribute!

vemel commented 1 year ago

So, it is a tricky change. Events are strings, so this type will not be directly used in any cloudwatch methods. Another thing is that there is no way to track if botocore changes the output format in any way.

Thank you for your participation in the project!

If you want to prepare a pull request:

CloudwatchEventTypeDef = TypeTypedDict(
    "CloudwatchEventTypeDef",
    [
        TypedDictAttribute("version", Type.str, True),
        ...
    ],
)

So end result in parse_service_package should be smth like

type_defs = self._get_sortable_type_defs()
if service_name == ServiceNameCatalog.cloudwatch:
   type_defs.add(CloudwatchEventTypeDef)
# probably we need eventbridge service as well

type_def_sorter = TypeDefSorter(self._get_sortable_type_defs())
result.type_defs = type_def_sorter.sort()

Generate and install package to cross-check:

Please let me know if you find this helpful or if you are stuck.

vemel commented 1 year ago

TypedDicts should be something like

CloudwatchEventStateTypeDef = TypeTypedDict(
    "CloudwatchEventStateTypeDef",
    [
        TypedDictAttribute("reason", Type.str, True),
        TypedDictAttribute("reasonData", Type.str, True),
        TypedDictAttribute("timestamp", Type.str, True),
        TypedDictAttribute("value", Type.str, True),
    ],
)

CloudwatchEventMetricTypeDef = TypeTypedDict(
    "CloudwatchEventMetricTypeDef",
    [
        TypedDictAttribute("id", Type.str, True),
        TypedDictAttribute(
            "metricStat", Type.DictStrAny, True
        ),  # probably we can improve typing here
        TypedDictAttribute("returnData", Type.bool, True),
    ],
)

CloudwatchEventConfigurationTypeDef = TypeTypedDict(
    "CloudwatchEventDetailConfigurationTypeDef",
    [
        TypedDictAttribute("description", Type.str, True),
        TypedDictAttribute("metrics", TypeSubscript(Type.List, [Type.str]), True),
    ],
)

CloudwatchEventDetailTypeDef = TypeTypedDict(
    "CloudwatchEventDetailTypeDef",
    [
        TypedDictAttribute("alarmName", Type.str, True),
        TypedDictAttribute("configuration", CloudwatchEventConfigurationTypeDef, True),
        TypedDictAttribute("previousState", CloudwatchEventStateTypeDef, True),
        TypedDictAttribute("state", CloudwatchEventStateTypeDef, True),
    ],
)

CloudwatchEventTypeDef = TypeTypedDict(
    "CloudwatchEventTypeDef",
    [
        TypedDictAttribute("version", Type.str, True),
        TypedDictAttribute("id", Type.str, True),
        TypedDictAttribute("detail-type", Type.str, True),
        TypedDictAttribute("source", Type.str, True),
        TypedDictAttribute("account", Type.str, True),
        TypedDictAttribute("time", Type.str, True),
        TypedDictAttribute("region", Type.str, True),
        TypedDictAttribute("resources", TypeSubscript(Type.List, [Type.str]), True),
        TypedDictAttribute("detail", CloudwatchEventDetailTypeDef, True),
    ],
)
vemel commented 1 year ago

I made some changes toServicePackageParser, so it is more refactoring-friendly now. Please let me know if you have time for a pull request.

xquek commented 1 year ago

hi vemel, thanks for the pointers! i will have time for a PR this week - but it looks like you already have the implementation above and i dont want to slow you down.

I can work to improve metricStat if you want to merge what you already have above.

Or if you dont mind waiting, i should be able to get them out in the next few days.

Thanks!! let me know!

vemel commented 1 year ago

I definitely do not mind waiting, it is not an urgent change. Take your time.

Once again, if you are stuck - please let me know.

vemel commented 11 months ago

@xquek Hello! Do you have any updates?

xquek commented 11 months ago

hi @vemel sorry for the wait. Work been busy. I put out a draft PR at https://github.com/youtype/mypy_boto3_builder/pull/233

While implmenting, i realised the cloudwatch notification for event bridge has lots of nested structs and different example. Maybe it might be reasonable to use Type.DictStrAny as you had in your example above.

Also can i check - there are some fields that are enums values, currently i have use type.str - let me know if i using Literal is preferred. Thanks!

vemel commented 10 months ago

Thank you for your contribution. I added your TypeDefs to cloudwatch service stubs. Please let me know if it works for you.