From b170604b631f4ce2622f086399df478aa642b7d2 Mon Sep 17 00:00:00 2001 From: anitarua Date: Mon, 23 Sep 2024 16:17:54 -0700 Subject: [PATCH 1/5] fix: do not use test util in package --- src/momento/internal/_utilities/_permissions.py | 2 +- src/momento/utilities/shared_sync_asyncio.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/momento/internal/_utilities/_permissions.py b/src/momento/internal/_utilities/_permissions.py index 08df2cbd..d446c38b 100644 --- a/src/momento/internal/_utilities/_permissions.py +++ b/src/momento/internal/_utilities/_permissions.py @@ -25,7 +25,7 @@ TopicPermission, TopicRole, ) -from tests.utils import str_to_bytes +from momento.utilities.shared_sync_asyncio import str_to_bytes class SuperuserPermissions(PredefinedScope): diff --git a/src/momento/utilities/shared_sync_asyncio.py b/src/momento/utilities/shared_sync_asyncio.py index 58411472..d407ba50 100644 --- a/src/momento/utilities/shared_sync_asyncio.py +++ b/src/momento/utilities/shared_sync_asyncio.py @@ -19,3 +19,15 @@ def validate_disposable_token_expiry(expires_in: ExpiresIn) -> None: raise ValueError("Disposable token expiry must be positive") if expires_in.valid_for_seconds() > 60 * 60: raise ValueError("Disposable tokens must expire within 1 hour") + + +def str_to_bytes(string: str) -> bytes: + """Convert a string to bytes. + + Args: + string (str): The string to convert. + + Returns: + bytes: A UTF-8 byte representation of the string. + """ + return string.encode("utf-8") From 0ac70a40c3aefe8c3189b7271774504c2df67152 Mon Sep 17 00:00:00 2001 From: anitarua Date: Mon, 23 Sep 2024 16:28:29 -0700 Subject: [PATCH 2/5] move validators to internal utils --- src/momento/cache_client.py | 2 +- src/momento/cache_client_async.py | 2 +- .../internal/_utilities/_data_validation.py | 15 +++++++++++++++ src/momento/internal/aio/_scs_token_client.py | 2 +- .../internal/synchronous/_scs_token_client.py | 2 +- src/momento/utilities/shared_sync_asyncio.py | 18 ------------------ 6 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/momento/cache_client.py b/src/momento/cache_client.py index f209e5e1..98a81c41 100644 --- a/src/momento/cache_client.py +++ b/src/momento/cache_client.py @@ -8,10 +8,10 @@ from momento.auth import CredentialProvider from momento.config import Configuration from momento.errors import UnknownException +from momento.internal._utilities._data_validation import validate_eager_connection_timeout from momento.requests import CollectionTtl, SortOrder from momento.utilities.shared_sync_asyncio import ( DEFAULT_EAGER_CONNECTION_TIMEOUT_SECONDS, - validate_eager_connection_timeout, ) try: diff --git a/src/momento/cache_client_async.py b/src/momento/cache_client_async.py index d2cf5fec..36f0860f 100644 --- a/src/momento/cache_client_async.py +++ b/src/momento/cache_client_async.py @@ -8,10 +8,10 @@ from momento.auth import CredentialProvider from momento.config import Configuration from momento.errors import UnknownException +from momento.internal._utilities._data_validation import validate_eager_connection_timeout from momento.requests import CollectionTtl, SortOrder from momento.utilities.shared_sync_asyncio import ( DEFAULT_EAGER_CONNECTION_TIMEOUT_SECONDS, - validate_eager_connection_timeout, ) try: diff --git a/src/momento/internal/_utilities/_data_validation.py b/src/momento/internal/_utilities/_data_validation.py index 8d70a4bb..2fcdedd3 100644 --- a/src/momento/internal/_utilities/_data_validation.py +++ b/src/momento/internal/_utilities/_data_validation.py @@ -15,6 +15,7 @@ TSortedSetElements, TSortedSetValues, ) +from momento.utilities.expiration import ExpiresIn DEFAULT_BYTES_CONVERSION_ERROR = "Could not convert the given type to bytes: " DEFAULT_LIST_CONVERSION_ERROR = "The given type is not list[str | bytes]: " @@ -137,3 +138,17 @@ def _validate_request_timeout(request_timeout: Optional[timedelta]) -> None: if request_timeout is None: return _validate_timedelta_ttl(ttl=request_timeout, field_name="Request timeout") + + +def validate_eager_connection_timeout(timeout: timedelta) -> None: + if timeout.total_seconds() < 0: + raise ValueError("The eager connection timeout must be greater than or equal to 0 seconds.") + + +def validate_disposable_token_expiry(expires_in: ExpiresIn) -> None: + if not expires_in.does_expire(): + raise ValueError("Disposable tokens must have an expiry") + if expires_in.valid_for_seconds() < 0: + raise ValueError("Disposable token expiry must be positive") + if expires_in.valid_for_seconds() > 60 * 60: + raise ValueError("Disposable tokens must expire within 1 hour") diff --git a/src/momento/internal/aio/_scs_token_client.py b/src/momento/internal/aio/_scs_token_client.py index 0abb9442..b1369442 100644 --- a/src/momento/internal/aio/_scs_token_client.py +++ b/src/momento/internal/aio/_scs_token_client.py @@ -8,12 +8,12 @@ from momento.auth.credential_provider import CredentialProvider from momento.config.auth_configuration import AuthConfiguration from momento.errors.error_converter import convert_error +from momento.internal._utilities._data_validation import validate_disposable_token_expiry from momento.internal._utilities._permissions import permissions_from_disposable_token_scope from momento.internal.aio._scs_grpc_manager import _TokenGrpcManager from momento.internal.services import Service from momento.responses.auth.generate_disposable_token import GenerateDisposableToken, GenerateDisposableTokenResponse from momento.utilities.expiration import ExpiresIn -from momento.utilities.shared_sync_asyncio import validate_disposable_token_expiry class _ScsTokenClient: diff --git a/src/momento/internal/synchronous/_scs_token_client.py b/src/momento/internal/synchronous/_scs_token_client.py index 61ed046a..8a05fc71 100644 --- a/src/momento/internal/synchronous/_scs_token_client.py +++ b/src/momento/internal/synchronous/_scs_token_client.py @@ -8,12 +8,12 @@ from momento.auth.credential_provider import CredentialProvider from momento.config.auth_configuration import AuthConfiguration from momento.errors.error_converter import convert_error +from momento.internal._utilities._data_validation import validate_disposable_token_expiry from momento.internal._utilities._permissions import permissions_from_disposable_token_scope from momento.internal.services import Service from momento.internal.synchronous._scs_grpc_manager import _TokenGrpcManager from momento.responses.auth.generate_disposable_token import GenerateDisposableToken, GenerateDisposableTokenResponse from momento.utilities.expiration import ExpiresIn -from momento.utilities.shared_sync_asyncio import validate_disposable_token_expiry class _ScsTokenClient: diff --git a/src/momento/utilities/shared_sync_asyncio.py b/src/momento/utilities/shared_sync_asyncio.py index d407ba50..4d8c7a86 100644 --- a/src/momento/utilities/shared_sync_asyncio.py +++ b/src/momento/utilities/shared_sync_asyncio.py @@ -1,26 +1,8 @@ from __future__ import annotations -from datetime import timedelta - -from momento.utilities.expiration import ExpiresIn - DEFAULT_EAGER_CONNECTION_TIMEOUT_SECONDS = 30 -def validate_eager_connection_timeout(timeout: timedelta) -> None: - if timeout.total_seconds() < 0: - raise ValueError("The eager connection timeout must be greater than or equal to 0 seconds.") - - -def validate_disposable_token_expiry(expires_in: ExpiresIn) -> None: - if not expires_in.does_expire(): - raise ValueError("Disposable tokens must have an expiry") - if expires_in.valid_for_seconds() < 0: - raise ValueError("Disposable token expiry must be positive") - if expires_in.valid_for_seconds() > 60 * 60: - raise ValueError("Disposable tokens must expire within 1 hour") - - def str_to_bytes(string: str) -> bytes: """Convert a string to bytes. From e564f65170305d274b6a450dab5838f563804e4c Mon Sep 17 00:00:00 2001 From: anitarua Date: Mon, 23 Sep 2024 16:49:28 -0700 Subject: [PATCH 3/5] slight renaming and add validators to init file --- src/momento/cache_client.py | 4 ++-- src/momento/cache_client_async.py | 4 ++-- src/momento/internal/_utilities/__init__.py | 2 ++ src/momento/internal/_utilities/_data_validation.py | 4 ++-- src/momento/internal/aio/_scs_token_client.py | 4 ++-- src/momento/internal/synchronous/_scs_token_client.py | 4 ++-- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/momento/cache_client.py b/src/momento/cache_client.py index 98a81c41..03ae4d80 100644 --- a/src/momento/cache_client.py +++ b/src/momento/cache_client.py @@ -8,7 +8,7 @@ from momento.auth import CredentialProvider from momento.config import Configuration from momento.errors import UnknownException -from momento.internal._utilities._data_validation import validate_eager_connection_timeout +from momento.internal._utilities._data_validation import _validate_eager_connection_timeout from momento.requests import CollectionTtl, SortOrder from momento.utilities.shared_sync_asyncio import ( DEFAULT_EAGER_CONNECTION_TIMEOUT_SECONDS, @@ -206,7 +206,7 @@ def create( eager_connection_timeout = timedelta(seconds=30) client = CacheClient.create(configuration, credential_provider, ttl_seconds, eager_connection_timeout) """ - validate_eager_connection_timeout(eager_connection_timeout) + _validate_eager_connection_timeout(eager_connection_timeout) # an explicit 0 means that the client disabled eager connections if eager_connection_timeout.total_seconds() != 0: client = CacheClient(configuration, credential_provider, default_ttl) diff --git a/src/momento/cache_client_async.py b/src/momento/cache_client_async.py index 36f0860f..4e27fc8c 100644 --- a/src/momento/cache_client_async.py +++ b/src/momento/cache_client_async.py @@ -8,7 +8,7 @@ from momento.auth import CredentialProvider from momento.config import Configuration from momento.errors import UnknownException -from momento.internal._utilities._data_validation import validate_eager_connection_timeout +from momento.internal._utilities._data_validation import _validate_eager_connection_timeout from momento.requests import CollectionTtl, SortOrder from momento.utilities.shared_sync_asyncio import ( DEFAULT_EAGER_CONNECTION_TIMEOUT_SECONDS, @@ -207,7 +207,7 @@ async def create( eager_connection_timeout = timedelta(seconds=30) client = CacheClientAsync.create(configuration, credential_provider, ttl_seconds, eager_connection_timeout) """ - validate_eager_connection_timeout(eager_connection_timeout) + _validate_eager_connection_timeout(eager_connection_timeout) # an explicit 0 means that the client disabled eager connections if eager_connection_timeout.total_seconds() != 0: client = CacheClientAsync(configuration, credential_provider, default_ttl) diff --git a/src/momento/internal/_utilities/__init__.py b/src/momento/internal/_utilities/__init__.py index 5f64b76c..7845d6f3 100644 --- a/src/momento/internal/_utilities/__init__.py +++ b/src/momento/internal/_utilities/__init__.py @@ -7,6 +7,8 @@ _gen_set_input_as_bytes, _validate_cache_name, _validate_dictionary_name, + _validate_disposable_token_expiry, + _validate_eager_connection_timeout, _validate_list_name, _validate_request_timeout, _validate_set_name, diff --git a/src/momento/internal/_utilities/_data_validation.py b/src/momento/internal/_utilities/_data_validation.py index 2fcdedd3..2f2d7a7f 100644 --- a/src/momento/internal/_utilities/_data_validation.py +++ b/src/momento/internal/_utilities/_data_validation.py @@ -140,12 +140,12 @@ def _validate_request_timeout(request_timeout: Optional[timedelta]) -> None: _validate_timedelta_ttl(ttl=request_timeout, field_name="Request timeout") -def validate_eager_connection_timeout(timeout: timedelta) -> None: +def _validate_eager_connection_timeout(timeout: timedelta) -> None: if timeout.total_seconds() < 0: raise ValueError("The eager connection timeout must be greater than or equal to 0 seconds.") -def validate_disposable_token_expiry(expires_in: ExpiresIn) -> None: +def _validate_disposable_token_expiry(expires_in: ExpiresIn) -> None: if not expires_in.does_expire(): raise ValueError("Disposable tokens must have an expiry") if expires_in.valid_for_seconds() < 0: diff --git a/src/momento/internal/aio/_scs_token_client.py b/src/momento/internal/aio/_scs_token_client.py index b1369442..4899db36 100644 --- a/src/momento/internal/aio/_scs_token_client.py +++ b/src/momento/internal/aio/_scs_token_client.py @@ -8,7 +8,7 @@ from momento.auth.credential_provider import CredentialProvider from momento.config.auth_configuration import AuthConfiguration from momento.errors.error_converter import convert_error -from momento.internal._utilities._data_validation import validate_disposable_token_expiry +from momento.internal._utilities._data_validation import _validate_disposable_token_expiry from momento.internal._utilities._permissions import permissions_from_disposable_token_scope from momento.internal.aio._scs_grpc_manager import _TokenGrpcManager from momento.internal.services import Service @@ -38,7 +38,7 @@ async def generate_disposable_token( disposable_token_props: Optional[DisposableTokenProps] = None, ) -> GenerateDisposableTokenResponse: try: - validate_disposable_token_expiry(expires_in) + _validate_disposable_token_expiry(expires_in) self._logger.info("Creating disposable token") token_id = disposable_token_props.token_id if disposable_token_props else None diff --git a/src/momento/internal/synchronous/_scs_token_client.py b/src/momento/internal/synchronous/_scs_token_client.py index 8a05fc71..b3876c62 100644 --- a/src/momento/internal/synchronous/_scs_token_client.py +++ b/src/momento/internal/synchronous/_scs_token_client.py @@ -8,7 +8,7 @@ from momento.auth.credential_provider import CredentialProvider from momento.config.auth_configuration import AuthConfiguration from momento.errors.error_converter import convert_error -from momento.internal._utilities._data_validation import validate_disposable_token_expiry +from momento.internal._utilities._data_validation import _validate_disposable_token_expiry from momento.internal._utilities._permissions import permissions_from_disposable_token_scope from momento.internal.services import Service from momento.internal.synchronous._scs_grpc_manager import _TokenGrpcManager @@ -38,7 +38,7 @@ def generate_disposable_token( disposable_token_props: Optional[DisposableTokenProps] = None, ) -> GenerateDisposableTokenResponse: try: - validate_disposable_token_expiry(expires_in) + _validate_disposable_token_expiry(expires_in) self._logger.info("Creating disposable token") token_id = disposable_token_props.token_id if disposable_token_props else None From a7808d853a0f7021c33cb325126da604f03b9a39 Mon Sep 17 00:00:00 2001 From: anitarua Date: Tue, 24 Sep 2024 09:59:53 -0700 Subject: [PATCH 4/5] more utilities init file organization --- src/momento/auth_client.py | 2 +- src/momento/auth_client_async.py | 2 +- src/momento/cache_client.py | 2 +- src/momento/cache_client_async.py | 2 +- src/momento/internal/_utilities/_data_validation.py | 2 +- src/momento/internal/aio/_scs_token_client.py | 2 +- src/momento/internal/synchronous/_scs_token_client.py | 2 +- src/momento/responses/auth/generate_disposable_token.py | 2 +- src/momento/utilities/__init__.py | 2 ++ src/momento/utilities/shared_sync_asyncio.py | 2 -- tests/momento/auth_client/test_auth_client.py | 2 +- tests/momento/auth_client/test_auth_client_async.py | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/momento/auth_client.py b/src/momento/auth_client.py index b4bcc30d..bf65d234 100644 --- a/src/momento/auth_client.py +++ b/src/momento/auth_client.py @@ -9,7 +9,7 @@ from momento.config.auth_configuration import AuthConfiguration from momento.internal.synchronous._scs_token_client import _ScsTokenClient from momento.responses.auth.generate_disposable_token import GenerateDisposableTokenResponse -from momento.utilities.expiration import ExpiresIn +from momento.utilities import ExpiresIn class AuthClient: diff --git a/src/momento/auth_client_async.py b/src/momento/auth_client_async.py index 25d5245b..51211718 100644 --- a/src/momento/auth_client_async.py +++ b/src/momento/auth_client_async.py @@ -9,7 +9,7 @@ from momento.config.auth_configuration import AuthConfiguration from momento.internal.aio._scs_token_client import _ScsTokenClient from momento.responses.auth.generate_disposable_token import GenerateDisposableTokenResponse -from momento.utilities.expiration import ExpiresIn +from momento.utilities import ExpiresIn class AuthClientAsync: diff --git a/src/momento/cache_client.py b/src/momento/cache_client.py index 03ae4d80..4e83a33c 100644 --- a/src/momento/cache_client.py +++ b/src/momento/cache_client.py @@ -8,7 +8,7 @@ from momento.auth import CredentialProvider from momento.config import Configuration from momento.errors import UnknownException -from momento.internal._utilities._data_validation import _validate_eager_connection_timeout +from momento.internal._utilities import _validate_eager_connection_timeout from momento.requests import CollectionTtl, SortOrder from momento.utilities.shared_sync_asyncio import ( DEFAULT_EAGER_CONNECTION_TIMEOUT_SECONDS, diff --git a/src/momento/cache_client_async.py b/src/momento/cache_client_async.py index 4e27fc8c..a7adf58c 100644 --- a/src/momento/cache_client_async.py +++ b/src/momento/cache_client_async.py @@ -8,7 +8,7 @@ from momento.auth import CredentialProvider from momento.config import Configuration from momento.errors import UnknownException -from momento.internal._utilities._data_validation import _validate_eager_connection_timeout +from momento.internal._utilities import _validate_eager_connection_timeout from momento.requests import CollectionTtl, SortOrder from momento.utilities.shared_sync_asyncio import ( DEFAULT_EAGER_CONNECTION_TIMEOUT_SECONDS, diff --git a/src/momento/internal/_utilities/_data_validation.py b/src/momento/internal/_utilities/_data_validation.py index 2f2d7a7f..c4d818ed 100644 --- a/src/momento/internal/_utilities/_data_validation.py +++ b/src/momento/internal/_utilities/_data_validation.py @@ -15,7 +15,7 @@ TSortedSetElements, TSortedSetValues, ) -from momento.utilities.expiration import ExpiresIn +from momento.utilities import ExpiresIn DEFAULT_BYTES_CONVERSION_ERROR = "Could not convert the given type to bytes: " DEFAULT_LIST_CONVERSION_ERROR = "The given type is not list[str | bytes]: " diff --git a/src/momento/internal/aio/_scs_token_client.py b/src/momento/internal/aio/_scs_token_client.py index 4899db36..eb94855d 100644 --- a/src/momento/internal/aio/_scs_token_client.py +++ b/src/momento/internal/aio/_scs_token_client.py @@ -13,7 +13,7 @@ from momento.internal.aio._scs_grpc_manager import _TokenGrpcManager from momento.internal.services import Service from momento.responses.auth.generate_disposable_token import GenerateDisposableToken, GenerateDisposableTokenResponse -from momento.utilities.expiration import ExpiresIn +from momento.utilities import ExpiresIn class _ScsTokenClient: diff --git a/src/momento/internal/synchronous/_scs_token_client.py b/src/momento/internal/synchronous/_scs_token_client.py index b3876c62..3f197b99 100644 --- a/src/momento/internal/synchronous/_scs_token_client.py +++ b/src/momento/internal/synchronous/_scs_token_client.py @@ -13,7 +13,7 @@ from momento.internal.services import Service from momento.internal.synchronous._scs_grpc_manager import _TokenGrpcManager from momento.responses.auth.generate_disposable_token import GenerateDisposableToken, GenerateDisposableTokenResponse -from momento.utilities.expiration import ExpiresIn +from momento.utilities import ExpiresIn class _ScsTokenClient: diff --git a/src/momento/responses/auth/generate_disposable_token.py b/src/momento/responses/auth/generate_disposable_token.py index ab216316..c3beddbd 100644 --- a/src/momento/responses/auth/generate_disposable_token.py +++ b/src/momento/responses/auth/generate_disposable_token.py @@ -8,7 +8,7 @@ from momento_wire_types import token_pb2 as token_pb from momento.responses.response import AuthResponse -from momento.utilities.expiration import ExpiresAt +from momento.utilities import ExpiresAt from ..mixins import ErrorResponseMixin diff --git a/src/momento/utilities/__init__.py b/src/momento/utilities/__init__.py index e69de29b..57edc808 100644 --- a/src/momento/utilities/__init__.py +++ b/src/momento/utilities/__init__.py @@ -0,0 +1,2 @@ +from .expiration import Expiration, ExpiresAt, ExpiresIn +from .shared_sync_asyncio import DEFAULT_EAGER_CONNECTION_TIMEOUT_SECONDS, str_to_bytes diff --git a/src/momento/utilities/shared_sync_asyncio.py b/src/momento/utilities/shared_sync_asyncio.py index 4d8c7a86..30b24438 100644 --- a/src/momento/utilities/shared_sync_asyncio.py +++ b/src/momento/utilities/shared_sync_asyncio.py @@ -1,5 +1,3 @@ -from __future__ import annotations - DEFAULT_EAGER_CONNECTION_TIMEOUT_SECONDS = 30 diff --git a/tests/momento/auth_client/test_auth_client.py b/tests/momento/auth_client/test_auth_client.py index 07705c75..f3306bb7 100644 --- a/tests/momento/auth_client/test_auth_client.py +++ b/tests/momento/auth_client/test_auth_client.py @@ -15,7 +15,7 @@ from momento.responses.pubsub.publish import TopicPublish from momento.responses.pubsub.subscribe import TopicSubscribe from momento.topic_client import TopicClient -from momento.utilities.expiration import ExpiresIn +from momento.utilities import ExpiresIn from tests.utils import uuid_str diff --git a/tests/momento/auth_client/test_auth_client_async.py b/tests/momento/auth_client/test_auth_client_async.py index f2615e72..cf54c8aa 100644 --- a/tests/momento/auth_client/test_auth_client_async.py +++ b/tests/momento/auth_client/test_auth_client_async.py @@ -15,7 +15,7 @@ from momento.responses.pubsub.publish import TopicPublish from momento.responses.pubsub.subscribe import TopicSubscribe from momento.topic_client_async import TopicClientAsync -from momento.utilities.expiration import ExpiresIn +from momento.utilities import ExpiresIn from tests.utils import uuid_str From 75de8583de7f8d200e513ab43f51eac814e9162a Mon Sep 17 00:00:00 2001 From: anitarua Date: Tue, 24 Sep 2024 11:05:36 -0700 Subject: [PATCH 5/5] add all expression to utilities init file --- src/momento/utilities/__init__.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/momento/utilities/__init__.py b/src/momento/utilities/__init__.py index 57edc808..5fc4b21a 100644 --- a/src/momento/utilities/__init__.py +++ b/src/momento/utilities/__init__.py @@ -1,2 +1,10 @@ from .expiration import Expiration, ExpiresAt, ExpiresIn from .shared_sync_asyncio import DEFAULT_EAGER_CONNECTION_TIMEOUT_SECONDS, str_to_bytes + +__all__ = [ + "Expiration", + "ExpiresAt", + "ExpiresIn", + "DEFAULT_EAGER_CONNECTION_TIMEOUT_SECONDS", + "str_to_bytes", +]