openrelik-api-client 0.2.0__py3-none-any.whl → 0.2.2__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.
- openrelik_api_client/api_client.py +33 -8
- openrelik_api_client/folders.py +28 -3
- openrelik_api_client/workflows.py +12 -14
- {openrelik_api_client-0.2.0.dist-info → openrelik_api_client-0.2.2.dist-info}/METADATA +1 -1
- openrelik_api_client-0.2.2.dist-info/RECORD +8 -0
- openrelik_api_client-0.2.0.dist-info/RECORD +0 -8
- {openrelik_api_client-0.2.0.dist-info → openrelik_api_client-0.2.2.dist-info}/LICENSE +0 -0
- {openrelik_api_client-0.2.0.dist-info → openrelik_api_client-0.2.2.dist-info}/WHEEL +0 -0
@@ -12,6 +12,7 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
import tempfile
|
15
16
|
from requests_toolbelt import MultipartEncoder
|
16
17
|
from requests.exceptions import RequestException
|
17
18
|
import requests
|
@@ -42,34 +43,58 @@ class APIClient:
|
|
42
43
|
api_server_url,
|
43
44
|
api_key=None,
|
44
45
|
api_version="v1",
|
46
|
+
session=None
|
45
47
|
):
|
46
48
|
self.base_url = f"{api_server_url}/api/{api_version}"
|
47
|
-
|
49
|
+
if session:
|
50
|
+
self.session = session
|
51
|
+
else:
|
52
|
+
self.session = TokenRefreshSession(api_server_url, api_key)
|
48
53
|
|
49
54
|
def get(self, endpoint, **kwargs):
|
50
55
|
"""Sends a GET request to the specified API endpoint."""
|
51
56
|
url = f"{self.base_url}{endpoint}"
|
52
|
-
return self.session.
|
57
|
+
return self.session.request("GET", url, **kwargs)
|
53
58
|
|
54
59
|
def post(self, endpoint, data=None, json=None, **kwargs):
|
55
60
|
"""Sends a POST request to the specified API endpoint."""
|
56
61
|
url = f"{self.base_url}{endpoint}"
|
57
|
-
return self.session.
|
62
|
+
return self.session.request("POST", url, data=data, json=json, **kwargs)
|
58
63
|
|
59
64
|
def put(self, endpoint, data=None, **kwargs):
|
60
65
|
"""Sends a PUT request to the specified API endpoint."""
|
61
66
|
url = f"{self.base_url}{endpoint}"
|
62
|
-
return self.session.
|
67
|
+
return self.session.request("PUT", url, data=data, **kwargs)
|
63
68
|
|
64
69
|
def patch(self, endpoint, data=None, json=None, **kwargs):
|
65
70
|
"""Sends a PATCH request to the specified API endpoint."""
|
66
71
|
url = f"{self.base_url}{endpoint}"
|
67
|
-
return self.session.
|
72
|
+
return self.session.request("PATCH", url, data=data, json=json, **kwargs)
|
68
73
|
|
69
74
|
def delete(self, endpoint, **kwargs):
|
70
75
|
"""Sends a DELETE request to the specified API endpoint."""
|
71
76
|
url = f"{self.base_url}{endpoint}"
|
72
|
-
return self.session.
|
77
|
+
return self.session.request("DELETE", url, **kwargs)
|
78
|
+
|
79
|
+
def download_file(self, file_id: int, filename: str) -> str | None:
|
80
|
+
"""Downloads a file from OpenRelik.
|
81
|
+
|
82
|
+
Args:
|
83
|
+
file_id: The ID of the file to download.
|
84
|
+
filename: The name of the file to download.
|
85
|
+
|
86
|
+
Returns:
|
87
|
+
str: The path to the downloaded file.
|
88
|
+
"""
|
89
|
+
endpoint = f"{self.base_url}/files/{file_id}/download"
|
90
|
+
response = self.get(endpoint)
|
91
|
+
filename_prefix, extension = os.path.splitext(filename)
|
92
|
+
file = tempfile.NamedTemporaryFile(
|
93
|
+
mode="wb", prefix=f"{filename_prefix}", suffix=extension, delete=False
|
94
|
+
)
|
95
|
+
file.write(response.content)
|
96
|
+
file.close()
|
97
|
+
return file.name
|
73
98
|
|
74
99
|
def upload_file(
|
75
100
|
self, file_path: str, folder_id: int) -> int | None:
|
@@ -98,7 +123,7 @@ class APIClient:
|
|
98
123
|
raise FileNotFoundError(f"File {file_path} not found.")
|
99
124
|
|
100
125
|
if folder_id:
|
101
|
-
response = self.
|
126
|
+
response = self.get(f"{self.base_url}/folders/{folder_id}")
|
102
127
|
if response.status_code == 404:
|
103
128
|
return file_id
|
104
129
|
|
@@ -119,7 +144,7 @@ class APIClient:
|
|
119
144
|
"application/octet-stream")}
|
120
145
|
)
|
121
146
|
headers = {"Content-Type": encoder.content_type}
|
122
|
-
response = self.
|
147
|
+
response = self.post(
|
123
148
|
f"{self.base_url}{endpoint}",
|
124
149
|
headers=headers,
|
125
150
|
data=encoder.to_string(),
|
openrelik_api_client/folders.py
CHANGED
@@ -12,6 +12,8 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
from typing import Any
|
16
|
+
|
15
17
|
from openrelik_api_client.api_client import APIClient
|
16
18
|
|
17
19
|
|
@@ -36,7 +38,7 @@ class FoldersAPI:
|
|
36
38
|
folder_id = None
|
37
39
|
endpoint = f"{self.api_client.base_url}/folders/"
|
38
40
|
params = {"display_name": display_name}
|
39
|
-
response = self.api_client.
|
41
|
+
response = self.api_client.post(endpoint, json=params)
|
40
42
|
response.raise_for_status()
|
41
43
|
if response.status_code == 201:
|
42
44
|
folder_id = response.json().get('id')
|
@@ -59,7 +61,7 @@ class FoldersAPI:
|
|
59
61
|
folder_id = None
|
60
62
|
endpoint = f"{self.api_client.base_url}/folders/{folder_id}/folders"
|
61
63
|
data = {"display_name": display_name}
|
62
|
-
response = self.api_client.
|
64
|
+
response = self.api_client.post(endpoint, json=data)
|
63
65
|
response.raise_for_status()
|
64
66
|
if response.status_code == 201:
|
65
67
|
folder_id = response.json().get("id")
|
@@ -78,6 +80,29 @@ class FoldersAPI:
|
|
78
80
|
HTTPError: If the API request failed.
|
79
81
|
"""
|
80
82
|
endpoint = f"{self.api_client.base_url}/folders/{folder_id}"
|
81
|
-
response = self.api_client.
|
83
|
+
response = self.api_client.get(endpoint)
|
82
84
|
response.raise_for_status()
|
83
85
|
return response.status_code == 200
|
86
|
+
|
87
|
+
def update_folder(
|
88
|
+
self, folder_id: int, folder_data: dict[str, Any]
|
89
|
+
):
|
90
|
+
"""Updates an existing folder.
|
91
|
+
|
92
|
+
Args:
|
93
|
+
folder_id: The ID of the folder to update.
|
94
|
+
folder_data: The updated folder data.
|
95
|
+
|
96
|
+
Returns:
|
97
|
+
The updated folder data, or None.
|
98
|
+
|
99
|
+
Raises:
|
100
|
+
HTTPError: If the API request failed.
|
101
|
+
"""
|
102
|
+
endpoint = f"{self.api_client.base_url}/folders/{folder_id}"
|
103
|
+
response = self.api_client.patch(
|
104
|
+
endpoint,
|
105
|
+
json=folder_data
|
106
|
+
)
|
107
|
+
response.raise_for_status()
|
108
|
+
return response.json()
|
@@ -21,6 +21,7 @@ class WorkflowsAPI:
|
|
21
21
|
def __init__(self, api_client: APIClient):
|
22
22
|
super().__init__()
|
23
23
|
self.api_client = api_client
|
24
|
+
self.folders_url = f"{self.api_client.base_url}/folders"
|
24
25
|
|
25
26
|
def create_workflow(
|
26
27
|
self, folder_id: int, file_ids: list, template_id: int = None) -> int | None:
|
@@ -38,10 +39,10 @@ class WorkflowsAPI:
|
|
38
39
|
HTTPError: If the API request failed.
|
39
40
|
"""
|
40
41
|
workflow_id = None
|
41
|
-
endpoint = f"{self.
|
42
|
+
endpoint = f"{self.folders_url}/{folder_id}/workflows/"
|
42
43
|
data = {"folder_id": folder_id,
|
43
44
|
"file_ids": file_ids, "template_id": template_id}
|
44
|
-
response = self.api_client.
|
45
|
+
response = self.api_client.post(endpoint, json=data)
|
45
46
|
response.raise_for_status()
|
46
47
|
if response.status_code == 200:
|
47
48
|
workflow_id = response.json().get("id")
|
@@ -60,9 +61,8 @@ class WorkflowsAPI:
|
|
60
61
|
Raises:
|
61
62
|
HTTPError: If the API request failed.
|
62
63
|
"""
|
63
|
-
endpoint = f"{
|
64
|
-
|
65
|
-
response = self.api_client.session.get(endpoint)
|
64
|
+
endpoint = f"{self.folders_url}/{folder_id}/workflows/{workflow_id}"
|
65
|
+
response = self.api_client.get(endpoint)
|
66
66
|
response.raise_for_status()
|
67
67
|
if response.status_code == 200:
|
68
68
|
return response.json()
|
@@ -82,9 +82,8 @@ class WorkflowsAPI:
|
|
82
82
|
HTTPError: If the API request failed.
|
83
83
|
"""
|
84
84
|
workflow = None
|
85
|
-
endpoint = f"{
|
86
|
-
|
87
|
-
response = self.api_client.session.patch(endpoint, json=workflow_data)
|
85
|
+
endpoint = f"{self.folders_url}/{folder_id}/workflows/{workflow_id}"
|
86
|
+
response = self.api_client.patch(endpoint, json=workflow_data)
|
88
87
|
response.raise_for_status()
|
89
88
|
if response.status_code == 200:
|
90
89
|
workflow = response.json()
|
@@ -103,9 +102,8 @@ class WorkflowsAPI:
|
|
103
102
|
Raises:
|
104
103
|
HTTPError: If the API request failed.
|
105
104
|
"""
|
106
|
-
endpoint = f"{
|
107
|
-
|
108
|
-
response = self.api_client.session.delete(endpoint)
|
105
|
+
endpoint = f"{self.folders_url}/{folder_id}/workflows/{workflow_id}"
|
106
|
+
response = self.api_client.delete(endpoint)
|
109
107
|
response.raise_for_status()
|
110
108
|
return response.status_code == 204
|
111
109
|
|
@@ -124,12 +122,12 @@ class WorkflowsAPI:
|
|
124
122
|
HTTPError: If the API request failed.
|
125
123
|
"""
|
126
124
|
workflow = None
|
127
|
-
endpoint =
|
128
|
-
self.
|
125
|
+
endpoint = (
|
126
|
+
f"{self.folders_url}/{folder_id}/workflows/{workflow_id}/run/")
|
129
127
|
workflow = self.get_workflow(folder_id, workflow_id)
|
130
128
|
spec = json.loads(workflow.get('spec_json'))
|
131
129
|
data = {'workflow_spec': spec}
|
132
|
-
response = self.api_client.
|
130
|
+
response = self.api_client.post(endpoint, json=data)
|
133
131
|
response.raise_for_status()
|
134
132
|
if response.status_code == 200:
|
135
133
|
workflow = response.json()
|
@@ -0,0 +1,8 @@
|
|
1
|
+
openrelik_api_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
openrelik_api_client/api_client.py,sha256=lOMGbAEGvUyWooldQaGqVDCk2A0J4spdrzR_J4vlwq8,7620
|
3
|
+
openrelik_api_client/folders.py,sha256=X8PjogrhO9fDBCfGVE63bCm0L4TsY6WxNXntGinPLRk,3426
|
4
|
+
openrelik_api_client/workflows.py,sha256=hVByxpCOQi9ScKGL3IjxxFhkQkKQzKxdwKT-l_stp4Y,4679
|
5
|
+
openrelik_api_client-0.2.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
6
|
+
openrelik_api_client-0.2.2.dist-info/METADATA,sha256=-Io2DGh5DreA96Ha9CFoWNhJ_mvjEXXcT6MbAE9vfPI,2063
|
7
|
+
openrelik_api_client-0.2.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
8
|
+
openrelik_api_client-0.2.2.dist-info/RECORD,,
|
@@ -1,8 +0,0 @@
|
|
1
|
-
openrelik_api_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
openrelik_api_client/api_client.py,sha256=omf6Bwo9-ounH04tb3GJAVkSatGUbjMMI6rTcaYyuFY,6765
|
3
|
-
openrelik_api_client/folders.py,sha256=VWQ3SYTpo5zU1aZ0c50rSqgpBySNHBTKKXmp4z0mrRA,2796
|
4
|
-
openrelik_api_client/workflows.py,sha256=P-1B0MQDujcMmI8R2SmzHtmpeYYoZGwLroZko-HNnd4,4771
|
5
|
-
openrelik_api_client-0.2.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
6
|
-
openrelik_api_client-0.2.0.dist-info/METADATA,sha256=XZBiBVOtWNXQoT94rqEiRBB3nVX2PsH73sqDHCeoz5Y,2063
|
7
|
-
openrelik_api_client-0.2.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
8
|
-
openrelik_api_client-0.2.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|