Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
cfbd889
initial commit
jaegeral Jun 25, 2026
41d4918
Merge branch 'master' into 2026-06-25-api-client
jaegeral Jun 25, 2026
0c43bbf
typing
jaegeral Jun 25, 2026
4fd1064
Update api_client/python/timesketch_api_client/sketch.py
jaegeral Jun 25, 2026
b0ef14f
Update api_client/python/timesketch_api_client/sketch.py
jaegeral Jun 25, 2026
bdea6b1
Update api_client/python/timesketch_api_client/sketch.py
jaegeral Jun 25, 2026
5151d97
Update api_client/python/timesketch_api_client/client.py
jaegeral Jun 25, 2026
1aba34d
Update api_client/python/timesketch_api_client/sketch.py
jaegeral Jun 25, 2026
d220f04
black
jaegeral Jun 25, 2026
db4a1a3
Update api_client/python/timesketch_api_client/story.py
jaegeral Jun 25, 2026
add2d97
black
jaegeral Jun 25, 2026
e02852b
more readable
jaegeral Jun 25, 2026
f539970
more readable
jaegeral Jun 25, 2026
b469b30
fix errors
jaegeral Jun 25, 2026
cd79ec4
Update api_client/python/timesketch_api_client/aggregation.py
jaegeral Jun 25, 2026
ae25539
Update api_client/python/timesketch_api_client/aggregation.py
jaegeral Jun 25, 2026
c1b2b25
Update api_client/python/timesketch_api_client/aggregation.py
jaegeral Jun 25, 2026
1ff5a5e
Update api_client/python/timesketch_api_client/cli_input.py
jaegeral Jun 25, 2026
b194652
fix errors
jaegeral Jun 25, 2026
28bcfac
fix errors
jaegeral Jun 25, 2026
503480e
black
jaegeral Jun 25, 2026
447daa7
black
jaegeral Jun 25, 2026
611304b
black
jaegeral Jun 25, 2026
4f371bb
Update api_client/python/timesketch_api_client/client.py
jaegeral Jun 25, 2026
c6c6697
Update api_client/python/timesketch_api_client/sketch.py
jaegeral Jun 25, 2026
bf2c62c
Update api_client/python/timesketch_api_client/sketch.py
jaegeral Jun 25, 2026
64acdbc
Update api_client/python/timesketch_api_client/sketch.py
jaegeral Jun 25, 2026
5e08b79
Update api_client/python/timesketch_api_client/aggregation.py
jaegeral Jun 25, 2026
f30a4d7
Update api_client/python/timesketch_api_client/aggregation.py
jaegeral Jun 25, 2026
4cc0d70
update docstring to not mention types
jaegeral Jun 25, 2026
89485e3
Merge branch 'master' into 2026-06-25-api-client
jkppr Jun 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 45 additions & 8 deletions api_client/python/timesketch_api_client/aggregation.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ class Aggregation(resource.SketchResource):
resource_data: dict[str, Any]

def __init__(self, sketch):
"""Initializes the Aggregation object.

Args:
sketch (Sketch): An instance of Sketch object.
"""
self._created_at = ""
self._name = ""
self._parameters = {}
Expand Down Expand Up @@ -288,7 +293,11 @@ def title(self):

@title.setter
def title(self, new_title):
"""Set the chart title of an aggregation."""
"""Set the chart title of an aggregation.

Args:
new_title (str): Chart title.
"""
self.chart_title = new_title

@property
Expand All @@ -307,7 +316,11 @@ def description(self):

@description.setter
def description(self, description):
"""Set the description of an aggregation."""
"""Set the description of an aggregation.

Args:
description (str): Description string.
"""
if "meta" not in self.resource_data:
return
Comment thread
jaegeral marked this conversation as resolved.
Outdated
meta = self.resource_data.get("meta", {})
Expand All @@ -320,7 +333,11 @@ def name(self):

@name.setter
def name(self, name):
"""Set the name of the aggregation."""
"""Set the name of the aggregation.

Args:
name (str): Name of the aggregation.
"""
if "meta" not in self.resource_data:
return
Comment thread
jaegeral marked this conversation as resolved.
Outdated
meta = self.resource_data.get("meta")
Expand Down Expand Up @@ -447,7 +464,11 @@ class AggregationGroup(resource.SketchResource):
"""Aggregation Group object."""

def __init__(self, sketch):
"""Initialize the aggregation group."""
"""Initialize the aggregation group.

Args:
sketch (Sketch): An instance of Sketch object.
"""
resource_uri = "sketches/{0:d}/aggregation/group/".format(sketch.id)
Comment thread
jaegeral marked this conversation as resolved.
Outdated
super().__init__(resource_uri=resource_uri, sketch=sketch)

Expand Down Expand Up @@ -499,7 +520,11 @@ def description(self):

@description.setter
def description(self, description):
"""Sets the description of the aggregation group."""
"""Sets the description of the aggregation group.

Args:
description (str): Description of the aggregation group.
"""
self._description = description
self.save()

