Skip to content

Commit 455ace2

Browse files
committed
chore: remove configuration bases and make middleware more pythonic
Remove the configuration base classes. These aren't used by any of the code that takes a configuration, so users can't implement new configurations with them and pass them into clients. I'm removing them instead of making the clients use them because config base classes make it difficult to add new configuration options breaking potential user implementations. Make the middleware classes into data classes. The existing standard classes with getters isn't pythonic. Make with_middlewares replace the configuration's middleware instead of adding to it. This matches the behavior in the other SDKs.
1 parent 1230510 commit 455ace2

9 files changed

Lines changed: 43 additions & 143 deletions

File tree

src/momento/config/auth_configuration.py

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,13 @@
11
from __future__ import annotations
22

3-
from abc import ABC, abstractmethod
43
from datetime import timedelta
54

65
from momento.config.transport.transport_strategy import TransportStrategy
76
from momento.retry.retry_strategy import RetryStrategy
87

98

10-
class AuthConfigurationBase(ABC):
11-
@abstractmethod
12-
def get_retry_strategy(self) -> RetryStrategy:
13-
pass
14-
15-
@abstractmethod
16-
def with_retry_strategy(self, retry_strategy: RetryStrategy) -> AuthConfiguration:
17-
pass
18-
19-
@abstractmethod
20-
def get_transport_strategy(self) -> TransportStrategy:
21-
pass
22-
23-
@abstractmethod
24-
def with_transport_strategy(self, transport_strategy: TransportStrategy) -> AuthConfiguration:
25-
pass
26-
27-
@abstractmethod
28-
def with_client_timeout(self, client_timeout: timedelta) -> AuthConfiguration:
29-
pass
30-
31-
32-
class AuthConfiguration(AuthConfigurationBase):
33-
"""AuthConfiguration options for Momento Simple Cache Client."""
9+
class AuthConfiguration:
10+
"""AuthConfiguration options for Momento Auth Client."""
3411

3512
def __init__(self, transport_strategy: TransportStrategy, retry_strategy: RetryStrategy):
3613
"""Instantiate a AuthConfiguration.

src/momento/config/configuration.py

Lines changed: 9 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import annotations
22

3-
from abc import ABC, abstractmethod
43
from datetime import timedelta
54
from pathlib import Path
65
from typing import List, Optional
@@ -12,46 +11,8 @@
1211
from .transport.transport_strategy import TransportStrategy
1312

1413

15-
class ConfigurationBase(ABC):
16-
@abstractmethod
17-
def get_retry_strategy(self) -> RetryStrategy:
18-
pass
19-
20-
@abstractmethod
21-
def with_retry_strategy(self, retry_strategy: RetryStrategy) -> Configuration:
22-
pass
23-
24-
@abstractmethod
25-
def get_transport_strategy(self) -> TransportStrategy:
26-
pass
27-
28-
@abstractmethod
29-
def with_transport_strategy(self, transport_strategy: TransportStrategy) -> Configuration:
30-
pass
31-
32-
@abstractmethod
33-
def with_client_timeout(self, client_timeout: timedelta) -> Configuration:
34-
pass
35-
36-
@abstractmethod
37-
def with_root_certificates_pem(self, root_certificate_path: Path) -> Configuration:
38-
pass
39-
40-
@abstractmethod
41-
def with_middlewares(self, middlewares: List[Middleware]) -> Configuration:
42-
pass
43-
44-
@abstractmethod
45-
def add_middleware(self, middleware: Middleware) -> Configuration:
46-
pass
47-
48-
@abstractmethod
49-
def get_middlewares(self) -> List[Middleware]:
50-
pass
51-
52-
53-
class Configuration(ConfigurationBase):
54-
"""Configuration options for Momento Simple Cache Client."""
14+
class Configuration:
15+
"""Configuration options for Momento Cache Client."""
5516

5617
def __init__(
5718
self,
@@ -140,11 +101,10 @@ def with_root_certificates_pem(self, root_certificates_pem_path: Path) -> Config
140101
return self.with_transport_strategy(transport_strategy)
141102

142103
def with_middlewares(self, middlewares: List[Middleware]) -> Configuration:
143-
"""Copies the Configuration and adds the new middlewares to the end of the list.
104+
"""Copies the Configuration and replaces the middleware with the given middleware list.
144105
145106
Args:
146-
middlewares: the middleware list to be appended to the Configuration's existing middleware. These can be
147-
aio or synchronous middleware.
107+
middlewares: the new middleware list. It can contain async or synchronous middleware.
148108
149109
Returns:
150110
Configuration: the new Configuration.
@@ -156,8 +116,8 @@ def add_middleware(self, middleware: Middleware) -> Configuration:
156116
"""Copies the Configuration and adds the new middleware to the end of the list.
157117
158118
Args:
159-
middleware: the middleware to be appended to the Configuration's existing middleware. This can be aio or
160-
synchronous middleware.
119+
middleware: the middleware to be appended to the Configuration's existing middleware. This can be an async
120+
or synchronous middleware.
161121
162122
Returns:
163123
Configuration: the new Configuration.
@@ -173,11 +133,11 @@ def get_middlewares(self) -> List[Middleware]:
173133
"""
174134
return self._middlewares.copy()
175135

176-
def get_aio_middlewares(self) -> List[momento.config.middleware.aio.Middleware]:
177-
"""Access the aio middleware from the middleware list.
136+
def get_async_middlewares(self) -> List[momento.config.middleware.aio.Middleware]:
137+
"""Access the async middleware from the middleware list.
178138
179139
Returns:
180-
the configuration's list of aio middleware.
140+
the configuration's list of async middleware.
181141
"""
182142
return [m for m in self._middlewares if isinstance(m, momento.config.middleware.aio.Middleware)]
183143

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1+
from dataclasses import dataclass
12
from typing import Optional
23

