splight-cli 5.0.0__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.
Files changed (89) hide show
  1. {splight_cli-5.0.0 → splight_cli-5.1.0}/PKG-INFO +5 -7
  2. {splight_cli-5.0.0 → splight_cli-5.1.0}/pyproject.toml +6 -6
  3. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/manager/manager.py +7 -7
  4. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/__init__.py +2 -0
  5. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/component/exceptions.py +1 -24
  6. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/component/hub_manager.py +1 -2
  7. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/component/tests/test_hub_manager.py +3 -2
  8. splight_cli-5.1.0/splight_cli/hub/exceptions.py +21 -0
  9. splight_cli-5.1.0/splight_cli/hub/server/__init__.py +60 -0
  10. splight_cli-5.1.0/splight_cli/hub/server/exceptions.py +28 -0
  11. splight_cli-5.1.0/splight_cli/hub/server/server_builder.py +73 -0
  12. splight_cli-5.1.0/splight_cli/hub/server/server_manager.py +116 -0
  13. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/solution/solution_manager.py +1 -4
  14. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/alert.py +1 -1
  15. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/asset.py +1 -1
  16. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/attribute.py +1 -1
  17. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/base.py +1 -1
  18. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/component.py +1 -1
  19. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/component_object.py +1 -1
  20. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/file.py +1 -1
  21. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/function.py +1 -1
  22. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/metadata.py +1 -1
  23. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/routine.py +1 -1
  24. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/secret.py +1 -1
  25. {splight_cli-5.0.0 → splight_cli-5.1.0}/README.md +0 -0
  26. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/__init__.py +0 -0
  27. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/cli.py +0 -0
  28. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/__init__.py +0 -0
  29. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/component.py +0 -0
  30. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/exceptions.py +0 -0
  31. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/loaders.py +0 -0
  32. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/templates/.splightignore +0 -0
  33. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/templates/Initialization +0 -0
  34. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/templates/README.md +0 -0
  35. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/templates/auto_readme.md +0 -0
  36. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/templates/main.py +0 -0
  37. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/templates/spec.json +0 -0
  38. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/templates/tests.py +0 -0
  39. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/tests/__init__.py +0 -0
  40. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/tests/test_component_manager.py +0 -0
  41. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/component/utils.py +0 -0
  42. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/config/__init__.py +0 -0
  43. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/constants.py +0 -0
  44. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/context/__init__.py +0 -0
  45. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/context/context.py +0 -0
  46. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/context/workspace.py +0 -0
  47. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/__init__.py +0 -0
  48. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/alert/__init__.py +0 -0
  49. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/asset/__init__.py +0 -0
  50. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/attribute/__init__.py +0 -0
  51. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/component/__init__.py +0 -0
  52. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/datalake/__init__.py +0 -0
  53. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/file/__init__.py +0 -0
  54. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/manager/__init__.py +0 -0
  55. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/manager/exceptions.py +0 -0
  56. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/manager/tests/test_datalake_manager.py +0 -0
  57. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/manager/tests/test_resource_manager.py +0 -0
  58. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/engine/secret/__init__.py +0 -0
  59. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/component/__init__.py +0 -0
  60. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/component/component_builder.py +0 -0
  61. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/component/resources/Dockerfile +0 -0
  62. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/component/resources/installer.py +0 -0
  63. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/solution/__init__.py +0 -0
  64. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/solution/constants.py +0 -0
  65. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/hub/solution/exceptions.py +0 -0
  66. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/settings.py +0 -0
  67. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/__init__.py +0 -0
  68. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/dict.py +0 -0
  69. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/parser.py +0 -0
  70. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/__init__.py +0 -0
  71. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/diff.py +0 -0
  72. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/logger.py +0 -0
  73. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/manager.py +0 -0
  74. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/resource/models/__init__.py +0 -0
  75. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/solution/state.py +0 -0
  76. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/tests/test_component/Initialization +0 -0
  77. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/tests/test_component/README.md +0 -0
  78. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/tests/test_component/main.py +0 -0
  79. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/tests/test_component/spec.json +0 -0
  80. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/tests/test_component/tests.py +0 -0
  81. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/utils/__init__.py +0 -0
  82. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/utils/input.py +0 -0
  83. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/utils/json.py +0 -0
  84. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/utils/loader.py +0 -0
  85. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/utils/pprint.py +0 -0
  86. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/utils/template.py +0 -0
  87. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/utils/yaml.py +0 -0
  88. {splight_cli-5.0.0 → splight_cli-5.1.0}/splight_cli/version.py +0 -0
  89. {splight_cli-5.0.0 → 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: 5.0.0
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.9,<4
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)
@@ -19,10 +17,10 @@ Requires-Dist: docker (==7.1.0)
19
17
  Requires-Dist: packaging (==23.0)
20
18
  Requires-Dist: pathspec (==0.11.1)
21
19
  Requires-Dist: py7zr (==0.20.8)
22
- Requires-Dist: requests (==2.31.0)
20
+ Requires-Dist: requests (==2.32.2)
23
21
  Requires-Dist: rich (==13.0.1)
24
- Requires-Dist: setuptools (==60.9.3)
25
- Requires-Dist: splight-lib (==5.9.0)
22
+ Requires-Dist: setuptools (==70.0.0)
23
+ Requires-Dist: splight-lib (>=5.11.0,<6.0.0)
26
24
  Requires-Dist: toposort (>=1.10,<2.0)
