cognite-toolkit 0.7.1__py3-none-any.whl → 0.7.3__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.
@@ -1,16 +1,25 @@
1
- from typing import Any
1
+ from pathlib import Path
2
+ from typing import Annotated, Any
2
3
 
3
4
  import typer
4
5
  from rich import print
5
6
 
7
+ from cognite_toolkit._cdf_tk.cdf_toml import CDFToml
8
+ from cognite_toolkit._cdf_tk.commands import ResourcesCommand
9
+ from cognite_toolkit._cdf_tk.feature_flags import FeatureFlag, Flags
10
+
6
11
  from ._run import RunApp
7
12
 
13
+ CDF_TOML = CDFToml.load(Path.cwd())
14
+
8
15
 
9
16
  class DevApp(typer.Typer):
10
17
  def __init__(self, *args: Any, **kwargs: Any) -> None:
11
18
  super().__init__(*args, **kwargs)
12
19
  self.callback(invoke_without_command=True)(self.main)
13
20
  self.add_typer(RunApp(*args, **kwargs), name="run")
21
+ if FeatureFlag.is_enabled(Flags.CREATE):
22
+ self.command("create")(self.create)
14
23
 
15
24
  @staticmethod
16
25
  def main(ctx: typer.Context) -> None:
@@ -18,3 +27,60 @@ class DevApp(typer.Typer):
18
27
  if ctx.invoked_subcommand is None:
19
28
  print("Use [bold yellow]cdf dev --help[/] for more information.")
20
29
  return None
30
+
31
+ def create(
32
+ self,
33
+ kind: Annotated[
34
+ list[str] | None,
35
+ typer.Argument(
36
+ help="The kind of resource to create. eg. container, space, view, datamodel, etc.",
37
+ callback=lambda ctx, param, value: [
38
+ s.strip() for item in value or [] for s in item.split(",") if s.strip()
39
+ ],
40
+ ),
41
+ ] = None,
42
+ module: Annotated[
43
+ str | None,
44
+ typer.Option(
45
+ "--module",
46
+ "-m",
47
+ help="Name of an existing module or a new module to create the resource in.",
48
+ ),
49
+ ] = None,
50
+ prefix: Annotated[
51
+ str | None,
52
+ typer.Option(
53
+ "--prefix",
54
+ "-p",
55
+ help="The prefix of the resource file to create without suffixes and extensions. "
56
+ "eg. --prefix=my_space. If not provided, a default prefix like 'my_<kind>' will be used.",
57
+ ),
58
+ ] = None,
59
+ verbose: Annotated[
60
+ bool,
61
+ typer.Option(
62
+ "--verbose",
63
+ "-v",
64
+ help="Turn on to get more verbose output when running the command",
65
+ ),
66
+ ] = False,
67
+ organization_dir: Annotated[
68
+ Path,
69
+ typer.Option(
70
+ "--organization-dir",
71
+ "-o",
72
+ help="Path to the organization directory",
73
+ ),
74
+ ] = CDF_TOML.cdf.default_organization_dir,
75
+ ) -> None:
76
+ """create resource YAMLs."""
77
+ cmd = ResourcesCommand()
78
+ cmd.run(
79
+ lambda: cmd.create(
80
+ organization_dir=organization_dir,
81
+ module_name=module,
82
+ kind=kind,
83
+ prefix=prefix,
84
+ verbose=verbose,
85
+ )
86
+ )
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
 
4
4
  from cognite_toolkit._cdf_tk.tk_warnings import ToolkitWarning
5
5
 
6
- from ._base import Builder, DefaultBuilder, get_loader
6
+ from ._base import Builder, DefaultBuilder, get_resource_crud
7
7
  from ._datamodels import DataModelBuilder
8
8
  from ._file import FileBuilder
9
9
  from ._function import FunctionBuilder
@@ -36,5 +36,5 @@ __all__ = [
36
36
  "StreamlitBuilder",
37
37
  "TransformationBuilder",
38
38
  "create_builder",
39
- "get_loader",
39
+ "get_resource_crud",
40
40
  ]
@@ -2,14 +2,12 @@ import difflib
2
2
  from abc import ABC, abstractmethod
3
3
  from collections.abc import Callable, Iterable, Sequence
4
4
  from pathlib import Path
5
- from typing import Any, ClassVar, cast
5
+ from typing import Any, ClassVar
6
6
 
7
7
  from cognite_toolkit._cdf_tk.constants import INDEX_PATTERN
8
8
  from cognite_toolkit._cdf_tk.cruds import (
9
- CRUDS_BY_FOLDER_NAME,
9
+ RESOURCE_CRUD_BY_FOLDER_NAME,
10
10
  GroupCRUD,
11
- RawDatabaseCRUD,
12
- RawTableCRUD,
13
11
  ResourceCRUD,
14
12
  )
