sierra-dev 0.1.0__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.
- sierra/__init__.py +118 -0
- sierra/__main__.py +6 -0
- sierra/_about.py +34 -0
- sierra/abc/__init__.py +33 -0
- sierra/abc/base.py +9 -0
- sierra/abc/sierra.py +63 -0
- sierra/client.py +264 -0
- sierra/core/__init__.py +43 -0
- sierra/core/base.py +51 -0
- sierra/core/builder.py +718 -0
- sierra/core/checker.py +1 -0
- sierra/core/compiler.py +131 -0
- sierra/core/environment.py +355 -0
- sierra/core/loader.py +515 -0
- sierra/internal/__init__.py +56 -0
- sierra/internal/cache.py +632 -0
- sierra/internal/errors.py +53 -0
- sierra/internal/logger.py +350 -0
- sierra/invoker.py +134 -0
- sierra/options.py +28 -0
- sierra/py.typed +0 -0
- sierra_dev-0.1.0.dist-info/METADATA +240 -0
- sierra_dev-0.1.0.dist-info/RECORD +27 -0
- sierra_dev-0.1.0.dist-info/WHEEL +5 -0
- sierra_dev-0.1.0.dist-info/entry_points.txt +2 -0
- sierra_dev-0.1.0.dist-info/licenses/LICENSE +661 -0
- sierra_dev-0.1.0.dist-info/top_level.txt +1 -0
sierra/__init__.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""
|
|
2
|
+
sierra-dev.
|
|
3
|
+
==========
|
|
4
|
+
|
|
5
|
+
A framework for building and managing invoker scripts that can be used across different nodes in Sierra during any investigation.
|
|
6
|
+
|
|
7
|
+
# Overview
|
|
8
|
+
--------
|
|
9
|
+
|
|
10
|
+
This package provides a comprehensive framework for building, compiling, and loading Sierra applications, including abstract base classes, core components, and internal utilities.
|
|
11
|
+
|
|
12
|
+
# Exposed Components
|
|
13
|
+
-----------------
|
|
14
|
+
|
|
15
|
+
- `create_error_result`: Function to create an error result.
|
|
16
|
+
- `create_tree_result`: Function to create a tree result.
|
|
17
|
+
- `SierraABC`: Abstract base class for Sierra components.
|
|
18
|
+
- `SierraBuilder`: Base class for building Sierra components.
|
|
19
|
+
- `SierraCompiler`: Base class for compiling Sierra components.
|
|
20
|
+
- `SierraConfig`: Top-level configuration for SIERRA invoker scripts.
|
|
21
|
+
- `SierraCoreObject`: Base class for all Sierra components.
|
|
22
|
+
- `SierraDevelopmentEnvironment`: Environment configuration class for Sierra development.
|
|
23
|
+
- `SierraInvokerBuilder`: Builder for Sierra invoker scripts.
|
|
24
|
+
- `SierraLoader`: Base class for loading Sierra components.
|
|
25
|
+
- `SierraSideloader`: Base class for side-loading Sierra components.
|
|
26
|
+
- `UniversalLogger`: Logger class for logging Sierra events.
|
|
27
|
+
|
|
28
|
+
# Integration Notes
|
|
29
|
+
-----------------
|
|
30
|
+
|
|
31
|
+
This package is designed to be used as a foundation for building complex Sierra applications, providing a robust and flexible framework for managing invoker scripts across different nodes.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
import typing
|
|
35
|
+
|
|
36
|
+
from sierra._about import *
|
|
37
|
+
from sierra.abc import *
|
|
38
|
+
from sierra.client import *
|
|
39
|
+
from sierra.core import *
|
|
40
|
+
from sierra.internal import *
|
|
41
|
+
from sierra.invoker import *
|
|
42
|
+
from sierra.options import *
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def create_tree_result(
|
|
46
|
+
results: list[typing.Union[str, dict[str, list[str]]]],
|
|
47
|
+
) -> dict[str, typing.Any]:
|
|
48
|
+
"""
|
|
49
|
+
Create a Tree type result.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
results : list[Union[str, dict[str, list[str]]]]
|
|
54
|
+
The tree results.
|
|
55
|
+
|
|
56
|
+
Returns
|
|
57
|
+
-------
|
|
58
|
+
TreeResult
|
|
59
|
+
The formatted tree result.
|
|
60
|
+
"""
|
|
61
|
+
result: dict[str, typing.Any] = {
|
|
62
|
+
"type": "Tree",
|
|
63
|
+
"results": results,
|
|
64
|
+
}
|
|
65
|
+
return result
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def create_network_result(
|
|
69
|
+
origins: list[str],
|
|
70
|
+
nodes: list[dict[str, str]],
|
|
71
|
+
edges: list[dict[str, str]],
|
|
72
|
+
) -> dict[str, str]:
|
|
73
|
+
"""
|
|
74
|
+
Create a Network type result.
|
|
75
|
+
|
|
76
|
+
Parameters
|
|
77
|
+
----------
|
|
78
|
+
origins : list[str]
|
|
79
|
+
List of origin node IDs.
|
|
80
|
+
nodes : list[dict[str, str]]
|
|
81
|
+
List of node definitions.
|
|
82
|
+
edges : list[dict[str, str]]
|
|
83
|
+
List of edge definitions.
|
|
84
|
+
|
|
85
|
+
Returns
|
|
86
|
+
-------
|
|
87
|
+
NetworkResult
|
|
88
|
+
The formatted network result.
|
|
89
|
+
"""
|
|
90
|
+
result: dict[str, typing.Any] = {
|
|
91
|
+
"type": "Network",
|
|
92
|
+
"origins": origins,
|
|
93
|
+
"nodes": nodes,
|
|
94
|
+
"edges": edges,
|
|
95
|
+
}
|
|
96
|
+
return result
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def create_error_result(message: str) -> dict[str, str]:
|
|
100
|
+
"""
|
|
101
|
+
Create an Error type result.
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
message : str
|
|
106
|
+
The error message.
|
|
107
|
+
|
|
108
|
+
Returns
|
|
109
|
+
-------
|
|
110
|
+
ErrorResult
|
|
111
|
+
The formatted error result.
|
|
112
|
+
"""
|
|
113
|
+
result: dict[str, typing.Any] = {
|
|
114
|
+
"type": "Error",
|
|
115
|
+
"message": message,
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return result
|
sierra/__main__.py
ADDED
sierra/_about.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
__author__: typing.Final = "Xsyncio"
|
|
4
|
+
__version__: typing.Final = "0.1.0"
|
|
5
|
+
__license__: typing.Final = "MIT"
|
|
6
|
+
__github__: typing.Final = "https://github.com/xsyncio/sierra-dev"
|
|
7
|
+
__description__: typing.Final = "Sierra is a framework for building and managing invoker scripts that can be used across different nodes in Sierra during any investigation."
|
|
8
|
+
__url__: typing.Final = "https://sierra-dev.readthedocs.io"
|
|
9
|
+
__email__: typing.Final = "xsyncio@gmail.com"
|
|
10
|
+
__copyright__: typing.Final = "Copyright 2022 Xsyncio"
|
|
11
|
+
|
|
12
|
+
__long_description__: typing.Final = (
|
|
13
|
+
__description__
|
|
14
|
+
+ """
|
|
15
|
+
Sierra is designed to be as lightweight as possible and is written in pure Python.
|
|
16
|
+
It is intended to be used with the Sierra platform.
|
|
17
|
+
"""
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
__keywords__: typing.Final = [
|
|
21
|
+
"sierra",
|
|
22
|
+
"invoker",
|
|
23
|
+
"script",
|
|
24
|
+
"node",
|
|
25
|
+
"platform",
|
|
26
|
+
"python",
|
|
27
|
+
"custom",
|
|
28
|
+
"command",
|
|
29
|
+
"argument",
|
|
30
|
+
"environment",
|
|
31
|
+
"type",
|
|
32
|
+
"state",
|
|
33
|
+
"property",
|
|
34
|
+
]
|
sierra/abc/__init__.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sierra ABCs.
|
|
3
|
+
============
|
|
4
|
+
|
|
5
|
+
Abstract Base Classes (ABCs) for Sierra Dev components.
|
|
6
|
+
|
|
7
|
+
# Overview
|
|
8
|
+
--------
|
|
9
|
+
|
|
10
|
+
This package contains abstract base classes (ABCs) for components of the
|
|
11
|
+
Sierra Dev framework.
|
|
12
|
+
|
|
13
|
+
# Exposed Components
|
|
14
|
+
-----------------
|
|
15
|
+
|
|
16
|
+
- `SierraABC`: Abstract base class for Sierra components.
|
|
17
|
+
- `SierraConfig`: Top-level configuration for SIERRA invoker scripts.
|
|
18
|
+
- `SierraInvokerParam`: Parameter description for invoker scripts.
|
|
19
|
+
- `SierraInvokerScript`: Invoker script definition.
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from sierra.abc.base import SierraABC
|
|
24
|
+
from sierra.abc.sierra import SierraConfig
|
|
25
|
+
from sierra.abc.sierra import SierraInvokerParam
|
|
26
|
+
from sierra.abc.sierra import SierraInvokerScript
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"SierraABC",
|
|
30
|
+
"SierraConfig",
|
|
31
|
+
"SierraInvokerParam",
|
|
32
|
+
"SierraInvokerScript",
|
|
33
|
+
]
|
sierra/abc/base.py
ADDED
sierra/abc/sierra.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
import sierra.abc.base as sierra_abc_base
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class SierraInvokerParam(sierra_abc_base.SierraABC):
|
|
7
|
+
"""
|
|
8
|
+
Represents a single parameter for an invoker script.
|
|
9
|
+
|
|
10
|
+
Attributes
|
|
11
|
+
----------
|
|
12
|
+
Name : str
|
|
13
|
+
The parameter's name.
|
|
14
|
+
Description : str | None
|
|
15
|
+
Human-readable description of the parameter.
|
|
16
|
+
Type : str
|
|
17
|
+
The data type of the parameter (e.g., 'STRING', 'FILE').
|
|
18
|
+
Options : list[str] | None
|
|
19
|
+
List of flags, such as 'PRIMARY' or 'MANDATORY'.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
Name: str
|
|
23
|
+
Type: str
|
|
24
|
+
Description: str | None
|
|
25
|
+
Options: typing.Literal["MANDATORY"] | None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SierraInvokerScript(sierra_abc_base.SierraABC):
|
|
29
|
+
"""
|
|
30
|
+
Represents an invoker script definition.
|
|
31
|
+
|
|
32
|
+
Attributes
|
|
33
|
+
----------
|
|
34
|
+
Name : str
|
|
35
|
+
Unique name of the script.
|
|
36
|
+
Description : str | None
|
|
37
|
+
Brief description of the script.
|
|
38
|
+
Params : list[SierraInvokerParam]
|
|
39
|
+
List of parameters for the script.
|
|
40
|
+
Command : str
|
|
41
|
+
Shell or Python command template, with placeholders for parameters.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
Name: str
|
|
45
|
+
Description: str | None
|
|
46
|
+
Params: list[SierraInvokerParam] | None
|
|
47
|
+
Command: str | None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class SierraConfig(sierra_abc_base.SierraABC):
|
|
51
|
+
"""
|
|
52
|
+
Top-level configuration for SIERRA invoker scripts.
|
|
53
|
+
|
|
54
|
+
Attributes
|
|
55
|
+
----------
|
|
56
|
+
PATHS : list[str] | None
|
|
57
|
+
Optional list of directories to search for scripts.
|
|
58
|
+
SCRIPTS : list[SierraInvokerScript]
|
|
59
|
+
Definitions of all invoker scripts.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
PATHS: list[str] | None
|
|
63
|
+
SCRIPTS: list[SierraInvokerScript]
|
sierra/client.py
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import importlib.util
|
|
2
|
+
import pathlib
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
import sierra.core.builder as sierra_core_builder
|
|
8
|
+
import sierra.core.compiler as sierra_core_compiler
|
|
9
|
+
import sierra.core.environment as sierra_core_environment
|
|
10
|
+
import sierra.core.loader as sierra_core_loader
|
|
11
|
+
import sierra.internal.cache as sierra_internal_cache
|
|
12
|
+
import sierra.internal.errors as sierra_internal_errors
|
|
13
|
+
import sierra.internal.logger as sierra_internal_logger
|
|
14
|
+
import sierra.invoker as sierra_invoker
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class InvokerWithLoad(typing.Protocol):
|
|
18
|
+
"""
|
|
19
|
+
Protocol for invoker scripts with a load method.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
client : SierraDevelopmentClient
|
|
24
|
+
The client instance to use for loading the invoker script.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def load(self, client: "SierraDevelopmentClient") -> None:
|
|
28
|
+
"""
|
|
29
|
+
Load the invoker script.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
client : SierraDevelopmentClient
|
|
34
|
+
The client instance to use for loading the invoker script.
|
|
35
|
+
"""
|
|
36
|
+
client.logger.log("Loading invoker script", "debug")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ClientParams(typing.TypedDict, total=False):
|
|
40
|
+
"""
|
|
41
|
+
A typed dictionary for passing client parameters.
|
|
42
|
+
|
|
43
|
+
Attributes
|
|
44
|
+
----------
|
|
45
|
+
logger : UniversalLogger, optional
|
|
46
|
+
The logger instance for capturing client activity.
|
|
47
|
+
cache : CacheManager, optional
|
|
48
|
+
The cache manager instance for handling caching operations.
|
|
49
|
+
|
|
50
|
+
Notes
|
|
51
|
+
-----
|
|
52
|
+
This TypedDict structure is used to encapsulate optional client parameters
|
|
53
|
+
that can be provided to the SierraDevelopmentClient.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
logger: sierra_internal_logger.UniversalLogger
|
|
57
|
+
cache: sierra_internal_cache.CacheManager
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class SierraDevelopmentClient:
|
|
61
|
+
def __init__(
|
|
62
|
+
self,
|
|
63
|
+
environment_path: pathlib.Path = pathlib.Path.cwd(),
|
|
64
|
+
environment_name: str = "default_env",
|
|
65
|
+
**kwargs: typing.Unpack[ClientParams],
|
|
66
|
+
) -> None:
|
|
67
|
+
"""
|
|
68
|
+
Initialize the Sierra Development Client.
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
environment_path : pathlib.Path
|
|
73
|
+
Path to the root of the Sierra environment.
|
|
74
|
+
environment_name : str
|
|
75
|
+
Name of the environment configuration to load.
|
|
76
|
+
**kwargs : ClientParams
|
|
77
|
+
Optional: logger and cache manager.
|
|
78
|
+
"""
|
|
79
|
+
self.logger: sierra_internal_logger.UniversalLogger = kwargs.get(
|
|
80
|
+
"logger", sierra_internal_logger.UniversalLogger()
|
|
81
|
+
)
|
|
82
|
+
self.logger.log("Logger initialized", "debug")
|
|
83
|
+
self.logger.log(
|
|
84
|
+
"Starting Sierra Development Client initialization", "info"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
self.environment: sierra_core_environment.SierraDevelopmentEnvironment = sierra_core_environment.SierraDevelopmentEnvironment(
|
|
88
|
+
client=self,
|
|
89
|
+
name=environment_name,
|
|
90
|
+
path=environment_path,
|
|
91
|
+
)
|
|
92
|
+
self.logger.log(
|
|
93
|
+
f"Environment created: name={self.environment.name}, path={self.environment.path}",
|
|
94
|
+
"debug",
|
|
95
|
+
)
|
|
96
|
+
self.logger.log("Initializing environment...", "debug")
|
|
97
|
+
self.environment.init()
|
|
98
|
+
self.logger.log("Environment initialized successfully", "debug")
|
|
99
|
+
|
|
100
|
+
self.cache: sierra_internal_cache.CacheManager = kwargs.get(
|
|
101
|
+
"cache",
|
|
102
|
+
sierra_internal_cache.CacheManager(
|
|
103
|
+
cache_dir=self.environment.config_path / "cache"
|
|
104
|
+
),
|
|
105
|
+
)
|
|
106
|
+
self.logger.log("Cache manager initialized", "debug")
|
|
107
|
+
|
|
108
|
+
self.http_client: httpx.Client = httpx.Client(
|
|
109
|
+
headers={"User-Agent": "Sierra-dev/1.0"}
|
|
110
|
+
)
|
|
111
|
+
self.logger.log("HTTP client initialized", "debug")
|
|
112
|
+
|
|
113
|
+
self.loader: sierra_core_loader.SierraSideloader = (
|
|
114
|
+
sierra_core_loader.SierraSideloader(client=self)
|
|
115
|
+
)
|
|
116
|
+
self.logger.log("Initializing sideloader", "debug")
|
|
117
|
+
self.loader.populate()
|
|
118
|
+
self.logger.log(
|
|
119
|
+
f"sideloader populated with sources count={len(self.loader.sources)}",
|
|
120
|
+
"debug",
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
self.invokers: list[sierra_invoker.InvokerScript] = []
|
|
124
|
+
self.logger.log("Preparing invokers list", "debug")
|
|
125
|
+
|
|
126
|
+
self.builder = sierra_core_builder.SierraInvokerBuilder(client=self)
|
|
127
|
+
self.logger.log("Initializing invoker builder", "debug")
|
|
128
|
+
self.compiler = sierra_core_compiler.SierraCompiler(client=self)
|
|
129
|
+
self.logger.log("Initializing compiler", "debug")
|
|
130
|
+
|
|
131
|
+
self.logger.log(
|
|
132
|
+
"Sierra Development Client initialization complete", "info"
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
def load_invoker(self, invoker: "sierra_invoker.InvokerScript") -> None:
|
|
136
|
+
"""
|
|
137
|
+
Register a single invoker instance with the client.
|
|
138
|
+
|
|
139
|
+
Parameters
|
|
140
|
+
----------
|
|
141
|
+
invoker : InvokerScript
|
|
142
|
+
An instance of an InvokerScript.
|
|
143
|
+
"""
|
|
144
|
+
if invoker not in self.invokers:
|
|
145
|
+
self.invokers.append(invoker)
|
|
146
|
+
self.logger.log(f"Invoker {invoker.name} registered", "debug")
|
|
147
|
+
else:
|
|
148
|
+
self.logger.log(
|
|
149
|
+
f"Invoker {invoker.name} already registered", "warning"
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
def unload_invoker(self, invoker: "sierra_invoker.InvokerScript") -> None:
|
|
153
|
+
"""
|
|
154
|
+
Unregister a single invoker instance from the client.
|
|
155
|
+
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
invoker : InvokerScript
|
|
159
|
+
An instance of an InvokerScript.
|
|
160
|
+
"""
|
|
161
|
+
if invoker in self.invokers:
|
|
162
|
+
self.invokers.remove(invoker)
|
|
163
|
+
self.logger.log(f"Invoker unregistered: {invoker.name}", "debug")
|
|
164
|
+
else:
|
|
165
|
+
self.logger.log(f"Invoker not found: {invoker.name}", "warning")
|
|
166
|
+
|
|
167
|
+
def load_invokers_from_scripts(self) -> None:
|
|
168
|
+
"""
|
|
169
|
+
Automatically discover and load all InvokerScript subclasses
|
|
170
|
+
from .py files in the environment's scripts directory.
|
|
171
|
+
"""
|
|
172
|
+
script_dir: pathlib.Path = self.environment.scripts_path.resolve()
|
|
173
|
+
self.logger.log(
|
|
174
|
+
f"Loading invokers from directory: {script_dir}", "info"
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
if not script_dir.is_dir():
|
|
178
|
+
raise sierra_internal_errors.SierraClientPathError(
|
|
179
|
+
f"scripts directory is not a valid directory: {script_dir}"
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
for file_path in script_dir.iterdir():
|
|
183
|
+
if not file_path.is_file() or file_path.suffix != ".py":
|
|
184
|
+
self.logger.log(
|
|
185
|
+
f"Skipping non-Python file: {file_path.name}", "debug"
|
|
186
|
+
)
|
|
187
|
+
continue
|
|
188
|
+
|
|
189
|
+
self.logger.log(f"Processing file: {file_path.name}", "debug")
|
|
190
|
+
try:
|
|
191
|
+
self._load_invoker_file(file_path)
|
|
192
|
+
except Exception as e:
|
|
193
|
+
self.logger.log(
|
|
194
|
+
f"Failed to load invoker from {file_path.name}: {e}",
|
|
195
|
+
"error",
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
def _load_invoker_file(
|
|
199
|
+
self, path_to_invoker: typing.Union[str, pathlib.Path]
|
|
200
|
+
) -> None:
|
|
201
|
+
"""
|
|
202
|
+
Load a Python module containing one or more InvokerScript instances.
|
|
203
|
+
|
|
204
|
+
Parameters
|
|
205
|
+
----------
|
|
206
|
+
path_to_invoker : Union[str, Path]
|
|
207
|
+
Path to the Python file containing the InvokerScript instances.
|
|
208
|
+
|
|
209
|
+
Raises
|
|
210
|
+
------
|
|
211
|
+
SierraClientPathError
|
|
212
|
+
If the file does not exist or is not a Python file.
|
|
213
|
+
SierraClientLoadError
|
|
214
|
+
If no InvokerScript instances are found in the module.
|
|
215
|
+
"""
|
|
216
|
+
path_obj: pathlib.Path = pathlib.Path(path_to_invoker).resolve()
|
|
217
|
+
|
|
218
|
+
self.logger.log(f"Importing module from: {path_obj}", "debug")
|
|
219
|
+
|
|
220
|
+
if not path_obj.is_file() or path_obj.suffix != ".py":
|
|
221
|
+
raise sierra_internal_errors.SierraClientPathError(
|
|
222
|
+
f"Cannot load invoker file: {path_obj}"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
spec = importlib.util.spec_from_file_location(path_obj.stem, path_obj)
|
|
226
|
+
|
|
227
|
+
if not spec or not spec.loader:
|
|
228
|
+
raise sierra_internal_errors.SierraClientPathError(
|
|
229
|
+
f"Cannot create spec for module: {path_obj}"
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
module = importlib.util.module_from_spec(spec)
|
|
233
|
+
spec.loader.exec_module(module) # type: ignore
|
|
234
|
+
self.logger.log(f"Module imported: {path_obj.name}", "debug")
|
|
235
|
+
|
|
236
|
+
found: list[sierra_invoker.InvokerScript] = []
|
|
237
|
+
for obj in vars(module).values():
|
|
238
|
+
if isinstance(obj, sierra_invoker.InvokerScript):
|
|
239
|
+
found.append(obj)
|
|
240
|
+
|
|
241
|
+
if not found:
|
|
242
|
+
raise sierra_internal_errors.SierraClientLoadError(
|
|
243
|
+
f"No InvokerScript instance found in {path_obj.name}"
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
for inv in found:
|
|
247
|
+
self.logger.log(f"Registering invoker: {inv.name}", "debug")
|
|
248
|
+
self.load_invoker(inv)
|
|
249
|
+
loader = typing.cast("InvokerWithLoad", inv)
|
|
250
|
+
if hasattr(inv, "load") and callable(loader.load):
|
|
251
|
+
self.logger.log(f"Executing load() for: {inv.name}", "debug")
|
|
252
|
+
try:
|
|
253
|
+
loader.load(self)
|
|
254
|
+
self.logger.log(f"Loaded invoker: {inv.name}", "info")
|
|
255
|
+
except Exception as err:
|
|
256
|
+
self.logger.log(
|
|
257
|
+
f"Error during load() of {inv.name}: {err}",
|
|
258
|
+
"error",
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
self.logger.log(
|
|
262
|
+
f"Finished processing {path_obj.name}, total invokers found: {len(found)}",
|
|
263
|
+
"debug",
|
|
264
|
+
)
|
sierra/core/__init__.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sierra Core.
|
|
3
|
+
============
|
|
4
|
+
|
|
5
|
+
🔩 Core components of the Sierra Dev framework.
|
|
6
|
+
|
|
7
|
+
# Overview
|
|
8
|
+
--------
|
|
9
|
+
|
|
10
|
+
This package contains the core components of the Sierra Dev framework, including
|
|
11
|
+
builders, compilers, environments, loaders, and base classes for Sierra objects.
|
|
12
|
+
|
|
13
|
+
# Exposed Components
|
|
14
|
+
-----------------
|
|
15
|
+
|
|
16
|
+
- `SierraBuilder`: Base class for building Sierra components.
|
|
17
|
+
- `SierraCompiler`: Base class for compiling Sierra components.
|
|
18
|
+
- [SierraCoreObject](cci:2://file:///home/xsyncio/Downloads/sierra-dev/sierra/core/base.py:14:0-50:9): Base class for all Sierra components.
|
|
19
|
+
- `SierraDevelopmentEnvironment`: Environment configuration class for Sierra development.
|
|
20
|
+
- `SierraInvokerBuilder`: Builder for Sierra invoker scripts.
|
|
21
|
+
- `SierraLoader`: Base class for loading Sierra components.
|
|
22
|
+
- `SierraSideloader`: Base class for side-loading Sierra components.
|
|
23
|
+
|
|
24
|
+
# Integration Notes
|
|
25
|
+
-----------------
|
|
26
|
+
|
|
27
|
+
This package is a fundamental part of the Sierra Dev framework, providing the core
|
|
28
|
+
components for building, compiling, and loading Sierra applications.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from sierra.core.base import SierraCoreObject
|
|
32
|
+
from sierra.core.builder import SierraInvokerBuilder
|
|
33
|
+
from sierra.core.compiler import SierraCompiler
|
|
34
|
+
from sierra.core.environment import SierraDevelopmentEnvironment
|
|
35
|
+
from sierra.core.loader import SierraSideloader
|
|
36
|
+
|
|
37
|
+
__all__ = [
|
|
38
|
+
"SierraCompiler",
|
|
39
|
+
"SierraCoreObject",
|
|
40
|
+
"SierraDevelopmentEnvironment",
|
|
41
|
+
"SierraInvokerBuilder",
|
|
42
|
+
"SierraSideloader",
|
|
43
|
+
]
|
sierra/core/base.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
if typing.TYPE_CHECKING:
|
|
4
|
+
import sierra.client as sierra_client
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
Module providing the SierraCoreObject base class.
|
|
8
|
+
|
|
9
|
+
This module defines the SierraCoreObject, which serves as the foundational class
|
|
10
|
+
for all Sierra components, ensuring each component has access to a common
|
|
11
|
+
SierraDevelopmentClient for logging and API interactions.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SierraCoreObject:
|
|
16
|
+
"""
|
|
17
|
+
Base class for Sierra core objects.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
client : SierraDevelopmentClient
|
|
22
|
+
Client instance used for operations, providing logger and HTTP access.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(
|
|
26
|
+
self, client: "sierra_client.SierraDevelopmentClient"
|
|
27
|
+
) -> None:
|
|
28
|
+
"""
|
|
29
|
+
Initialize a SierraCoreObject.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
client : SierraDevelopmentClient
|
|
34
|
+
The Sierra development client.
|
|
35
|
+
|
|
36
|
+
Notes
|
|
37
|
+
-----
|
|
38
|
+
Logs each initialization step via the client's logger.
|
|
39
|
+
"""
|
|
40
|
+
# Assign client instance
|
|
41
|
+
self.client = client # type: ignore[name-defined]
|
|
42
|
+
# Log the start of initialization
|
|
43
|
+
self.client.logger.log(
|
|
44
|
+
message=f"Initializing SierraCoreObject with client: {client}",
|
|
45
|
+
log_type="debug",
|
|
46
|
+
)
|
|
47
|
+
# Confirm assignment of client
|
|
48
|
+
self.client.logger.log(
|
|
49
|
+
message="SierraCoreObject.client set successfully",
|
|
50
|
+
log_type="debug",
|
|
51
|
+
)
|