Expand All @@ -510,7 +535,11 @@ def name(self):

@name.setter
def name(self, name):
"""Sets the name of the aggregation group."""
"""Sets the name of the aggregation group.

Args:
name (str): Name of the aggregation group.
"""
self._name = name
self.save()

Expand All @@ -521,7 +550,11 @@ def orientation(self):

@orientation.setter
def orientation(self, orientation):
"""Sets the chart orientation."""
"""Sets the chart orientation.

Args:
orientation (str): Chart orientation.
"""
self._orientation = orientation
self.save()

Expand All @@ -532,7 +565,11 @@ def parameters(self):

@parameters.setter
def parameters(self, parameters):
"""Sets the group parameters."""
"""Sets the group parameters.

Args:
parameters (dict): Aggregation group parameters.
Comment thread
jaegeral marked this conversation as resolved.
Outdated
"""
self._parameters = parameters
self.save()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"""Tests for the Timesketch API aggregation object."""

import unittest
import mock
from unittest import mock

import altair as alt

Expand Down
10 changes: 8 additions & 2 deletions api_client/python/timesketch_api_client/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.
"""Timesketch API analyzer result object."""

from __future__ import unicode_literals

import datetime
import json
Expand All @@ -29,7 +28,14 @@ class AnalyzerResult(resource.BaseResource):
"""Class to store and retrieve session information for an analyzer."""

