Skip to content

Commit

Permalink
Make lifetime argument to SignedURLService optional
Browse files Browse the repository at this point in the history
Reverse the order of the arguments and default to a one hour
lifetime, since that's a reasonable value for most services and
it's one fewer thing the caller has to think about.
  • Loading branch information
rra committed Jan 12, 2023
1 parent 747c14c commit 0cc5d8e
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 7 deletions.
7 changes: 5 additions & 2 deletions docs/user-guide/gcs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,16 @@ Then, do the following:
from safir.gcs import SignedURLService
url_service = SignedURLService(timedelta(hours=1), "service-account")
url_service = SignedURLService("service-account")
url = url_service.signed_url("s3://bucket/path/to/file", "application/fits")
The first parameter to the constructor is the lifetime of signed URLs, and the second is the name of the Google Cloud service account that will be used to sign the URLs.
The argument to the constructor is the name of the Google Cloud service account that will be used to sign the URLs.
This should be the one for which the workload identity has impersonation permissions.
(Generally, this should be the same service account to which the workload identity is bound.)

Optionally, you can specify the lifetime of the signed URLs as a second argument, which should be a `datetime.timedelta`.
If not given, the default is one hour.

The path to the Google Cloud Storage object for which to create a signed URL must be an S3 URL.
The second argument to `~safir.gcs.SignedURLService.signed_url` is the MIME type of the underlying object, which will be encoded in the signed URL.

Expand Down
8 changes: 5 additions & 3 deletions src/safir/gcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ class SignedURLService:
Parameters
----------
lifetime
Lifetime of the generated signed URLs.
service_account
The service account to use to sign the URLs. The workload identity
must have access to generate service account tokens for that service
account.
lifetime
Lifetime of the generated signed URLs.
Notes
-----
Expand All @@ -41,7 +41,9 @@ class SignedURLService:
additional details on how this works.
"""

def __init__(self, lifetime: timedelta, service_account: str) -> None:
def __init__(
self, service_account: str, lifetime: timedelta = timedelta(hours=1)
) -> None:
self._lifetime = lifetime
self._service_account = service_account
self._gcs = storage.Client()
Expand Down
7 changes: 5 additions & 2 deletions tests/gcs_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@


def test_signed_url(mock_gcs: MockStorageClient) -> None:
url_service = SignedURLService(timedelta(hours=1), "service-account")
url_service = SignedURLService("service-account", timedelta(hours=1))
url = url_service.signed_url("s3://some-bucket/path/to/blob", "text/plain")
assert url == "https://example.com/path/to/blob"

# Test that the lifetime is passed down to the mock, which will reject it
# if it's not an hour.
url_service = SignedURLService(timedelta(minutes=30), "foo")
url_service = SignedURLService("foo", timedelta(minutes=30))
with pytest.raises(AssertionError):
url_service.signed_url("s3://some-bucket/blob", "text/plain")

# Test that lifetime defaults to one hour.
url_service = SignedURLService("foo")

0 comments on commit 0cc5d8e

Please sign in to comment.