34
from grpc.aio import Metadata
45

56

7+
@dataclass
68
class MiddlewareMetadata:
79
"""Wrapper for gRPC metadata."""
810

9-
def __init__(self, metadata: Optional[Metadata]):
10-
self.grpc_metadata = metadata
11-
12-
def get_grpc_metadata(self) -> Optional[Metadata]:
13-
"""Get the underlying gRPC metadata."""
14-
return self.grpc_metadata
11+
grpc_metadata: Optional[Metadata]
Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from dataclasses import dataclass
12
from typing import Dict
23

34
import grpc
@@ -6,41 +7,32 @@
67
CONNECTION_ID_KEY = "connectionID"
78

89

10+
@dataclass
911
class MiddlewareMessage:
1012
"""Wrapper for a gRPC protobuf message."""
1113

12-
def __init__(self, message: Message):
13-
self.grpc_message = message
14+
grpc_message: Message
1415

15-
def get_message_length(self) -> int:
16-
"""Get the length of the message in bytes."""
16+
@property
17+
def message_length(self) -> int:
18+
"""Length of the message in bytes."""
1719
return len(self.grpc_message.SerializeToString())
1820

19-
def get_constructor_name(self) -> str:
20-
"""Get the class name of the message."""
21+
@property
22+
def constructor_name(self) -> str:
23+
"""The class name of the message."""
2124
return str(self.grpc_message.__class__.__name__)
2225

23-
def get_message(self) -> Message:
24-
"""Get the underlying gRPC message."""
25-
return self.grpc_message
26-
2726

27+
@dataclass
2828
class MiddlewareStatus:
2929
"""Wrapper for gRPC status."""
3030

31-
def __init__(self, status: grpc.StatusCode):
32-
self.grpc_status = status
33-
34-
def get_code(self) -> grpc.StatusCode:
35-
"""Get the status code."""
36-
return self.grpc_status
31+
grpc_status: grpc.StatusCode
3732

3833

34+
@dataclass
3935
class MiddlewareRequestHandlerContext:
4036
"""Context for middleware request handlers."""
4137

42-
def __init__(self, context: Dict[str, str]):
43-
self.context = context
44-
45-
def get_context(self) -> Dict[str, str]:
46-
return self.context
38+
context: Dict[str, str]
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1+
from dataclasses import dataclass
12
from typing import Optional
23

34
from grpc._typing import MetadataType
45

56

7+
@dataclass
68
class MiddlewareMetadata:
79
"""Wrapper for gRPC metadata."""
810

9-
def __init__(self, metadata: Optional[MetadataType]):
10-
self.grpc_metadata = metadata
11-
12-
def get_grpc_metadata(self) -> Optional[MetadataType]:
13-
"""Get the underlying gRPC metadata."""
14-
return self.grpc_metadata
11+
grpc_metadata: Optional[MetadataType]

src/momento/config/topic_configuration.py

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,11 @@
11
from __future__ import annotations
22

3-
from abc import ABC, abstractmethod
43
from datetime import timedelta
54

65
from momento.config.transport.topic_transport_strategy import TopicTransportStrategy
76

87

9-
class TopicConfigurationBase(ABC):
10-
@abstractmethod
11-
def get_max_subscriptions(self) -> int:
12-
pass
13-
14-
@abstractmethod
15-
def with_max_subscriptions(self, max_subscriptions: int) -> TopicConfiguration:
16-
pass
17-
18-
@abstractmethod
19-
def get_transport_strategy(self) -> TopicTransportStrategy:
20-
pass
21-
22-
@abstractmethod
23-
def with_transport_strategy(self, transport_strategy: TopicTransportStrategy) -> TopicConfiguration:
24-
pass
25-
26-
@abstractmethod
27-
def with_client_timeout(self, client_timeout: timedelta) -> TopicConfiguration:
28-
pass
29-
30-
31-
class TopicConfiguration(TopicConfigurationBase):
8+
class TopicConfiguration:
329
"""Configuration options for Momento topic client."""
3310

3411
def __init__(self, transport_strategy: TopicTransportStrategy, max_subscriptions: int = 0):

