sagemaker-core 1.0.4__py3-none-any.whl → 1.0.5__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 sagemaker-core might be problematic. Click here for more details.

@@ -5,6 +5,8 @@ from pydantic import BaseModel
5
5
 
6
6
  from sagemaker_core.tools.constants import (
7
7
  ADDITIONAL_OPERATION_FILE_PATH,
8
+ FEATURE_STORE_SERVICE_JSON_FILE_PATH,
9
+ METRICS_SERVICE_JSON_FILE_PATH,
8
10
  SERVICE_JSON_FILE_PATH,
9
11
  RUNTIME_SERVICE_JSON_FILE_PATH,
10
12
  )
@@ -13,6 +15,8 @@ from sagemaker_core.tools.constants import (
13
15
  class ServiceJsonData(BaseModel):
14
16
  sagemaker: dict
15
17
  sagemaker_runtime: dict
18
+ sagemaker_feature_store: dict
19
+ sagemaker_metrics: dict
16
20
 
17
21
 
18
22
  @lru_cache(maxsize=1)
@@ -21,15 +25,26 @@ def load_service_jsons() -> ServiceJsonData:
21
25
  service_json = json.load(file)
22
26
  with open(RUNTIME_SERVICE_JSON_FILE_PATH, "r") as file:
23
27
  runtime_service_json = json.load(file)
24
- return ServiceJsonData(sagemaker=service_json, sagemaker_runtime=runtime_service_json)
28
+ with open(FEATURE_STORE_SERVICE_JSON_FILE_PATH, "r") as file:
29
+ feature_store_service_json = json.load(file)
30
+ with open(METRICS_SERVICE_JSON_FILE_PATH, "r") as file:
31
+ metrics_service_json = json.load(file)
32
+ return ServiceJsonData(
33
+ sagemaker=service_json,
34
+ sagemaker_runtime=runtime_service_json,
35
+ sagemaker_feature_store=feature_store_service_json,
36
+ sagemaker_metrics=metrics_service_json,
37
+ )
25
38
 
26
39
 
27
40
  @lru_cache(maxsize=1)
28
41
  def load_combined_shapes_data() -> dict:
29
42
  service_json_data = load_service_jsons()
30
43
  return {
31
- **service_json_data.sagemaker["shapes"],
32
44
  **service_json_data.sagemaker_runtime["shapes"],
45
+ **service_json_data.sagemaker_feature_store["shapes"],
46
+ **service_json_data.sagemaker_metrics["shapes"],
47
+ **service_json_data.sagemaker["shapes"],
33
48
  }
34
49
 
35
50
 
@@ -37,8 +52,10 @@ def load_combined_shapes_data() -> dict:
37
52
  def load_combined_operations_data() -> dict:
38
53
  service_json_data = load_service_jsons()
39
54
  return {
40
- **service_json_data.sagemaker["operations"],
41
55
  **service_json_data.sagemaker_runtime["operations"],
56
+ **service_json_data.sagemaker_feature_store["operations"],
57
+ **service_json_data.sagemaker_metrics["operations"],
58
+ **service_json_data.sagemaker["operations"],
42
59
  }
43
60
 
44
61
 
@@ -64,9 +64,6 @@ from sagemaker_core.tools.templates import (
64
64
  UPDATE_METHOD_TEMPLATE,
65
65
  POPULATE_DEFAULTS_DECORATOR_TEMPLATE,
66
66
  CREATE_METHOD_TEMPLATE_WITHOUT_DEFAULTS,
67
- INVOKE_METHOD_TEMPLATE,
68
- INVOKE_ASYNC_METHOD_TEMPLATE,
69
- INVOKE_WITH_RESPONSE_STREAM_METHOD_TEMPLATE,
70
67
  IMPORT_METHOD_TEMPLATE,
71
68
  FAILED_STATUS_ERROR_TEMPLATE,
72
69
  GET_NAME_METHOD_TEMPLATE,
@@ -188,8 +185,8 @@ class ResourcesCodeGen:
188
185
  "from rich.style import Style",
189
186
  "from sagemaker_core.main.code_injection.codec import transform",
190
187
  "from sagemaker_core.main.code_injection.constants import Color",
191
- "from sagemaker_core.main.utils import SageMakerClient, SageMakerRuntimeClient, ResourceIterator, Unassigned, get_textual_rich_logger, "
192
- "snake_to_pascal, pascal_to_snake, is_not_primitive, is_not_str_dict, is_snake_case, is_primitive_list, serialize",
188
+ "from sagemaker_core.main.utils import SageMakerClient, ResourceIterator, Unassigned, get_textual_rich_logger, "
189
+ "snake_to_pascal, pascal_to_snake, is_not_primitive, is_not_str_dict, is_primitive_list, serialize",
193
190
  "from sagemaker_core.main.intelligent_defaults_helper import load_default_configs_for_resource_name, get_config_value",
194
191
  "from sagemaker_core.main.shapes import *",
195
192
  "from sagemaker_core.main.exceptions import *",
@@ -434,30 +431,6 @@ class ResourcesCodeGen:
434
431
  ):
435
432
  resource_class += add_indent(wait_for_delete_method, 4)
436
433
 
437
- if invoke_method := self._evaluate_method(
438
- resource_name,
439
- "invoke",
440
- object_methods,
441
- resource_attributes=resource_attributes,
442
- ):
443
- resource_class += add_indent(invoke_method, 4)
444
-
445
- if invoke_async_method := self._evaluate_method(
446
- resource_name,
447
- "invoke_async",
448
- object_methods,
449
- resource_attributes=resource_attributes,
450
- ):
451
- resource_class += add_indent(invoke_async_method, 4)
452
-
453
- if invoke_with_response_stream_method := self._evaluate_method(
454
- resource_name,
455
- "invoke_with_response_stream",
456
- object_methods,
457
- resource_attributes=resource_attributes,
458
- ):
459
- resource_class += add_indent(invoke_with_response_stream_method, 4)
460
-
461
434
  if import_method := self._evaluate_method(resource_name, "import", class_methods):
462
435
  resource_class += add_indent(import_method, 4)
463
436
 
@@ -1172,174 +1145,6 @@ class ResourcesCodeGen:
1172
1145
  # Return the formatted method
1173
1146
  return formatted_method
1174
1147
 
1175
- def generate_invoke_method(self, resource_name: str, **kwargs) -> str:
1176
- """
1177
- Auto-generate the INVOKE ASYNC method for a resource.
1178
-
1179
- Args:
1180
- resource_name (str): The resource name.
1181
-
1182
- Returns:
1183
- str: The formatted Update Method template.
1184
-
1185
- """
1186
- # Get the operation and shape for the 'create' method
1187
- operation_name = "Invoke" + resource_name
1188
- operation_metadata = self.operations[operation_name]
1189
- operation_input_shape_name = operation_metadata["input"]["shape"]
1190
-
1191
- # Generate the arguments for the 'create' method
1192
- invoke_args = self._generate_method_args(
1193
- operation_input_shape_name, kwargs["resource_attributes"]
1194
- )
1195
-
1196
- operation_input_args = self._generate_operation_input_necessary_args(
1197
- operation_metadata, kwargs["resource_attributes"]
1198
- )
1199
-
1200
- # Convert the resource name to snake case
1201
- resource_lower = convert_to_snake_case(resource_name)
1202
-
1203
- # Convert the operation name to snake case
1204
- operation = convert_to_snake_case(operation_name)
1205
-
1206
- # generate docstring
1207
- docstring = self._generate_docstring(
1208
- title=f"Invoke a {resource_name} resource",
1209
- operation_name=operation_name,
1210
- resource_name=resource_name,
1211
- operation_input_shape_name=operation_input_shape_name,
1212
- include_session_region=False,
1213
- include_return_resource_docstring=False,
1214
- return_string=f"Returns:\n" f" The Invoke response.\n",
1215
- exclude_resource_attrs=kwargs["resource_attributes"],
1216
- )
1217
- # Format the method using the CREATE_METHOD_TEMPLATE
1218
- formatted_method = INVOKE_METHOD_TEMPLATE.format(
1219
- docstring=docstring,
1220
- service_name="sagemaker-runtime",
1221
- invoke_args=invoke_args,
1222
- resource_name=resource_name,
1223
- resource_lower=resource_lower,
1224
- operation_input_args=operation_input_args,
1225
- operation=operation,
1226
- )
1227
-
1228
- # Return the formatted method
1229
- return formatted_method
1230
-
1231
- def generate_invoke_async_method(self, resource_name: str, **kwargs) -> str:
1232
- """
1233
- Auto-generate the INVOKE method for a resource.
1234
-
1235
- Args:
1236
- resource_name (str): The resource name.
1237
-
1238
- Returns:
1239
- str: The formatted Update Method template.
1240
-
1241
- """
1242
- # Get the operation and shape for the 'create' method
1243
- operation_name = "Invoke" + resource_name + "Async"
1244
- operation_metadata = self.operations[operation_name]
1245
- operation_input_shape_name = operation_metadata["input"]["shape"]
1246
-
1247
- # Generate the arguments for the 'create' method
1248
- invoke_args = self._generate_method_args(
1249
- operation_input_shape_name, kwargs["resource_attributes"]
1250
- )
1251
-
1252
- operation_input_args = self._generate_operation_input_necessary_args(
1253
- operation_metadata, kwargs["resource_attributes"]
1254
- )
1255
-
1256
- # Convert the resource name to snake case
1257
- resource_lower = convert_to_snake_case(resource_name)
1258
-
1259
- # Convert the operation name to snake case
1260
- operation = convert_to_snake_case(operation_name)
1261
-
1262
- # generate docstring
1263
- docstring = self._generate_docstring(
1264
- title=f"Invoke Async a {resource_name} resource",
1265
- operation_name=operation_name,
1266
- resource_name=resource_name,
1267
- operation_input_shape_name=operation_input_shape_name,
1268
- include_session_region=False,
1269
- include_return_resource_docstring=False,
1270
- return_string=f"Returns:\n" f" The Invoke response.\n",
1271
- exclude_resource_attrs=kwargs["resource_attributes"],
1272
- )
1273
- # Format the method using the CREATE_METHOD_TEMPLATE
1274
- formatted_method = INVOKE_ASYNC_METHOD_TEMPLATE.format(
1275
- docstring=docstring,
1276
- service_name="sagemaker-runtime",
1277
- create_args=invoke_args,
1278
- resource_name=resource_name,
1279
- resource_lower=resource_lower,
1280
- operation_input_args=operation_input_args,
1281
- operation=operation,
1282
- )
1283
-
1284
- # Return the formatted method
1285
- return formatted_method
1286
-
1287
- def generate_invoke_with_response_stream_method(self, resource_name: str, **kwargs) -> str:
1288
- """
1289
- Auto-generate the INVOKE with response stream method for a resource.
1290
-
1291
- Args:
1292
- resource_name (str): The resource name.
1293
-
1294
- Returns:
1295
- str: The formatted Update Method template.
1296
-
1297
- """
1298
- # Get the operation and shape for the 'create' method
1299
- operation_name = "Invoke" + resource_name + "WithResponseStream"
1300
- operation_metadata = self.operations[operation_name]
1301
- operation_input_shape_name = operation_metadata["input"]["shape"]
1302
-
1303
- # Generate the arguments for the 'create' method
1304
- invoke_args = self._generate_method_args(
1305
- operation_input_shape_name, kwargs["resource_attributes"]
1306
- )
1307
-
1308
- operation_input_args = self._generate_operation_input_necessary_args(
1309
- operation_metadata, kwargs["resource_attributes"]
1310
- )
1311
-
1312
- # Convert the resource name to snake case
1313
- resource_lower = convert_to_snake_case(resource_name)
1314
-
1315
- # Convert the operation name to snake case
1316
- operation = convert_to_snake_case(operation_name)
1317
-
1318
- # generate docstring
1319
- docstring = self._generate_docstring(
1320
- title=f"Invoke with response stream a {resource_name} resource",
1321
- operation_name=operation_name,
1322
- resource_name=resource_name,
1323
- operation_input_shape_name=operation_input_shape_name,
1324
- include_session_region=False,
1325
- include_return_resource_docstring=False,
1326
- return_string=f"Returns:\n" f" The Invoke response.\n",
1327
- exclude_resource_attrs=kwargs["resource_attributes"],
1328
- )
1329
- # Format the method using the CREATE_METHOD_TEMPLATE
1330
- formatted_method = INVOKE_WITH_RESPONSE_STREAM_METHOD_TEMPLATE.format(
1331
- docstring=docstring,
1332
- service_name="sagemaker-runtime",
1333
- create_args=invoke_args,
1334
- resource_name=resource_name,
1335
- resource_lower=resource_lower,
1336
- operation_input_args=operation_input_args,
1337
- operation=operation,
1338
- )
1339
-
1340
- # Return the formatted method
1341
- return formatted_method
1342
-
1343
1148
  def generate_get_method(self, resource_name: str) -> str:
1344
1149
  """
1345
1150
  Auto-generate the GET method (describe API) for a resource.
@@ -97,7 +97,7 @@ class ResourcesExtractor:
97
97
  if resource_name not in self.resource_methods:
98
98
  self.resource_methods[resource_name] = dict()
99
99
  for operation_name, operation in resource_operations.items():
100
- self.actions_under_resource.update(operation_name)
100
+ self.actions_under_resource.add(operation_name)
101
101
  method = Method(**operation)
102
102
  method.get_docstring_title(self.operations[operation_name])
103
103
  self.resource_methods[resource_name][operation["method_name"]] = method
@@ -197,77 +197,6 @@ def update(
197
197
  return self
198
198
  """
199
199
 
200
- INVOKE_METHOD_TEMPLATE = """
201
- @Base.add_validate_call
202
- def invoke(self,
203
- {invoke_args}
204
- ) -> Optional[object]:
205
- {docstring}
206
- logger.info(f"Invoking {resource_lower} resource.")
207
- client = SageMakerRuntimeClient(service_name="{service_name}").client
208
- operation_input_args = {{
209
- {operation_input_args}
210
- }}
211
- logger.debug(f"Input request: {{operation_input_args}}")
212
- # serialize the input request
213
- operation_input_args = serialize(operation_input_args)
214
- logger.debug(f"Serialized input request: {{operation_input_args}}")
215
-
216
- # create the resource
217
- response = client.{operation}(**operation_input_args)
218
- logger.debug(f"Response: {{response}}")
219
-
220
- return response
221
- """
222
-
223
- INVOKE_ASYNC_METHOD_TEMPLATE = """
224
- @Base.add_validate_call
225
- def invoke_async(self,
226
- {create_args}
227
- ) -> Optional[object]:
228
- {docstring}
229
- logger.info(f"Invoking {resource_lower} resource Async.")
230
- client = SageMakerRuntimeClient(service_name="{service_name}").client
231
-
232
- operation_input_args = {{
233
- {operation_input_args}
234
- }}
235
- logger.debug(f"Input request: {{operation_input_args}}")
236
- # serialize the input request
237
- operation_input_args = serialize(operation_input_args)
238
- logger.debug(f"Serialized input request: {{operation_input_args}}")
239
-
240
- # create the resource
241
- response = client.{operation}(**operation_input_args)
242
- logger.debug(f"Response: {{response}}")
243
-
244
- return response
245
- """
246
-
247
- INVOKE_WITH_RESPONSE_STREAM_METHOD_TEMPLATE = """
248
- @Base.add_validate_call
249
- def invoke_with_response_stream(self,
250
- {create_args}
251
- ) -> Optional[object]:
252
- {docstring}
253
- logger.info(f"Invoking {resource_lower} resource with Response Stream.")
254
- client = SageMakerRuntimeClient(service_name="{service_name}").client
255
-
256
- operation_input_args = {{
257
- {operation_input_args}
258
- }}
259
- logger.debug(f"Input request: {{operation_input_args}}")
260
- # serialize the input request
261
- operation_input_args = serialize(operation_input_args)
262
- logger.debug(f"Serialized input request: {{operation_input_args}}")
263
-
264
- # create the resource
265
- response = client.{operation}(**operation_input_args)
266
- logger.debug(f"Response: {{response}}")
267
-
268
- return response
269
- """
270
-
271
200
  POPULATE_DEFAULTS_DECORATOR_TEMPLATE = """
272
201
  def populate_inputs_decorator(create_func):
273
202
  @functools.wraps(create_func)
@@ -639,7 +568,7 @@ class Base(BaseModel):
639
568
 
640
569
  @classmethod
641
570
  def get_sagemaker_client(cls, session = None, region_name = None, service_name = 'sagemaker'):
642
- return SageMakerClient(session=session, region_name=region_name, service_name=service_name).client
571
+ return SageMakerClient(session=session, region_name=region_name).get_client(service_name=service_name)
643
572
 
644
573
  @staticmethod
645
574
  def get_updated_kwargs_with_configured_attributes(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sagemaker-core
3
- Version: 1.0.4
3
+ Version: 1.0.5
4
4
  Summary: An python package for sagemaker core functionalities
5
5
  Author-email: AWS <sagemaker-interests@amazon.com>
6
6
  Project-URL: Repository, https://github.com/aws/sagemaker-core.git
@@ -6,29 +6,29 @@ sagemaker_core/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
6
6
  sagemaker_core/main/config_schema.py,sha256=IDvL1YuMOwVg4nb0D4ysU51tc1UjlQASyz1QZoncs7I,56907
7
7
  sagemaker_core/main/exceptions.py,sha256=87DUlrmHxaWoiYNlpNY9ixxFMPRk_dIGPsA2e_xdVwQ,5602
8
8
  sagemaker_core/main/intelligent_defaults_helper.py,sha256=5SDM6UavZtp-k5LhqRL7GRIDgzFB5UsC_p7YuiSPK9A,8334
9
- sagemaker_core/main/resources.py,sha256=3ivOSUiWqH8VWmOwxz1Oa45aet7CTsc8mZott-ge7yc,1299296
10
- sagemaker_core/main/shapes.py,sha256=mxsgFQYYMCWrZm_GF3w_wwgfTon0AgheZoXKu17ux1c,683409
9
+ sagemaker_core/main/resources.py,sha256=S4wuM705rkah3cFO-kfWAXPgYq7SI3PG2Qh6ZHtfTfk,1314805
10
+ sagemaker_core/main/shapes.py,sha256=kuefQBAgOogQynQikMq-6RxNezaVXE3ChwJedvVMAFw,693437
11
11
  sagemaker_core/main/user_agent.py,sha256=4sZybDXkzRoZnOnVDQ8p8zFTfiRJdsH7amDWInVQ4xU,2708
12
- sagemaker_core/main/utils.py,sha256=I7WsC-DdbnAZg_PtqcLPywXlqjAwj7ZYbeHhv93Z1O4,18840
12
+ sagemaker_core/main/utils.py,sha256=lXkJyiCow5uf32l0EmkimB0RKVk2BS7OM2fYoLsOfD4,18346
13
13
  sagemaker_core/main/code_injection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  sagemaker_core/main/code_injection/base.py,sha256=11_Jif0nOzfbLGlXaacKf-wcizzfS64U0OSZGoVffFU,1733
15
15
  sagemaker_core/main/code_injection/codec.py,sha256=2DjmeD2uND307UqDefvVEpE0rZ8yfFU3Bi3TvQCQveI,7658
16
16
  sagemaker_core/main/code_injection/constants.py,sha256=2ICExGge8vAWx7lSTW0JGh-bH1korkvpOpDu5M63eI4,980
17
- sagemaker_core/main/code_injection/shape_dag.py,sha256=mQR562skpJVs3VbNS-dtGvF94JXVcRBZS5b0cpKH3x0,648111
17
+ sagemaker_core/main/code_injection/shape_dag.py,sha256=iIkfDlMpNdzeLY958ZB3VTD55BJC1sid3qry-YOG-rM,655019
18
18
  sagemaker_core/resources/__init__.py,sha256=EAYTFMN-nPjnPjjBbhIUeaL67FLKNPd7qbcbl9VIrws,31
19
19
  sagemaker_core/shapes/__init__.py,sha256=RnbIu9eTxKt-DNsOFJabrWIgrrtS9_SdAozP9JBl_ic,28
20
20
  sagemaker_core/tools/__init__.py,sha256=xX79JImxCVzrWMnjgntLCve2G5I-R4pRar5s20kT9Rs,56
21
21
  sagemaker_core/tools/codegen.py,sha256=mKWVi2pWnPxyIoWUEPYjEc9Gw7D9bCOrHqa00yzIZ1o,2005
22
- sagemaker_core/tools/constants.py,sha256=lJ-KqRtv0F4mtZBqUNCX5RbOhXmPUsIslLPVVFJunDA,3080
23
- sagemaker_core/tools/data_extractor.py,sha256=NpP22uCaWgvn9uOHsFEkgtn3h2nOIKDvJTLihN01f1A,1368
22
+ sagemaker_core/tools/constants.py,sha256=8oM0nHuzXWnOJTIdXsu50f9RsEz4rgmmZKWhLkrTP-s,3309
23
+ sagemaker_core/tools/data_extractor.py,sha256=pNfmTA0NUA96IgfLrla7a36Qjc1NljbwgZYaOhouKqQ,2113
24
24
  sagemaker_core/tools/method.py,sha256=4Hmu4UWpiBgUTZljYdW1KIKDduDxf_nfhCyuWgLVMWI,717
25
- sagemaker_core/tools/resources_codegen.py,sha256=m7B2vrkfokLmzND9tCkty7EhVMk1FLevTd2LmJd_GKg,89974
26
- sagemaker_core/tools/resources_extractor.py,sha256=B9Twlf2vb7AkZUKLnxSdQZ_rNLPz0ROk9kuq-6uB1As,14526
25
+ sagemaker_core/tools/resources_codegen.py,sha256=ShsWjABBkSpPlp3gByzpe36M6hfYfBofODlUynqVXTY,82405
26
+ sagemaker_core/tools/resources_extractor.py,sha256=hN61ehZbPnhFW-2FIVDi7NsEz4rLvGr-WoglHQGfrug,14523
27
27
  sagemaker_core/tools/shapes_codegen.py,sha256=_ve959bwH8usZ6dPlpXxi2on9t0hLpcmhRWnaWHCWMQ,11745
28
28
  sagemaker_core/tools/shapes_extractor.py,sha256=4KjgDmhlPM4G1f1NeYbORKlXs1s7Q_sm_NK31S_ROQ0,11950
29
- sagemaker_core/tools/templates.py,sha256=IvL9ykLvOXDNCMnIZn30o-6Cmx4fw-BIJz3nl9LD4dc,24614
30
- sagemaker_core-1.0.4.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
31
- sagemaker_core-1.0.4.dist-info/METADATA,sha256=62vOPMIkSDkfR_ekA4qjnxJ96kC4hbzlhAtd2w52Qk0,4877
32
- sagemaker_core-1.0.4.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
33
- sagemaker_core-1.0.4.dist-info/top_level.txt,sha256=R3GAZZ1zC5JxqdE_0x2Lu_WYi2Xfke7VsiP3L5zngfA,15
34
- sagemaker_core-1.0.4.dist-info/RECORD,,
29
+ sagemaker_core/tools/templates.py,sha256=nze_A01EpegYUwoR_gRv2qBNKNFruBY8L3RiIX5lz3M,22458
30
+ sagemaker_core-1.0.5.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
31
+ sagemaker_core-1.0.5.dist-info/METADATA,sha256=H-1KZPKDIpM0IwqMxScfrbVB1RDN2PlaTB7zLlE89x8,4877
32
+ sagemaker_core-1.0.5.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
33
+ sagemaker_core-1.0.5.dist-info/top_level.txt,sha256=R3GAZZ1zC5JxqdE_0x2Lu_WYi2Xfke7VsiP3L5zngfA,15
34
+ sagemaker_core-1.0.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (74.1.2)
2
+ Generator: setuptools (75.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5