@@ -55,6 +55,19 @@ def _validate_attribute(attributes: dict[str, Any]) -> None:
55
55
56
56
See https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#required-attributes
57
57
"""
58
+ CloudEvent ._validate_required_attributes (attributes )
59
+ CloudEvent ._validate_attribute_types (attributes )
60
+ CloudEvent ._validate_optional_attributes (attributes )
61
+ CloudEvent ._validate_extension_attributes (attributes )
62
+
63
+ @staticmethod
64
+ def _validate_required_attributes (attributes : dict [str , Any ]) -> None :
65
+ """
66
+ Validates that all required attributes are present.
67
+
68
+ :param attributes: The attributes of the CloudEvent instance.
69
+ :raises ValueError: If any of the required attributes are missing.
70
+ """
58
71
missing_attributes = [
59
72
attr for attr in REQUIRED_ATTRIBUTES if attr not in attributes
60
73
]
@@ -63,65 +76,77 @@ def _validate_attribute(attributes: dict[str, Any]) -> None:
63
76
f"Missing required attribute(s): { ', ' .join (missing_attributes )} "
64
77
)
65
78
79
+ @staticmethod
80
+ def _validate_attribute_types (attributes : dict [str , Any ]) -> None :
81
+ """
82
+ Validates the types of the required attributes.
83
+
84
+ :param attributes: The attributes of the CloudEvent instance.
85
+ :raises ValueError: If any of the required attributes have invalid values.
86
+ :raises TypeError: If any of the required attributes have invalid types.
87
+ """
66
88
if attributes ["id" ] is None :
67
89
raise ValueError ("Attribute 'id' must not be None" )
68
-
69
90
if not isinstance (attributes ["id" ], str ):
70
91
raise TypeError ("Attribute 'id' must be a string" )
71
-
72
92
if not isinstance (attributes ["source" ], str ):
73
93
raise TypeError ("Attribute 'source' must be a string" )
74
-
75
94
if not isinstance (attributes ["type" ], str ):
76
95
raise TypeError ("Attribute 'type' must be a string" )
77
-
78
96
if not isinstance (attributes ["specversion" ], str ):
79
97
raise TypeError ("Attribute 'specversion' must be a string" )
80
-
81
98
if attributes ["specversion" ] != "1.0" :
82
99
raise ValueError ("Attribute 'specversion' must be '1.0'" )
83
100
101
+ @staticmethod
102
+ def _validate_optional_attributes (attributes : dict [str , Any ]) -> None :
103
+ """
104
+ Validates the types and values of the optional attributes.
105
+
106
+ :param attributes: The attributes of the CloudEvent instance.
107
+ :raises ValueError: If any of the optional attributes have invalid values.
108
+ :raises TypeError: If any of the optional attributes have invalid types.
109
+ """
84
110
if "time" in attributes :
85
111
if not isinstance (attributes ["time" ], datetime ):
86
112
raise TypeError ("Attribute 'time' must be a datetime object" )
87
-
88
113
if not attributes ["time" ].tzinfo :
89
114
raise ValueError ("Attribute 'time' must be timezone aware" )
90
-
91
115
if "subject" in attributes :
92
116
if not isinstance (attributes ["subject" ], str ):
93
117
raise TypeError ("Attribute 'subject' must be a string" )
94
-
95
118
if not attributes ["subject" ]:
96
119
raise ValueError ("Attribute 'subject' must not be empty" )
97
-
98
120
if "datacontenttype" in attributes :
99
121
if not isinstance (attributes ["datacontenttype" ], str ):
100
122
raise TypeError ("Attribute 'datacontenttype' must be a string" )
101
-
102
123
if not attributes ["datacontenttype" ]:
103
124
raise ValueError ("Attribute 'datacontenttype' must not be empty" )
104
-
105
125
if "dataschema" in attributes :
106
126
if not isinstance (attributes ["dataschema" ], str ):
107
127
raise TypeError ("Attribute 'dataschema' must be a string" )
108
-
109
128
if not attributes ["dataschema" ]:
110
129
raise ValueError ("Attribute 'dataschema' must not be empty" )
111
130
131
+ @staticmethod
132
+ def _validate_extension_attributes (attributes : dict [str , Any ]) -> None :
133
+ """
134
+ Validates the extension attributes.
135
+
136
+ :param attributes: The attributes of the CloudEvent instance.
137
+ :raises ValueError: If any of the extension attributes have invalid values.
138
+ """
112
139
for extension_attributes in (
113
140
set (attributes .keys ()) - REQUIRED_ATTRIBUTES - OPTIONAL_ATTRIBUTES
114
141
):
115
142
if extension_attributes == "data" :
116
143
raise ValueError (
117
144
"Extension attribute 'data' is reserved and must not be used"
118
145
)
119
-
120
146
if not (1 <= len (extension_attributes ) <= 20 ):
121
147
raise ValueError (
122
148
f"Extension attribute '{ extension_attributes } ' should be between 1 and 20 characters long"
123
149
)
124
-
125
150
if not re .match (r"^[a-z0-9]+$" , extension_attributes ):
126
151
raise ValueError (
127
152
f"Extension attribute '{ extension_attributes } ' should only contain lowercase letters and numbers"
0 commit comments