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 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
@@ -0,0 +1,6 @@
1
+ import sierra._about as sierra_about
2
+
3
+
4
+ def cli() -> None:
5
+ print(f"sierra-dev {sierra_about.__version__}")
6
+ print(f"Github: {sierra_about.__github__}")
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
@@ -0,0 +1,9 @@
1
+ import typing
2
+
3
+
4
+ class SierraABC(typing.TypedDict, total=False):
5
+ """
6
+ Base class for all Sierra ABCs.
7
+
8
+ This class is used to define the structure of Sierra ABCs.
9
+ """
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
+ )
@@ -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
+ )