criteo-api-retailmedia-sdk 0.0.240118__py3-none-any.whl → 0.0.240207__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of criteo-api-retailmedia-sdk might be problematic. Click here for more details.

Files changed (25) hide show
  1. criteo_api_retailmedia_preview/__init__.py +1 -1
  2. criteo_api_retailmedia_preview/api/audience_api.py +2 -313
  3. criteo_api_retailmedia_preview/api_client.py +1 -1
  4. criteo_api_retailmedia_preview/configuration.py +1 -1
  5. criteo_api_retailmedia_preview/model/external_account.py +4 -0
  6. criteo_api_retailmedia_preview/model/retail_media_account.py +4 -0
  7. criteo_api_retailmedia_preview/model/retail_media_brand_account_creation.py +4 -0
  8. criteo_api_retailmedia_preview/model/retail_media_seller_account_creation.py +4 -0
  9. criteo_api_retailmedia_preview/model/rm_legacy_audience_get_entity_v2.py +3 -3
  10. criteo_api_retailmedia_preview/models/__init__.py +0 -11
  11. {criteo_api_retailmedia_sdk-0.0.240118.dist-info → criteo_api_retailmedia_sdk-0.0.240207.dist-info}/METADATA +3 -3
  12. {criteo_api_retailmedia_sdk-0.0.240118.dist-info → criteo_api_retailmedia_sdk-0.0.240207.dist-info}/RECORD +14 -25
  13. criteo_api_retailmedia_preview/model/common_status_code_response.py +0 -275
  14. criteo_api_retailmedia_preview/model/create_user_behavior_segment_v2.py +0 -309
  15. criteo_api_retailmedia_preview/model/customer_list_details.py +0 -269
  16. criteo_api_retailmedia_preview/model/get_page_of_audiences_by_account_id_response.py +0 -295
  17. criteo_api_retailmedia_preview/model/retail_media_audience.py +0 -297
  18. criteo_api_retailmedia_preview/model/retail_media_audience_attributes.py +0 -291
  19. criteo_api_retailmedia_preview/model/retail_media_audience_v2.py +0 -291
  20. criteo_api_retailmedia_preview/model/retail_media_audience_v2_attributes.py +0 -291
  21. criteo_api_retailmedia_preview/model/retail_media_audience_v2_list_response.py +0 -293
  22. criteo_api_retailmedia_preview/model/user_behavior_details.py +0 -306
  23. criteo_api_retailmedia_preview/model/user_behavior_details_v2.py +0 -279
  24. {criteo_api_retailmedia_sdk-0.0.240118.dist-info → criteo_api_retailmedia_sdk-0.0.240207.dist-info}/WHEEL +0 -0
  25. {criteo_api_retailmedia_sdk-0.0.240118.dist-info → criteo_api_retailmedia_sdk-0.0.240207.dist-info}/top_level.txt +0 -0