def __init__(self, timeline_id, session_id, sketch_id, api):
"""Initialize the class."""
"""Initialize the class.

Args:
timeline_id (int): The ID of the timeline.
session_id (int): The ID of the analyzer session.
sketch_id (int): The ID of the sketch.
api (TimesketchApi): An instance of TimesketchApi.
"""
self._session_id = session_id
self._sketch_id = sketch_id
self._timeline_id = timeline_id
Expand Down
2 changes: 1 addition & 1 deletion api_client/python/timesketch_api_client/cli_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def ask_question(
Args:
question (str): the text that the user will be prompted.
input_type (type): the type of the input data.
default (object): default value for the question, optional.
default: default value for the question, optional.
Comment thread
jaegeral marked this conversation as resolved.
hide_input (bool): whether the input should be hidden, eg. when asking
for a password.

Expand Down
48 changes: 30 additions & 18 deletions api_client/python/timesketch_api_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.
"""Timesketch API client."""

from __future__ import unicode_literals


import os
Expand Down Expand Up @@ -100,23 +99,24 @@ def __init__(
"""Initializes the TimesketchApi object.

Args:
host_uri: URI to the Timesketch server (https://<server>/).
username: User username.
password: User password.
verify: Verify server SSL certificate.
client_id: The client ID if OAUTH auth is used.
client_secret: The OAUTH client secret if OAUTH is used.
auth_mode: The authentication mode to use. Defaults to 'userpass'
host_uri (str): URI to the Timesketch server (https://<server>/).
username (str): User username.
password (str): User password.
verify (bool): Verify server SSL certificate.
client_id (int): The client ID if OAUTH auth is used.
Comment thread
jaegeral marked this conversation as resolved.
Outdated
client_secret (str): The OAUTH client secret if OAUTH is used.
auth_mode (str): The authentication mode to use. Defaults to 'userpass'
Supported values are 'userpass' (username/password combo),
'http-basic' (HTTP Basic authentication) and oauth.
create_session: Boolean indicating whether the client object
create_session (bool): Boolean indicating whether the client object
should create a session object. If set to False the
function "set_session" needs to be called before proceeding.
retry_count: Number of retries for HTTP requests and internal API
retry_count (int): Number of retries for HTTP requests and internal API
request retries. Defaults to DEFAULT_RETRY_COUNT.
backoff_factor: The backoff factor to use for retries. Defaults to 0.5.
backoff_factor (float): The backoff factor to use for retries. Defaults to 0.5.
auth_timeout: Optional timeout in seconds for the authentication.


Raises:
ConnectionError: If the Timesketch server is unreachable.
RuntimeError: If the client is unable to authenticate to the
Expand Down Expand Up @@ -184,11 +184,19 @@ def session(self):
return self._session

def set_credentials(self, credential_object):
"""Sets the credential object."""
"""Sets the credential object.

Args:
credential_object (credentials.AuthCredentials): Credential object.
"""
self.credentials = credential_object

def set_session(self, session_object):
"""Sets the session object."""
"""Sets the session object.

Args:
session_object (requests.Session): Instance of requests.Session.
"""
self._session = session_object

def _authenticate_session(self, session, username, password):
Expand Down Expand Up @@ -482,7 +490,7 @@ def _send_request_with_retry(self, method, resource_uri, **kwargs):
Args:
method (str): HTTP method (e.g., 'GET', 'POST').
resource_uri (str): The URI for the resource.
**kwargs: Keyword arguments passed to the request.
**kwargs: Optional arguments to send with the request.

Returns:
dict: The JSON response data.
Expand Down Expand Up @@ -661,7 +669,7 @@ def get_user(self, user_id):
"""Get a user.

Args:
user_id: Primary key ID of the user.
user_id (int): Primary key ID of the user.

Returns:
Instance of a User object.
Expand All @@ -681,7 +689,7 @@ def get_sketch(self, sketch_id):
"""Get a sketch.

Args:
sketch_id: Primary key ID of the sketch.
sketch_id (int): Primary key ID of the sketch.

Returns:
Instance of a Sketch object.
Expand Down Expand Up @@ -782,7 +790,7 @@ def get_searchindex(self, searchindex_id):
"""Get a searchindex.

Args:
searchindex_id: Primary key ID of the searchindex.
searchindex_id (int): Primary key ID of the searchindex.

Returns:
Instance of a SearchIndex object.
Expand Down Expand Up @@ -966,7 +974,7 @@ def get_sigmarule(self, rule_uuid):
Fetches a single Sigma rule selected by the `UUID`

Args:
rule_uuid: UUID of the Sigma rule.
rule_uuid (str): UUID of the Sigma rule.

Returns:
Instance of a SigmaRule object.
Expand Down Expand Up @@ -1015,6 +1023,10 @@ def increment(self, *args, **kwargs):
This method is called by urllib3 before each retry attempt. It's overridden
here to add custom logging for 5xx errors and to enhance the final
MaxRetryError message with server response details and attempt count.

Args:
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.
"""
response = kwargs.get("response")
decoded_body = None
Expand Down
1 change: 0 additions & 1 deletion api_client/python/timesketch_api_client/client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.
"""Tests for the Timesketch API client"""

from __future__ import unicode_literals

import unittest
from unittest import mock
Expand Down
15 changes: 8 additions & 7 deletions api_client/python/timesketch_api_client/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from . import cli_input
from . import credentials as ts_credentials
from . import crypto
from . import definitions

logger = logging.getLogger("timesketch_api.config_assistance")

Expand Down Expand Up @@ -221,7 +222,7 @@ def has_config(self, name: Text) -> bool:
def load_config_file(
self,
config_file_path: Optional[Text] = "",
section: Optional[Text] = "timesketch",
section: Optional[Text] = definitions.DEFAULT_CONFIG_SECTION,
load_cli_config: Optional[bool] = False,
):
"""Load the config from file.
Expand Down Expand Up @@ -271,7 +272,7 @@ def load_config_file(
return

if not section:
section = "timesketch"
section = definitions.DEFAULT_CONFIG_SECTION

if section not in config.sections():
logger.warning("No %s section in the config", section)
Expand Down Expand Up @@ -322,7 +323,7 @@ def load_config_dict(self, config_dict: Dict[Text, Text]):
def save_config(
self,
file_path: Optional[Text] = "",
section: Optional[Text] = "timesketch",
section: Optional[Text] = definitions.DEFAULT_CONFIG_SECTION,
token_file_path: Optional[Text] = "",
):
"""Save the current config to a file.
Expand Down Expand Up @@ -364,7 +365,7 @@ def save_config(
auth_mode = "userpass"

if not section:
section = "timesketch"
section = definitions.DEFAULT_CONFIG_SECTION

config[section] = {
"host_uri": self._config.get("host_uri"),
Expand Down Expand Up @@ -404,15 +405,15 @@ def set_config(self, name: Text, value: Any):

Args:
name (str): the name of the configuration value to be set.
value (object): the value of the configuration object.
value: the value of the configuration object.
"""
self._config[name.lower()] = value


def get_client(
config_dict: Optional[Dict[Text, Any]] = None,
config_path: Optional[Text] = "",
config_section: Optional[Text] = "timesketch",
config_section: Optional[Text] = definitions.DEFAULT_CONFIG_SECTION,
token_password: Optional[Text] = "",
confirm_choices: Optional[bool] = False,
load_cli_config: Optional[bool] = False,
Expand Down Expand Up @@ -487,7 +488,7 @@ def configure_missing_parameters(
config_assistant: ConfigAssistant,
token_password: Optional[Text] = "",
confirm_choices: Optional[bool] = False,
config_section: Optional[Text] = "timesketch",
config_section: Optional[Text] = definitions.DEFAULT_CONFIG_SECTION,
):
"""Fill in missing configuration for a config assistant.

Expand Down
1 change: 0 additions & 1 deletion api_client/python/timesketch_api_client/config_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.
"""Tests for the Timesketch config library for the API client."""

from __future__ import unicode_literals

import unittest
import tempfile
Expand Down
7 changes: 5 additions & 2 deletions api_client/python/timesketch_api_client/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
credential objects Timesketch supports.
"""

from __future__ import unicode_literals

import json

Expand All @@ -41,7 +40,11 @@ def credential(self):

@credential.setter
def credential(self, credential_obj):
"""Sets the credential object."""
"""Sets the credential object.

Args:
credential_obj (object): The credential object.
"""
self._credential = credential_obj

def serialize(self):
Expand Down
Loading
Loading