automizor 0.3.1__py3-none-any.whl → 0.4.1__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.
- automizor/__init__.py +1 -1
- automizor/exceptions.py +69 -0
- automizor/job/__init__.py +0 -2
- automizor/job/_job.py +15 -18
- automizor/log/__init__.py +95 -0
- automizor/log/_log.py +91 -0
- automizor/storage/__init__.py +101 -2
- automizor/storage/_storage.py +169 -34
- automizor/utils/__init__.py +31 -0
- automizor/vault/__init__.py +35 -6
- automizor/vault/_container.py +3 -2
- automizor/vault/_vault.py +68 -68
- {automizor-0.3.1.dist-info → automizor-0.4.1.dist-info}/METADATA +2 -2
- automizor-0.4.1.dist-info/RECORD +17 -0
- {automizor-0.3.1.dist-info → automizor-0.4.1.dist-info}/WHEEL +1 -1
- automizor/job/_exceptions.py +0 -2
- automizor/job.py +0 -132
- automizor/storage/_exceptions.py +0 -2
- automizor/storage.py +0 -0
- automizor/vault/_exceptions.py +0 -2
- automizor/vault/_secret.py +0 -45
- automizor/vault.py +0 -190
- automizor-0.3.1.dist-info/RECORD +0 -20
- {automizor-0.3.1.dist-info → automizor-0.4.1.dist-info}/LICENSE +0 -0
- {automizor-0.3.1.dist-info → automizor-0.4.1.dist-info}/top_level.txt +0 -0
automizor/job.py
DELETED
@@ -1,132 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import os
|
3
|
-
from typing import Any, Dict, List, Union
|
4
|
-
|
5
|
-
import requests
|
6
|
-
|
7
|
-
JSONType = Union[str, int, float, bool, None, Dict[str, Any], List[Any]]
|
8
|
-
|
9
|
-
|
10
|
-
class AutomizorJobError(RuntimeError):
|
11
|
-
"""Exception raised for errors encountered while interacting with the Job."""
|
12
|
-
|
13
|
-
|
14
|
-
class Job:
|
15
|
-
"""
|
16
|
-
Represents a job in the `Automizor Platform`, managing the retrieval and storage of job
|
17
|
-
context and results.
|
18
|
-
|
19
|
-
This class provides functionality to interact with the `Automizor API` or local files to
|
20
|
-
obtain job context and persist job results.
|
21
|
-
|
22
|
-
For testing purposes, you may want to set the environment variables in your local environment.
|
23
|
-
The required variables are:
|
24
|
-
|
25
|
-
- ``AUTOMIZOR_API_HOST``: The host URL of the `Automizor API`
|
26
|
-
- ``AUTOMIZOR_API_TOKEN``: The token used for authenticating with the `Automizor API`
|
27
|
-
- ``AUTOMIZOR_JOB_ID``: The ID of the job from which to retrieve context
|
28
|
-
|
29
|
-
Additionally, you can specify a local context file; in this case, you don't need to set the
|
30
|
-
above environment variables:
|
31
|
-
|
32
|
-
- ``AUTOMIZOR_CONTEXT_FILE``: The path to a local file containing the job context.
|
33
|
-
|
34
|
-
Example of a local context file:
|
35
|
-
|
36
|
-
.. code-block:: json
|
37
|
-
|
38
|
-
{
|
39
|
-
"key": "value"
|
40
|
-
}
|
41
|
-
|
42
|
-
Example usage:
|
43
|
-
|
44
|
-
.. code-block:: python
|
45
|
-
|
46
|
-
from automizor.job import Job
|
47
|
-
|
48
|
-
job = Job()
|
49
|
-
|
50
|
-
def read_context():
|
51
|
-
context = job.get_job_context()
|
52
|
-
print(context["key"]) # Output: "value"
|
53
|
-
|
54
|
-
def save_result():
|
55
|
-
job.set_job_result("result_key", "result_value")
|
56
|
-
|
57
|
-
"""
|
58
|
-
|
59
|
-
def __init__(self):
|
60
|
-
self._api_host = os.getenv("AUTOMIZOR_API_HOST")
|
61
|
-
self._api_token = os.getenv("AUTOMIZOR_API_TOKEN")
|
62
|
-
self._context_file = os.getenv("AUTOMIZOR_CONTEXT_FILE")
|
63
|
-
self._job_id = os.getenv("AUTOMIZOR_JOB_ID")
|
64
|
-
|
65
|
-
@property
|
66
|
-
def headers(self) -> dict:
|
67
|
-
"""Headers for API requests, including Authorization and Content-Type."""
|
68
|
-
return {
|
69
|
-
"Authorization": f"Token {self._api_token}",
|
70
|
-
"Content-Type": "application/json",
|
71
|
-
}
|
72
|
-
|
73
|
-
def get_job_context(self) -> dict:
|
74
|
-
"""
|
75
|
-
Retrieves the job's context from either a local file or via an API call, based on
|
76
|
-
the configuration.
|
77
|
-
|
78
|
-
If a local context file is specified (via `AUTOMIZOR_CONTEXT_FILE`), it reads the context
|
79
|
-
from the file. Otherwise, it fetches the context from the Automizor API using the job ID
|
80
|
-
and API credentials.
|
81
|
-
|
82
|
-
Returns:
|
83
|
-
A dictionary with the job's context.
|
84
|
-
|
85
|
-
Raises:
|
86
|
-
AutomizorJobError: If retrieving the job context fails.
|
87
|
-
"""
|
88
|
-
|
89
|
-
if self._context_file:
|
90
|
-
return self._read_file_context()
|
91
|
-
return self._read_job_context()
|
92
|
-
|
93
|
-
def set_job_result(self, name: str, value: JSONType):
|
94
|
-
"""
|
95
|
-
Saves a job result into a JSON file (`output/result.json`).
|
96
|
-
|
97
|
-
Updates the file with the new result, creating or overwriting the file as necessary.
|
98
|
-
If the file exists and contains data, it merges the new result with the existing data.
|
99
|
-
|
100
|
-
Parameters:
|
101
|
-
name (str): The key under which to store the result.
|
102
|
-
value (JSONType): The result value, must be JSON serializable.
|
103
|
-
|
104
|
-
Note: Errors during file operations will raise unhandled exceptions.
|
105
|
-
"""
|
106
|
-
|
107
|
-
data = {}
|
108
|
-
file_path = "output/result.json"
|
109
|
-
try:
|
110
|
-
if os.path.exists(file_path):
|
111
|
-
with open(file_path, "r", encoding="utf-8") as file:
|
112
|
-
data = json.load(file)
|
113
|
-
except json.JSONDecodeError:
|
114
|
-
pass
|
115
|
-
|
116
|
-
data[name] = value
|
117
|
-
|
118
|
-
with open(file_path, "w", encoding="utf-8") as file:
|
119
|
-
json.dump(data, file, ensure_ascii=False, indent=4)
|
120
|
-
|
121
|
-
def _read_file_context(self) -> dict:
|
122
|
-
with open(self._context_file, "r", encoding="utf-8") as file:
|
123
|
-
return json.load(file)
|
124
|
-
|
125
|
-
def _read_job_context(self) -> dict:
|
126
|
-
url = f"https://{self._api_host}/api/v1/rpa/job/{self._job_id}/"
|
127
|
-
try:
|
128
|
-
response = requests.get(url, headers=self.headers, timeout=10)
|
129
|
-
response.raise_for_status()
|
130
|
-
return response.json().get("context", {})
|
131
|
-
except Exception as exc:
|
132
|
-
raise AutomizorJobError(f"Failed to get job context: {exc}") from exc
|
automizor/storage/_exceptions.py
DELETED
automizor/storage.py
DELETED
File without changes
|
automizor/vault/_exceptions.py
DELETED
automizor/vault/_secret.py
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
from dataclasses import dataclass
|
2
|
-
|
3
|
-
|
4
|
-
@dataclass
|
5
|
-
class Secret:
|
6
|
-
"""
|
7
|
-
Represents a secret, comprising a name and its associated values.
|
8
|
-
|
9
|
-
Attributes:
|
10
|
-
name: The name of the secret.
|
11
|
-
value: The secret's values, stored in a dictionary as key-value pairs.
|
12
|
-
"""
|
13
|
-
|
14
|
-
name: str
|
15
|
-
value: dict
|
16
|
-
|
17
|
-
def get(self, key, default=None):
|
18
|
-
"""Return the value for key if key is in the dictionary, else default."""
|
19
|
-
return self.value.get(key, default)
|
20
|
-
|
21
|
-
def items(self):
|
22
|
-
"""secret.items() -> a set-like object providing a view on secret's items."""
|
23
|
-
return self.value.items()
|
24
|
-
|
25
|
-
def update(self, pairs: dict) -> None:
|
26
|
-
self.value.update(pairs)
|
27
|
-
|
28
|
-
def __getitem__(self, key):
|
29
|
-
return self.value[key]
|
30
|
-
|
31
|
-
def __setitem__(self, key, value):
|
32
|
-
self.value[key] = value
|
33
|
-
|
34
|
-
def __contains__(self, key):
|
35
|
-
return key in self.value
|
36
|
-
|
37
|
-
def __iter__(self):
|
38
|
-
return iter(self.value)
|
39
|
-
|
40
|
-
def __len__(self):
|
41
|
-
return len(self.value)
|
42
|
-
|
43
|
-
def __repr__(self):
|
44
|
-
keys = ", ".join(self.value.keys())
|
45
|
-
return f"Secret(name={self.name}, keys={keys})"
|
automizor/vault.py
DELETED
@@ -1,190 +0,0 @@
|
|
1
|
-
import json
|
2
|
-
import os
|
3
|
-
from dataclasses import asdict, dataclass
|
4
|
-
|
5
|
-
import requests
|
6
|
-
|
7
|
-
|
8
|
-
class AutomizorVaultError(RuntimeError):
|
9
|
-
"""Exception raised for errors encountered while interacting with the Vault."""
|
10
|
-
|
11
|
-
|
12
|
-
@dataclass
|
13
|
-
class Secret:
|
14
|
-
"""
|
15
|
-
Represents a secret, comprising a name and its associated values.
|
16
|
-
|
17
|
-
Attributes:
|
18
|
-
name (str): The name of the secret.
|
19
|
-
value (dict): The secret's values, stored in a dictionary as key-value pairs.
|
20
|
-
"""
|
21
|
-
|
22
|
-
name: str
|
23
|
-
value: dict
|
24
|
-
|
25
|
-
def get(self, key, default=None):
|
26
|
-
"""Return the value for key if key is in the dictionary, else default."""
|
27
|
-
return self.value.get(key, default)
|
28
|
-
|
29
|
-
def items(self):
|
30
|
-
"""secret.items() -> a set-like object providing a view on secret's items."""
|
31
|
-
return self.value.items()
|
32
|
-
|
33
|
-
def update(self, pairs: dict) -> None:
|
34
|
-
self.value.update(pairs)
|
35
|
-
|
36
|
-
def __getitem__(self, key):
|
37
|
-
return self.value[key]
|
38
|
-
|
39
|
-
def __setitem__(self, key, value):
|
40
|
-
self.value[key] = value
|
41
|
-
|
42
|
-
def __contains__(self, key):
|
43
|
-
return key in self.value
|
44
|
-
|
45
|
-
def __iter__(self):
|
46
|
-
return iter(self.value)
|
47
|
-
|
48
|
-
def __len__(self):
|
49
|
-
return len(self.value)
|
50
|
-
|
51
|
-
def __repr__(self):
|
52
|
-
keys = ", ".join(self.value.keys())
|
53
|
-
return f"Secret(name={self.name}, keys={keys})"
|
54
|
-
|
55
|
-
|
56
|
-
class Vault:
|
57
|
-
"""
|
58
|
-
`Vault` is a library to manage secrets within an the `Automizor Platform`,
|
59
|
-
providing functionality to retrieve and update secrets. It supports interaction
|
60
|
-
with the `Vault API` (by default) or a local file for secret storage, determined
|
61
|
-
by environment variable configuration.
|
62
|
-
|
63
|
-
The Vault class uses environment variables to configure the API host, API token,
|
64
|
-
which are set by the `Automizor Agent`.
|
65
|
-
|
66
|
-
You may want to set the environment variables in your local environment for testing
|
67
|
-
purposes. The variables which must exist are:
|
68
|
-
|
69
|
-
- ``AUTOMIZOR_API_HOST``: The host URL of the `Automizor API`
|
70
|
-
- ``AUTOMIZOR_API_TOKEN``: The token used for authenticating with the `Automizor API`
|
71
|
-
|
72
|
-
In addition, you can set the following environment variable to use a local file for
|
73
|
-
secret storage:
|
74
|
-
|
75
|
-
- ``AUTOMIZOR_SECRET_FILE``: The path to a local file where secrets are stored.
|
76
|
-
|
77
|
-
Example of a local secret file:
|
78
|
-
|
79
|
-
.. code-block:: json
|
80
|
-
|
81
|
-
{
|
82
|
-
"my_secret_name": {
|
83
|
-
"key": "value"
|
84
|
-
}
|
85
|
-
}
|
86
|
-
|
87
|
-
Example usage:
|
88
|
-
|
89
|
-
.. code-block:: python
|
90
|
-
|
91
|
-
from automizor.vault import Vault
|
92
|
-
|
93
|
-
vault = Vault()
|
94
|
-
|
95
|
-
def read_secret():
|
96
|
-
secret = vault.get_secret("my_secret_name")
|
97
|
-
print(secret["key"]) # Output: "value"
|
98
|
-
|
99
|
-
def update_secret():
|
100
|
-
secret = vault.get_secret("my_secret_name")
|
101
|
-
secret["new_key"] = "new_value"
|
102
|
-
vault.set_secret(secret)
|
103
|
-
|
104
|
-
"""
|
105
|
-
|
106
|
-
def __init__(self):
|
107
|
-
self._api_host = os.getenv("AUTOMIZOR_API_HOST")
|
108
|
-
self._api_token = os.getenv("AUTOMIZOR_API_TOKEN")
|
109
|
-
self._secret_file = os.getenv("AUTOMIZOR_SECRET_FILE")
|
110
|
-
|
111
|
-
@property
|
112
|
-
def headers(self) -> dict:
|
113
|
-
"""Headers for API requests, including Authorization and Content-Type."""
|
114
|
-
return {
|
115
|
-
"Authorization": f"Token {self._api_token}",
|
116
|
-
"Content-Type": "application/json",
|
117
|
-
}
|
118
|
-
|
119
|
-
def get_secret(self, name) -> Secret:
|
120
|
-
"""
|
121
|
-
Retrieves a secret by its name. Fetches from a local file or queries the
|
122
|
-
`Automizor API`, based on configuration.
|
123
|
-
|
124
|
-
Args:
|
125
|
-
name (str): The name of the secret to retrieve.
|
126
|
-
|
127
|
-
Returns:
|
128
|
-
Secret: The retrieved secret.
|
129
|
-
|
130
|
-
Raises:
|
131
|
-
AutomizorVaultError: If retrieving the secret fails.
|
132
|
-
"""
|
133
|
-
|
134
|
-
if self._secret_file:
|
135
|
-
return self._read_file_secret(name)
|
136
|
-
return self._read_vault_secret(name)
|
137
|
-
|
138
|
-
def set_secret(self, secret: Secret) -> Secret:
|
139
|
-
"""
|
140
|
-
Updates a secret. Writes to a local file or sends to the `Automizor API`,
|
141
|
-
based on configuration.
|
142
|
-
|
143
|
-
Args:
|
144
|
-
secret (Secret): The secret to update.
|
145
|
-
|
146
|
-
Returns:
|
147
|
-
Secret: The updated secret.
|
148
|
-
|
149
|
-
Raises:
|
150
|
-
AutomizorVaultError: If updating the secret fails.
|
151
|
-
"""
|
152
|
-
|
153
|
-
if self._secret_file:
|
154
|
-
return self._write_file_secret(secret)
|
155
|
-
return self._write_vault_secret(secret)
|
156
|
-
|
157
|
-
def _read_file_secret(self, name: str) -> Secret:
|
158
|
-
with open(self._secret_file, "r", encoding="utf-8") as file:
|
159
|
-
secrets = json.load(file)
|
160
|
-
value = secrets.get(name, {})
|
161
|
-
return Secret(name=name, value=value)
|
162
|
-
|
163
|
-
def _read_vault_secret(self, name: str) -> Secret:
|
164
|
-
url = f"https://{self._api_host}/api/v1/vault/secret/{name}/"
|
165
|
-
try:
|
166
|
-
response = requests.get(url, headers=self.headers, timeout=10)
|
167
|
-
response.raise_for_status()
|
168
|
-
return Secret(**response.json())
|
169
|
-
except Exception as exc:
|
170
|
-
raise AutomizorVaultError(f"Failed to get secret: {exc}") from exc
|
171
|
-
|
172
|
-
def _write_file_secret(self, secret: Secret):
|
173
|
-
with open(self._secret_file, "r+", encoding="utf-8") as file:
|
174
|
-
secrets = json.load(file)
|
175
|
-
secrets[secret.name] = secret.value
|
176
|
-
file.seek(0)
|
177
|
-
file.write(json.dumps(secrets, indent=4))
|
178
|
-
file.truncate()
|
179
|
-
return secret
|
180
|
-
|
181
|
-
def _write_vault_secret(self, secret: Secret) -> Secret:
|
182
|
-
url = f"https://{self._api_host}/api/v1/vault/secret/{secret.name}/"
|
183
|
-
try:
|
184
|
-
response = requests.put(
|
185
|
-
url, headers=self.headers, timeout=10, json=asdict(secret)
|
186
|
-
)
|
187
|
-
response.raise_for_status()
|
188
|
-
return Secret(**response.json())
|
189
|
-
except Exception as exc:
|
190
|
-
raise AutomizorVaultError(f"Failed to set secret: {exc}") from exc
|
automizor-0.3.1.dist-info/RECORD
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
automizor/__init__.py,sha256=sEAhGxRzEBE5t0VjAcJ-336II62pGIQ0eLrs42I-sGU,18
|
2
|
-
automizor/job.py,sha256=L2NkM-BkvJpeO_SH0BMgternD9M83K_Yv_ANhf1k3FI,4354
|
3
|
-
automizor/storage.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
automizor/vault.py,sha256=mluaCcJCMxu2g0iTBJ6ntoZATn8eotfZb4rdzWsBslU,5845
|
5
|
-
automizor/job/__init__.py,sha256=g-n56j50AGPCE23Nm0QFZCrkCa-c_weqvPcEX3I1NQY,1087
|
6
|
-
automizor/job/_exceptions.py,sha256=zngd7Vv4dkCfwmkigaHiyu5gKAgmcRHt095h55KlbDg,121
|
7
|
-
automizor/job/_job.py,sha256=NkoNnJxmdkqdF-Qxm4taal-Go0COVFo57tZAaWM1ihI,5365
|
8
|
-
automizor/storage/__init__.py,sha256=KuWO-Pb4FQXj68Ewv8QZR9XeKsROCR-wusdWf0osaLw,1674
|
9
|
-
automizor/storage/_exceptions.py,sha256=LOtgshWg3gOFhDZlcMWhXLT_q11zpTBEA85NqKnSi4A,129
|
10
|
-
automizor/storage/_storage.py,sha256=IwTw6PYYNwJtGI4ZfiqY0-SkgCoaYnykkP_hHVuy9IU,5777
|
11
|
-
automizor/vault/__init__.py,sha256=Y3FsdG5cdksVO8nBzIPt8Wwxg8VkFtkpu-kn1xWxrGo,1140
|
12
|
-
automizor/vault/_container.py,sha256=QgTZtBQrX8wZSEjJqTkn2_S-rwIRxukdBQYIRd7md_g,1904
|
13
|
-
automizor/vault/_exceptions.py,sha256=Wblvmaj6F0pIiTAH7X3JuxqTprUA5tvuuRAs9YgbiBI,125
|
14
|
-
automizor/vault/_secret.py,sha256=pks_3uvD1IhYirOaZ2cAOxX2r9vzvXqLa-aDzJysreE,1136
|
15
|
-
automizor/vault/_vault.py,sha256=G1IryuPfXeMUMoAFmGgPibD70zn307KQLNcNitd3D1A,4825
|
16
|
-
automizor-0.3.1.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
17
|
-
automizor-0.3.1.dist-info/METADATA,sha256=SkNNe2kHyA9aGX2275j7RFOy6GqKb9eN3WwQBT3sRpM,661
|
18
|
-
automizor-0.3.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
19
|
-
automizor-0.3.1.dist-info/top_level.txt,sha256=gScDy4I3tP6BMYAsTAlBXrxVh3E00zV0UioxwXJOI3Y,10
|
20
|
-
automizor-0.3.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|