splight-cli 4.14.1__tar.gz → 5.1.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.
- {splight_cli-4.14.1 → splight_cli-5.1.0}/PKG-INFO +6 -7
- {splight_cli-4.14.1 → splight_cli-5.1.0}/pyproject.toml +7 -6
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/manager/manager.py +7 -7
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/hub/__init__.py +2 -0
- splight_cli-5.1.0/splight_cli/hub/component/component_builder.py +109 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/hub/component/exceptions.py +4 -23
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/hub/component/hub_manager.py +6 -12
- splight_cli-5.1.0/splight_cli/hub/component/resources/Dockerfile +21 -0
- splight_cli-5.1.0/splight_cli/hub/component/resources/installer.py +80 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/hub/component/tests/test_hub_manager.py +3 -2
- splight_cli-5.1.0/splight_cli/hub/exceptions.py +21 -0
- splight_cli-5.1.0/splight_cli/hub/server/__init__.py +60 -0
- splight_cli-5.1.0/splight_cli/hub/server/exceptions.py +28 -0
- splight_cli-5.1.0/splight_cli/hub/server/server_builder.py +73 -0
- splight_cli-5.1.0/splight_cli/hub/server/server_manager.py +116 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/hub/solution/__init__.py +0 -3
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/hub/solution/solution_manager.py +1 -4
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/alert.py +1 -1
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/asset.py +1 -1
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/attribute.py +1 -1
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/base.py +1 -1
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/component.py +1 -1
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/component_object.py +1 -1
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/file.py +1 -1
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/function.py +1 -1
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/metadata.py +1 -1
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/routine.py +1 -1
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/secret.py +1 -1
- {splight_cli-4.14.1 → splight_cli-5.1.0}/README.md +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/cli.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/component.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/exceptions.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/loaders.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/templates/.splightignore +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/templates/Initialization +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/templates/README.md +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/templates/auto_readme.md +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/templates/main.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/templates/spec.json +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/templates/tests.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/tests/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/tests/test_component_manager.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/utils.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/config/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/constants.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/context/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/context/context.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/context/workspace.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/alert/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/asset/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/attribute/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/component/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/datalake/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/file/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/manager/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/manager/exceptions.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/manager/tests/test_datalake_manager.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/manager/tests/test_resource_manager.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/secret/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/hub/component/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/hub/solution/constants.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/hub/solution/exceptions.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/settings.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/dict.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/parser.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/diff.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/logger.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/manager.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/state.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/tests/test_component/Initialization +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/tests/test_component/README.md +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/tests/test_component/main.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/tests/test_component/spec.json +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/tests/test_component/tests.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/utils/__init__.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/utils/input.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/utils/json.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/utils/loader.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/utils/pprint.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/utils/template.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/utils/yaml.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/version.py +0 -0
- {splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/workspace/__init__.py +0 -0
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: splight-cli
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.1.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.
|
|
7
|
+
Requires-Python: >=3.11,<4
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
11
9
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
10
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
11
|
Requires-Dist: PyYAML (==6.0.1)
|
|
@@ -15,13 +13,14 @@ Requires-Dist: case-converter (==1.1.0)
|
|
|
15
13
|
Requires-Dist: click (==8.0.4)
|
|
16
14
|
Requires-Dist: click-default-group (==1.2.2)
|
|
17
15
|
Requires-Dist: colorama (==0.4.4)
|
|
16
|
+
Requires-Dist: docker (==7.1.0)
|
|
18
17
|
Requires-Dist: packaging (==23.0)
|
|
19
18
|
Requires-Dist: pathspec (==0.11.1)
|
|
20
19
|
Requires-Dist: py7zr (==0.20.8)
|
|
21
|
-
Requires-Dist: requests (==2.
|
|
20
|
+
Requires-Dist: requests (==2.32.2)
|
|
22
21
|
Requires-Dist: rich (==13.0.1)
|
|
23
|
-
Requires-Dist: setuptools (==
|
|
24
|
-
Requires-Dist: splight-lib (>=5.
|
|
22
|
+
Requires-Dist: setuptools (==70.0.0)
|
|
23
|
+
Requires-Dist: splight-lib (>=5.11.0,<6.0.0)
|
|
25
24
|
Requires-Dist: toposort (>=1.10,<2.0)
|
|
26
25
|
Requires-Dist: typer (==0.9.0)
|
|
27
26
|
Description-Content-Type: text/markdown
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "splight-cli"
|
|
3
|
-
version = "
|
|
3
|
+
version = "5.1.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.
|
|
9
|
+
python = ">=3.11,<4"
|
|
10
10
|
case-converter = "1.1.0"
|
|
11
11
|
click = "8.0.4"
|
|
12
12
|
click-default-group = "1.2.2"
|
|
13
|
-
setuptools = "
|
|
14
|
-
splight-lib = "
|
|
13
|
+
setuptools = "70.0.0"
|
|
14
|
+
splight-lib = "^5.11.0"
|
|
15
15
|
py7zr = "0.20.8"
|
|
16
16
|
typer = "0.9.0"
|
|
17
17
|
colorama = "0.4.4"
|
|
18
|
-
requests = "2.
|
|
18
|
+
requests = "2.32.2"
|
|
19
19
|
PyYAML = "6.0.1"
|
|
20
20
|
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
|
-
black = "
|
|
27
|
+
black = "24.3.0"
|
|
27
28
|
isort = "5.12.0"
|
|
28
29
|
ipdb = "^0.13.13"
|
|
29
30
|
ipython = "8.12.2"
|
|
@@ -15,16 +15,14 @@ from splight_lib.models import (
|
|
|
15
15
|
HubComponent,
|
|
16
16
|
RoutineObject,
|
|
17
17
|
)
|
|
18
|
-
from splight_lib.models.base import (
|
|
19
|
-
SplightDatabaseBaseModel,
|
|
20
|
-
SplightDatalakeBaseModel,
|
|
21
|
-
)
|
|
22
18
|
from splight_lib.models.component import (
|
|
23
19
|
DataAddress,
|
|
24
20
|
InputDataAddress,
|
|
25
21
|
InputParameter,
|
|
26
22
|
Parameter,
|
|
27
23
|
)
|
|
24
|
+
from splight_lib.models.database_base import SplightDatabaseBaseModel
|
|
25
|
+
from splight_lib.models.datalake_base import SplightDatalakeBaseModel
|
|
28
26
|
|
|
29
27
|
from splight_cli.component.exceptions import InvalidCSVColumns
|
|
30
28
|
from splight_cli.constants import (
|
|
@@ -102,9 +100,11 @@ class ResourceManager:
|
|
|
102
100
|
table.add_row(
|
|
103
101
|
str(counter),
|
|
104
102
|
item.id,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
(
|
|
104
|
+
item.name
|
|
105
|
+
if hasattr(item, "name")
|
|
106
|
+
else getattr(item, "title", "")
|
|
107
|
+
),
|
|
108
108
|
)
|
|
109
109
|
for counter, item in enumerate(instances)
|
|
110
110
|
]
|
|
@@ -2,6 +2,7 @@ import typer
|
|
|
2
2
|
|
|
3
3
|
from splight_cli.context import check_credentials
|
|
4
4
|
from splight_cli.hub.component import component_app
|
|
5
|
+
from splight_cli.hub.server import server_app
|
|
5
6
|
from splight_cli.hub.solution import solution_app
|
|
6
7
|
|
|
7
8
|
hub_app = typer.Typer(
|
|
@@ -13,6 +14,7 @@ hub_app = typer.Typer(
|
|
|
13
14
|
|
|
14
15
|
hub_app.add_typer(component_app, name="component")
|
|
15
16
|
hub_app.add_typer(solution_app, name="solution")
|
|
17
|
+
hub_app.add_typer(server_app, name="server")
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
@hub_app.callback(invoke_without_command=True)
|
|
@@ -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 ""
|
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
from json import loads
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class SpecFormatError(Exception):
|
|
5
|
-
def __init__(self, error):
|
|
6
|
-
self._msg = f"Error while parsing 'spec.json': {error}"
|
|
7
|
-
|
|
8
|
-
def __str__(self) -> str:
|
|
9
|
-
return self._msg
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class SpecValidationError(Exception):
|
|
13
|
-
def __init__(self, error):
|
|
14
|
-
field = loads(error.json())[0]["loc"][0]
|
|
15
|
-
message = loads(error.json())[0]["msg"]
|
|
16
|
-
self._msg = (
|
|
17
|
-
f"Validation error for field in 'spec.json': '{field}' {message}"
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
def __str__(self) -> str:
|
|
21
|
-
return self._msg
|
|
22
|
-
|
|
23
|
-
|
|
24
1
|
class ComponentAlreadyExists(Exception):
|
|
25
2
|
def __init__(self, name: str, version: str):
|
|
26
3
|
self._msg = f"Component {name}-{version} already exists in HUB"
|
|
@@ -45,3 +22,7 @@ class HubComponentNotFound(Exception):
|
|
|
45
22
|
|
|
46
23
|
def __str__(self) -> str:
|
|
47
24
|
return self._msg
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class BuildError(Exception):
|
|
28
|
+
pass
|
|
@@ -10,21 +10,19 @@ 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,
|
|
24
23
|
HubComponentNotFound,
|
|
25
|
-
SpecFormatError,
|
|
26
|
-
SpecValidationError,
|
|
27
24
|
)
|
|
25
|
+
from splight_cli.hub.exceptions import SpecFormatError, SpecValidationError
|
|
28
26
|
from splight_cli.utils.loader import Loader
|
|
29
27
|
|
|
30
28
|
console = Console()
|
|
@@ -40,7 +38,7 @@ class HubComponentManager:
|
|
|
40
38
|
|
|
41
39
|
# Validate spec fields before pushing the model
|
|
42
40
|
try:
|
|
43
|
-
HubComponent.model_validate(spec)
|
|
41
|
+
component = HubComponent.model_validate(spec)
|
|
44
42
|
except ValidationError as exc:
|
|
45
43
|
raise SpecValidationError(exc)
|
|
46
44
|
|
|
@@ -50,15 +48,11 @@ class HubComponentManager:
|
|
|
50
48
|
if not force and self._exists_in_hub(name, version):
|
|
51
49
|
raise ComponentAlreadyExists(name, version)
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
console.print(
|
|
56
|
-
"Testing component before push to hub...", style=success_style
|
|
57
|
-
)
|
|
58
|
-
ComponentManager().test(path)
|
|
51
|
+
builder = ComponentBuilder(spec, path)
|
|
52
|
+
image_file = builder.build()
|
|
59
53
|
|
|
60
54
|
with Loader("Pushing Component to Splight Hub"):
|
|
61
|
-
component = HubComponent.upload(path)
|
|
55
|
+
component = HubComponent.upload(path, image_file)
|
|
62
56
|
|
|
63
57
|
console.print(
|
|
64
58
|
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()
|
{splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/hub/component/tests/test_hub_manager.py
RENAMED
|
@@ -9,10 +9,9 @@ from splight_cli.component import ComponentManager
|
|
|
9
9
|
from splight_cli.hub.component.exceptions import (
|
|
10
10
|
ComponentAlreadyExists,
|
|
11
11
|
HubComponentNotFound,
|
|
12
|
-
SpecFormatError,
|
|
13
|
-
SpecValidationError,
|
|
14
12
|
)
|
|
15
13
|
from splight_cli.hub.component.hub_manager import HubComponentManager
|
|
14
|
+
from splight_cli.hub.exceptions import SpecFormatError, SpecValidationError
|
|
16
15
|
|
|
17
16
|
BASE_PATH = os.getcwd()
|
|
18
17
|
TEST_COMPONENT_PATH = os.path.join(
|
|
@@ -23,6 +22,7 @@ with open(os.path.join(TEST_COMPONENT_PATH, "spec.json"), "r") as fid:
|
|
|
23
22
|
HUB_COMPONENT.id = str(uuid4())
|
|
24
23
|
|
|
25
24
|
|
|
25
|
+
@pytest.mark.skip
|
|
26
26
|
@patch.object(ComponentManager, "test", return_value=None)
|
|
27
27
|
@patch.object(HubComponentManager, "_exists_in_hub", return_value=False)
|
|
28
28
|
def test_push(mock_exists, mock_component_manager):
|
|
@@ -94,6 +94,7 @@ def test_push_already_exists(mock_exists, mock_component_manager):
|
|
|
94
94
|
manager.push(test_component_path, force=False)
|
|
95
95
|
|
|
96
96
|
|
|
97
|
+
@pytest.mark.skip
|
|
97
98
|
@patch.object(ComponentManager, "test", return_value=None)
|
|
98
99
|
@patch.object(HubComponentManager, "_exists_in_hub", return_value=True)
|
|
99
100
|
def test_push_already_exists_with_force(mock_exists, mock_component_manager):
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from json import loads
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SpecFormatError(Exception):
|
|
5
|
+
def __init__(self, error):
|
|
6
|
+
self._msg = f"Error while parsing 'spec.json': {error}"
|
|
7
|
+
|
|
8
|
+
def __str__(self) -> str:
|
|
9
|
+
return self._msg
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SpecValidationError(Exception):
|
|
13
|
+
def __init__(self, error):
|
|
14
|
+
field = loads(error.json())[0]["loc"][0]
|
|
15
|
+
message = loads(error.json())[0]["msg"]
|
|
16
|
+
self._msg = (
|
|
17
|
+
f"Validation error for field in 'spec.json': '{field}' {message}"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
def __str__(self) -> str:
|
|
21
|
+
return self._msg
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
from rich.console import Console
|
|
3
|
+
from splight_lib.models import Component
|
|
4
|
+
|
|
5
|
+
from splight_cli.constants import error_style
|
|
6
|
+
from splight_cli.hub.server.server_manager import HubServerManager
|
|
7
|
+
|
|
8
|
+
server_app = typer.Typer(
|
|
9
|
+
name="Splight Hub Server",
|
|
10
|
+
add_completion=True,
|
|
11
|
+
rich_markup_mode="rich",
|
|
12
|
+
no_args_is_help=True,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
console = Console()
|
|
16
|
+
MODEL = Component
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@server_app.command()
|
|
20
|
+
def push(
|
|
21
|
+
ctx: typer.Context,
|
|
22
|
+
path: str = typer.Argument(..., help="Path to server files"),
|
|
23
|
+
force: bool = typer.Option(
|
|
24
|
+
False,
|
|
25
|
+
"--force",
|
|
26
|
+
"-f",
|
|
27
|
+
help="Overwrite existing server in Splight HUB",
|
|
28
|
+
),
|
|
29
|
+
):
|
|
30
|
+
try:
|
|
31
|
+
manager = HubServerManager()
|
|
32
|
+
manager.push(path, force=force)
|
|
33
|
+
except Exception as exc:
|
|
34
|
+
console.print(f"Error pushing server: {exc}", style=error_style)
|
|
35
|
+
raise
|
|
36
|
+
raise typer.Exit(code=1)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@server_app.command()
|
|
40
|
+
def pull(
|
|
41
|
+
ctx: typer.Context,
|
|
42
|
+
name: str = typer.Argument(..., help="The servers's name"),
|
|
43
|
+
version: str = typer.Argument(..., help="The servers's version"),
|
|
44
|
+
):
|
|
45
|
+
try:
|
|
46
|
+
manager = HubServerManager()
|
|
47
|
+
manager.pull(name=name, version=version)
|
|
48
|
+
except Exception as exc:
|
|
49
|
+
console.print(f"Error pulling server: {exc}", style=error_style)
|
|
50
|
+
raise typer.Exit(code=1)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@server_app.command()
|
|
54
|
+
def list(ctx: typer.Context):
|
|
55
|
+
try:
|
|
56
|
+
manager = HubServerManager()
|
|
57
|
+
manager.list_servers()
|
|
58
|
+
except Exception as exc:
|
|
59
|
+
console.print(f"Error listing servers: {exc}", style=error_style)
|
|
60
|
+
raise typer.Exit(code=1)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class ServerAlreadyExists(Exception):
|
|
2
|
+
def __init__(self, name: str, version: str):
|
|
3
|
+
self._msg = f"Server {name}-{version} already exists in HUB"
|
|
4
|
+
|
|
5
|
+
def __str__(self) -> str:
|
|
6
|
+
return self._msg
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ServerDirectoryAlreadyExists(Exception):
|
|
10
|
+
def __init__(self, directory: str):
|
|
11
|
+
self._msg = f"Directory with name {directory} already exists in path"
|
|
12
|
+
|
|
13
|
+
def __str__(self) -> str:
|
|
14
|
+
return self._msg
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class HubServerNotFound(Exception):
|
|
18
|
+
"""Exception raised when a version is invalid."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, name: str, version: str):
|
|
21
|
+
self._msg = f"Hub server {name} version {version} not found."
|
|
22
|
+
|
|
23
|
+
def __str__(self) -> str:
|
|
24
|
+
return self._msg
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class BuildError(Exception):
|
|
28
|
+
pass
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import gzip
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
import docker
|
|
7
|
+
|
|
8
|
+
from splight_cli.hub.server.exceptions import BuildError
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ServerBuilder:
|
|
12
|
+
def __init__(self, server_spec: dict, server_path: str):
|
|
13
|
+
self._base_path = os.path.dirname(__file__)
|
|
14
|
+
self._server_name = server_spec["name"]
|
|
15
|
+
self._server_version = server_spec["version"]
|
|
16
|
+
self._server_path = server_path
|
|
17
|
+
self._docker_client = docker.from_env()
|
|
18
|
+
|
|
19
|
+
def build(self) -> str:
|
|
20
|
+
original_path = os.getcwd()
|
|
21
|
+
os.chdir(self._server_path)
|
|
22
|
+
image_file = self._build_server()
|
|
23
|
+
os.chdir(original_path)
|
|
24
|
+
return image_file
|
|
25
|
+
|
|
26
|
+
def _build_server(self) -> str:
|
|
27
|
+
full_name = f"{self._server_name}-{self._server_version}"
|
|
28
|
+
tag = f"server:{full_name}"
|
|
29
|
+
streamer = self._build_server_image(tag)
|
|
30
|
+
for chunk in streamer:
|
|
31
|
+
try:
|
|
32
|
+
log = self._parse_chunk(chunk)
|
|
33
|
+
except BuildError as exc:
|
|
34
|
+
sys.stdout.write(exc)
|
|
35
|
+
sys.stdout.flush()
|
|
36
|
+
raise exc
|
|
37
|
+
if log:
|
|
38
|
+
sys.stdout.write(f"{log}\n")
|
|
39
|
+
sys.stdout.flush()
|
|
40
|
+
|
|
41
|
+
if "stream" in chunk:
|
|
42
|
+
match = re.search(
|
|
43
|
+
r"(^Successfully built |sha256:)([0-9a-f]+)$",
|
|
44
|
+
chunk["stream"],
|
|
45
|
+
)
|
|
46
|
+
if match:
|
|
47
|
+
image_id = match.group(2)
|
|
48
|
+
image = self._docker_client.images.get(image_id)
|
|
49
|
+
file_name = f"{full_name}.tgz"
|
|
50
|
+
with gzip.open(file_name, "wb") as image_file:
|
|
51
|
+
for chunk in image.save(named=True):
|
|
52
|
+
image_file.write(chunk)
|
|
53
|
+
return file_name
|
|
54
|
+
|
|
55
|
+
def _build_server_image(self, tag: str):
|
|
56
|
+
client = self._docker_client.api
|
|
57
|
+
streamer = client.build(
|
|
58
|
+
path=".",
|
|
59
|
+
tag=tag,
|
|
60
|
+
dockerfile="Dockerfile",
|
|
61
|
+
rm=True,
|
|
62
|
+
pull=True,
|
|
63
|
+
quiet=False,
|
|
64
|
+
decode=True,
|
|
65
|
+
)
|
|
66
|
+
return streamer
|
|
67
|
+
|
|
68
|
+
def _parse_chunk(self, chunk: dict) -> str:
|
|
69
|
+
if "errorDetail" in chunk:
|
|
70
|
+
message = chunk["error"]
|
|
71
|
+
raise BuildError(message)
|
|
72
|
+
log = "".join([str(item) for item in chunk.values()])
|
|
73
|
+
return log.strip("\n") if log != "\n" else ""
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
from collections import namedtuple
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
import py7zr
|
|
8
|
+
from pydantic import ValidationError
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.table import Table
|
|
11
|
+
from splight_lib.models import HubServer
|
|
12
|
+
|
|
13
|
+
from splight_cli.constants import COMPRESSION_TYPE, SPEC_FILE, success_style
|
|
14
|
+
from splight_cli.hub.exceptions import SpecFormatError, SpecValidationError
|
|
15
|
+
from splight_cli.hub.server.exceptions import (
|
|
16
|
+
HubServerNotFound,
|
|
17
|
+
ServerAlreadyExists,
|
|
18
|
+
ServerDirectoryAlreadyExists,
|
|
19
|
+
)
|
|
20
|
+
from splight_cli.hub.server.server_builder import ServerBuilder
|
|
21
|
+
from splight_cli.utils.loader import Loader
|
|
22
|
+
|
|
23
|
+
console = Console()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class HubServerManager:
|
|
27
|
+
def push(self, path: str, force: Optional[bool] = False):
|
|
28
|
+
try:
|
|
29
|
+
with open(os.path.join(path, SPEC_FILE)) as fid:
|
|
30
|
+
spec = json.load(fid)
|
|
31
|
+
except Exception as exc:
|
|
32
|
+
raise SpecFormatError(exc)
|
|
33
|
+
|
|
34
|
+
# Validate spec fields before pushing the model
|
|
35
|
+
try:
|
|
36
|
+
server = HubServer.model_validate(spec)
|
|
37
|
+
except ValidationError as exc:
|
|
38
|
+
raise SpecValidationError(exc)
|
|
39
|
+
|
|
40
|
+
name = spec["name"]
|
|
41
|
+
version = spec["version"]
|
|
42
|
+
|
|
43
|
+
if not force and self._exists_in_hub(name, version):
|
|
44
|
+
raise ServerAlreadyExists(name, version)
|
|
45
|
+
|
|
46
|
+
builder = ServerBuilder(spec, path)
|
|
47
|
+
image_file = builder.build()
|
|
48
|
+
|
|
49
|
+
with Loader("Pushing Server to Splight Hub"):
|
|
50
|
+
server = HubServer.upload(path, image_file)
|
|
51
|
+
|
|
52
|
+
if image_file:
|
|
53
|
+
os.remove(image_file)
|
|
54
|
+
|
|
55
|
+
console.print(
|
|
56
|
+
f"Server {server.id} pushed succesfully", style=success_style
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def pull(self, name: str, version: str):
|
|
60
|
+
with Loader("Pulling server from Splight Hub"):
|
|
61
|
+
self._pull_server(name, version)
|
|
62
|
+
console.print(f"Server {name} pulled succesfully", style=success_style)
|
|
63
|
+
|
|
64
|
+
def _pull_server(self, name: str, version: str):
|
|
65
|
+
server = self._get_hub_server(name, version)
|
|
66
|
+
name, version = server.name, server.version
|
|
67
|
+
|
|
68
|
+
file_wrapper = server.download()
|
|
69
|
+
file_data = file_wrapper.read()
|
|
70
|
+
|
|
71
|
+
version_modified = version.replace(".", "_")
|
|
72
|
+
server_path = f"{name}/{version_modified}"
|
|
73
|
+
versioned_name = f"{name}-{version}"
|
|
74
|
+
file_name = f"{versioned_name}.{COMPRESSION_TYPE}"
|
|
75
|
+
if os.path.exists(server_path):
|
|
76
|
+
raise ServerDirectoryAlreadyExists(server_path)
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
with open(file_name, "wb") as fid:
|
|
80
|
+
fid.write(file_data)
|
|
81
|
+
|
|
82
|
+
with py7zr.SevenZipFile(file_name, "r") as z:
|
|
83
|
+
z.extractall(path=".")
|
|
84
|
+
shutil.move(f"{versioned_name}", server_path)
|
|
85
|
+
|
|
86
|
+
except Exception as exc:
|
|
87
|
+
raise exc
|
|
88
|
+
finally:
|
|
89
|
+
if os.path.exists(file_name):
|
|
90
|
+
os.remove(file_name)
|
|
91
|
+
|
|
92
|
+
def _get_hub_server(self, name: str, version: str) -> HubServer:
|
|
93
|
+
servers = HubServer.list(name=name, version=version)
|
|
94
|
+
if not servers:
|
|
95
|
+
raise HubServerNotFound(name, version)
|
|
96
|
+
return servers[0]
|
|
97
|
+
|
|
98
|
+
def list_servers(self):
|
|
99
|
+
servers_tuple = namedtuple("Server", ["name", "version"])
|
|
100
|
+
all_servers = HubServer.list()
|
|
101
|
+
servers = set(
|
|
102
|
+
[
|
|
103
|
+
servers_tuple(server.name, server.version)
|
|
104
|
+
for server in all_servers
|
|
105
|
+
]
|
|
106
|
+
)
|
|
107
|
+
table = Table("Name", "Version", title="Hub Server List")
|
|
108
|
+
[table.add_row(server.name, server.version) for server in servers]
|
|
109
|
+
console.print(table)
|
|
110
|
+
|
|
111
|
+
def _exists_in_hub(self, name: str, version: str) -> bool:
|
|
112
|
+
try:
|
|
113
|
+
self._get_hub_server(name, version)
|
|
114
|
+
return True
|
|
115
|
+
except HubServerNotFound:
|
|
116
|
+
return False
|
|
@@ -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
|
|
|
@@ -10,10 +10,7 @@ from rich.table import Table
|
|
|
10
10
|
from splight_lib.models import HubSolution
|
|
11
11
|
|
|
12
12
|
from splight_cli.constants import COMPRESSION_TYPE, SPEC_FILE, success_style
|
|
13
|
-
from splight_cli.hub.
|
|
14
|
-
SpecFormatError,
|
|
15
|
-
SpecValidationError,
|
|
16
|
-
)
|
|
13
|
+
from splight_cli.hub.exceptions import SpecFormatError, SpecValidationError
|
|
17
14
|
from splight_cli.hub.solution.exceptions import (
|
|
18
15
|
HubSolutionAlreadyExists,
|
|
19
16
|
HubSolutionNotFound,
|
{splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/solution/resource/models/component_object.py
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from splight_lib.models import ComponentObject as ComponentObjectSchema
|
|
2
|
-
from splight_lib.models.
|
|
2
|
+
from splight_lib.models.database_base import SplightDatabaseBaseModel
|
|
3
3
|
|
|
4
4
|
from splight_cli.solution.resource.models.base import Resource
|
|
5
5
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/component/tests/test_component_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/manager/tests/test_datalake_manager.py
RENAMED
|
File without changes
|
{splight_cli-4.14.1 → splight_cli-5.1.0}/splight_cli/engine/manager/tests/test_resource_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|