atlan-application-sdk 0.1.1rc35__py3-none-any.whl → 0.1.1rc36__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,12 @@
1
1
  import asyncio
2
2
  import uuid
3
3
  from concurrent.futures import ThreadPoolExecutor
4
- from datetime import timedelta
5
4
  from typing import Any, Dict, Optional, Sequence, Type
6
5
 
7
6
  from temporalio import activity, workflow
8
7
  from temporalio.client import Client, WorkflowExecutionStatus, WorkflowFailureError
9
- from temporalio.common import RetryPolicy
10
8
  from temporalio.types import CallableType, ClassType
11
- from temporalio.worker import (
12
- ActivityInboundInterceptor,
13
- ExecuteActivityInput,
14
- ExecuteWorkflowInput,
15
- Interceptor,
16
- Worker,
17
- WorkflowInboundInterceptor,
18
- WorkflowInterceptorClassInput,
19
- )
9
+ from temporalio.worker import Worker
20
10
  from temporalio.worker.workflow_sandbox import (
21
11
  SandboxedWorkflowRunner,
22
12
  SandboxRestrictions,
@@ -28,6 +18,7 @@ from application_sdk.constants import (
28
18
  APPLICATION_NAME,
29
19
  DEPLOYMENT_NAME,
30
20
  DEPLOYMENT_NAME_KEY,
21
+ IS_LOCKING_DISABLED,
31
22
  MAX_CONCURRENT_ACTIVITIES,
32
23
  WORKFLOW_HOST,
33
24
  WORKFLOW_MAX_TIMEOUT_HOURS,
@@ -35,15 +26,9 @@ from application_sdk.constants import (
35
26
  WORKFLOW_PORT,
36
27
  WORKFLOW_TLS_ENABLED_KEY,
37
28
  )
38
- from application_sdk.events.models import (
39
- ApplicationEventNames,
40
- Event,
41
- EventMetadata,
42
- EventTypes,
43
- WorkflowStates,
44
- )
29
+ from application_sdk.interceptors.events import EventInterceptor, publish_event
30
+ from application_sdk.interceptors.lock import RedisLockInterceptor
45
31
  from application_sdk.observability.logger_adaptor import get_logger
46
- from application_sdk.services.eventstore import EventStore
47
32
  from application_sdk.services.secretstore import SecretStore
48
33
  from application_sdk.services.statestore import StateStore, StateType
49
34
  from application_sdk.workflows import WorkflowInterface
@@ -55,170 +40,6 @@ TEMPORAL_NOT_FOUND_FAILURE = (
55
40
  )
56
41
 
57
42
 
58
- # Activity for publishing events (runs outside sandbox)
59
- @activity.defn
60
- async def publish_event(event_data: dict) -> None:
61
- """Activity to publish events outside the workflow sandbox.
62
-
63
- Args:
64
- event_data (dict): Event data to publish containing event_type, event_name,
65
- metadata, and data fields.
66
- """
67
- try:
68
- event = Event(**event_data)
69
- await EventStore.publish_event(event)
70
- activity.logger.info(f"Published event: {event_data.get('event_name','')}")
71
- except Exception as e:
72
- activity.logger.error(f"Failed to publish event: {e}")
73
- raise
74
-
75
-
76
- class EventActivityInboundInterceptor(ActivityInboundInterceptor):
77
- """Interceptor for tracking activity execution events.
78
-
79
- This interceptor captures the start and end of activity executions,
80
- creating events that can be used for monitoring and tracking.
81
- Activities run outside the sandbox so they can directly call EventStore.
82
- """
83
-
84
- async def execute_activity(self, input: ExecuteActivityInput) -> Any:
85
- """Execute an activity with event tracking.
86
-
87
- Args:
88
- input (ExecuteActivityInput): The activity execution input.
89
-
90
- Returns:
91
- Any: The result of the activity execution.
92
- """
93
- # Extract activity information for tracking
94
-
95
- start_event = Event(
96
- event_type=EventTypes.APPLICATION_EVENT.value,
97
- event_name=ApplicationEventNames.ACTIVITY_START.value,
98
- data={},
99
- )
100
- await EventStore.publish_event(start_event)
101
-
102
- output = None
103
- try:
104
- output = await super().execute_activity(input)
105
- except Exception:
106
- raise
107
- finally:
108
- end_event = Event(
109
- event_type=EventTypes.APPLICATION_EVENT.value,
110
- event_name=ApplicationEventNames.ACTIVITY_END.value,
111
- data={},
112
- )
113
- await EventStore.publish_event(end_event)
114
-
115
- return output
116
-
117
-
118
- class EventWorkflowInboundInterceptor(WorkflowInboundInterceptor):
119
- """Interceptor for tracking workflow execution events.
120
-
121
- This interceptor captures the start and end of workflow executions,
122
- creating events that can be used for monitoring and tracking.
123
- Uses activities to publish events to avoid sandbox restrictions.
124
- """
125
-
126
- async def execute_workflow(self, input: ExecuteWorkflowInput) -> Any:
127
- """Execute a workflow with event tracking.
128
-
129
- Args:
130
- input (ExecuteWorkflowInput): The workflow execution input.
131
-
132
- Returns:
133
- Any: The result of the workflow execution.
134
- """
135
-
136
- # Publish workflow start event via activity
137
- try:
138
- await workflow.execute_activity(
139
- publish_event,
140
- {
141
- "metadata": EventMetadata(
142
- workflow_state=WorkflowStates.RUNNING.value
143
- ),
144
- "event_type": EventTypes.APPLICATION_EVENT.value,
145
- "event_name": ApplicationEventNames.WORKFLOW_START.value,
146
- "data": {},
147
- },
148
- schedule_to_close_timeout=timedelta(seconds=30),
149
- retry_policy=RetryPolicy(maximum_attempts=3),
150
- )
151
- except Exception as e:
152
- workflow.logger.warning(f"Failed to publish workflow start event: {e}")
153
- # Don't fail the workflow if event publishing fails
154
-
155
- output = None
156
- workflow_state = WorkflowStates.FAILED.value # Default to failed
157
-
158
- try:
159
- output = await super().execute_workflow(input)
160
- workflow_state = (
161
- WorkflowStates.COMPLETED.value
162
- ) # Update to completed on success
163
- except Exception:
164
- workflow_state = WorkflowStates.FAILED.value # Keep as failed
165
- raise
166
- finally:
167
- # Always publish workflow end event
168
- try:
169
- await workflow.execute_activity(
170
- publish_event,
171
- {
172
- "metadata": EventMetadata(workflow_state=workflow_state),
173
- "event_type": EventTypes.APPLICATION_EVENT.value,
174
- "event_name": ApplicationEventNames.WORKFLOW_END.value,
175
- "data": {},
176
- },
177
- schedule_to_close_timeout=timedelta(seconds=30),
178
- retry_policy=RetryPolicy(maximum_attempts=3),
179
- )
180
- except Exception as publish_error:
181
- workflow.logger.warning(
182
- f"Failed to publish workflow end event: {publish_error}"
183
- )
184
-
185
- return output
186
-
187
-
188
- class EventInterceptor(Interceptor):
189
- """Temporal interceptor for event tracking.
190
-
191
- This interceptor provides event tracking capabilities for both
192
- workflow and activity executions.
193
- """
194
-
195
- def intercept_activity(
196
- self, next: ActivityInboundInterceptor
197
- ) -> ActivityInboundInterceptor:
198
- """Intercept activity executions.
199
-
200
- Args:
201
- next (ActivityInboundInterceptor): The next interceptor in the chain.
202
-
203
- Returns:
204
- ActivityInboundInterceptor: The activity interceptor.
205
- """
206
- return EventActivityInboundInterceptor(super().intercept_activity(next))
207
-
208
- def workflow_interceptor_class(
209
- self, input: WorkflowInterceptorClassInput
210
- ) -> Optional[Type[WorkflowInboundInterceptor]]:
211
- """Get the workflow interceptor class.
212
-
213
- Args:
214
- input (WorkflowInterceptorClassInput): The interceptor input.
215
-
216
- Returns:
217
- Optional[Type[WorkflowInboundInterceptor]]: The workflow interceptor class.
218
- """
219
- return EventWorkflowInboundInterceptor
220
-
221
-
222
43
  class TemporalWorkflowClient(WorkflowClient):
223
44
  """Temporal-specific implementation of WorkflowClient with simple token refresh.
224
45
 
@@ -537,14 +358,34 @@ class TemporalWorkflowClient(WorkflowClient):
537
358
  f"Started token refresh loop with dynamic interval (initial: {self._token_refresh_interval}s)"
538
359
  )
539
360
 
540
- # Add the publish_event to the activities list
541
- extended_activities = list(activities) + [publish_event]
361
+ # Start with provided activities and add system activities
362
+ final_activities = list(activities) + [publish_event]
363
+
364
+ # Add lock management activities if needed
365
+ if not IS_LOCKING_DISABLED:
366
+ from application_sdk.activities.lock_management import (
367
+ acquire_distributed_lock,
368
+ release_distributed_lock,
369
+ )
370
+
371
+ final_activities.extend(
372
+ [
373
+ acquire_distributed_lock,
374
+ release_distributed_lock,
375
+ ]
376
+ )
377
+ logger.info(
378
+ "Auto-registered lock management activities for @needs_lock decorated activities"
379
+ )
380
+
381
+ # Create activities lookup dict for interceptors
382
+ activities_dict = {getattr(a, "__name__", str(a)): a for a in final_activities}
542
383
 
543
384
  return Worker(
544
385
  self.client,
545
386
  task_queue=self.worker_task_queue,
546
387
  workflows=workflow_classes,
547
- activities=extended_activities, # Use extended activities list
388
+ activities=final_activities,
548
389
  workflow_runner=SandboxedWorkflowRunner(
549
390
  restrictions=SandboxRestrictions.default.with_passthrough_modules(
550
391
  *passthrough_modules
@@ -552,7 +393,10 @@ class TemporalWorkflowClient(WorkflowClient):
552
393
  ),
553
394
  max_concurrent_activities=max_concurrent_activities,
554
395
  activity_executor=activity_executor,
555
- interceptors=[EventInterceptor()],
396
+ interceptors=[
397
+ EventInterceptor(),
398
+ RedisLockInterceptor(activities_dict),
399
+ ],
556
400
  )
557
401
 
558
402
  async def get_workflow_run_status(
@@ -81,6 +81,18 @@ class ClientError(AtlanError):
81
81
  AUTH_CONFIG_ERROR = ErrorCode(
82
82
  ErrorComponent.CLIENT, "400", "00", "Authentication configuration error"
83
83
  )
84
+ REDIS_CONNECTION_ERROR = ErrorCode(
85
+ ErrorComponent.CLIENT, "503", "00", "Redis connection failed"
86
+ )
87
+ REDIS_TIMEOUT_ERROR = ErrorCode(
88
+ ErrorComponent.CLIENT, "408", "00", "Redis operation timeout"
89
+ )
90
+ REDIS_AUTH_ERROR = ErrorCode(
91
+ ErrorComponent.CLIENT, "401", "05", "Redis authentication failed"
92
+ )
93
+ REDIS_PROTOCOL_ERROR = ErrorCode(
94
+ ErrorComponent.CLIENT, "502", "00", "Redis protocol error"
95
+ )
84
96
 
85
97
 
86
98
  class ApiError(AtlanError):
@@ -174,7 +186,7 @@ class IOError(AtlanError):
174
186
  INPUT_PROCESSING_ERROR = ErrorCode(
175
187
  ErrorComponent.IO, "500", "01", "Input processing error"
176
188
  )
177
- SQL_QUERY_ERROR = ErrorCode(ErrorComponent.IO, "400", "00", "SQL query error")
189
+ SQL_QUERY_ERROR = ErrorCode(ErrorComponent.IO, "400", "01", "SQL query error")
178
190
  SQL_QUERY_BATCH_ERROR = ErrorCode(
179
191
  ErrorComponent.IO, "500", "02", "SQL query batch error"
180
192
  )
@@ -268,10 +280,10 @@ class CommonError(AtlanError):
268
280
  ErrorComponent.COMMON, "400", "01", "Query preparation error"
269
281
  )
270
282
  FILTER_PREPARATION_ERROR = ErrorCode(
271
- ErrorComponent.COMMON, "400", "00", "Filter preparation error"
283
+ ErrorComponent.COMMON, "400", "02", "Filter preparation error"
272
284
  )
273
285
  CREDENTIALS_PARSE_ERROR = ErrorCode(
274
- ErrorComponent.COMMON, "400", "02", "Credentials parse error"
286
+ ErrorComponent.COMMON, "400", "03", "Credentials parse error"
275
287
  )
276
288
  CREDENTIALS_RESOLUTION_ERROR = ErrorCode(
277
289
  ErrorComponent.COMMON, "401", "03", "Credentials resolution error"
@@ -367,3 +379,12 @@ class ActivityError(AtlanError):
367
379
  ATLAN_UPLOAD_ERROR = ErrorCode(
368
380
  ErrorComponent.ACTIVITY, "500", "08", "Atlan upload error"
369
381
  )
382
+ LOCK_ACQUISITION_ERROR = ErrorCode(
383
+ ErrorComponent.ACTIVITY, "503", "01", "Distributed lock acquisition error"
384
+ )
385
+ LOCK_RELEASE_ERROR = ErrorCode(
386
+ ErrorComponent.ACTIVITY, "500", "09", "Distributed lock release error"
387
+ )
388
+ LOCK_TIMEOUT_ERROR = ErrorCode(
389
+ ErrorComponent.ACTIVITY, "408", "00", "Lock acquisition timeout"
390
+ )
@@ -146,7 +146,6 @@ DEPLOYMENT_SECRET_STORE_NAME = os.getenv(
146
146
  "DEPLOYMENT_SECRET_STORE_NAME", "deployment-secret-store"
147
147
  )
148
148
 
149
-
150
149
  # Logger Constants
151
150
  #: Log level for the application (DEBUG, INFO, WARNING, ERROR, CRITICAL)
152
151
  LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper()
@@ -230,3 +229,21 @@ ATLAN_BASE_URL = os.getenv("ATLAN_BASE_URL")
230
229
  ATLAN_API_KEY = os.getenv("ATLAN_API_KEY")
231
230
  ATLAN_CLIENT_ID = os.getenv("CLIENT_ID")
232
231
  ATLAN_CLIENT_SECRET = os.getenv("CLIENT_SECRET")
232
+ # Lock Configuration
233
+ LOCK_METADATA_KEY = "__lock_metadata__"
234
+
235
+ # Redis Lock Configuration
236
+ #: Redis host for direct connection (when not using Sentinel)
237
+ REDIS_HOST = os.getenv("REDIS_HOST", "")
238
+ #: Redis port for direct connection (when not using Sentinel)
239
+ REDIS_PORT = os.getenv("REDIS_PORT", "")
240
+ #: Redis password (required for authenticated Redis instances)
241
+ REDIS_PASSWORD = os.getenv("REDIS_PASSWORD")
242
+ #: Redis Sentinel service name (default: mymaster)
243
+ REDIS_SENTINEL_SERVICE_NAME = os.getenv("REDIS_SENTINEL_SERVICE_NAME", "mymaster")
244
+ #: Redis Sentinel hosts (comma-separated host:port pairs)
245
+ REDIS_SENTINEL_HOSTS = os.getenv("REDIS_SENTINEL_HOSTS", "")
246
+ #: Whether to enable strict locking
247
+ IS_LOCKING_DISABLED = os.getenv("IS_LOCKING_DISABLED", "true").lower() == "true"
248
+ #: Retry interval for lock acquisition
249
+ LOCK_RETRY_INTERVAL = int(os.getenv("LOCK_RETRY_INTERVAL", "5"))
File without changes
@@ -0,0 +1,42 @@
1
+ from typing import Any, Callable, Optional
2
+
3
+ from application_sdk.constants import LOCK_METADATA_KEY
4
+ from application_sdk.observability.logger_adaptor import get_logger
5
+
6
+ logger = get_logger(__name__)
7
+
8
+
9
+ def needs_lock(max_locks: int = 5, lock_name: Optional[str] = None):
10
+ """Decorator to mark activities that require distributed locking.
11
+
12
+ This decorator attaches lock configuration directly to the activity
13
+ definition that will be used by the workflow interceptor to acquire
14
+ locks before executing activities.
15
+
16
+ Note:
17
+ Activities decorated with ``needs_lock`` must be called with
18
+ ``schedule_to_close_timeout`` to ensure proper lock TTL calculation
19
+ that covers retries.
20
+
21
+ Args:
22
+ max_locks (int): Maximum number of concurrent locks allowed.
23
+ lock_name (str | None): Optional custom name for the lock (defaults to activity name).
24
+
25
+ Raises:
26
+ WorkflowError: If activity is called without ``schedule_to_close_timeout``.
27
+ """
28
+
29
+ def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
30
+ # Store lock metadata directly on the function object
31
+ metadata = {
32
+ "is_needs_lock": True,
33
+ "max_locks": max_locks,
34
+ "lock_name": lock_name or func.__name__,
35
+ }
36
+
37
+ # Attach metadata to the function
38
+ setattr(func, LOCK_METADATA_KEY, metadata)
39
+
40
+ return func
41
+
42
+ return decorator
@@ -44,7 +44,24 @@ class BaseHandler(HandlerInterface):
44
44
 
45
45
  # The following methods are inherited from HandlerInterface and should be implemented
46
46
  # by subclasses to handle calls from their respective FastAPI endpoints:
47
- #
48
47
  # - test_auth(**kwargs) -> bool: Called by /workflow/v1/auth endpoint
49
48
  # - preflight_check(**kwargs) -> Any: Called by /workflow/v1/check endpoint
50
49
  # - fetch_metadata(**kwargs) -> Any: Called by /workflow/v1/metadata endpoint
50
+
51
+ async def test_auth(self, **kwargs: Any) -> bool:
52
+ """
53
+ Test the authentication of the handler.
54
+ """
55
+ raise NotImplementedError("test_auth is not implemented")
56
+
57
+ async def preflight_check(self, **kwargs: Any) -> Any:
58
+ """
59
+ Check the preflight of the handler.
60
+ """
61
+ raise NotImplementedError("preflight_check is not implemented")
62
+
63
+ async def fetch_metadata(self, **kwargs: Any) -> Any:
64
+ """
65
+ Fetch the metadata of the handler.
66
+ """
67
+ raise NotImplementedError("fetch_metadata is not implemented")
File without changes
@@ -0,0 +1,193 @@
1
+ from datetime import timedelta
2
+ from typing import Any, Optional, Type
3
+
4
+ from temporalio import activity, workflow
5
+ from temporalio.common import RetryPolicy
6
+ from temporalio.worker import (
7
+ ActivityInboundInterceptor,
8
+ ExecuteActivityInput,
9
+ ExecuteWorkflowInput,
10
+ Interceptor,
11
+ WorkflowInboundInterceptor,
12
+ WorkflowInterceptorClassInput,
13
+ )
14
+
15
+ from application_sdk.events.models import (
16
+ ApplicationEventNames,
17
+ Event,
18
+ EventMetadata,
19
+ EventTypes,
20
+ WorkflowStates,
21
+ )
22
+ from application_sdk.observability.logger_adaptor import get_logger
23
+ from application_sdk.services.eventstore import EventStore
24
+
25
+ logger = get_logger(__name__)
26
+
27
+ TEMPORAL_NOT_FOUND_FAILURE = (
28
+ "type.googleapis.com/temporal.api.errordetails.v1.NotFoundFailure"
29
+ )
30
+
31
+
32
+ # Activity for publishing events (runs outside sandbox)
33
+ @activity.defn
34
+ async def publish_event(event_data: dict) -> None:
35
+ """Activity to publish events outside the workflow sandbox.
36
+
37
+ Args:
38
+ event_data (dict): Event data to publish containing event_type, event_name,
39
+ metadata, and data fields.
40
+ """
41
+ try:
42
+ event = Event(**event_data)
43
+ await EventStore.publish_event(event)
44
+ activity.logger.info(f"Published event: {event_data.get('event_name','')}")
45
+ except Exception as e:
46
+ activity.logger.error(f"Failed to publish event: {e}")
47
+ raise
48
+
49
+
50
+ class EventActivityInboundInterceptor(ActivityInboundInterceptor):
51
+ """Interceptor for tracking activity execution events.
52
+
53
+ This interceptor captures the start and end of activity executions,
54
+ creating events that can be used for monitoring and tracking.
55
+ Activities run outside the sandbox so they can directly call EventStore.
56
+ """
57
+
58
+ async def execute_activity(self, input: ExecuteActivityInput) -> Any:
59
+ """Execute an activity with event tracking.
60
+
61
+ Args:
62
+ input (ExecuteActivityInput): The activity execution input.
63
+
64
+ Returns:
65
+ Any: The result of the activity execution.
66
+ """
67
+ # Extract activity information for tracking
68
+
69
+ start_event = Event(
70
+ event_type=EventTypes.APPLICATION_EVENT.value,
71
+ event_name=ApplicationEventNames.ACTIVITY_START.value,
72
+ data={},
73
+ )
74
+ await EventStore.publish_event(start_event)
75
+
76
+ output = None
77
+ try:
78
+ output = await super().execute_activity(input)
79
+ except Exception:
80
+ raise
81
+ finally:
82
+ end_event = Event(
83
+ event_type=EventTypes.APPLICATION_EVENT.value,
84
+ event_name=ApplicationEventNames.ACTIVITY_END.value,
85
+ data={},
86
+ )
87
+ await EventStore.publish_event(end_event)
88
+
89
+ return output
90
+
91
+
92
+ class EventWorkflowInboundInterceptor(WorkflowInboundInterceptor):
93
+ """Interceptor for tracking workflow execution events.
94
+
95
+ This interceptor captures the start and end of workflow executions,
96
+ creating events that can be used for monitoring and tracking.
97
+ Uses activities to publish events to avoid sandbox restrictions.
98
+ """
99
+
100
+ async def execute_workflow(self, input: ExecuteWorkflowInput) -> Any:
101
+ """Execute a workflow with event tracking.
102
+
103
+ Args:
104
+ input (ExecuteWorkflowInput): The workflow execution input.
105
+
106
+ Returns:
107
+ Any: The result of the workflow execution.
108
+ """
109
+
110
+ # Publish workflow start event via activity
111
+ try:
112
+ await workflow.execute_activity(
113
+ publish_event,
114
+ {
115
+ "metadata": EventMetadata(
116
+ workflow_state=WorkflowStates.RUNNING.value
117
+ ),
118
+ "event_type": EventTypes.APPLICATION_EVENT.value,
119
+ "event_name": ApplicationEventNames.WORKFLOW_START.value,
120
+ "data": {},
121
+ },
122
+ schedule_to_close_timeout=timedelta(seconds=30),
123
+ retry_policy=RetryPolicy(maximum_attempts=3),
124
+ )
125
+ except Exception as e:
126
+ workflow.logger.warning(f"Failed to publish workflow start event: {e}")
127
+ # Don't fail the workflow if event publishing fails
128
+
129
+ output = None
130
+ workflow_state = WorkflowStates.FAILED.value # Default to failed
131
+
132
+ try:
133
+ output = await super().execute_workflow(input)
134
+ workflow_state = (
135
+ WorkflowStates.COMPLETED.value
136
+ ) # Update to completed on success
137
+ except Exception:
138
+ workflow_state = WorkflowStates.FAILED.value # Keep as failed
139
+ raise
140
+ finally:
141
+ # Always publish workflow end event
142
+ try:
143
+ await workflow.execute_activity(
144
+ publish_event,
145
+ {
146
+ "metadata": EventMetadata(workflow_state=workflow_state),
147
+ "event_type": EventTypes.APPLICATION_EVENT.value,
148
+ "event_name": ApplicationEventNames.WORKFLOW_END.value,
149
+ "data": {},
150
+ },
151
+ schedule_to_close_timeout=timedelta(seconds=30),
152
+ retry_policy=RetryPolicy(maximum_attempts=3),
153
+ )
154
+ except Exception as publish_error:
155
+ workflow.logger.warning(
156
+ f"Failed to publish workflow end event: {publish_error}"
157
+ )
158
+
159
+ return output
160
+
161
+
162
+ class EventInterceptor(Interceptor):
163
+ """Temporal interceptor for event tracking.
164
+
165
+ This interceptor provides event tracking capabilities for both
166
+ workflow and activity executions.
167
+ """
168
+
169
+ def intercept_activity(
170
+ self, next: ActivityInboundInterceptor
171
+ ) -> ActivityInboundInterceptor:
172
+ """Intercept activity executions.
173
+
174
+ Args:
175
+ next (ActivityInboundInterceptor): The next interceptor in the chain.
176
+
177
+ Returns:
178
+ ActivityInboundInterceptor: The activity interceptor.
179
+ """
180
+ return EventActivityInboundInterceptor(super().intercept_activity(next))
181
+
182
+ def workflow_interceptor_class(
183
+ self, input: WorkflowInterceptorClassInput
184
+ ) -> Optional[Type[WorkflowInboundInterceptor]]:
185
+ """Get the workflow interceptor class.
186
+
187
+ Args:
188
+ input (WorkflowInterceptorClassInput): The interceptor input.
189
+
190
+ Returns:
191
+ Optional[Type[WorkflowInboundInterceptor]]: The workflow interceptor class.
192
+ """
193
+ return EventWorkflowInboundInterceptor