Skip to content

Commit d68cc4b

Browse files
committed
Update docs for s3 auto refresh token logic
1 parent c49cb0e commit d68cc4b

4 files changed

Lines changed: 51 additions & 15 deletions

File tree

docs/sdk/api.mdx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -728,26 +728,41 @@ def get_user(self) -> UserResponse:
728728
### get\_user\_data\_credentials
729729

730730
```python
731-
get_user_data_credentials() -> UserDataCredentials
731+
get_user_data_credentials(
732+
duration: int = DEFAULT_FS_CREDENTIAL_DURATION,
733+
) -> UserDataCredentials
732734
```
733735

734736
Retrieves user data credentials for secondary storage access.
735737

738+
**Parameters:**
739+
740+
* **`duration`**
741+
(`int`, default:
742+
`DEFAULT_FS_CREDENTIAL_DURATION`
743+
)
744+
–Credential lifetime in seconds (default: 4 hours)
745+
736746
**Returns:**
737747

738748
* `UserDataCredentials`
739749
–The user data credentials object.
740750

741751
<Accordion title="Source code in dreadnode/api/client.py" icon="code">
742752
```python
743-
def get_user_data_credentials(self) -> UserDataCredentials:
753+
def get_user_data_credentials(
754+
self, duration: int = DEFAULT_FS_CREDENTIAL_DURATION
755+
) -> UserDataCredentials:
744756
"""
745757
Retrieves user data credentials for secondary storage access.
746758
759+
Args:
760+
duration: Credential lifetime in seconds (default: 4 hours)
761+
747762
Returns:
748763
The user data credentials object.
749764
"""
750-
response = self.request("GET", "/user-data/credentials")
765+
response = self._request("GET", "/user-data/credentials", params={"duration": duration})
751766
return UserDataCredentials(**response.json())
752767
```
753768

docs/sdk/artifact.mdx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,10 @@ ArtifactStorage
244244
---------------
245245

246246
```python
247-
ArtifactStorage(file_system: AbstractFileSystem)
247+
ArtifactStorage(
248+
file_system: AbstractFileSystem,
249+
credential_refresher: Callable[[], bool] | None = None,
250+
)
248251
```
249252

250253
Storage for artifacts with efficient handling of large files and directories.
@@ -260,17 +263,28 @@ Initialize artifact storage with a file system and prefix path.
260263
* **`file_system`**
261264
(`AbstractFileSystem`)
262265
–FSSpec-compatible file system
266+
* **`credential_refresher`**
267+
(`Callable[[], bool] | None`, default:
268+
`None`
269+
)
270+
–Optional function to refresh credentials when it's about to expire
263271

264272
<Accordion title="Source code in dreadnode/artifact/storage.py" icon="code">
265273
```python
266-
def __init__(self, file_system: fsspec.AbstractFileSystem):
274+
def __init__(
275+
self,
276+
file_system: fsspec.AbstractFileSystem,
277+
credential_refresher: t.Callable[[], bool] | None = None,
278+
):
267279
"""
268280
Initialize artifact storage with a file system and prefix path.
269281
270282
Args:
271283
file_system: FSSpec-compatible file system
284+
credential_refresher: Optional function to refresh credentials when it's about to expire
272285
"""
273286
self._file_system = file_system
287+
self._credential_refresher = credential_refresher
274288
```
275289

276290

@@ -464,6 +478,7 @@ Store a file in the storage system, using multipart upload for large files.
464478

465479
<Accordion title="Source code in dreadnode/artifact/storage.py" icon="code">
466480
```python
481+
@with_credential_refresh
467482
def store_file(self, file_path: Path, target_key: str) -> str:
468483
"""
469484
Store a file in the storage system, using multipart upload for large files.

docs/sdk/main.mdx

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ def __init__(
6565
self._fs_prefix: str = ".dreadnode/storage/"
6666

6767
self._initialized = False
68+
self._credentials: UserDataCredentials | None = None
69+
self._credentials_expiry: datetime | None = None
6870
```
6971

7072

@@ -380,6 +382,7 @@ def continue_run(self, run_context: RunContext) -> RunSpan:
380382
tracer=self._get_tracer(),
381383
file_system=self._fs,
382384
prefix_path=self._fs_prefix,
385+
credential_refresher=self._refresh_storage_credentials if self._credentials else None,
383386
)
384387
```
385388

@@ -523,19 +526,21 @@ def initialize(self) -> None:
523526
# )
524527
# )
525528
# )
526-
527-
credentials = self._api.get_user_data_credentials()
528-
resolved_endpoint = resolve_endpoint(credentials.endpoint)
529+
self._credentials = self._api.get_user_data_credentials(
530+
duration=DEFAULT_FS_CREDENTIAL_DURATION
531+
)
532+
self._credentials_expiry = self._credentials.expiration
533+
resolved_endpoint = resolve_endpoint(self._credentials.endpoint)
529534
self._fs = S3FileSystem(
530-
key=credentials.access_key_id,
531-
secret=credentials.secret_access_key,
532-
token=credentials.session_token,
535+
key=self._credentials.access_key_id,
536+
secret=self._credentials.secret_access_key,
537+
token=self._credentials.session_token,
533538
client_kwargs={
534539
"endpoint_url": resolved_endpoint,
535-
"region_name": credentials.region,
540+
"region_name": self._credentials.region,
536541
},
537542
)
538-
self._fs_prefix = f"{credentials.bucket}/{credentials.prefix}/"
543+
self._fs_prefix = f"{self._credentials.bucket}/{self._credentials.prefix}/"
539544

540545
self._logfire = logfire.configure(
541546
local=not self.is_default,
@@ -1723,6 +1728,7 @@ def run(
17231728
file_system=self._fs,
17241729
prefix_path=self._fs_prefix,
17251730
autolog=autolog,
1731+
credential_refresher=self._refresh_storage_credentials if self._credentials else None,
17261732
)
17271733
```
17281734

docs/sdk/metric.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ Metric
3131
Metric(
3232
value: float,
3333
step: int = 0,
34-
timestamp: datetime = lambda: datetime.now(
35-
timezone.utc
34+
timestamp: datetime = (
35+
lambda: datetime.now(timezone.utc)
3636
)(),
3737
attributes: JsonDict = dict(),
3838
)

0 commit comments

Comments
 (0)