splight-cli 4.14.0__tar.gz → 5.0.0__tar.gz

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.
Files changed (84) hide show
  1. {splight_cli-4.14.0 → splight_cli-5.0.0}/PKG-INFO +4 -3
  2. {splight_cli-4.14.0 → splight_cli-5.0.0}/pyproject.toml +4 -3
  3. splight_cli-5.0.0/splight_cli/hub/component/component_builder.py +109 -0
  4. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/hub/component/exceptions.py +4 -0
  5. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/hub/component/hub_manager.py +5 -10
  6. splight_cli-5.0.0/splight_cli/hub/component/resources/Dockerfile +21 -0
  7. splight_cli-5.0.0/splight_cli/hub/component/resources/installer.py +80 -0
  8. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/hub/solution/__init__.py +0 -3
  9. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/hub/solution/solution_manager.py +6 -6
  10. {splight_cli-4.14.0 → splight_cli-5.0.0}/README.md +0 -0
  11. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/__init__.py +0 -0
  12. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/cli.py +0 -0
  13. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/__init__.py +0 -0
  14. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/component.py +0 -0
  15. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/exceptions.py +0 -0
  16. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/loaders.py +0 -0
  17. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/templates/.splightignore +0 -0
  18. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/templates/Initialization +0 -0
  19. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/templates/README.md +0 -0
  20. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/templates/auto_readme.md +0 -0
  21. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/templates/main.py +0 -0
  22. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/templates/spec.json +0 -0
  23. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/templates/tests.py +0 -0
  24. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/tests/__init__.py +0 -0
  25. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/tests/test_component_manager.py +0 -0
  26. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/component/utils.py +0 -0
  27. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/config/__init__.py +0 -0
  28. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/constants.py +0 -0
  29. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/context/__init__.py +0 -0
  30. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/context/context.py +0 -0
  31. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/context/workspace.py +0 -0
  32. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/__init__.py +0 -0
  33. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/alert/__init__.py +0 -0
  34. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/asset/__init__.py +0 -0
  35. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/attribute/__init__.py +0 -0
  36. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/component/__init__.py +0 -0
  37. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/datalake/__init__.py +0 -0
  38. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/file/__init__.py +0 -0
  39. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/manager/__init__.py +0 -0
  40. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/manager/exceptions.py +0 -0
  41. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/manager/manager.py +0 -0
  42. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/manager/tests/test_datalake_manager.py +0 -0
  43. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/manager/tests/test_resource_manager.py +0 -0
  44. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/engine/secret/__init__.py +0 -0
  45. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/hub/__init__.py +0 -0
  46. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/hub/component/__init__.py +0 -0
  47. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/hub/component/tests/test_hub_manager.py +0 -0
  48. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/hub/solution/constants.py +0 -0
  49. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/hub/solution/exceptions.py +0 -0
  50. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/settings.py +0 -0
  51. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/__init__.py +0 -0
  52. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/dict.py +0 -0
  53. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/parser.py +0 -0
  54. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/__init__.py +0 -0
  55. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/diff.py +0 -0
  56. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/logger.py +0 -0
  57. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/manager.py +0 -0
  58. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/__init__.py +0 -0
  59. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/alert.py +0 -0
  60. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/asset.py +0 -0
  61. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/attribute.py +0 -0
  62. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/base.py +0 -0
  63. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/component.py +0 -0
  64. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/component_object.py +0 -0
  65. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/file.py +0 -0
  66. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/function.py +0 -0
  67. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/metadata.py +0 -0
  68. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/routine.py +0 -0
  69. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/resource/models/secret.py +0 -0
  70. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/solution/state.py +0 -0
  71. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/tests/test_component/Initialization +0 -0
  72. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/tests/test_component/README.md +0 -0
  73. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/tests/test_component/main.py +0 -0
  74. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/tests/test_component/spec.json +0 -0
  75. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/tests/test_component/tests.py +0 -0
  76. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/utils/__init__.py +0 -0
  77. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/utils/input.py +0 -0
  78. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/utils/json.py +0 -0
  79. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/utils/loader.py +0 -0
  80. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/utils/pprint.py +0 -0
  81. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/utils/template.py +0 -0
  82. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/utils/yaml.py +0 -0
  83. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/version.py +0 -0
  84. {splight_cli-4.14.0 → splight_cli-5.0.0}/splight_cli/workspace/__init__.py +0 -0
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: splight-cli
3
- Version: 4.14.0
3
+ Version: 5.0.0
4
4
  Summary: Splight Command Line Interface
5
5
  Author: Splight Dev