15
13
  from cognite_toolkit._cdf_tk.data_classes import (
@@ -31,7 +29,6 @@ from cognite_toolkit._cdf_tk.tk_warnings.fileread import (
31
29
  )
32
30
  from cognite_toolkit._cdf_tk.utils import (
33
31
  humanize_collection,
34
- safe_read,
35
32
  )
36
33
 
37
34
 
@@ -103,34 +100,31 @@ class Builder(ABC):
103
100
  return destination_path
104
101
 
105
102
  def _get_loader(self, source_path: Path) -> tuple[None, ToolkitWarning] | tuple[type[ResourceCRUD], None]:
106
- return get_loader(source_path, self.resource_folder)
103
+ return get_resource_crud(source_path, self.resource_folder)
107
104
 
108
105
 
109
- def get_loader(
110
- source_path: Path,
111
- resource_folder: str,
112
- force_pattern: bool = False,
106
+ def get_resource_crud(
107
+ source_path: Path, resource_folder: str
113
108
  ) -> tuple[None, ToolkitWarning] | tuple[type[ResourceCRUD], None]:
114
- folder_loaders = CRUDS_BY_FOLDER_NAME.get(resource_folder, [])
115
- if not folder_loaders:
109
+ """Get the appropriate CRUD class for the given source file and resource folder."""
110
+ folder_cruds = RESOURCE_CRUD_BY_FOLDER_NAME.get(resource_folder, [])
111
+ if not folder_cruds:
116
112
  return None, ToolkitNotSupportedWarning(
117
113
  f"resource of type {resource_folder!r} in {source_path.name}.",
118
- details=f"Available resources are: {', '.join(CRUDS_BY_FOLDER_NAME.keys())}",
114
+ details=f"Available resources are: {humanize_collection(RESOURCE_CRUD_BY_FOLDER_NAME.keys())}",
119
115
  )
120
116
 
121
- loaders = [
122
- loader for loader in folder_loaders if loader.is_supported_file(source_path, force_pattern=force_pattern)
123
- ]
124
- if len(loaders) == 0:
117
+ crud_candidates = [crud_cls for crud_cls in folder_cruds if crud_cls.is_supported_file(source_path)]
118
+ if len(crud_candidates) == 0:
125
119
  suggestion: str | None = None
126
120
  if "." in source_path.stem:
127
121
  core, kind = source_path.stem.rsplit(".", 1)
128
- match = difflib.get_close_matches(kind, [loader.kind for loader in folder_loaders])
122
+ match = difflib.get_close_matches(kind, [crud_cls.kind for crud_cls in folder_cruds])
129
123
  if match:
130
124
  suggested_name = f"{core}.{match[0]}{source_path.suffix}"
131
125
  suggestion = f"Did you mean to call the file {suggested_name!r}?"
132
126
  else:
133
- kinds = [loader.kind for loader in folder_loaders]
127
+ kinds = [crud.kind for crud in folder_cruds]
134
128
  if len(kinds) == 1:
135
129
  suggestion = f"Did you mean to call the file '{source_path.stem}.{kinds[0]}{source_path.suffix}'?"
136
130
  else:
@@ -139,30 +133,22 @@ def get_loader(
139
133
  f"the resource type. Supported types are: {humanize_collection(kinds)}."
140
134
  )
141
135
  return None, UnknownResourceTypeWarning(source_path, suggestion)
142
- elif len(loaders) > 1 and all(loader.folder_name == "raw" for loader in loaders):
143
- # Raw files can be ambiguous, so we need to check the content.
144
- # If there is a tableName field, it is a table, otherwise it is a database.
145
- if any(
146
- line.strip().startswith("tableName:") or line.strip().startswith("- tableName:")
147
- for line in safe_read(source_path).splitlines()
148
- ):
149
- return RawTableCRUD, None
150
- else:
151
- return RawDatabaseCRUD, None
152
- elif len(loaders) > 1 and all(issubclass(loader, GroupCRUD) for loader in loaders):
153
- # There are two group loaders, one for resource scoped and one for all scoped.
136
+ elif len(crud_candidates) > 1 and all(issubclass(loader, GroupCRUD) for loader in crud_candidates):
137
+ # There are two group cruds, one for resource scoped and one for all scoped.
154
138
  return GroupCRUD, None
155
- elif len(loaders) > 1:
156
- names = humanize_collection(
157
- [f"'{source_path.stem}.{loader.kind}{source_path.suffix}'" for loader in loaders], bind_word="or"
158
- )
159
- raise AmbiguousResourceFileError(
160
- f"Ambiguous resource file {source_path.name} in {resource_folder} folder. "
161
- f"Unclear whether it is {humanize_collection([loader.kind for loader in loaders], bind_word='or')}."
162
- f"\nPlease name the file {names}."
163
- )
164
-
165
- return cast(type[ResourceCRUD], loaders[0]), None
139
+ elif len(crud_candidates) == 1:
140
+ return crud_candidates[0], None
141
+
142
+ # This is unreachable with our current ResourceCRUD classes. We have tests that is exhaustive over
143
+ # all ResourceCRUDs to ensure this.
144
+ names = humanize_collection(
145
+ [f"'{source_path.stem}.{loader.kind}{source_path.suffix}'" for loader in crud_candidates], bind_word="or"
146
+ )
147
+ raise AmbiguousResourceFileError(
148
+ f"Ambiguous resource file {source_path.name} in {resource_folder} folder. "
149
+ f"Unclear whether it is {humanize_collection([crud_cls.kind for crud_cls in crud_candidates], bind_word='or')}."
150
+ f"\nPlease name the file {names}."
151
+ )
166
152
 
167
153
 
168
154
  class DefaultBuilder(Builder):
@@ -17,6 +17,7 @@ from .init import InitCommand
17
17
  from .modules import ModulesCommand
18
18
  from .pull import PullCommand
19
19
  from .repo import RepoCommand
20
+ from .resources import ResourcesCommand
20
21
  from .run import RunFunctionCommand, RunTransformationCommand, RunWorkflowCommand
21
22
 
22
23
  __all__ = [
@@ -39,6 +40,7 @@ __all__ = [
39
40
  "PullCommand",
40
41
  "PurgeCommand",
41
42
  "RepoCommand",
43
+ "ResourcesCommand",
42
44
  "RunFunctionCommand",
43
45
  "RunTransformationCommand",
44
46
  "RunWorkflowCommand",
@@ -11,10 +11,8 @@ from packaging.version import Version
11
11
  from packaging.version import parse as parse_version
12
12
  from rich import print
13
13
 
14
- from cognite_toolkit._cdf_tk.builders import get_loader
15
14
  from cognite_toolkit._cdf_tk.cdf_toml import CDFToml
16
15
  from cognite_toolkit._cdf_tk.constants import DOCKER_IMAGE_NAME
17
- from cognite_toolkit._cdf_tk.data_classes import ModuleDirectories
18
16
  from cognite_toolkit._cdf_tk.utils import iterate_modules, read_yaml_file, safe_read, safe_write
19
17
  from cognite_toolkit._version import __version__
20
18
 
@@ -52,40 +50,6 @@ class ManualChange(Change):
52
50
  return ""
53
51
 
54
52
 
55
- class SetKindOnFile(AutomaticChange):
56
- """Adds the kind to the filename of all resource files.
57
-
58
- Before `your_file.yaml`:
59
- After `your_file.FileMetadata.yaml`:
60
- """
61
-
62
- deprecated_from = Version("0.4.0")
63
- has_file_changes = True
64
-
65
- def do(self) -> set[Path]:
66
- module_directories = ModuleDirectories.load(self._organization_dir)
67
- changed: set[Path] = set()
68
- for module in module_directories:
69
- for resource_folder, source_files in module.source_paths_by_resource_folder.items():
70
- for source_file in source_files:
71
- if source_file.suffix not in {".yaml", ".yml"}:
72
- continue
73
- loader, _ = get_loader(source_file, resource_folder, force_pattern=True)
74
- if loader is None:
75
- print(f"Could not find loader for {source_file}")
76
- continue
77
- if source_file.stem.casefold().endswith(loader.kind.casefold()):
78
- continue
79
- new_name = source_file.with_name(f"{source_file.stem}.{loader.kind}{source_file.suffix}")
80
- source_file.rename(new_name)
81
- changed.add(source_file)
82
- for suffix in [".sql", ".csv", ".parquet"]:
83
- if (adjacent_file := source_file.with_suffix(suffix)).exists():
84
- adjacent_file.rename(new_name.with_suffix(suffix))
85
- changed.add(adjacent_file)
86
-
87
- return changed
88
-
89
53
 
90
54
  class FixViewBasedLocationFilter(AutomaticChange):
91
55
  """The created view-based location filter has been fixed to be compatible with the CDF API.
@@ -0,0 +1,179 @@
1
+ import difflib
2
+ from pathlib import Path
3
+ from typing import cast
4
+
5
+ import questionary
6
+ import typer
7
+ from questionary import Choice
8
+ from rich import print
9
+
10
+ from cognite_toolkit._cdf_tk.commands._base import ToolkitCommand
11
+ from cognite_toolkit._cdf_tk.constants import MODULES
12
+ from cognite_toolkit._cdf_tk.cruds import RESOURCE_CRUD_LIST, ResourceCRUD
13
+ from cognite_toolkit._cdf_tk.data_classes import ModuleDirectories
14
+ from cognite_toolkit._cdf_tk.resource_classes import ToolkitResource
15
+ from cognite_toolkit._cdf_tk.utils.collection import humanize_collection
16
+ from cognite_toolkit._cdf_tk.utils.file import yaml_safe_dump
17
+
18
+
19
+ class ResourcesCommand(ToolkitCommand):
20
+ def __init__(self, print_warning: bool = True, skip_tracking: bool = False, silent: bool = False) -> None:
21
+ super().__init__(print_warning, skip_tracking, silent)
22
+
23
+ def _get_or_prompt_module_path(self, module: str | None, organization_dir: Path, verbose: bool) -> Path:
24
+ """
25
+ Check if the module exists in the organization directory and return the module path.
26
+ If module is not provided, ask the user to select or create a new module.
27
+ """
28
+ present_modules = ModuleDirectories.load(organization_dir, None)
29
+
30
+ if module:
31
+ for mod in present_modules:
32
+ if mod.name.casefold() == module.casefold():
33
+ return mod.dir
34
+
35
+ if questionary.confirm(f"{module} module not found. Do you want to create a new one?").ask():
36
+ return organization_dir / MODULES / module
37
+
38
+ if verbose:
39
+ print(f"[red]Aborting as {module} module not found...[/red]")
40
+ else:
41
+ print("[red]Aborting...[/red]")
42
+ raise typer.Exit()
43
+
44
+ choices = [Choice(title=mod.name, value=mod.dir) for mod in present_modules]
45
+ choices.append(Choice(title="<Create new module>", value="NEW"))
46
+
47
+ selected = questionary.select("Select a module:", choices=choices).ask()
48
+
49
+ if selected == "NEW":
50
+ new_module_name = questionary.text("Enter name for new module:").ask()
51
+ if not new_module_name:
52
+ print("[red]No module name provided. Aborting...[/red]")
53
+ raise typer.Exit()
54
+ return organization_dir / MODULES / new_module_name
55
+
56
+ if not selected:
57
+ print("[red]No module selected. Aborting...[/red]")
58
+ raise typer.Exit()
59
+
60
+ return cast(Path, selected)
61
+
62
+ def _resolve_kinds(self, kinds: list[str] | None) -> list[type[ResourceCRUD]]:
63
+ """
64
+ Resolve kinds from list of strings or do an interactive selection.
65
+ """
66
+ all_cruds = {crud.kind.casefold(): crud for crud in RESOURCE_CRUD_LIST}
67
+
68
+ if not kinds:
69
+ sorted_cruds = sorted(RESOURCE_CRUD_LIST, key=lambda x: x.kind)
70
+ choices = [Choice(title=crud.kind, value=crud) for crud in sorted_cruds]
71
+
72
+ selected = questionary.select("Select resource type:", choices=choices).ask()
73
+ if not selected:
74
+ print("[red]No resource type selected. Aborting...[/red]")
75
+ raise typer.Exit()
76
+ return [selected]
77
+
78
+ resolved_cruds = []
79
+ for kind in kinds:
80
+ kind_lower = kind.casefold()
81
+ if kind_lower in all_cruds:
82
+ resolved_cruds.append(all_cruds[kind_lower])
83
+ else:
84
+ matches = difflib.get_close_matches(kind_lower, all_cruds.keys())
85
+ if matches:
86
+ suggestion = all_cruds[matches[0]].kind
87
+ print(f"[red]Unknown resource type '{kind}'. Did you mean '{suggestion}'?[/red]")
88
+ else:
89
+ print(
90
+ f"[red]Unknown resource type '{kind}'. "
91
+ f"Available types: {humanize_collection(sorted([c.kind for c in RESOURCE_CRUD_LIST]))}[/red]"
92
+ )
93
+ raise typer.Exit()
94
+
95
+ return resolved_cruds
96
+
97
+ def _create_resource_yaml_skeleton(self, yaml_cls: type[ToolkitResource]) -> dict[str, str]:
98
+ """
99
+ Build YAML skeleton from a Pydantic model class using JSON schema for better type information.
100
+ """
101
+ yaml_skeleton: dict[str, str] = {}
102
+ for field_name, field in yaml_cls.model_fields.items():
103
+ name = field.alias or field_name
104
+ description = field.description or name
105
+ if field.is_required():
106
+ yaml_skeleton[name] = f"(Required) {description}"
107
+ else:
108
+ yaml_skeleton[name] = description
109
+
110
+ return yaml_skeleton
111
+
112
+ def _get_resource_yaml_content(self, resource_crud: type[ResourceCRUD]) -> str:
113
+ """
114
+ Creates a new resource in the specified module using the resource_crud.yaml_cls.
115
+ """
116
+ yaml_header = (
117
+ f"# API docs: {resource_crud.doc_url()}\n"
118
+ f"# YAML reference: https://docs.cognite.com/cdf/deploy/cdf_toolkit/references/resource_library"
119
+ )
120
+ yaml_skeleton = self._create_resource_yaml_skeleton(resource_crud.yaml_cls)
121
+ yaml_contents = yaml_safe_dump(yaml_skeleton)
122
+ return yaml_header + "\n\n" + yaml_contents
123
+
124
+ def _create_resource_yaml_file(
125
+ self,
126
+ resource_crud: type[ResourceCRUD],
127
+ module_path: Path,
128
+ prefix: str | None = None,
129
+ verbose: bool = False,
130
+ ) -> None:
131
+ """
132
+ Creates a new resource YAML file in the specified module using the resource_crud.yaml_cls.
133
+ """
134
+ resource_dir: Path = module_path / resource_crud.folder_name
135
+ if resource_crud.sub_folder_name:
136
+ resource_dir = resource_dir / resource_crud.sub_folder_name
137
+
138
+ if not resource_dir.exists():
139
+ resource_dir.mkdir(parents=True, exist_ok=True)
140
+
141
+ final_prefix = prefix if prefix is not None else f"my_{resource_crud.kind}"
142
+ file_name = f"{final_prefix}.{resource_crud.kind}.yaml"
143
+ file_path: Path = resource_dir / file_name
144
+
145
+ if file_path.exists() and not questionary.confirm(f"{file_path.name} file already exists. Overwrite?").ask():
146
+ print("[red]Skipping...[/red]")
147
+ return
148
+
149
+ yaml_content = self._get_resource_yaml_content(resource_crud)
150
+ file_path.write_text(yaml_content)
151
+ if verbose:
152
+ print(
153
+ f"[green]{resource_crud.kind} Resource YAML file created successfully at {file_path.as_posix()}[/green]"
154
+ )
155
+ else:
156
+ print(f"[green]Created {file_path.as_posix()}[/green]")
157
+
158
+ def create(
159
+ self,
160
+ organization_dir: Path,
161
+ module_name: str | None = None,
162
+ kind: list[str] | None = None,
163
+ prefix: str | None = None,
164
+ verbose: bool = False,
165
+ ) -> None:
166
+ """
167
+ create resource YAMLs.
168
+
169
+ Args:
170
+ organization_dir: The directory of the organization.
171
+ module_name: The name of the module.
172
+ kind: The kind(s) of resource to create.
173
+ prefix: The prefix for the resource file.
174
+ verbose: Whether to print verbose output.
175
+ """
176
+ module_path = self._get_or_prompt_module_path(module_name, organization_dir, verbose)
177
+ resource_cruds = self._resolve_kinds(kind)
178
+ for crud in resource_cruds:
179
+ self._create_resource_yaml_file(crud, module_path, prefix, verbose)
@@ -61,7 +61,7 @@ ROOT_PATH = Path(__file__).parent.parent
61
61
  COGNITE_MODULES_PATH = ROOT_PATH / COGNITE_MODULES
62
62
  MODULES_PATH = ROOT_PATH / MODULES
63
63
  RESOURCES_PATH = ROOT_PATH / RESOURCES
64
- SUPPORT_MODULE_UPGRADE_FROM_VERSION = "0.2.0"
64
+ SUPPORT_MODULE_UPGRADE_FROM_VERSION = "0.4.0"
65
65
  # This is used in the build directory to keep track of order and flatten the
66
66
  # module directory structure with accounting for duplicated names.
67
67
  INDEX_PATTERN = re.compile("^[0-9]+\\.")
@@ -104,6 +104,11 @@ del _loader # cleanup module namespace
104
104
 
105
105
  # For backwards compatibility
106
106
  CRUDS_BY_FOLDER_NAME["data_models"] = CRUDS_BY_FOLDER_NAME["data_modeling"] # Todo: Remove in v1.0
107
+ RESOURCE_CRUD_BY_FOLDER_NAME = {
108
+ folder_name: cruds
109
+ for folder_name, loaders in CRUDS_BY_FOLDER_NAME.items()
110
+ if (cruds := [crud for crud in loaders if issubclass(crud, ResourceCRUD)])
111
+ }
107
112
 
108
113
  CRUD_LIST = list(itertools.chain.from_iterable(CRUDS_BY_FOLDER_NAME.values()))
109
114
  RESOURCE_CRUD_LIST = [loader for loader in CRUD_LIST if issubclass(loader, ResourceCRUD)]
@@ -152,6 +157,7 @@ __all__ = [
152
157
  "CRUDS_BY_FOLDER_NAME",
153
158
  "CRUD_LIST",
154
159
  "KINDS_BY_FOLDER_NAME",
160
+ "RESOURCE_CRUD_BY_FOLDER_NAME",
155
161
  "RESOURCE_CRUD_CONTAINER_LIST",
156
162
  "RESOURCE_CRUD_LIST",
157
163
  "RESOURCE_DATA_CRUD_LIST",
@@ -1,4 +1,3 @@
1
- import re
2
1
  import sys
3
2
  from abc import ABC, abstractmethod
4
3
  from collections.abc import Hashable, Iterable, Sequence, Set, Sized
@@ -31,9 +30,6 @@ else:
31
30
  from typing_extensions import Self
32
31
 
33
32
 
34
- _COMPILED_PATTERN: dict[str, re.Pattern] = {}
35
-
36
-
37
33
  class Loader(ABC):
38
34
  """This is the base class for all loaders
39
35
 
@@ -58,6 +54,7 @@ class Loader(ABC):
58
54
  exclude_filetypes: frozenset[str] = frozenset()
59
55
  _doc_base_url: str = "https://api-docs.cognite.com/20230101/tag/"
60
56
  _doc_url: str = ""
57
+ sub_folder_name: str | None = None
61
58
 
62
59
  def __init__(self, client: ToolkitClient, build_dir: Path | None, console: Console | None = None) -> None:
63
60
  self.client = client
@@ -119,14 +116,11 @@ class Loader(ABC):
119
116
  return any(cls.is_supported_file(file) for file in directory.glob("**/*"))
120
117
 
121
118
  @classmethod
122
- def is_supported_file(cls, file: Path, force_pattern: bool = False) -> bool:
119
+ def is_supported_file(cls, file: Path) -> bool:
123
120
  """Check if hte file is supported by this loader.
124
121
 
125
122
  Args:
126
123
  file: The filepath to check.
127
- force_pattern: If True, the filename pattern is used to determine if the file is supported. If False, the
128
- file extension is used to determine if the file is supported (given that the
129
- RequireKind flag is enabled).
130
124
 
131
125
  Returns:
132
126
  bool: True if the file is supported, False otherwise.
@@ -136,14 +130,7 @@ class Loader(ABC):
136
130
  return False
137
131
  if cls.exclude_filetypes and file.suffix[1:] in cls.exclude_filetypes:
138
132
  return False
139
- if force_pattern is False and not issubclass(cls, DataCRUD):
140
- return file.stem.casefold().endswith(cls.kind.casefold())
141
- else:
142
- if cls.filename_pattern:
143
- if cls.filename_pattern not in _COMPILED_PATTERN:
144
- _COMPILED_PATTERN[cls.filename_pattern] = re.compile(cls.filename_pattern, re.IGNORECASE)
145
- return _COMPILED_PATTERN[cls.filename_pattern].match(file.stem) is not None
146
- return True
133
+ return file.stem.casefold().endswith(cls.kind.casefold())
147
134
 
148
135
 
149
136
  T_Loader = TypeVar("T_Loader", bound=Loader)
@@ -262,6 +262,7 @@ class ContainerCRUD(ResourceContainerCRUD[ContainerId, ContainerApply, Container
262
262
  dependencies = frozenset({SpaceCRUD})
263
263
  yaml_cls = ContainerYAML
264
264
  _doc_url = "Containers/operation/ApplyContainers"
265
+ sub_folder_name = "containers"
265
266
 
266
267
  def __init__(
267
268
  self,
@@ -526,6 +527,7 @@ class ViewCRUD(ResourceCRUD[ViewId, ViewApply, View, ViewApplyList, ViewList]):
526
527
  dependencies = frozenset({SpaceCRUD, ContainerCRUD})
527
528
  yaml_cls = ViewYAML
528
529
  _doc_url = "Views/operation/ApplyViews"
530
+ sub_folder_name = "views"
529
531
 
530
532
  def __init__(
531
533
  self,
@@ -1001,6 +1003,7 @@ class NodeCRUD(ResourceContainerCRUD[NodeId, NodeApply, Node, NodeApplyList, Nod
1001
1003
  yaml_cls = NodeYAML
1002
1004
  dependencies = frozenset({SpaceCRUD, ViewCRUD, ContainerCRUD})
1003
1005
  _doc_url = "Instances/operation/applyNodeAndEdges"
1006
+ sub_folder_name = "nodes"
1004
1007
 
1005
1008
  def __init__(
1006
1009
  self,
@@ -49,6 +49,10 @@ class Flags(Enum):
49
49
  visible=False,
50
50
  description="Enables features planned for Cognite Toolkit version 0.8.0",
51
51
  )
52
+ CREATE = FlagMetadata(
53
+ visible=True,
54
+ description="Enables the support for the resources create command under dev plugin",
55
+ )
52
56
 
53
57
  def is_enabled(self) -> bool:
54
58
  return FeatureFlag.is_enabled(self)
@@ -12,7 +12,7 @@ jobs:
12
12
  environment: dev
13
13
  name: Deploy
14
14
  container:
15
- image: cognite/toolkit:0.7.1
15
+ image: cognite/toolkit:0.7.3
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.1
13
+ image: cognite/toolkit:0.7.3
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.1"
7
+ version = "0.7.3"
8
8
 
9
9
 
10
10
  [plugins]
@@ -1 +1 @@
1
- __version__ = "0.7.1"
1
+ __version__ = "0.7.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cognite_toolkit
3
- Version: 0.7.1
3
+ Version: 0.7.3
4
4
  Summary: Official Cognite Data Fusion tool for project templates and configuration deployment
5
5
  Project-URL: Homepage, https://docs.cognite.com/cdf/deploy/cdf_toolkit/
6
6
  Project-URL: Changelog, https://github.com/cognitedata/toolkit/releases
@@ -1,11 +1,11 @@
1
1
  cognite_toolkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  cognite_toolkit/_cdf.py,sha256=PzDig6dgbDX5VL88AeijQuTeYb2SS_yvenw9gr4fnxY,5794
3
- cognite_toolkit/_version.py,sha256=2KJZDSMOG7KS82AxYOrZ4ZihYxX0wjfUjDsIZh3L024,22
3
+ cognite_toolkit/_version.py,sha256=G0rwkDLSytonr7idr8ma7KaTUnRCn3-Ripum70RSeh0,22
4
4
  cognite_toolkit/_cdf_tk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  cognite_toolkit/_cdf_tk/cdf_toml.py,sha256=VSWV9h44HusWIaKpWgjrOMrc3hDoPTTXBXlp6-NOrIM,9079
6
- cognite_toolkit/_cdf_tk/constants.py,sha256=3UpFZ60xXdqgPqqpqCITQuAvjnVExH_IlbASxoelvu8,7236
6
+ cognite_toolkit/_cdf_tk/constants.py,sha256=TplKm2J9pGRHq7nAnLI0caTMHetS04OIz3hfq-jvGzo,7236
7
7
  cognite_toolkit/_cdf_tk/exceptions.py,sha256=xG0jMwi5A20nvPvyo6sCyz_cyKycynPyIzpYiGR4gcU,6064
8
- cognite_toolkit/_cdf_tk/feature_flags.py,sha256=4tMcBX_5-4i65je0kZfzpfDlIfcbD-2XHMtkd1g1iFQ,1758
8
+ cognite_toolkit/_cdf_tk/feature_flags.py,sha256=h9Vhw-u1OQIjckAe0Ec2qug3Z-FRn_aJGglWu2u2BEc,1906
9
9
  cognite_toolkit/_cdf_tk/hints.py,sha256=UI1ymi2T5wCcYOpEbKbVaDnlyFReFy8TDtMVt-5E1h8,6493
10
10
  cognite_toolkit/_cdf_tk/plugins.py,sha256=0V14rceAWLZQF8iWdyL5QmK7xB796YaDEtb9RIj5AOc,836
11
11
  cognite_toolkit/_cdf_tk/protocols.py,sha256=Lc8XnBfmDZN6dwmSopmK7cFE9a9jZ2zdUryEeCXn27I,3052
@@ -15,7 +15,7 @@ cognite_toolkit/_cdf_tk/apps/__init__.py,sha256=KKmhbpvPKTwqQS2g_XqAC2yvtPsvdl8w
15
15
  cognite_toolkit/_cdf_tk/apps/_auth_app.py,sha256=ER7uYb3ViwsHMXiQEZpyhwU6TIjKaB9aEy32VI4MPpg,3397
16
16
  cognite_toolkit/_cdf_tk/apps/_core_app.py,sha256=YK0MOK7Tv3cDSe5_6o9GtM5n_6sE7I0Wm-Se4eJnyNM,13744
17
17
  cognite_toolkit/_cdf_tk/apps/_data_app.py,sha256=LeplXlxXtyIymRPgbatQrRFodU4VZBFxI0bqDutLSbg,806
18
- cognite_toolkit/_cdf_tk/apps/_dev_app.py,sha256=q8DBr4BAK33AwsHW3gAWZWSjSaQRuCisqPbsBjmYSxk,589
18
+ cognite_toolkit/_cdf_tk/apps/_dev_app.py,sha256=FaY67PFdKwdiMKgJbTcjHT1X2Xfbog2PKL6T-kcawyc,2818
19
19
  cognite_toolkit/_cdf_tk/apps/_download_app.py,sha256=g-VA51KI91wziVuO3w305rmr33xIb0ghYTtW06LhNz8,31994
20
20
  cognite_toolkit/_cdf_tk/apps/_dump_app.py,sha256=EPq6fWSaScj9ncKfRY253rRJ37er47PIM60IFgkQK_k,37127
21
21
  cognite_toolkit/_cdf_tk/apps/_landing_app.py,sha256=YR9z83OY7PhhgBVC5gmRLgo9iTXoGoZfRhOU3gd_r2o,888
@@ -26,8 +26,8 @@ cognite_toolkit/_cdf_tk/apps/_purge.py,sha256=KYI1wFy7yHFEM1qJnTYc4_8E2FVGu4QhPs
26
26
  cognite_toolkit/_cdf_tk/apps/_repo_app.py,sha256=jOf_s7oUWJqnRyz89JFiSzT2l8GlyQ7wqidHUQavGo0,1455
27
27
  cognite_toolkit/_cdf_tk/apps/_run.py,sha256=eXua4n0hW4qRMkzaxR0PiZh-JFLf8gnWw1_5O-0-vm0,8987
28
28
  cognite_toolkit/_cdf_tk/apps/_upload_app.py,sha256=1nF0-7oCAXLlmTGyUOKTmxkZqvA0Xo6U6lqk-SqKmCc,4227
29
- cognite_toolkit/_cdf_tk/builders/__init__.py,sha256=Y-AJ4VrcUCRquGNEgDCiwmWW3iGWnJl2DrL17gsUIBg,1172
30
- cognite_toolkit/_cdf_tk/builders/_base.py,sha256=N32Y17hfepp45rMW_o4qeUY9nsysmtcxpX4GkF-tsio,7829
29
+ cognite_toolkit/_cdf_tk/builders/__init__.py,sha256=8073Ijf621XiAtiwup-rLfrbYd403H8lo9e65_iP1JA,1186
30
+ cognite_toolkit/_cdf_tk/builders/_base.py,sha256=_4Gd6GtuAmnPvl3IjvuAUfuSQtEVJekUaqzk3IH-tIY,7462
31
31
  cognite_toolkit/_cdf_tk/builders/_datamodels.py,sha256=hN3fWQAktrWdaGAItZ0tHpBXqJDu0JfH6t7pO7EIl2Q,3541
32
32
  cognite_toolkit/_cdf_tk/builders/_file.py,sha256=ZRTlyb-MnmJhBhfPeQ9h7gM2T4nllyjonwYBj31cv1Q,3847
33
33
  cognite_toolkit/_cdf_tk/builders/_function.py,sha256=ID5hGCjT1i0MreswLXgUqOYh7sGuBrwiyjpuzYV7Bm0,5246
@@ -100,9 +100,9 @@ cognite_toolkit/_cdf_tk/client/data_classes/streams.py,sha256=DHSDrBax81fUzneIik
100
100
  cognite_toolkit/_cdf_tk/client/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
101
  cognite_toolkit/_cdf_tk/client/utils/_concurrency.py,sha256=3GtQbKDaosyKHEt-KzxKK9Yie4TvZPdoou2vUk6dUa8,2298
102
102
  cognite_toolkit/_cdf_tk/client/utils/_http_client.py,sha256=oXNKrIaizG4WiSAhL_kSCHAuL4aaaEhCU4pOJGxh6Xs,483
103
- cognite_toolkit/_cdf_tk/commands/__init__.py,sha256=gHA3yWI3UacMD79ZpCyh8MjA1fzuEg5pxZGts2VsXLs,1356
103
+ cognite_toolkit/_cdf_tk/commands/__init__.py,sha256=xLaEOLVZ93MVkWzbTGwYhe-negSdBjnPnCBp0jil2d8,1420
104
104
  cognite_toolkit/_cdf_tk/commands/_base.py,sha256=1gl8Y-yqfedRMfdbwM3iPTIUIZriX1UvC1deLsJSJwM,2667
105
- cognite_toolkit/_cdf_tk/commands/_changes.py,sha256=fvw2C5N2BVf-7MUpiB1FkDVCJ0xIy4lfDyFgpWaLPeo,24651
105
+ cognite_toolkit/_cdf_tk/commands/_changes.py,sha256=sU0KaTtPVSJgAZcaZ1Tkcajj36pmhd13kh7V8QbIED8,22987
106
106
  cognite_toolkit/_cdf_tk/commands/_cli_commands.py,sha256=TK6U_rm6VZT_V941kTyHMoulWgJzbDC8YIIQDPJ5x3w,1011
107
107
  cognite_toolkit/_cdf_tk/commands/_download.py,sha256=OBKPM_HGGA1i32th1SAgkQM_81CUFvm39kGqBuOeeTs,6816
108
108
  cognite_toolkit/_cdf_tk/commands/_profile.py,sha256=_4iX3AHAI6eLmRVUlWXCSvVHx1BZW2yDr_i2i9ECg6U,43120
@@ -122,6 +122,7 @@ cognite_toolkit/_cdf_tk/commands/init.py,sha256=pcxFhZheXm3FPU1pkeh10M0WXPg7EcLF
122
122
  cognite_toolkit/_cdf_tk/commands/modules.py,sha256=91Fov16fEIVk-3ZmBd3MlibbbzRuYLjUY9CUnudV4w0,40976
123
123
  cognite_toolkit/_cdf_tk/commands/pull.py,sha256=ktPXHW3f0HpmqCxeMhH8Ac52dAuQqAum3VBmLWJwQSM,39246
124
124
  cognite_toolkit/_cdf_tk/commands/repo.py,sha256=MNy8MWphTklIZHvQOROCweq8_SYxGv6BaqnLpkFFnuk,3845
125
+ cognite_toolkit/_cdf_tk/commands/resources.py,sha256=NeHVA1b1TMsP-2wgd5u1vif_N6nln7ePxZ0BXypwt-k,7377
125
126
  cognite_toolkit/_cdf_tk/commands/run.py,sha256=JyX9jLEQej9eRrHVCCNlw4GuF80qETSol3-T5CCofgw,37331
126
127
  cognite_toolkit/_cdf_tk/commands/_migrate/__init__.py,sha256=i5ldcTah59K0E4fH5gHTV0GRvtDCEvVses9WQzn9Lno,226
127
128
  cognite_toolkit/_cdf_tk/commands/_migrate/canvas.py,sha256=R-z0yfOFcJZj-zRLhN-7z_-SLxqzSmONMgrbzNF9dGs,8843
@@ -136,8 +137,8 @@ cognite_toolkit/_cdf_tk/commands/_migrate/issues.py,sha256=L2-kODPavEwcuhte7EXAN
136
137
  cognite_toolkit/_cdf_tk/commands/_migrate/migration_io.py,sha256=wrdBH5P6NgiZQSYLR0iJ3ZvqfQ5fY-_Ne2yKv9E1g4o,16277
137
138
  cognite_toolkit/_cdf_tk/commands/_migrate/prepare.py,sha256=RfqaNoso5CyBwc-p6ckwcYqBfZXKhdJgdGIyd0TATaI,2635
138
139
  cognite_toolkit/_cdf_tk/commands/_migrate/selectors.py,sha256=N1H_-rBpPUD6pbrlcofn1uEK1bA694EUXEe1zIXeqyo,2489
139
- cognite_toolkit/_cdf_tk/cruds/__init__.py,sha256=n8_4bkxXjXKUaYgrcP5NxomfWf9nwAU6KlpVrHw2ZAw,6317
140
- cognite_toolkit/_cdf_tk/cruds/_base_cruds.py,sha256=3ExMHowKi9jV-EwfKL1jfeSfQLM59z8jZAGq_wJb5Jc,20088
140
+ cognite_toolkit/_cdf_tk/cruds/__init__.py,sha256=Qxb_Vjv6maJePvO7hunUAtUqXIXW3vi1-hLoWQVs__4,6551
141
+ cognite_toolkit/_cdf_tk/cruds/_base_cruds.py,sha256=DmdgY5rSKDZuuFvoBEE7FG0X-7fY5qWwjskzFqwA6qg,19371
141
142
  cognite_toolkit/_cdf_tk/cruds/_data_cruds.py,sha256=PacTXdXaw0sf38tM6_DgNXVYdZXf_J90ZUeLk5v2VRg,9071
142
143
  cognite_toolkit/_cdf_tk/cruds/_worker.py,sha256=XdLm6DMFln9DqDgEbeqzepw9WRSXx7WdChbDtmOc89Q,9358
143
144
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/__init__.py,sha256=gSbQHXTgbkguEc2kFckgt13JVO5GXol_JXT2LW4T5o0,2879
@@ -146,7 +147,7 @@ cognite_toolkit/_cdf_tk/cruds/_resource_cruds/auth.py,sha256=iGG2_btpEqip3o6OKpc
146
147
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/classic.py,sha256=7RdiWvh6MLI1lLmt3gcqDQj61xbwREhsvoyjFuJn2F0,26402
147
148
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/configuration.py,sha256=KrL7bj8q5q18mGB2V-NDkW5U5nfseZOyorXiUbp2uLw,6100
148
149
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/data_organization.py,sha256=iXn9iAtwA8mhH-7j9GF-MlLomTcaw3GhEbFY28Wx0iA,9927
149
- cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py,sha256=kX5psba0lUlvKKabstJWxM8eZsHDD7rTR_FOkHBukBE,65837
150
+ cognite_toolkit/_cdf_tk/cruds/_resource_cruds/datamodel.py,sha256=46bhUnD7162SsVTZkAlnIBs3D7_GU1p-eK9R7Z7Y9cc,65932
150
151
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/extraction_pipeline.py,sha256=zv36HPO9goRmU3NM_i1wOvWQEdsgpQTI4bcAl-eis1g,18232
151
152
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/fieldops.py,sha256=SnQMbxiZ3SSYkTLXQ_vIu2HVf_WyD1jplNRJuoeOUfA,16723
152
153
  cognite_toolkit/_cdf_tk/cruds/_resource_cruds/file.py,sha256=F3n2FOWAPder4z3OTYs81VB-6C6r3oUzJsHvigdhaD0,15500
@@ -300,13 +301,13 @@ cognite_toolkit/_repo_files/.gitignore,sha256=ip9kf9tcC5OguF4YF4JFEApnKYw0nG0vPi
300
301
  cognite_toolkit/_repo_files/AzureDevOps/.devops/README.md,sha256=OLA0D7yCX2tACpzvkA0IfkgQ4_swSd-OlJ1tYcTBpsA,240
301
302
  cognite_toolkit/_repo_files/AzureDevOps/.devops/deploy-pipeline.yml,sha256=brULcs8joAeBC_w_aoWjDDUHs3JheLMIR9ajPUK96nc,693
302
303
  cognite_toolkit/_repo_files/AzureDevOps/.devops/dry-run-pipeline.yml,sha256=OBFDhFWK1mlT4Dc6mDUE2Es834l8sAlYG50-5RxRtHk,723
303
- cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml,sha256=PpKK3jflxLwNjCldzTWYHhg2hQ0Omi1BonQrnjWmgXo,666
304
- cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml,sha256=ASOi_Om6-yPgKXo8NQE4xSju0f7c0BCGPVjFlNKTyeg,2429
305
- cognite_toolkit/_resources/cdf.toml,sha256=A4-O_130gdFgF96eY8qDobuPNcGvhb2LPE6Rbs8PnkI,474
304
+ cognite_toolkit/_repo_files/GitHub/.github/workflows/deploy.yaml,sha256=3fv8l7iPS_BeEQ79QIXET7O6XEvukagJRzK70ALmWCw,666
305
+ cognite_toolkit/_repo_files/GitHub/.github/workflows/dry-run.yaml,sha256=kf9xrljnG0rMso3aDNRaYFv9YrjR249rZ_PjdcqIj8E,2429
306
+ cognite_toolkit/_resources/cdf.toml,sha256=k4WAcvwYM778k6Odf2dvjFVAQKOtTd0ltYdGSHnsFho,474
306
307
  cognite_toolkit/demo/__init__.py,sha256=-m1JoUiwRhNCL18eJ6t7fZOL7RPfowhCuqhYFtLgrss,72
307
308
  cognite_toolkit/demo/_base.py,sha256=6xKBUQpXZXGQ3fJ5f7nj7oT0s2n7OTAGIa17ZlKHZ5U,8052
308
- cognite_toolkit-0.7.1.dist-info/METADATA,sha256=n8jC9M1BlwW_IosE5ybERRNMUPxfyKTxvN4QDL7PltM,4500
309
- cognite_toolkit-0.7.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
310
- cognite_toolkit-0.7.1.dist-info/entry_points.txt,sha256=JlR7MH1_UMogC3QOyN4-1l36VbrCX9xUdQoHGkuJ6-4,83
311
- cognite_toolkit-0.7.1.dist-info/licenses/LICENSE,sha256=CW0DRcx5tL-pCxLEN7ts2S9g2sLRAsWgHVEX4SN9_Mc,752
312
- cognite_toolkit-0.7.1.dist-info/RECORD,,
309
+ cognite_toolkit-0.7.3.dist-info/METADATA,sha256=zxny_a9c5UR8VeS9f5hLzHn8xpbxqBxv-_rtVy6Bkbg,4500
310
+ cognite_toolkit-0.7.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
311
+ cognite_toolkit-0.7.3.dist-info/entry_points.txt,sha256=JlR7MH1_UMogC3QOyN4-1l36VbrCX9xUdQoHGkuJ6-4,83
312
+ cognite_toolkit-0.7.3.dist-info/licenses/LICENSE,sha256=CW0DRcx5tL-pCxLEN7ts2S9g2sLRAsWgHVEX4SN9_Mc,752
313
+ cognite_toolkit-0.7.3.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any