cognite-toolkit 0.7.64__py3-none-any.whl → 0.7.66__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.
@@ -16,18 +16,15 @@ from cognite_toolkit._cdf_tk.exceptions import ToolkitFileExistsError, ToolkitNo
16
16
  from cognite_toolkit._cdf_tk.feature_flags import Flags
17
17
  from cognite_toolkit._cdf_tk.tk_warnings import (
18
18
  FileReadWarning,
19
- FunctionRequirementsValidationWarning,
20
19
  HighSeverityWarning,
21
20
  LowSeverityWarning,
22
21
  MediumSeverityWarning,
22
+ RequirementsTXTValidationWarning,
23
23
  ToolkitWarning,
24
24
  WarningList,
25
25
  )
26
26
  from cognite_toolkit._cdf_tk.utils import validate_requirements_with_pip
27
27
 
28
- # Maximum number of error lines to display in warnings
29
- _MAX_ERROR_LINES = 3
30
-
31
28
 
32
29
  class FunctionBuilder(Builder):
33
30
  _resource_folder = FunctionCRUD.folder_name
@@ -46,7 +43,7 @@ class FunctionBuilder(Builder):
46
43
  raw_function: dict[str, Any],
47
44
  filepath: Path,
48
45
  external_id: str,
49
- ) -> FunctionRequirementsValidationWarning | None:
46
+ ) -> RequirementsTXTValidationWarning | None:
50
47
  """Validate function requirements.txt using pip dry-run."""
51
48
  start_time = time.time()
52
49
  validation_result = validate_requirements_with_pip(
@@ -65,15 +62,12 @@ class FunctionBuilder(Builder):
65
62
  if validation_result.is_credential_error:
66
63
  self.validation_credential_errors += 1
67
64
 
68
- error_detail = validation_result.error_message or "Unknown error"
69
- relevant_lines = [line for line in error_detail.strip().split("\n") if line.strip()][-_MAX_ERROR_LINES:]
70
- error_detail = "\n ".join(relevant_lines)
71
-
72
- return FunctionRequirementsValidationWarning(
65
+ return RequirementsTXTValidationWarning(
73
66
  filepath=filepath,
74
- function_external_id=external_id,
75
- error_details=error_detail,
67
+ external_id=external_id,
68
+ error_details=validation_result.short_error,
76
69
  is_credential_error=validation_result.is_credential_error,
70
+ resource="function",
77
71
  )
78
72
 
79
73
  def build(
@@ -9,13 +9,16 @@ from cognite_toolkit._cdf_tk.data_classes import (
9
9
  ModuleLocation,
10
10
  )
11
11
  from cognite_toolkit._cdf_tk.exceptions import ToolkitFileExistsError, ToolkitNotADirectoryError, ToolkitValueError
12
+ from cognite_toolkit._cdf_tk.feature_flags import Flags
12
13
  from cognite_toolkit._cdf_tk.tk_warnings import (
13
14
  FileReadWarning,
14
15
  HighSeverityWarning,
16
+ RequirementsTXTValidationWarning,
15
17
  StreamlitRequirementsWarning,
16
18
  ToolkitWarning,
17
19
  WarningList,
18
20
  )
21
+ from cognite_toolkit._cdf_tk.utils import validate_requirements_with_pip
19
22
  from cognite_toolkit._cdf_tk.utils.file import safe_read
20
23
 
21
24
 
@@ -77,6 +80,21 @@ class StreamlitBuilder(Builder):
77
80
  f"StreamlitApp directory not found in {app_directory}(based on externalId {external_id} defined in {source_file.source.path.as_posix()!r}.)"
78
81
  )
79
82
 
83
+ if (requirements_txt := app_directory / "requirements.txt").exists() and (
84
+ Flags.FUNCTION_REQUIREMENTS_VALIDATION.is_enabled()
85
+ ):
86
+ validation_result = validate_requirements_with_pip(requirements_txt_path=requirements_txt)
87
+ if not validation_result.success:
88
+ warnings.append(
89
+ RequirementsTXTValidationWarning(
90
+ filepath=source_file.source.path,
91
+ error_details=validation_result.short_error,
92
+ is_credential_error=validation_result.is_credential_error,
93
+ external_id=external_id,
94
+ resource="streamlit",
95
+ )
96
+ )
97
+
80
98
  requirements_file_content = safe_read(app_directory / "requirements.txt").splitlines()
81
99
  missing_packages = StreamlitCRUD._missing_recommended_requirements(requirements_file_content)
82
100
  if len(missing_packages) > 0:
@@ -193,6 +193,10 @@ class TextProperty(ListablePropertyTypeDefinition):
193
193
  default=None,
194
194
  description="he set of language specific rules - used when sorting text fields.",
195
195
  )
196
+ max_text_size: int | None = Field(
197
+ default=None,
198
+ description="Specifies the maximum size in bytes of the text property, when encoded with utf-8",
199
+ )
196
200
 
197
201
 
198
202
  class FloatPrimitiveProperty(ListablePropertyTypeDefinition):
@@ -42,7 +42,7 @@ class ContainerYAML(ToolkitResource):
42
42
  description="Description of the container.",
43
43
  max_length=1024,
44
44
  )