6
6
  Author-email: dev@splight-ae.com
7
- Requires-Python: >=3.8.1,<4
7
+ Requires-Python: >=3.9,<4
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3.9
10
10
  Classifier: Programming Language :: Python :: 3.10
@@ -15,13 +15,14 @@ Requires-Dist: case-converter (==1.1.0)
15
15
  Requires-Dist: click (==8.0.4)
16
16
  Requires-Dist: click-default-group (==1.2.2)
17
17
  Requires-Dist: colorama (==0.4.4)
18
+ Requires-Dist: docker (==7.1.0)
18
19
  Requires-Dist: packaging (==23.0)
19
20
  Requires-Dist: pathspec (==0.11.1)
20
21
  Requires-Dist: py7zr (==0.20.8)
21
22
  Requires-Dist: requests (==2.31.0)
22
23
  Requires-Dist: rich (==13.0.1)
23
24
  Requires-Dist: setuptools (==60.9.3)
24
- Requires-Dist: splight-lib (>=5.8.0)
25
+ Requires-Dist: splight-lib (==5.9.0)
25
26
  Requires-Dist: toposort (>=1.10,<2.0)
26
27
  Requires-Dist: typer (==0.9.0)
27
28
  Description-Content-Type: text/markdown
@@ -1,17 +1,17 @@
1
1
  [tool.poetry]
2
2
  name = "splight-cli"
3
- version = "4.14.0"
3
+ version = "5.0.0"
4
4
  description = "Splight Command Line Interface"
5
5
  authors = ["Splight Dev <dev@splight-ae.com>"]
6
6
  readme = "README.md"
7
7
 
8
8
  [tool.poetry.dependencies]
9
- python = ">=3.8.1,<4"
9
+ python = ">=3.9,<4"
10
10
  case-converter = "1.1.0"
11
11
  click = "8.0.4"
12
12
  click-default-group = "1.2.2"
13
13
  setuptools = "60.9.3"
14
- splight-lib = ">=5.8.0"
14
+ splight-lib = "5.9.0"
15
15
  py7zr = "0.20.8"
16
16
  typer = "0.9.0"
17
17
  colorama = "0.4.4"
@@ -21,6 +21,7 @@ rich = "13.0.1"
21
21
  pathspec = "0.11.1"
22
22
  packaging = "23.0"
23
23
  toposort = "^1.10"
24
+ docker = "7.1.0"
24
25
 
25
26
  [tool.poetry.group.dev.dependencies]
26
27
  black = "23.3.0"
@@ -0,0 +1,109 @@
1
+ import gzip
2
+ import os
3
+ import re
4
+ import shutil
5
+ import sys
6
+
7
+ import docker
8
+
9
+ from splight_cli.hub.component.exceptions import BuildError
10
+
11
+
12
+ class ComponentBuilder:
13
+ _RESOURCES_PATH = "resources"
14
+ _RESOURCES = [
15
+ "Dockerfile",
16
+ "installer.py",
17
+ ]
18
+
19
+ def __init__(self, component_spec: dict, component_path: str):
20
+ self._base_path = os.path.dirname(__file__)
21
+ self._component_name = component_spec["name"]
22
+ self._component_version = component_spec["version"]
23
+ self._spl_pkg = (
24
+ "splight-lib"
25
+ if component_spec["splight_lib_version"]
26
+ else "splight-cli"
27
+ )
28
+ self._spl_pkg_version = (
29
+ component_spec["splight_lib_version"]
30
+ if component_spec["splight_lib_version"]
31
+ else component_spec["splight_cli_version"]
32
+ )
33
+ self._component_path = component_path
34
+ self._docker_client = docker.from_env()
35
+
36
+ def build(self) -> str:
37
+ original_path = os.getcwd()
38
+ self._copy_resources()
39
+ os.chdir(self._component_path)
40
+ image_file = self._build_component()
41
+ self._clean_up()
42
+ os.chdir(original_path)
43
+ return image_file
44
+
45
+ def _build_component(self) -> str:
46
+ full_name = f"{self._component_name}-{self._component_version}"
47
+ tag = f"component:{full_name}"
48
+ streamer = self._build_component_image(tag)
49
+ for chunk in streamer:
50
+ try:
51
+ log = self._parse_chunk(chunk)
52
+ except BuildError as exc:
53
+ sys.stdout.write(exc)
54
+ sys.stdout.flush()
55
+ raise exc
56
+ if log:
57
+ sys.stdout.write(f"{log}\n")
58
+ sys.stdout.flush()
59
+
60
+ if "stream" in chunk:
61
+ match = re.search(
62
+ r"(^Successfully built |sha256:)([0-9a-f]+)$",
63
+ chunk["stream"],
64
+ )
65
+ if match:
66
+ image_id = match.group(2)
67
+ image = self._docker_client.images.get(image_id)
68
+ file_name = f"{full_name}.tgz"
69
+ with gzip.open(file_name, "wb") as image_file:
70
+ for chunk in image.save(named=True):
71
+ image_file.write(chunk)
72
+ return file_name
73
+
74
+ def _build_component_image(self, tag: str):
75
+ client = self._docker_client.api
76
+ streamer = client.build(
77
+ path=".",
78
+ tag=tag,
79
+ dockerfile="Dockerfile",
80
+ rm=True,
81
+ pull=True,
82
+ quiet=False,
83
+ buildargs={
84
+ "COMPONENT_NAME": self._component_name,
85
+ "COMPONENT_VERSION": self._component_version,
86
+ "SPL_PACKAGE": self._spl_pkg,
87
+ "SPL_PACKAGE_VERSION": self._spl_pkg_version,
88
+ },
89
+ decode=True,
90
+ )
91
+ return streamer
92
+
93
+ def _copy_resources(self):
94
+ for resource in self._RESOURCES:
95
+ resource_path = os.path.join(
96
+ self._base_path, self._RESOURCES_PATH, resource
97
+ )
98
+ shutil.copy(resource_path, self._component_path)
99
+
100
+ def _clean_up(self):
101
+ for resource in self._RESOURCES:
102
+ os.remove(resource)
103
+
104
+ def _parse_chunk(self, chunk: dict) -> str:
105
+ if "errorDetail" in chunk:
106
+ message = chunk["error"]
107
+ raise BuildError(message)
108
+ log = "".join([str(item) for item in chunk.values()])
109
+ return log.strip("\n") if log != "\n" else ""
@@ -45,3 +45,7 @@ class HubComponentNotFound(Exception):
45
45
 