27
25
  Requires-Dist: typer (==0.9.0)
28
26
  Description-Content-Type: text/markdown
@@ -1,21 +1,21 @@
1
1
  [tool.poetry]
2
2
  name = "splight-cli"
3
- version = "5.0.0"
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,<4"
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 = "60.9.3"
14
- splight-lib = "5.9.0"
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.31.0"
18
+ requests = "2.32.2"
19
19
  PyYAML = "6.0.1"
20
20
  rich = "13.0.1"
21
21
  pathspec = "0.11.1"
@@ -24,7 +24,7 @@ toposort = "^1.10"
24
24
  docker = "7.1.0"
25
25
 
26
26
  [tool.poetry.group.dev.dependencies]
27
- black = "23.3.0"
27
+ black = "24.3.0"
28
28
  isort = "5.12.0"
29
29
  ipdb = "^0.13.13"
30
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
- item.name
106
- if hasattr(item, "name")
107
- else getattr(item, "title", ""),
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)
@@ -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"
@@ -48,4 +25,4 @@ class HubComponentNotFound(Exception):
48
25
 
49
26
 
50
27
  class BuildError(Exception):
51
- ...
28
+ pass
@@ -21,9 +21,8 @@ from splight_cli.hub.component.exceptions import (
21
21
  ComponentAlreadyExists,
22
22
  ComponentDirectoryAlreadyExists,
23
23
  HubComponentNotFound,
24
- SpecFormatError,
25
- SpecValidationError,
26
24
  )
25
+ from splight_cli.hub.exceptions import SpecFormatError, SpecValidationError
27
26
  from splight_cli.utils.loader import Loader
28
27
 
29
28
  console = Console()
@@ -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
@@ -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.component.exceptions import (
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,
@@ -1,5 +1,5 @@
1
1
  from splight_lib.models import Alert as AlertSchema
2
- from splight_lib.models.base import SplightDatabaseBaseModel
2
+ from splight_lib.models.database_base import SplightDatabaseBaseModel
3
3
 
4
4
  from splight_cli.solution.resource.models.base import Resource
5
5
 
@@ -1,5 +1,5 @@
1
1
  from splight_lib.models import Asset as AssetSchema
2
- from splight_lib.models.base import SplightDatabaseBaseModel
2
+ from splight_lib.models.database_base import SplightDatabaseBaseModel
3
3
 
4
4
  from splight_cli.solution.resource.models.base import Resource
5
5
 
@@ -1,5 +1,5 @@
1
1
  from splight_lib.models import Attribute as AttributeSchema
2
- from splight_lib.models.base import SplightDatabaseBaseModel
2
+ from splight_lib.models.database_base import SplightDatabaseBaseModel
3
3
 
4
4
  from splight_cli.solution.resource.models.base import Resource
5
5
 
@@ -1,6 +1,6 @@
1
1
  from typing import Any, Dict, List, Optional
2
2
 
3
- from splight_lib.models.base import SplightDatabaseBaseModel
3
+ from splight_lib.models.database_base import SplightDatabaseBaseModel
4
4
 
5
5
  from splight_cli.solution.dict import get_dict_value, set_dict_value, walk_dict
6
6
 
@@ -1,5 +1,5 @@
1
1
  from splight_lib.models import Component as ComponentSchema
2
- from splight_lib.models.base import SplightDatabaseBaseModel
2
+ from splight_lib.models.database_base import SplightDatabaseBaseModel
3
3
 
4
4
  from splight_cli.solution.resource.models.base import Resource
5
5
 
@@ -1,5 +1,5 @@
1
1
  from splight_lib.models import ComponentObject as ComponentObjectSchema
2
- from splight_lib.models.base import SplightDatabaseBaseModel
2
+ from splight_lib.models.database_base import SplightDatabaseBaseModel
3
3
 
4
4
  from splight_cli.solution.resource.models.base import Resource
5
5
 
@@ -1,5 +1,5 @@
1
1
  from splight_lib.models import File as FileSchema
2
- from splight_lib.models.base import SplightDatabaseBaseModel
2
+ from splight_lib.models.database_base import SplightDatabaseBaseModel
3
3
 
4
4
  from splight_cli.solution.resource.models.base import Resource
5
5
 
@@ -1,5 +1,5 @@
1
1
  from splight_lib.models import Function as FunctionSchema
2
- from splight_lib.models.base import SplightDatabaseBaseModel
2
+ from splight_lib.models.database_base import SplightDatabaseBaseModel
3
3
 
4
4
  from splight_cli.solution.resource.models.base import Resource
5
5
 
@@ -1,5 +1,5 @@
1
1
  from splight_lib.models import Metadata as MetadataSchema
2
- from splight_lib.models.base import SplightDatabaseBaseModel
2
+ from splight_lib.models.database_base import SplightDatabaseBaseModel
3
3
 
4
4
  from splight_cli.solution.resource.models.base import Resource
5
5
 
@@ -1,5 +1,5 @@
1
1
  from splight_lib.models import RoutineObject as RoutineSchema
2
- from splight_lib.models.base import SplightDatabaseBaseModel
2
+ from splight_lib.models.database_base import SplightDatabaseBaseModel
3
3
 
4
4
  from splight_cli.solution.resource.models.base import Resource
5
5
 
@@ -1,5 +1,5 @@
1
1
  from splight_lib.models import Secret as SecretSchema
2
- from splight_lib.models.base import SplightDatabaseBaseModel
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