45
- used_for: Literal["node", "edge", "all"] | None = Field(
45
+ used_for: Literal["node", "edge", "record", "all"] | None = Field(
46
46
  default=None,
47
47
  description="Should this operation apply to nodes, edges or both.",
48
48
  )
@@ -6,19 +6,18 @@ from .base import (
6
6
  catch_warnings,
7
7
  )
8
8
  from .fileread import (
9
- CaseTypoWarning,
10
9
  DataSetMissingWarning,
11
10
  DuplicatedItemWarning,
12
11
  EnvironmentVariableMissingWarning,
13
12
  FileExistsWarning,
14
13
  FileReadWarning,
15
- FunctionRequirementsValidationWarning,
16
14
  MissingFileWarning,
17
15
  MissingReferencedWarning,
18
16
  MissingRequiredParameterWarning,
19
17
  NamespacingConventionWarning,
20
18
  NamingConventionWarning,
21
19
  PrefixConventionWarning,
20
+ RequirementsTXTValidationWarning,
22
21
  ResourceMissingIdentifierWarning,
23
22
  SourceFileModifiedWarning,
24
23
  StreamlitRequirementsWarning,
@@ -46,13 +45,11 @@ from .other import (
46
45
  )
47
46
 
48
47
  __all__ = [
49
- "CaseTypoWarning",
50
48
  "DataSetMissingWarning",
51
49
  "DuplicatedItemWarning",
52
50
  "EnvironmentVariableMissingWarning",
53
51
  "FileExistsWarning",
54
52
  "FileReadWarning",
55
- "FunctionRequirementsValidationWarning",
56
53
  "GeneralWarning",
57
54
  "HTTPWarning",
58
55
  "HighSeverityWarning",
@@ -69,6 +66,7 @@ __all__ = [
69
66
  "NamespacingConventionWarning",
70
67
  "NamingConventionWarning",
71
68
  "PrefixConventionWarning",
69
+ "RequirementsTXTValidationWarning",
72
70
  "ResourceMissingIdentifierWarning",
73
71
  "SeverityLevel",
74
72
  "SourceFileModifiedWarning",
@@ -2,7 +2,7 @@ from abc import ABC, abstractmethod
2
2
  from collections.abc import Hashable
3
3
  from dataclasses import dataclass
4
4
  from pathlib import Path
5
- from typing import Any, ClassVar
5
+ from typing import Any, ClassVar, Literal
6
6
 
7
7
  from rich.markup import escape
8
8
 
@@ -167,14 +167,6 @@ class NamespacingConventionWarning(NamingConventionWarning):
167
167
  return f"of using {self.namespace!r} as separator."
168
168
 
169
169
 
170
- @dataclass(frozen=True)
171
- class CaseTypoWarning(UnusedParameterWarning):
172
- expected: str
173
-
174
- def get_message(self) -> str:
175
- return f"{type(self).__name__}: Got {self.actual!r}. Did you mean {self.expected!r}?{self._location}."
176
-
177
-
178
170
  @dataclass(frozen=True)
179
171
  class MissingRequiredParameterWarning(YAMLFileWithElementWarning):
180
172
  severity: ClassVar[SeverityLevel] = SeverityLevel.HIGH
@@ -271,15 +263,16 @@ class StreamlitRequirementsWarning(FileReadWarning):
271
263
 
272
264
 
273
265
  @dataclass(frozen=True)
274
- class FunctionRequirementsValidationWarning(FileReadWarning):
266
+ class RequirementsTXTValidationWarning(FileReadWarning):
275
267
  severity: ClassVar[SeverityLevel] = SeverityLevel.HIGH
276
- function_external_id: str
268
+ external_id: str
277
269
  error_details: str
278
270
  is_credential_error: bool
271
+ resource: Literal["function", "streamlit"]
279
272
 
280
273
  def get_message(self) -> str:
281
274
  message = (
282
- f"Function [bold]{self.function_external_id}[/bold] requirements.txt validation failed. "
275
+ f"{self.resource.title()} [bold]{self.external_id}[/bold] requirements.txt validation failed. "
283
276
  f"Packages could not be resolved: {self.error_details}"
284
277
  )
285
278
  if self.is_credential_error:
@@ -5,15 +5,14 @@ import sys
5
5
  from dataclasses import dataclass
6
6
  from pathlib import Path
7
7
 
8
- # Maximum number of error lines to include in warnings
9
- _MAX_ERROR_LINES = 3
10
-
11
8
 
12
9
  @dataclass
13
10
  class PipValidationResult:
14
11
  """Result from validating a requirements.txt file."""
15
12
 
16
13
  error_message: str | None = None
14
+ # The number of lines to include in the short error message
15
+ max_error_lines: int = 3
17
16
 
18
17
  @property
19
18
  def success(self) -> bool:
@@ -38,6 +37,14 @@ class PipValidationResult:
38
37
  ]
39
38
  return any(indicator in self.error_message for indicator in credential_indicators)
40
39
 
40
+ @property
41
+ def short_error(self) -> str:
42
+ """Get a shortened version of the error message with limited lines."""
43
+ error_detail = self.error_message or "Unknown error"
44
+ relevant_lines = [line for line in error_detail.strip().split("\n") if line.strip()][-self.max_error_lines :]
45
+ error_detail = "\n ".join(relevant_lines)
46
+ return error_detail
47
+
41
48
 
42
49
  def validate_requirements_with_pip(
43
50
  requirements_txt_path: Path,
@@ -12,7 +12,7 @@ jobs:
12
12
  environment: dev
13
13
  name: Deploy
14
14
  container:
15
- image: cognite/toolkit:0.7.64
15
+ image: cognite/toolkit:0.7.66
16
16
  env:
17
17
  CDF_CLUSTER: ${{ vars.CDF_CLUSTER }}
18
18
  CDF_PROJECT: ${{ vars.CDF_PROJECT }}
@@ -10,7 +10,7 @@ jobs:
10
10
  environment: dev
11
11
  name: Deploy Dry Run
12
12
  container:
13
- image: cognite/toolkit:0.7.64
13
+ image: cognite/toolkit:0.7.66
14
14
  env:
15
15
  CDF_CLUSTER: ${{ vars.CDF_CLUSTER }}
16
16
  CDF_PROJECT: ${{ vars.CDF_PROJECT }}
@@ -4,7 +4,7 @@ default_env = "<DEFAULT_ENV_PLACEHOLDER>"
4
4
  [modules]
5
5
  # This is the version of the modules. It should not be changed manually.
6
6
  # It will be updated by the 'cdf modules upgrade' command.
7
- version = "0.7.64"
7
+ version = "0.7.66"
8
8
 
9
9
 
10
10
  [plugins]
@@ -1 +1 @@
1
- __version__ = "0.7.64"
1
+ __version__ = "0.7.66"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cognite_toolkit
3
- Version: 0.7.64
3
+ Version: 0.7.66
4
4
  Summary: Official Cognite Data Fusion tool for project templates and configuration deployment
5
5
  Author: Cognite AS
6
6
  Author-email: Cognite AS <support@cognite.com>
@@ -21,10 +21,10 @@ cognite_toolkit/_cdf_tk/builders/__init__.py,sha256=8073Ijf621XiAtiwup-rLfrbYd40
21
21
  cognite_toolkit/_cdf_tk/builders/_base.py,sha256=_4Gd6GtuAmnPvl3IjvuAUfuSQtEVJekUaqzk3IH-tIY,7462
22
22
  cognite_toolkit/_cdf_tk/builders/_datamodels.py,sha256=hN3fWQAktrWdaGAItZ0tHpBXqJDu0JfH6t7pO7EIl2Q,3541
23
23
  cognite_toolkit/_cdf_tk/builders/_file.py,sha256=ZRTlyb-MnmJhBhfPeQ9h7gM2T4nllyjonwYBj31cv1Q,3847
24
- cognite_toolkit/_cdf_tk/builders/_function.py,sha256=bCseIh19oDuw1gU2whJ8WFeHAZvL1J-0ilUt7TmYdPg,7908
24
+ cognite_toolkit/_cdf_tk/builders/_function.py,sha256=jrXZPSck6GVguChl1kiWRTbrsiLWjyC5FupNDvAZWek,7614
25
25
  cognite_toolkit/_cdf_tk/builders/_location.py,sha256=Ix26T6JSlmp_Ij3iKaClbBQtRF3hR-wDKkZu9B-NblA,3968
26
26
  cognite_toolkit/_cdf_tk/builders/_raw.py,sha256=3XjPHfzPRYRJ2QPP-D8S9uW2gppnzEdqyICBqwGRRXo,3265
27
- cognite_toolkit/_cdf_tk/builders/_streamlit.py,sha256=8Pu_zgyKZjbAsPWywjzB2KWD7hQ2G6393xZbJWH2wtM,4033
27
+ cognite_toolkit/_cdf_tk/builders/_streamlit.py,sha256=WsrQTaTwuyewNJ2y04tA16iEK-bpr0cL4sup9-89H6o,4996
28
28
  cognite_toolkit/_cdf_tk/builders/_transformation.py,sha256=STB42zhzOW5M_-b8cKOQ_cegnr7FtMoMxZ87gPLXft4,4723
29
29
  cognite_toolkit/_cdf_tk/cdf_toml.py,sha256=VSWV9h44HusWIaKpWgjrOMrc3hDoPTTXBXlp6-NOrIM,9079
30
30
  cognite_toolkit/_cdf_tk/client/__init__.py,sha256=a6rQXDGfW2g7K5WwrOW5oakh1TdFlBjUVjf9wusOox8,135
@@ -318,8 +318,8 @@ cognite_toolkit/_cdf_tk/resource_classes/authentication.py,sha256=RTLjFXWhpg2tLo
318
318
  cognite_toolkit/_cdf_tk/resource_classes/base.py,sha256=nbAWSBkV-GL0co5UNMXvYMIw_-qhJ8uoXy9wz6KmI-w,723
319
319
  cognite_toolkit/_cdf_tk/resource_classes/capabilities.py,sha256=c50B8apsEiJ55bf-nWYfhy4uV9uMhZ-mRnXslZ80030,14898
320
320
  cognite_toolkit/_cdf_tk/resource_classes/cognitefile.py,sha256=nsLBw6CxwrmfxliO0vsGSc4vfaDONPsNHPFT6ckvudk,2800
321
- cognite_toolkit/_cdf_tk/resource_classes/container_field_definitions.py,sha256=grjzoW8AwujPJV70QyKBmhJ0m99kED9KMttoongnpL4,11428
322
- cognite_toolkit/_cdf_tk/resource_classes/containers.py,sha256=cWLB6CTvBkdwrMg4bw1S72s7IZo7O_pYNNTTUwNqXpY,3701
321
+ cognite_toolkit/_cdf_tk/resource_classes/container_field_definitions.py,sha256=s4M2SAEWbV1TPszldzS_gY9AY77-_il08HDmflvqTgs,11600
322
+ cognite_toolkit/_cdf_tk/resource_classes/containers.py,sha256=SE7I_VyPqV3J5n_REfGuxPv6Jzc4dQYsFYkVRBrkhZE,3711
323
323
  cognite_toolkit/_cdf_tk/resource_classes/data_model.py,sha256=kETO_C--w1EFmaZmPxeiZ0W5xRgVswUmVjc0dSKTTdQ,1471
324
324
  cognite_toolkit/_cdf_tk/resource_classes/datapoint_subscription.py,sha256=41sK5cpNRCmMwqqK_zYVq8GonqFCpIde357osqNKOAk,2787
325
325
  cognite_toolkit/_cdf_tk/resource_classes/dataset.py,sha256=kCEQUswgTgtb8fdd9mMg50MuY34zjDmdh4ZUmxu2A74,816
@@ -389,9 +389,9 @@ cognite_toolkit/_cdf_tk/storageio/selectors/_file_content.py,sha256=e7riknOinuhJ
389
389
  cognite_toolkit/_cdf_tk/storageio/selectors/_instances.py,sha256=NCFSJrAw52bNX6UTfOali8PvNjlqHnvxzL0hYBr7ZmA,4934
390
390
  cognite_toolkit/_cdf_tk/storageio/selectors/_raw.py,sha256=sZq9C4G9DMe3S46_usKet0FphQ6ow7cWM_PfXrEAakk,503
391
391
  cognite_toolkit/_cdf_tk/storageio/selectors/_three_d.py,sha256=0dT1vVG6EIyo0OJK3t_vwtE63i0dZvH8nZT7ebl1Ku0,924
392
- cognite_toolkit/_cdf_tk/tk_warnings/__init__.py,sha256=4vSQJE7ZCzfoJv3TmVYZl9R2Ubf6Mf-Te7ex_gcsDaY,2404
392
+ cognite_toolkit/_cdf_tk/tk_warnings/__init__.py,sha256=WFxtoT3FodaXjhA5PCEy4mXNvcycYfnZtWKJcIpyTo8,2350
393
393
  cognite_toolkit/_cdf_tk/tk_warnings/base.py,sha256=cX8TCmb56gqx3lc7dankXuqpm5HGASJ4wTb07-MCJWs,4401
394
- cognite_toolkit/_cdf_tk/tk_warnings/fileread.py,sha256=QXs3g-WubOlO-HXvM_RzDVRyr-ZqELSev7XWiRjY2CM,9716
394
+ cognite_toolkit/_cdf_tk/tk_warnings/fileread.py,sha256=RB-3ltSJjbL1GqQAJOvqXDZYdObjpV8QM3TWDsVWyUE,9527
395
395
  cognite_toolkit/_cdf_tk/tk_warnings/other.py,sha256=D8EubXyW4qigscBEiedQJuT5c6yYoFIEhBPa1DggD3I,5808
396
396
  cognite_toolkit/_cdf_tk/tracker.py,sha256=jhxzI8LOSZw3zDBPsTLW3zC2YcQK2abp_aVtRKcUIwE,5913
397
397
  cognite_toolkit/_cdf_tk/utils/__init__.py,sha256=DGuPTiY3fRhPuR_r-bCT_bDKl46nvF3q2ZY-yt2okT8,1640
@@ -415,7 +415,7 @@ cognite_toolkit/_cdf_tk/utils/graphql_parser.py,sha256=2i2wDjg_Uw3hJ-pHtPK8hczIu
415
415
  cognite_toolkit/_cdf_tk/utils/hashing.py,sha256=3NyNfljyYNTqAyAFBd6XlyWaj43jRzENxIuPdOY6nqo,2116
416
416
  cognite_toolkit/_cdf_tk/utils/interactive_select.py,sha256=G8UqFMzxOOImMwHfCvXEe-nTTqay9PYCwbpyIQae_XU,38000
417
417
  cognite_toolkit/_cdf_tk/utils/modules.py,sha256=zI0Qv1WSZRj3B58TwItnXwEtahwpRpDXU3GHew3Qffs,6216
418
- cognite_toolkit/_cdf_tk/utils/pip_validator.py,sha256=dzizb6-U0bee4ismqrvccUq_K2ASKY0xk40RbDzorEg,3231
418
+ cognite_toolkit/_cdf_tk/utils/pip_validator.py,sha256=G_idBJak_ZeYW_gJ_tX_KuW6zUPk3asvXmSCDW4yXpY,3637
419
419
  cognite_toolkit/_cdf_tk/utils/producer_worker.py,sha256=1l77HIehkq1ARCBH6SlZ_V-jd6QKijYKeWetcUmAXg0,14216
420
420
  cognite_toolkit/_cdf_tk/utils/progress_tracker.py,sha256=LGpC22iSTTlo6FWi38kqBu_E4XouTvZU_N953WAzZWA,3865
421
421
  cognite_toolkit/_cdf_tk/utils/repository.py,sha256=voQLZ6NiNvdAFxqeWHbvzDLsLHl6spjQBihiLyCsGW8,4104
@@ -432,13 +432,13 @@ cognite_toolkit/_repo_files/.gitignore,sha256=ip9kf9tcC5OguF4YF4JFEApnKYw0nG0vPi
432
432
  cognite_toolkit/_repo_files/AzureDevOps/.devops/README.md,sha256=OLA0D7yCX2tACpzvkA0IfkgQ4_swSd-OlJ1tYcTBpsA,240
433
433
  cognite_toolkit/_repo_files/AzureDevOps/.devops/deploy-pipeline.yml,sha256=brULcs8joAeBC_w_aoWjDDUHs3JheLMIR9ajPUK96nc,693
434
434
  cognite_toolkit/_repo_files/AzureDevOps/.devops/dry-run-pipeline.yml,sha256=OBFDhFWK1mlT4Dc6mDUE2Es834l8sAlYG50-5RxRtHk,723
435
- cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml,sha256=7FN5fi7yF2adj-ke8bq9ctcgQzGtCyOaIuKkoK3qYTs,667
436
- cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml,sha256=fvN1_GVygzZ1hiDlE6riH89hGodmICuVtsGQNBXR10I,2430
437
- cognite_toolkit/_resources/cdf.toml,sha256=Wx_KlVj5a5EoQXUMrQEy7jYT8hlejSLRi52EtHQKHrk,475
438
- cognite_toolkit/_version.py,sha256=YcVDXDbCWggmIHUePf77MZIOJHqpdf1nK5FnmEuIUrY,23
435
+ cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml,sha256=063nvjA8IiZpk_FOTGNVLWxYBe3geceghlk3RgBqt_w,667
436
+ cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml,sha256=r5QSmFI0RyZs1QsyOjV40upQnhrb9E_8SfwIMq8q0TE,2430
437
+ cognite_toolkit/_resources/cdf.toml,sha256=N1290ajTgb9r6KjawkxXEM_mj0YBg7CwcKLK0vsuc54,475
438
+ cognite_toolkit/_version.py,sha256=1JY7-lV_Ug19kyUkqPINs1zBYHRVQ5BIUdGiziLkLkY,23
439
439
  cognite_toolkit/demo/__init__.py,sha256=-m1JoUiwRhNCL18eJ6t7fZOL7RPfowhCuqhYFtLgrss,72
440
440
  cognite_toolkit/demo/_base.py,sha256=6xKBUQpXZXGQ3fJ5f7nj7oT0s2n7OTAGIa17ZlKHZ5U,8052
441
- cognite_toolkit-0.7.64.dist-info/WHEEL,sha256=fAguSjoiATBe7TNBkJwOjyL1Tt4wwiaQGtNtjRPNMQA,80
442
- cognite_toolkit-0.7.64.dist-info/entry_points.txt,sha256=EtZ17K2mUjh-AY0QNU1CPIB_aDSSOdmtNI_4Fj967mA,84
443
- cognite_toolkit-0.7.64.dist-info/METADATA,sha256=MJAqtZLpAeeqDqCyUiJIvxCJJmlcE51qJjNmN-YsaYw,5026
444
- cognite_toolkit-0.7.64.dist-info/RECORD,,
441
+ cognite_toolkit-0.7.66.dist-info/WHEEL,sha256=fAguSjoiATBe7TNBkJwOjyL1Tt4wwiaQGtNtjRPNMQA,80
442
+ cognite_toolkit-0.7.66.dist-info/entry_points.txt,sha256=EtZ17K2mUjh-AY0QNU1CPIB_aDSSOdmtNI_4Fj967mA,84
443
+ cognite_toolkit-0.7.66.dist-info/METADATA,sha256=pra2xaV8-K3VEQ0ozcuT5lsfurUoD4XIDcrowM0vbKE,5026
444
+ cognite_toolkit-0.7.66.dist-info/RECORD,,