46
46
  def __str__(self) -> str:
47
47
  return self._msg
48
+
49
+
50
+ class BuildError(Exception):
51
+ ...
@@ -10,14 +10,13 @@ from rich.console import Console
10
10
  from rich.table import Table
11
11
  from splight_lib.models import HubComponent
12
12
 
13
- from splight_cli.component.component import ComponentManager
14
13
  from splight_cli.constants import (
15
14
  COMPRESSION_TYPE,
16
- PYTHON_TESTS_FILE,
17
15
  SPEC_FILE,
18
16
  SPLIGHT_IGNORE,
19
17
  success_style,
20
18
  )
19
+ from splight_cli.hub.component.component_builder import ComponentBuilder
21
20
  from splight_cli.hub.component.exceptions import (
22
21
  ComponentAlreadyExists,
23
22
  ComponentDirectoryAlreadyExists,
@@ -40,7 +39,7 @@ class HubComponentManager:
40
39
 
41
40
  # Validate spec fields before pushing the model
42
41
  try:
43
- HubComponent.model_validate(spec)
42
+ component = HubComponent.model_validate(spec)
44
43
  except ValidationError as exc:
45
44
  raise SpecValidationError(exc)
46
45
 
@@ -50,15 +49,11 @@ class HubComponentManager:
50
49
  if not force and self._exists_in_hub(name, version):
51
50
  raise ComponentAlreadyExists(name, version)
52
51
 
53
- if os.path.exists(os.path.join(path, PYTHON_TESTS_FILE)):
54
- # run test before push to hub. To run test, ctx isn't needed
55
- console.print(
56
- "Testing component before push to hub...", style=success_style
57
- )
58
- ComponentManager().test(path)
52
+ builder = ComponentBuilder(spec, path)
53
+ image_file = builder.build()
59
54
 
60
55
  with Loader("Pushing Component to Splight Hub"):
61
- component = HubComponent.upload(path)
56
+ component = HubComponent.upload(path, image_file)
62
57
 
63
58
  console.print(
64
59
  f"Component {component.id} pushed succesfully", style=success_style
@@ -0,0 +1,21 @@
1
+ # syntax=docker/dockerfile:1
2
+ FROM --platform=linux/amd64 python:3.11.7-slim
3
+
4
+ WORKDIR /whl
5
+ RUN pip install --upgrade splight-runner
6
+
7
+ ARG SPL_PACKAGE
8
+ ARG SPL_PACKAGE_VERSION
9
+ RUN pip install ${SPL_PACKAGE}==${SPL_PACKAGE_VERSION}
10
+
11
+ ARG COMPONENT_NAME
12
+ ARG COMPONENT_VERSION
13
+
14
+ WORKDIR /app
15
+ COPY . .
16
+ RUN python installer.py --name ${COMPONENT_NAME} --version ${COMPONENT_VERSION}
17
+
18
+ # Cleaning up files
19
+ RUN rm installer.py Dockerfile
20
+
21
+ ENTRYPOINT ["splight-runner", "run-component"]
@@ -0,0 +1,80 @@
1
+ import argparse
2
+ import os
3
+ import subprocess
4
+ from typing import List
5
+
6
+
7
+ class HubComponentInstaller:
8
+ _INIT_FILE = "Initialization"
9
+
10
+ def __init__(self, name: str, version: str) -> None:
11
+ self._name = name
12
+ self._version = version
13
+ self._component_path = os.getenv("APP_DIR", "/app")
14
+
15
+ def _handle_run(self, command: List[str]) -> None:
16
+ command: str = " ".join(command)
17
+ try:
18
+ subprocess.run(
19
+ command, check=True, cwd=self._component_path, shell=True
20
+ )
21
+ except subprocess.CalledProcessError as e:
22
+ raise Exception(
23
+ f"Failed to run command: {e.cmd}. Output: {e.output}"
24
+ )
25
+
26
+ def _validate(self):
27
+ # VALIDATE INIT FILE EXISTS
28
+ if not os.path.isfile(
29
+ os.path.join(self._component_path, self._INIT_FILE)
30
+ ):
31
+ raise Exception(
32
+ f"{self._INIT_FILE} file is missing in {self._component_path}"
33
+ )
34
+
35
+ def _load_commands(self) -> List[List[str]]:
36
+ file = os.path.join(self._component_path, self._INIT_FILE)
37
+ lines: List[List[str]] = []
38
+ lines.append(["RUN", "pip", "cache", "purge"])
39
+ with open(file) as f:
40
+ for line in f:
41
+ line = line.strip()
42
+ if line.startswith("#") or line == "":
43
+ continue
44
+ lines.append(line.split(" "))
45
+ return lines
46
+
47
+ def install(self):
48
+ self._validate()
49
+ commands = self._load_commands()
50
+ for command in commands:
51
+ prefix: str = command[0].lower()
52
+ handler = getattr(self, f"_handle_{prefix}", None)
53
+ if not handler:
54
+ raise Exception(f"Invalid command: {prefix}")
55
+ handler(command[1:])
56
+
57
+
58
+ if __name__ == "__main__":
59
+ parser = argparse.ArgumentParser(description="Install Hub Component")
60
+ parser.add_argument(
61
+ "-n",
62
+ "--name",
63
+ type=str,
64
+ nargs=1,
65
+ help="Hub Component Name",
66
+ required=True,
67
+ )
68
+ parser.add_argument(
69
+ "-v",
70
+ "--version",
71
+ type=str,
72
+ nargs=1,
73
+ help="Hub Component Version",
74
+ required=True,
75
+ )
76
+
77
+ args = parser.parse_args()
78
+
79
+ manager = HubComponentInstaller(name=args.name[0], version=args.version[0])
80
+ manager.install()
@@ -31,9 +31,6 @@ def push(
31
31
  manager = HubSolutionManager()
32
32
  manager.push(path, force=force)
33
33
  except Exception as exc:
34
- import traceback
35
- import sys
36
- traceback.print_exc(file=sys.stdout)
37
34
  console.print(f"Error pushing solution: {exc}", style=error_style)
38
35
  raise typer.Exit(code=1)
39
36
 
@@ -9,11 +9,7 @@ from rich.console import Console
9
9
  from rich.table import Table
10
10
  from splight_lib.models import HubSolution
11
11
 
12
- from splight_cli.constants import (
13
- COMPRESSION_TYPE,
14
- SPEC_FILE,
15
- success_style,
16
- )
12
+ from splight_cli.constants import COMPRESSION_TYPE, SPEC_FILE, success_style
17
13
  from splight_cli.hub.component.exceptions import (
18
14
  SpecFormatError,
19
15
  SpecValidationError,
@@ -112,4 +108,8 @@ class HubSolutionManager:
112
108
  return solutions[0]
113
109
 
114
110
  def _exists_in_hub(self, name: str, version: str) -> bool:
115
- return bool(self._get_hub_solution(name, version))
111
+ try:
112
+ self._get_hub_solution(name, version)
113
+ return True
114
+ except HubSolutionNotFound:
115
+ return False
File without changes