@@ -55,6 +55,19 @@ def _validate_attribute(attributes: dict[str, Any]) -> None:
5555
5656 See https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md#required-attributes
5757 """
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+ """
5871 missing_attributes = [
5972 attr for attr in REQUIRED_ATTRIBUTES if attr not in attributes
6073 ]
@@ -63,65 +76,77 @@ def _validate_attribute(attributes: dict[str, Any]) -> None:
6376 f"Missing required attribute(s): { ', ' .join (missing_attributes )} "
6477 )
6578
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+ """
6688 if attributes ["id" ] is None :
6789 raise ValueError ("Attribute 'id' must not be None" )
68-
6990 if not isinstance (attributes ["id" ], str ):
7091 raise TypeError ("Attribute 'id' must be a string" )
71-
7292 if not isinstance (attributes ["source" ], str ):
7393 raise TypeError ("Attribute 'source' must be a string" )
74-
7594 if not isinstance (attributes ["type" ], str ):
7695 raise TypeError ("Attribute 'type' must be a string" )
77-
7896 if not isinstance (attributes ["specversion" ], str ):
7997 raise TypeError ("Attribute 'specversion' must be a string" )
80-
8198 if attributes ["specversion" ] != "1.0" :
8299 raise ValueError ("Attribute 'specversion' must be '1.0'" )
83100
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+ """
84110 if "time" in attributes :
85111 if not isinstance (attributes ["time" ], datetime ):
86112 raise TypeError ("Attribute 'time' must be a datetime object" )
87-
88113 if not attributes ["time" ].tzinfo :
89114 raise ValueError ("Attribute 'time' must be timezone aware" )
90-
91115 if "subject" in attributes :
92116 if not isinstance (attributes ["subject" ], str ):
93117 raise TypeError ("Attribute 'subject' must be a string" )
94-
95118 if not attributes ["subject" ]:
96119 raise ValueError ("Attribute 'subject' must not be empty" )
97-
98120 if "datacontenttype" in attributes :
99121 if not isinstance (attributes ["datacontenttype" ], str ):
100122 raise TypeError ("Attribute 'datacontenttype' must be a string" )
101-
102123 if not attributes ["datacontenttype" ]:
103124 raise ValueError ("Attribute 'datacontenttype' must not be empty" )
104-
105125 if "dataschema" in attributes :
106126 if not isinstance (attributes ["dataschema" ], str ):
107127 raise TypeError ("Attribute 'dataschema' must be a string" )
108-
109128 if not attributes ["dataschema" ]:
110129 raise ValueError ("Attribute 'dataschema' must not be empty" )
111130
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+ """
112139 for extension_attributes in (
113140 set (attributes .keys ()) - REQUIRED_ATTRIBUTES - OPTIONAL_ATTRIBUTES
114141 ):
115142 if extension_attributes == "data" :
116143 raise ValueError (
117144 "Extension attribute 'data' is reserved and must not be used"
118145 )
119-
120146 if not (1 <= len (extension_attributes ) <= 20 ):
121147 raise ValueError (
122148 f"Extension attribute '{ extension_attributes } ' should be between 1 and 20 characters long"
123149 )
124-
125150 if not re .match (r"^[a-z0-9]+$" , extension_attributes ):
126151 raise ValueError (
127152 f"Extension attribute '{ extension_attributes } ' should only contain lowercase letters and numbers"
0 commit comments