Skip to content

Commit 8e67381

Browse files
authored
docs: autogenerate docs (#56)
* wip * chore: stubbed workflow * chore: fixed 3.10 typing issue with backslash in fstring * fix: updated docs workflow- tokens and client payload * fix: updated doc workflow- changed repo to sdk
1 parent 9ebf762 commit 8e67381

File tree

6 files changed

+930
-7
lines changed

6 files changed

+930
-7
lines changed

.github/workflows/docs.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Notify Documentation Update
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "docs/**"
8+
- "scripts/make_docs.py"
9+
workflow_dispatch:
10+
11+
jobs:
12+
notify-docs:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/create-github-app-token@df432ceedc7162793a195dd1713ff69aefc7379e # v2.0.6
16+
id: app-token
17+
with:
18+
app-id: ${{ vars.UPDATE_DOCS_APP_ID }}
19+
private-key: ${{ secrets.UPDATE_DOCS_PRIVATE_KEY }}
20+
owner: "${{ github.repository_owner }}"
21+
repositories: |
22+
sdk
23+
prod-docs
24+
25+
- name: Trigger docs repository workflow
26+
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3.0.0
27+
with:
28+
token: ${{ steps.app-token.outputs.token }}
29+
repository: dreadnode/prod-docs
30+
event-type: code-update
31+
client-payload: '{"repository": "${{ github.repository }}", "ref": "${{ github.ref }}", "sha": "${{ github.sha }}", "product": "strikes", "docs_dir": "docs", "module_dir": "dreadnode"}'

dreadnode/api/client.py

Lines changed: 122 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@
3737

3838

3939
class ApiClient:
40-
"""Client for the Dreadnode API."""
40+
"""Client for the Dreadnode API.
41+
42+
This class provides methods to interact with the Dreadnode API, including
43+
retrieving projects, runs, tasks, and exporting data.
44+
"""
4145

4246
def __init__(
4347
self,
@@ -46,6 +50,13 @@ def __init__(
4650
*,
4751
debug: bool = False,
4852
):
53+
"""Initializes the API client.
54+
55+
Args:
56+
base_url (str): The base URL of the Dreadnode API.
57+
api_key (str): The API key for authentication.
58+
debug (bool, optional): Whether to enable debug logging. Defaults to False.
59+
"""
4960
self._base_url = base_url.rstrip("/")
5061
if not self._base_url.endswith("/api"):
5162
self._base_url += "/api"
@@ -65,7 +76,11 @@ def __init__(
6576
self._client.event_hooks["response"].append(self._log_response)
6677

6778
def _log_request(self, request: httpx.Request) -> None:
68-
"""Log every request to the console if debug is enabled."""
79+
"""Logs HTTP requests if debug mode is enabled.
80+
81+
Args:
82+
request (httpx.Request): The HTTP request object.
83+
"""
6984

7085
logger.debug("-------------------------------------------")
7186
logger.debug("%s %s", request.method, request.url)
@@ -74,7 +89,11 @@ def _log_request(self, request: httpx.Request) -> None:
7489
logger.debug("-------------------------------------------")
7590

7691
def _log_response(self, response: httpx.Response) -> None:
77-
"""Log every response to the console if debug is enabled."""
92+
"""Logs HTTP responses if debug mode is enabled.
93+
94+
Args:
95+
response (httpx.Response): The HTTP response object.
96+
"""
7897

7998
logger.debug("-------------------------------------------")
8099
logger.debug("Response: %s", response.status_code)
@@ -83,7 +102,14 @@ def _log_response(self, response: httpx.Response) -> None:
83102
logger.debug("--------------------------------------------")
84103

85104
def _get_error_message(self, response: httpx.Response) -> str:
86-
"""Get the error message from the response."""
105+
"""Extracts the error message from an HTTP response.
106+
107+
Args:
108+
response (httpx.Response): The HTTP response object.
109+
110+
Returns:
111+
str: The error message extracted from the response.
112+
"""
87113

88114
try:
89115
obj = response.json()
@@ -98,7 +124,17 @@ def _request(
98124
params: dict[str, t.Any] | None = None,
99125
json_data: dict[str, t.Any] | None = None,
100126
) -> httpx.Response:
101-
"""Make a raw request to the API."""
127+
"""Makes a raw HTTP request to the API.
128+
129+
Args:
130+
method (str): The HTTP method (e.g., "GET", "POST").
131+
path (str): The API endpoint path.
132+
params (dict[str, Any] | None, optional): Query parameters for the request. Defaults to None.
133+
json_data (dict[str, Any] | None, optional): JSON payload for the request. Defaults to None.
134+
135+
Returns:
136+
httpx.Response: The HTTP response object.
137+
"""
102138

103139
return self._client.request(method, path, json=json_data, params=params)
104140

@@ -109,7 +145,20 @@ def request(
109145
params: dict[str, t.Any] | None = None,
110146
json_data: dict[str, t.Any] | None = None,
111147
) -> httpx.Response:
112-
"""Make a request to the API. Raise an exception for non-200 status codes."""
148+
"""Makes an HTTP request to the API and raises exceptions for errors.
149+
150+
Args:
151+
method (str): The HTTP method (e.g., "GET", "POST").
152+
path (str): The API endpoint path.
153+
params (dict[str, Any] | None, optional): Query parameters for the request. Defaults to None.
154+
json_data (dict[str, Any] | None, optional): JSON payload for the request. Defaults to None.
155+
156+
Returns:
157+
httpx.Response: The HTTP response object.
158+
159+
Raises:
160+
RuntimeError: If the response status code indicates an error.
161+
"""
113162

114163
response = self._request(method, path, params, json_data)
115164

@@ -121,10 +170,23 @@ def request(
121170
return response
122171

123172
def list_projects(self) -> list[Project]:
173+
"""Retrieves a list of projects.
174+
175+
Returns:
176+
list[Project]: A list of Project objects.
177+
"""
124178
response = self.request("GET", "/strikes/projects")
125179
return [Project(**project) for project in response.json()]
126180

127181
def get_project(self, project: str) -> Project:
182+
"""Retrieves details of a specific project.
183+
184+
Args:
185+
project (str): The project identifier.
186+
187+
Returns:
188+
Project: The Project object.
189+
"""
128190
response = self.request("GET", f"/strikes/projects/{project!s}")
129191
return Project(**response.json())
130192

@@ -193,6 +255,17 @@ def export_runs(
193255
status: StatusFilter = "completed",
194256
aggregations: list[MetricAggregationType] | None = None,
195257
) -> pd.DataFrame:
258+
"""Exports run data for a specific project.
259+
260+
Args:
261+
project (str): The project identifier.
262+
filter (str | None, optional): A filter to apply to the exported data. Defaults to None.
263+
status (StatusFilter, optional): The status of runs to include. Defaults to "completed".
264+
aggregations (list[MetricAggregationType] | None, optional): A list of aggregation types to apply. Defaults to None.
265+
266+
Returns:
267+
pd.DataFrame: A DataFrame containing the exported run data.
268+
"""
196269
response = self.request(
197270
"GET",
198271
f"/strikes/projects/{project!s}/export",
@@ -215,6 +288,18 @@ def export_metrics(
215288
metrics: list[str] | None = None,
216289
aggregations: list[MetricAggregationType] | None = None,
217290
) -> pd.DataFrame:
291+
"""Exports metric data for a specific project.
292+
293+
Args:
294+
project (str): The project identifier.
295+
filter (str | None, optional): A filter to apply to the exported data. Defaults to None.
296+
status (StatusFilter, optional): The status of metrics to include. Defaults to "completed".
297+
metrics (list[str] | None, optional): A list of metric names to include. Defaults to None.
298+
aggregations (list[MetricAggregationType] | None, optional): A list of aggregation types to apply. Defaults to None.
299+
300+
Returns:
301+
pd.DataFrame: A DataFrame containing the exported metric data.
302+
"""
218303
response = self.request(
219304
"GET",
220305
f"/strikes/projects/{project!s}/export/metrics",
@@ -239,6 +324,19 @@ def export_parameters(
239324
metrics: list[str] | None = None,
240325
aggregations: list[MetricAggregationType] | None = None,
241326
) -> pd.DataFrame:
327+
"""Exports parameter data for a specific project.
328+
329+
Args:
330+
project (str): The project identifier.
331+
filter (str | None, optional): A filter to apply to the exported data. Defaults to None.
332+
status (StatusFilter, optional): The status of parameters to include. Defaults to "completed".
333+
parameters (list[str] | None, optional): A list of parameter names to include. Defaults to None.
334+
metrics (list[str] | None, optional): A list of metric names to include. Defaults to None.
335+
aggregations (list[MetricAggregationType] | None, optional): A list of aggregation types to apply. Defaults to None.
336+
337+
Returns:
338+
pd.DataFrame: A DataFrame containing the exported parameter data.
339+
"""
242340
response = self.request(
243341
"GET",
244342
f"/strikes/projects/{project!s}/export/parameters",
@@ -264,6 +362,19 @@ def export_timeseries(
264362
time_axis: TimeAxisType = "relative",
265363
aggregations: list[TimeAggregationType] | None = None,
266364
) -> pd.DataFrame:
365+
"""Exports timeseries data for a specific project.
366+
367+
Args:
368+
project (str): The project identifier.
369+
filter (str | None, optional): A filter to apply to the exported data. Defaults to None.
370+
status (StatusFilter, optional): The status of timeseries to include. Defaults to "completed".
371+
metrics (list[str] | None, optional): A list of metric names to include. Defaults to None.
372+
time_axis (TimeAxisType, optional): The type of time axis to use. Defaults to "relative".
373+
aggregations (list[TimeAggregationType] | None, optional): A list of aggregation types to apply. Defaults to None.
374+
375+
Returns:
376+
pd.DataFrame: A DataFrame containing the exported timeseries data.
377+
"""
267378
response = self.request(
268379
"GET",
269380
f"/strikes/projects/{project!s}/export/timeseries",
@@ -281,5 +392,10 @@ def export_timeseries(
281392
# User data access
282393

283394
def get_user_data_credentials(self) -> UserDataCredentials:
395+
"""Retrieves user data credentials.
396+
397+
Returns:
398+
UserDataCredentials: The user data credentials object.
399+
"""
284400
response = self.request("GET", "/user-data/credentials")
285401
return UserDataCredentials(**response.json())

0 commit comments

Comments
 (0)