graylog-api-client 0.1.0__tar.gz → 0.1.1__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.
- graylog_api_client-0.1.1/LICENSE +21 -0
- {graylog_api_client-0.1.0 → graylog_api_client-0.1.1}/PKG-INFO +7 -3
- {graylog_api_client-0.1.0 → graylog_api_client-0.1.1}/README.md +1 -1
- {graylog_api_client-0.1.0 → graylog_api_client-0.1.1}/pyproject.toml +7 -2
- {graylog_api_client-0.1.0 → graylog_api_client-0.1.1}/src/graylog_api_client/graylog_api_client.py +34 -3
- {graylog_api_client-0.1.0 → graylog_api_client-0.1.1}/src/graylog_api_client/rest_adapter.py +8 -6
- {graylog_api_client-0.1.0 → graylog_api_client-0.1.1}/src/graylog_api_client/__init__.py +0 -0
- {graylog_api_client-0.1.0 → graylog_api_client-0.1.1}/src/graylog_api_client/data_structures.py +0 -0
- {graylog_api_client-0.1.0 → graylog_api_client-0.1.1}/src/graylog_api_client/exceptions.py +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Chrxxxxs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: graylog-api-client
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: A Python wrapper for the Graylog REST API
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: graylog,REST,API Wrapper
|
|
5
8
|
Author: Chrxxxxs
|
|
6
9
|
Author-email: 134285960+Chrxxxxs@users.noreply.github.com
|
|
7
10
|
Requires-Python: >=3.13
|
|
@@ -9,6 +12,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
10
13
|
Classifier: Programming Language :: Python :: 3.14
|
|
11
14
|
Requires-Dist: requests (>=2.32.5,<3.0.0)
|
|
15
|
+
Project-URL: Repository, https://github.com/Chrxxxxs/graylog_api_client
|
|
12
16
|
Description-Content-Type: text/markdown
|
|
13
17
|
|
|
14
18
|
### This is a low level Graylog API Wrapper heavily based on the guide by [pretzel](https://www.pretzellogix.net/2021/12/08/how-to-write-a-python3-sdk-library-module-for-a-json-rest-api/).
|
|
@@ -23,6 +27,6 @@ Planned:
|
|
|
23
27
|
|
|
24
28
|
### Test Environment:
|
|
25
29
|
1. Install docker and docker-compose
|
|
26
|
-
2. Copy the sample docker-compose file by [Graylog](https://github.com/Graylog2/docker-compose) for the open-core and create a .env file with the needed values
|
|
30
|
+
2. Copy the sample docker-compose file by [Graylog](https://github.com/Graylog2/docker-compose) for the open-core (or enterprise if you want to see all API endpoints) and create a .env file with the needed values
|
|
27
31
|
3. docker-compose up
|
|
28
32
|
4. Log in and create an api-key
|
|
@@ -10,6 +10,6 @@ Planned:
|
|
|
10
10
|
|
|
11
11
|
### Test Environment:
|
|
12
12
|
1. Install docker and docker-compose
|
|
13
|
-
2. Copy the sample docker-compose file by [Graylog](https://github.com/Graylog2/docker-compose) for the open-core and create a .env file with the needed values
|
|
13
|
+
2. Copy the sample docker-compose file by [Graylog](https://github.com/Graylog2/docker-compose) for the open-core (or enterprise if you want to see all API endpoints) and create a .env file with the needed values
|
|
14
14
|
3. docker-compose up
|
|
15
15
|
4. Log in and create an api-key
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "graylog-api-client"
|
|
3
|
-
version = "0.1.
|
|
4
|
-
description = ""
|
|
3
|
+
version = "0.1.1"
|
|
4
|
+
description = "A Python wrapper for the Graylog REST API"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Chrxxxxs",email = "134285960+Chrxxxxs@users.noreply.github.com"}
|
|
7
7
|
]
|
|
8
|
+
keywords = ["graylog", "REST", "API Wrapper"]
|
|
9
|
+
license = "MIT"
|
|
8
10
|
readme = "README.md"
|
|
9
11
|
requires-python = ">=3.13"
|
|
10
12
|
dependencies = [
|
|
11
13
|
"requests (>=2.32.5,<3.0.0)",
|
|
12
14
|
]
|
|
13
15
|
|
|
16
|
+
[project.urls]
|
|
17
|
+
Repository = "https://github.com/Chrxxxxs/graylog_api_client"
|
|
18
|
+
|
|
14
19
|
[tool.poetry]
|
|
15
20
|
packages = [{include = "graylog_api_client", from = "src"}]
|
|
16
21
|
|
{graylog_api_client-0.1.0 → graylog_api_client-0.1.1}/src/graylog_api_client/graylog_api_client.py
RENAMED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Union, Dict
|
|
3
|
-
|
|
4
|
-
from
|
|
2
|
+
from typing import List, Union, Dict
|
|
3
|
+
|
|
4
|
+
from .rest_adapter import RestAdapter
|
|
5
|
+
from .data_structures import GraylogApiResult
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class GraylogAPI:
|
|
8
9
|
def __init__(self, host: str, api_key: str, ssl_verify: Union[str, bool] = True, logger: logging.Logger = None):
|
|
9
10
|
self._rest_adapter = RestAdapter(host=host, api_key=api_key, ssl_verify=ssl_verify, logger=logger)
|
|
11
|
+
|
|
10
12
|
# The endpoints grouped like they are in the api-browser
|
|
11
13
|
# /authz Authorization
|
|
12
14
|
def get_auth_grants_overview(self) -> GraylogApiResult:
|
|
@@ -89,6 +91,21 @@ class GraylogAPI:
|
|
|
89
91
|
# /telemetry
|
|
90
92
|
# /token_usage
|
|
91
93
|
# /users
|
|
94
|
+
def create_user(self, username: str, first_name: str, last_name: str, email: str, password: str, permissions: List[str], data: Dict = None) -> GraylogApiResult:
|
|
95
|
+
user_data = {
|
|
96
|
+
"username": username,
|
|
97
|
+
"first_name": first_name,
|
|
98
|
+
"last_name": last_name,
|
|
99
|
+
"email": email,
|
|
100
|
+
"password": password,
|
|
101
|
+
}
|
|
102
|
+
if permissions:
|
|
103
|
+
user_data["permissions"] = permissions
|
|
104
|
+
if data:
|
|
105
|
+
user_data.update(data)
|
|
106
|
+
result = self._rest_adapter.post("users", data=user_data)
|
|
107
|
+
return result
|
|
108
|
+
|
|
92
109
|
def get_users(self, parameters: Dict = None) -> GraylogApiResult:
|
|
93
110
|
result = self._rest_adapter.get("users", parameters)
|
|
94
111
|
return result
|
|
@@ -109,6 +126,20 @@ class GraylogAPI:
|
|
|
109
126
|
result = self._rest_adapter.get(f"users/{user_id}/tokens")
|
|
110
127
|
return result
|
|
111
128
|
|
|
129
|
+
def delete_user_by_id(self, user_id: str) -> GraylogApiResult:
|
|
130
|
+
result = self._rest_adapter.delete(f"users/id/{user_id}")
|
|
131
|
+
return result
|
|
132
|
+
|
|
133
|
+
def delete_user_by_username(self, username: str) -> GraylogApiResult:
|
|
134
|
+
result = self._rest_adapter.delete(f"users/{username}")
|
|
135
|
+
return result
|
|
136
|
+
|
|
137
|
+
def change_user_status(self, user_id: str, status: str) -> GraylogApiResult:
|
|
138
|
+
if status not in ["enabled", "disabled", "deleted"]:
|
|
139
|
+
raise ValueError(f"Status must be either 'enabled', 'disabled' or 'deleted' but was: {status}")
|
|
140
|
+
result = self._rest_adapter.put(f"users/{user_id}/status/{status}")
|
|
141
|
+
return result
|
|
142
|
+
|
|
112
143
|
# /views Main Views Endpoints
|
|
113
144
|
def get_views(self, parameters: Dict = None) -> GraylogApiResult:
|
|
114
145
|
result = self._rest_adapter.get("views", parameters)
|
{graylog_api_client-0.1.0 → graylog_api_client-0.1.1}/src/graylog_api_client/rest_adapter.py
RENAMED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import requests
|
|
3
2
|
import logging
|
|
4
3
|
from typing import Dict, Union
|
|
5
4
|
|
|
6
|
-
from
|
|
7
|
-
from
|
|
5
|
+
from .exceptions import GraylogApiException
|
|
6
|
+
from .data_structures import GraylogApiResult
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
class RestAdapter:
|
|
@@ -21,7 +20,7 @@ class RestAdapter:
|
|
|
21
20
|
self._api_key = api_key
|
|
22
21
|
self._ssl_verify = ssl_verify
|
|
23
22
|
self._session = requests.Session()
|
|
24
|
-
self._session.headers.update({"Accept": "application/json"})
|
|
23
|
+
self._session.headers.update({"Accept": "application/json", "X-Requested-By": "python-graylog-api-client"})
|
|
25
24
|
self._session.auth = (self._api_key, "token") # Graylog uses the format Basic Auth: "<API-token>:token"
|
|
26
25
|
if not ssl_verify:
|
|
27
26
|
requests.packages.urllib3.disable_warnings()
|
|
@@ -46,7 +45,10 @@ class RestAdapter:
|
|
|
46
45
|
self._logger.error(msg=str(e))
|
|
47
46
|
raise GraylogApiException("Invalid API Response") from e
|
|
48
47
|
try:
|
|
49
|
-
|
|
48
|
+
if response.content != b'':
|
|
49
|
+
data_out = response.json()
|
|
50
|
+
else:
|
|
51
|
+
data_out = None
|
|
50
52
|
except (ValueError, requests.exceptions.JSONDecodeError) as e:
|
|
51
53
|
self._logger.error(msg=log_line_post.format(False, None, e))
|
|
52
54
|
raise GraylogApiException("Bad JSON in response") from e
|
|
@@ -54,7 +56,7 @@ class RestAdapter:
|
|
|
54
56
|
log_line = log_line_post.format(is_success, response.status_code, response.reason)
|
|
55
57
|
if is_success:
|
|
56
58
|
self._logger.debug(msg=log_line)
|
|
57
|
-
return GraylogApiResult(status_code=response.status_code, message=response.reason, data=
|
|
59
|
+
return GraylogApiResult(status_code=response.status_code, message=response.reason, data=data_out)
|
|
58
60
|
self._logger.error(msg=log_line)
|
|
59
61
|
raise GraylogApiException(f"{response.status_code}: {response.reason}")
|
|
60
62
|
|
|
File without changes
|
{graylog_api_client-0.1.0 → graylog_api_client-0.1.1}/src/graylog_api_client/data_structures.py
RENAMED
|
File without changes
|
|
File without changes
|