@@ -1,291 +0,0 @@
1
- """
2
- Criteo API
3
-
4
- Criteo API - RetailMedia # noqa: E501
5
-
6
- The version of the OpenAPI document: Preview
7
- Generated by: https://openapi-generator.tech
8
- """
9
-
10
-
11
- import re # noqa: F401
12
- import sys # noqa: F401
13
-
14
- from criteo_api_retailmedia_preview.model_utils import ( # noqa: F401
15
- ApiTypeError,
16
- ModelComposed,
17
- ModelNormal,
18
- ModelSimple,
19
- cached_property,
20
- change_keys_js_to_python,
21
- convert_js_args_to_python_args,
22
- date,
23
- datetime,
24
- file_type,
25
- none_type,
26
- validate_get_composed_info,
27
- OpenApiModel
28
- )
29
- from criteo_api_retailmedia_preview.exceptions import ApiAttributeError
30
-
31
-
32
- def lazy_import():
33
- from criteo_api_retailmedia_preview.model.customer_list_details import CustomerListDetails
34
- from criteo_api_retailmedia_preview.model.user_behavior_details_v2 import UserBehaviorDetailsV2
35
- globals()['CustomerListDetails'] = CustomerListDetails
36
- globals()['UserBehaviorDetailsV2'] = UserBehaviorDetailsV2
37
-
38
-
39
- class RetailMediaAudienceV2Attributes(ModelNormal):
40
- """NOTE: This class is auto generated by OpenAPI Generator.
41
- Ref: https://openapi-generator.tech
42
-
43
- Do not edit the class manually.
44
-
45
- Attributes:
46
- allowed_values (dict): The key is the tuple path to the attribute
47
- and the for var_name this is (var_name,). The value is a dict
48
- with a capitalized key describing the allowed value and an allowed
49
- value. These dicts store the allowed enum values.
50
- attribute_map (dict): The key is attribute name
51
- and the value is json key in definition.
52
- discriminator_value_class_map (dict): A dict to go from the discriminator
53
- variable value to the discriminator class name.
54
- validations (dict): The key is the tuple path to the attribute
55
- and the for var_name this is (var_name,). The value is a dict
56
- that stores validations for max_length, min_length, max_items,
57
- min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum,
58
- inclusive_minimum, and regex.
59
- additional_properties_type (tuple): A tuple of classes accepted
60
- as additional properties values.
61
- """
62
-
63
- allowed_values = {
64
- }
65
-
66
- validations = {
67
- }
68
-
69
- @cached_property
70
- def additional_properties_type():
71
- """
72
- This must be a method because a model may have properties that are
73
- of type self, this must run after the class is loaded
74
- """
75
- lazy_import()
76
- return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501
77
-
78
- _nullable = False
79
-
80
- @cached_property
81
- def openapi_types():
82
- """
83
- This must be a method because a model may have properties that are
84
- of type self, this must run after the class is loaded
85
-
86
- Returns
87
- openapi_types (dict): The key is attribute name
88
- and the value is attribute type.
89
- """
90
- lazy_import()
91
- return {
92
- 'retailer_id': (int,), # noqa: E501
93
- 'name': (str,), # noqa: E501
94
- 'user_behavior_details': (UserBehaviorDetailsV2,), # noqa: E501
95
- 'customer_list_details': (CustomerListDetails,), # noqa: E501
96
- }
97
-
98
- @cached_property
99
- def discriminator():
100
- return None
101
-
102
-
103
- attribute_map = {
104
- 'retailer_id': 'retailerId', # noqa: E501
105
- 'name': 'name', # noqa: E501
106
- 'user_behavior_details': 'userBehaviorDetails', # noqa: E501
107
- 'customer_list_details': 'customerListDetails', # noqa: E501
108
- }
109
-
110
- read_only_vars = {
111
- }
112
-
113
- _composed_schemas = {}
114
-
115
- @classmethod
116
- @convert_js_args_to_python_args
117
- def _from_openapi_data(cls, retailer_id, name, *args, **kwargs): # noqa: E501
118
- """RetailMediaAudienceV2Attributes - a model defined in OpenAPI
119
-
120
- Args:
121
- retailer_id (int): ID of the retailer associated with this audience
122
- name (str): Name of the audience.
123
-
124
- Keyword Args:
125
- _check_type (bool): if True, values for parameters in openapi_types
126
- will be type checked and a TypeError will be
127
- raised if the wrong type is input.
128
- Defaults to True
129
- _path_to_item (tuple/list): This is a list of keys or values to
130
- drill down to the model in received_data
131
- when deserializing a response
132
- _spec_property_naming (bool): True if the variable names in the input data
133
- are serialized names, as specified in the OpenAPI document.
134
- False if the variable names in the input data
135
- are pythonic names, e.g. snake case (default)
136
- _configuration (Configuration): the instance to use when
137
- deserializing a file_type parameter.
138
- If passed, type conversion is attempted
139
- If omitted no type conversion is done.
140
- _visited_composed_classes (tuple): This stores a tuple of
141
- classes that we have traveled through so that
142
- if we see that class again we will not use its
143
- discriminator again.
144
- When traveling through a discriminator, the
145
- composed schema that is
146
- is traveled through is added to this set.
147
- For example if Animal has a discriminator
148
- petType and we pass in "Dog", and the class Dog
149
- allOf includes Animal, we move through Animal
150
- once using the discriminator, and pick Dog.
151
- Then in Dog, we will make an instance of the
152
- Animal class but this time we won't travel
153
- through its discriminator because we passed in
154
- _visited_composed_classes = (Animal,)
155
- user_behavior_details (UserBehaviorDetailsV2): [optional] # noqa: E501
156
- customer_list_details (CustomerListDetails): [optional] # noqa: E501
157
- """
158
-
159
- _check_type = kwargs.pop('_check_type', True)
160
- _spec_property_naming = kwargs.pop('_spec_property_naming', True)
161
- _path_to_item = kwargs.pop('_path_to_item', ())
162
- _configuration = kwargs.pop('_configuration', None)
163
- _visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
164
-
165
- self = super(OpenApiModel, cls).__new__(cls)
166
-
167
- if args:
168
- for arg in args:
169
- if isinstance(arg, dict):
170
- kwargs.update(arg)
171
- else:
172
- raise ApiTypeError(
173
- "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
174
- args,
175
- self.__class__.__name__,
176
- ),
177
- path_to_item=_path_to_item,
178
- valid_classes=(self.__class__,),
179
- )
180
-
181
- self._data_store = {}
182
- self._check_type = _check_type
183
- self._spec_property_naming = _spec_property_naming
184
- self._path_to_item = _path_to_item
185
- self._configuration = _configuration
186
- self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
187
-
188
- self.retailer_id = retailer_id
189
- self.name = name
190
- for var_name, var_value in kwargs.items():
191
- if var_name not in self.attribute_map and \
192
- self._configuration is not None and \
193
- self._configuration.discard_unknown_keys and \
194
- self.additional_properties_type is None:
195
- # discard variable.
196
- continue
197
- setattr(self, var_name, var_value)
198
- return self
199
-
200
- required_properties = set([
201
- '_data_store',
202
- '_check_type',
203
- '_spec_property_naming',
204
- '_path_to_item',
205
- '_configuration',
206
- '_visited_composed_classes',
207
- ])
208
-
209
- @convert_js_args_to_python_args
210
- def __init__(self, retailer_id, name, *args, **kwargs): # noqa: E501
211
- """RetailMediaAudienceV2Attributes - a model defined in OpenAPI
212
-
213
- Args:
214
- retailer_id (int): ID of the retailer associated with this audience
215
- name (str): Name of the audience.
216
-
217
- Keyword Args:
218
- _check_type (bool): if True, values for parameters in openapi_types
219
- will be type checked and a TypeError will be
220
- raised if the wrong type is input.
221
- Defaults to True
222
- _path_to_item (tuple/list): This is a list of keys or values to
223
- drill down to the model in received_data
224
- when deserializing a response
225
- _spec_property_naming (bool): True if the variable names in the input data
226
- are serialized names, as specified in the OpenAPI document.
227
- False if the variable names in the input data
228
- are pythonic names, e.g. snake case (default)
229
- _configuration (Configuration): the instance to use when
230
- deserializing a file_type parameter.
231
- If passed, type conversion is attempted
232
- If omitted no type conversion is done.
233
- _visited_composed_classes (tuple): This stores a tuple of
234
- classes that we have traveled through so that
235
- if we see that class again we will not use its
236
- discriminator again.
237
- When traveling through a discriminator, the
238
- composed schema that is
239
- is traveled through is added to this set.
240
- For example if Animal has a discriminator
241
- petType and we pass in "Dog", and the class Dog
242
- allOf includes Animal, we move through Animal
243
- once using the discriminator, and pick Dog.
244
- Then in Dog, we will make an instance of the
245
- Animal class but this time we won't travel
246
- through its discriminator because we passed in
247
- _visited_composed_classes = (Animal,)
248
- user_behavior_details (UserBehaviorDetailsV2): [optional] # noqa: E501
249
- customer_list_details (CustomerListDetails): [optional] # noqa: E501
250
- """
251
-
252
- _check_type = kwargs.pop('_check_type', True)
253
- _spec_property_naming = kwargs.pop('_spec_property_naming', False)
254
- _path_to_item = kwargs.pop('_path_to_item', ())
255
- _configuration = kwargs.pop('_configuration', None)
256
- _visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
257
-
258
- if args:
259
- for arg in args:
260
- if isinstance(arg, dict):
261
- kwargs.update(arg)
262
- else:
263
- raise ApiTypeError(
264
- "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
265
- args,
266
- self.__class__.__name__,
267
- ),
268
- path_to_item=_path_to_item,
269
- valid_classes=(self.__class__,),
270
- )
271
-
272
- self._data_store = {}
273
- self._check_type = _check_type
274
- self._spec_property_naming = _spec_property_naming
275
- self._path_to_item = _path_to_item
276
- self._configuration = _configuration
277
- self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
278
-
279
- self.retailer_id = retailer_id
280
- self.name = name
281
- for var_name, var_value in kwargs.items():
282
- if var_name not in self.attribute_map and \
283
- self._configuration is not None and \
284
- self._configuration.discard_unknown_keys and \
285
- self.additional_properties_type is None:
286
- # discard variable.
287
- continue
288
- setattr(self, var_name, var_value)
289
- if var_name in self.read_only_vars:
290
- raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate "
291
- f"class with read only attributes.")
@@ -1,293 +0,0 @@
1
- """
2
- Criteo API
3
-
4
- Criteo API - RetailMedia # noqa: E501
5
-
6
- The version of the OpenAPI document: Preview
7
- Generated by: https://openapi-generator.tech
8
- """
9
-
10
-
11
- import re # noqa: F401
12
- import sys # noqa: F401
13
-
14
- from criteo_api_retailmedia_preview.model_utils import ( # noqa: F401
15
- ApiTypeError,
16
- ModelComposed,
17
- ModelNormal,
18
- ModelSimple,
19
- cached_property,
20
- change_keys_js_to_python,
21
- convert_js_args_to_python_args,
22
- date,
23
- datetime,
24
- file_type,
25
- none_type,
26
- validate_get_composed_info,
27
- OpenApiModel
28
- )
29
- from criteo_api_retailmedia_preview.exceptions import ApiAttributeError
30
-
31
-
32
- def lazy_import():
33
- from criteo_api_retailmedia_preview.model.common_problem import CommonProblem
34
- from criteo_api_retailmedia_preview.model.page_metadata import PageMetadata
35
- from criteo_api_retailmedia_preview.model.retail_media_audience_v2 import RetailMediaAudienceV2
36
- globals()['CommonProblem'] = CommonProblem
37
- globals()['PageMetadata'] = PageMetadata
38
- globals()['RetailMediaAudienceV2'] = RetailMediaAudienceV2
39
-
40
-
41
- class RetailMediaAudienceV2ListResponse(ModelNormal):
42
- """NOTE: This class is auto generated by OpenAPI Generator.
43
- Ref: https://openapi-generator.tech
44
-
45
- Do not edit the class manually.
46
-
47
- Attributes:
48
- allowed_values (dict): The key is the tuple path to the attribute
49
- and the for var_name this is (var_name,). The value is a dict
50
- with a capitalized key describing the allowed value and an allowed
51
- value. These dicts store the allowed enum values.
52
- attribute_map (dict): The key is attribute name
53
- and the value is json key in definition.
54
- discriminator_value_class_map (dict): A dict to go from the discriminator
55
- variable value to the discriminator class name.
56
- validations (dict): The key is the tuple path to the attribute
57
- and the for var_name this is (var_name,). The value is a dict
58
- that stores validations for max_length, min_length, max_items,
59
- min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum,
60
- inclusive_minimum, and regex.
61
- additional_properties_type (tuple): A tuple of classes accepted
62
- as additional properties values.
63
- """
64
-
65
- allowed_values = {
66
- }
67
-
68
- validations = {
69
- }
70
-
71
- @cached_property
72
- def additional_properties_type():
73
- """
74
- This must be a method because a model may have properties that are
75
- of type self, this must run after the class is loaded
76
- """
77
- lazy_import()
78
- return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501
79
-
80
- _nullable = False
81
-
82
- @cached_property
83
- def openapi_types():
84
- """
85
- This must be a method because a model may have properties that are
86
- of type self, this must run after the class is loaded
87
-
88
- Returns
89
- openapi_types (dict): The key is attribute name
90
- and the value is attribute type.
91
- """
92
- lazy_import()
93
- return {
94
- 'data': ([RetailMediaAudienceV2],), # noqa: E501
95
- 'metadata': (PageMetadata,), # noqa: E501
96
- 'errors': ([CommonProblem], none_type,), # noqa: E501
97
- 'warnings': ([CommonProblem], none_type,), # noqa: E501
98
- }
99
-
100
- @cached_property
101
- def discriminator():
102
- return None
103
-
104
-
105
- attribute_map = {
106
- 'data': 'data', # noqa: E501
107
- 'metadata': 'metadata', # noqa: E501
108
- 'errors': 'errors', # noqa: E501
109
- 'warnings': 'warnings', # noqa: E501
110
- }
111
-
112
- read_only_vars = {
113
- 'data', # noqa: E501
114
- 'errors', # noqa: E501
115
- 'warnings', # noqa: E501
116
- }
117
-
118
- _composed_schemas = {}
119
-
120
- @classmethod
121
- @convert_js_args_to_python_args
122
- def _from_openapi_data(cls, data, metadata, *args, **kwargs): # noqa: E501
123
- """RetailMediaAudienceV2ListResponse - a model defined in OpenAPI
124
-
125
- Args:
126
- data ([RetailMediaAudienceV2]): data
127
- metadata (PageMetadata):
128
-
129
- Keyword Args:
130
- _check_type (bool): if True, values for parameters in openapi_types
131
- will be type checked and a TypeError will be
132
- raised if the wrong type is input.
133
- Defaults to True
134
- _path_to_item (tuple/list): This is a list of keys or values to
135
- drill down to the model in received_data
136
- when deserializing a response
137
- _spec_property_naming (bool): True if the variable names in the input data
138
- are serialized names, as specified in the OpenAPI document.
139
- False if the variable names in the input data
140
- are pythonic names, e.g. snake case (default)
141
- _configuration (Configuration): the instance to use when
142
- deserializing a file_type parameter.
143
- If passed, type conversion is attempted
144
- If omitted no type conversion is done.
145
- _visited_composed_classes (tuple): This stores a tuple of
146
- classes that we have traveled through so that
147
- if we see that class again we will not use its
148
- discriminator again.
149
- When traveling through a discriminator, the
150
- composed schema that is
151
- is traveled through is added to this set.
152
- For example if Animal has a discriminator
153
- petType and we pass in "Dog", and the class Dog
154
- allOf includes Animal, we move through Animal
155
- once using the discriminator, and pick Dog.
156
- Then in Dog, we will make an instance of the
157
- Animal class but this time we won't travel
158
- through its discriminator because we passed in
159
- _visited_composed_classes = (Animal,)
160
- errors ([CommonProblem], none_type): errors. [optional] # noqa: E501
161
- warnings ([CommonProblem], none_type): warnings. [optional] # noqa: E501
162
- """
163
-
164
- _check_type = kwargs.pop('_check_type', True)
165
- _spec_property_naming = kwargs.pop('_spec_property_naming', True)
166
- _path_to_item = kwargs.pop('_path_to_item', ())
167
- _configuration = kwargs.pop('_configuration', None)
168
- _visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
169
-
170
- self = super(OpenApiModel, cls).__new__(cls)
171
-
172
- if args:
173
- for arg in args:
174
- if isinstance(arg, dict):
175
- kwargs.update(arg)
176
- else:
177
- raise ApiTypeError(
178
- "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
179
- args,
180
- self.__class__.__name__,
181
- ),
182
- path_to_item=_path_to_item,
183
- valid_classes=(self.__class__,),
184
- )
185
-
186
- self._data_store = {}
187
- self._check_type = _check_type
188
- self._spec_property_naming = _spec_property_naming
189
- self._path_to_item = _path_to_item
190
- self._configuration = _configuration
191
- self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
192
-
193
- self.data = data
194
- self.metadata = metadata
195
- for var_name, var_value in kwargs.items():
196
- if var_name not in self.attribute_map and \
197
- self._configuration is not None and \
198
- self._configuration.discard_unknown_keys and \
199
- self.additional_properties_type is None:
200
- # discard variable.
201
- continue
202
- setattr(self, var_name, var_value)
203
- return self
204
-
205
- required_properties = set([
206
- '_data_store',
207
- '_check_type',
208
- '_spec_property_naming',
209
- '_path_to_item',
210
- '_configuration',
211
- '_visited_composed_classes',
212
- ])
213
-
214
- @convert_js_args_to_python_args
215
- def __init__(self, metadata, *args, **kwargs): # noqa: E501
216
- """RetailMediaAudienceV2ListResponse - a model defined in OpenAPI
217
-
218
- metadata (PageMetadata):
219
-
220
- Keyword Args:
221
- _check_type (bool): if True, values for parameters in openapi_types
222
- will be type checked and a TypeError will be
223
- raised if the wrong type is input.
224
- Defaults to True
225
- _path_to_item (tuple/list): This is a list of keys or values to
226
- drill down to the model in received_data
227
- when deserializing a response
228
- _spec_property_naming (bool): True if the variable names in the input data
229
- are serialized names, as specified in the OpenAPI document.
230
- False if the variable names in the input data
231
- are pythonic names, e.g. snake case (default)
232
- _configuration (Configuration): the instance to use when
233
- deserializing a file_type parameter.
234
- If passed, type conversion is attempted
235
- If omitted no type conversion is done.
236
- _visited_composed_classes (tuple): This stores a tuple of
237
- classes that we have traveled through so that
238
- if we see that class again we will not use its
239
- discriminator again.
240
- When traveling through a discriminator, the
241
- composed schema that is
242
- is traveled through is added to this set.
243
- For example if Animal has a discriminator
244
- petType and we pass in "Dog", and the class Dog
245
- allOf includes Animal, we move through Animal
246
- once using the discriminator, and pick Dog.
247
- Then in Dog, we will make an instance of the
248
- Animal class but this time we won't travel
249
- through its discriminator because we passed in
250
- _visited_composed_classes = (Animal,)
251
- errors ([CommonProblem], none_type): errors. [optional] # noqa: E501
252
- warnings ([CommonProblem], none_type): warnings. [optional] # noqa: E501
253
- """
254
-
255
- _check_type = kwargs.pop('_check_type', True)
256
- _spec_property_naming = kwargs.pop('_spec_property_naming', False)
257
- _path_to_item = kwargs.pop('_path_to_item', ())
258
- _configuration = kwargs.pop('_configuration', None)
259
- _visited_composed_classes = kwargs.pop('_visited_composed_classes', ())
260
-
261
- if args:
262
- for arg in args:
263
- if isinstance(arg, dict):
264
- kwargs.update(arg)
265
- else:
266
- raise ApiTypeError(
267
- "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % (
268
- args,
269
- self.__class__.__name__,
270
- ),
271
- path_to_item=_path_to_item,
272
- valid_classes=(self.__class__,),
273
- )
274
-
275
- self._data_store = {}
276
- self._check_type = _check_type
277
- self._spec_property_naming = _spec_property_naming
278
- self._path_to_item = _path_to_item
279
- self._configuration = _configuration
280
- self._visited_composed_classes = _visited_composed_classes + (self.__class__,)
281
-
282
- self.metadata = metadata
283
- for var_name, var_value in kwargs.items():
284
- if var_name not in self.attribute_map and \
285
- self._configuration is not None and \
286
- self._configuration.discard_unknown_keys and \
287
- self.additional_properties_type is None:
288
- # discard variable.
289
- continue
290
- setattr(self, var_name, var_value)
291
- if var_name in self.read_only_vars:
292
- raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate "
293
- f"class with read only attributes.")