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.
@@ -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.0
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.0"
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
 
@@ -1,12 +1,14 @@
1
1
  import logging
2
- from typing import Union, Dict
3
- from src.graylog_api_client.rest_adapter import RestAdapter
4
- from src.graylog_api_client.data_structures import GraylogApiResult
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)
@@ -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 src.graylog_api_client.exceptions import GraylogApiException
7
- from src.graylog_api_client.data_structures import GraylogApiResult
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
- data = response.json()
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=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