src/momento/internal/aio/_middleware_interceptor.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ async def intercept_unary_unary(
118118
new_client_call_details = create_client_call_details(
119119
method=client_call_details.method,
120120
timeout=client_call_details.timeout,
121-
metadata=metadata.get_grpc_metadata(),
121+
metadata=metadata.grpc_metadata,
122122
credentials=client_call_details.credentials,
123123
wait_for_ready=client_call_details.wait_for_ready,
124124
)
@@ -127,15 +127,15 @@ async def intercept_unary_unary(
127127
middleware_message = await self.apply_handler_methods(
128128
[handler.on_request_body for handler in handlers], MiddlewareMessage(request)
129129
)
130-
request = middleware_message.get_message()
130+
request = middleware_message.grpc_message
131131

132132
call = await continuation(new_client_call_details, request)
133133
try:
134134
initial_metadata = await call.initial_metadata()
135135
response_metadata = await self.apply_handler_methods(
136136
[handler.on_response_metadata for handler in reversed_handlers], MiddlewareMetadata(initial_metadata)
137137
)
138-
initial_metadata = response_metadata.get_grpc_metadata()
138+
initial_metadata = response_metadata.grpc_metadata
139139

140140
# if the call returns an error, awaiting it will raise an RpcError, which we handle below
141141
original_response = await call
@@ -144,7 +144,7 @@ async def intercept_unary_unary(
144144
middleware_response = await self.apply_handler_methods(
145145
[handler.on_response_body for handler in reversed_handlers], MiddlewareMessage(original_response)
146146
)
147-
response = middleware_response.get_message()
147+
response = middleware_response.grpc_message
148148
else:
149149
response = original_response
150150

src/momento/internal/aio/_scs_grpc_manager.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def __init__(self, configuration: Configuration, credential_provider: Credential
5050
interceptors=_interceptors(
5151
credential_provider.auth_token,
5252
ClientType.CACHE,
53-
configuration.get_aio_middlewares(),
53+
configuration.get_async_middlewares(),
5454
configuration.get_retry_strategy(),
5555
),
5656
options=grpc_control_channel_options_from_grpc_config(
@@ -63,7 +63,7 @@ def __init__(self, configuration: Configuration, credential_provider: Credential
6363
interceptors=_interceptors(
6464
credential_provider.auth_token,
6565
ClientType.CACHE,
66-
configuration.get_aio_middlewares(),
66+
configuration.get_async_middlewares(),
6767
configuration.get_retry_strategy(),
6868
),
6969
options=grpc_control_channel_options_from_grpc_config(
@@ -90,7 +90,7 @@ def __init__(self, configuration: Configuration, credential_provider: Credential
9090
interceptors=_interceptors(
9191
credential_provider.auth_token,
9292
ClientType.CACHE,
93-
configuration.get_aio_middlewares(),
93+
configuration.get_async_middlewares(),
9494
configuration.get_retry_strategy(),
9595
),
9696
# Here is where you would pass override configuration to the underlying C gRPC layer.
@@ -117,7 +117,7 @@ def __init__(self, configuration: Configuration, credential_provider: Credential
117117
interceptors=_interceptors(
118118
credential_provider.auth_token,
119119
ClientType.CACHE,
120-
configuration.get_aio_middlewares(),
120+
configuration.get_async_middlewares(),
121121
configuration.get_retry_strategy(),
122122
),
123123
options=grpc_data_channel_options_from_grpc_config(

src/momento/internal/synchronous/_middleware_interceptor.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,15 @@ def intercept_unary_unary(
9898
new_client_call_details = _ClientCallDetails(
9999
method=client_call_details.method,
100100
timeout=client_call_details.timeout,
101-
metadata=metadata.get_grpc_metadata(),
101+
metadata=metadata.grpc_metadata,
102102
credentials=client_call_details.credentials,
103103
)
104104

105105
if isinstance(request, Message):
106106
middleware_message = self.apply_handler_methods(
107107
[handler.on_request_body for handler in handlers], MiddlewareMessage(request)
108108
)
109-
request = middleware_message.get_message()
109+
request = middleware_message.grpc_message
110110

111111
try:
112112
call = continuation(new_client_call_details, request)
@@ -115,15 +115,15 @@ def intercept_unary_unary(
115115
response_metadata = self.apply_handler_methods(
116116
[handler.on_response_metadata for handler in reversed_handlers], MiddlewareMetadata(initial_metadata)
117117
)
118-
initial_metadata = response_metadata.get_grpc_metadata()
118+
initial_metadata = response_metadata.grpc_metadata
119119

120120
# if the call returns an error, call.result() will raise an RpcError, which we handle below
121121
response_body = call.result()
122122
if isinstance(response_body, Message):
123123
middleware_message = self.apply_handler_methods(
124124
[handler.on_response_body for handler in reversed_handlers], MiddlewareMessage(response_body)
125125
)
126-
response_body = middleware_message.get_message()
126+
response_body = middleware_message.grpc_message
127127

128128
status_code = call.code()
129129
middleware_status = self.apply_handler_methods(

0 commit comments

Comments
 (0)