julee 0.1.4__py3-none-any.whl → 0.1.6__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.
Files changed (165) hide show
  1. julee/__init__.py +1 -1
  2. julee/api/tests/routers/test_assembly_specifications.py +2 -0
  3. julee/api/tests/routers/test_documents.py +2 -0
  4. julee/api/tests/routers/test_knowledge_service_configs.py +2 -0
  5. julee/api/tests/routers/test_knowledge_service_queries.py +2 -0
  6. julee/api/tests/routers/test_system.py +2 -0
  7. julee/api/tests/routers/test_workflows.py +2 -0
  8. julee/api/tests/test_app.py +2 -0
  9. julee/api/tests/test_dependencies.py +2 -0
  10. julee/api/tests/test_requests.py +2 -0
  11. julee/contrib/polling/__init__.py +22 -19
  12. julee/contrib/polling/apps/__init__.py +17 -0
  13. julee/contrib/polling/apps/worker/__init__.py +17 -0
  14. julee/contrib/polling/apps/worker/pipelines.py +288 -0
  15. julee/contrib/polling/domain/__init__.py +7 -9
  16. julee/contrib/polling/domain/models/__init__.py +6 -7
  17. julee/contrib/polling/domain/models/polling_config.py +18 -1
  18. julee/contrib/polling/domain/services/__init__.py +6 -5
  19. julee/contrib/polling/domain/services/poller.py +1 -1
  20. julee/contrib/polling/infrastructure/__init__.py +9 -8
  21. julee/contrib/polling/infrastructure/services/__init__.py +6 -5
  22. julee/contrib/polling/infrastructure/services/polling/__init__.py +6 -5
  23. julee/contrib/polling/infrastructure/services/polling/http/__init__.py +6 -5
  24. julee/contrib/polling/infrastructure/services/polling/http/http_poller_service.py +5 -2
  25. julee/contrib/polling/infrastructure/temporal/__init__.py +12 -12
  26. julee/contrib/polling/infrastructure/temporal/activities.py +1 -1
  27. julee/contrib/polling/infrastructure/temporal/manager.py +291 -0
  28. julee/contrib/polling/infrastructure/temporal/proxies.py +1 -1
  29. julee/contrib/polling/tests/unit/apps/worker/test_pipelines.py +580 -0
  30. julee/contrib/polling/tests/unit/infrastructure/services/polling/http/test_http_poller_service.py +40 -2
  31. julee/contrib/polling/tests/unit/infrastructure/temporal/__init__.py +7 -0
  32. julee/contrib/polling/tests/unit/infrastructure/temporal/test_manager.py +475 -0
  33. julee/docs/sphinx_hcd/__init__.py +146 -13
  34. julee/docs/sphinx_hcd/domain/__init__.py +5 -0
  35. julee/docs/sphinx_hcd/domain/models/__init__.py +32 -0
  36. julee/docs/sphinx_hcd/domain/models/accelerator.py +152 -0
  37. julee/docs/sphinx_hcd/domain/models/app.py +151 -0
  38. julee/docs/sphinx_hcd/domain/models/code_info.py +121 -0
  39. julee/docs/sphinx_hcd/domain/models/epic.py +79 -0
  40. julee/docs/sphinx_hcd/domain/models/integration.py +230 -0
  41. julee/docs/sphinx_hcd/domain/models/journey.py +222 -0
  42. julee/docs/sphinx_hcd/domain/models/persona.py +106 -0
  43. julee/docs/sphinx_hcd/domain/models/story.py +128 -0
  44. julee/docs/sphinx_hcd/domain/repositories/__init__.py +25 -0
  45. julee/docs/sphinx_hcd/domain/repositories/accelerator.py +98 -0
  46. julee/docs/sphinx_hcd/domain/repositories/app.py +57 -0
  47. julee/docs/sphinx_hcd/domain/repositories/base.py +89 -0
  48. julee/docs/sphinx_hcd/domain/repositories/code_info.py +69 -0
  49. julee/docs/sphinx_hcd/domain/repositories/epic.py +62 -0
  50. julee/docs/sphinx_hcd/domain/repositories/integration.py +79 -0
  51. julee/docs/sphinx_hcd/domain/repositories/journey.py +106 -0
  52. julee/docs/sphinx_hcd/domain/repositories/story.py +68 -0
  53. julee/docs/sphinx_hcd/domain/use_cases/__init__.py +64 -0
  54. julee/docs/sphinx_hcd/domain/use_cases/derive_personas.py +166 -0
  55. julee/docs/sphinx_hcd/domain/use_cases/resolve_accelerator_references.py +236 -0
  56. julee/docs/sphinx_hcd/domain/use_cases/resolve_app_references.py +144 -0
  57. julee/docs/sphinx_hcd/domain/use_cases/resolve_story_references.py +121 -0
  58. julee/docs/sphinx_hcd/parsers/__init__.py +48 -0
  59. julee/docs/sphinx_hcd/parsers/ast.py +150 -0
  60. julee/docs/sphinx_hcd/parsers/gherkin.py +155 -0
  61. julee/docs/sphinx_hcd/parsers/yaml.py +184 -0
  62. julee/docs/sphinx_hcd/repositories/__init__.py +4 -0
  63. julee/docs/sphinx_hcd/repositories/memory/__init__.py +25 -0
  64. julee/docs/sphinx_hcd/repositories/memory/accelerator.py +86 -0
  65. julee/docs/sphinx_hcd/repositories/memory/app.py +45 -0
  66. julee/docs/sphinx_hcd/repositories/memory/base.py +106 -0
  67. julee/docs/sphinx_hcd/repositories/memory/code_info.py +59 -0
  68. julee/docs/sphinx_hcd/repositories/memory/epic.py +54 -0
  69. julee/docs/sphinx_hcd/repositories/memory/integration.py +70 -0
  70. julee/docs/sphinx_hcd/repositories/memory/journey.py +96 -0
  71. julee/docs/sphinx_hcd/repositories/memory/story.py +63 -0
  72. julee/docs/sphinx_hcd/sphinx/__init__.py +28 -0
  73. julee/docs/sphinx_hcd/sphinx/adapters.py +116 -0
  74. julee/docs/sphinx_hcd/sphinx/context.py +163 -0
  75. julee/docs/sphinx_hcd/sphinx/directives/__init__.py +160 -0
  76. julee/docs/sphinx_hcd/sphinx/directives/accelerator.py +576 -0
  77. julee/docs/sphinx_hcd/sphinx/directives/app.py +349 -0
  78. julee/docs/sphinx_hcd/sphinx/directives/base.py +211 -0
  79. julee/docs/sphinx_hcd/sphinx/directives/epic.py +434 -0
  80. julee/docs/sphinx_hcd/sphinx/directives/integration.py +220 -0
  81. julee/docs/sphinx_hcd/sphinx/directives/journey.py +642 -0
  82. julee/docs/sphinx_hcd/sphinx/directives/persona.py +345 -0
  83. julee/docs/sphinx_hcd/sphinx/directives/story.py +575 -0
  84. julee/docs/sphinx_hcd/sphinx/event_handlers/__init__.py +16 -0
  85. julee/docs/sphinx_hcd/sphinx/event_handlers/builder_inited.py +31 -0
  86. julee/docs/sphinx_hcd/sphinx/event_handlers/doctree_read.py +27 -0
  87. julee/docs/sphinx_hcd/sphinx/event_handlers/doctree_resolved.py +43 -0
  88. julee/docs/sphinx_hcd/sphinx/event_handlers/env_purge_doc.py +42 -0
  89. julee/docs/sphinx_hcd/sphinx/initialization.py +139 -0
  90. julee/docs/sphinx_hcd/tests/__init__.py +9 -0
  91. julee/docs/sphinx_hcd/tests/conftest.py +6 -0
  92. julee/docs/sphinx_hcd/tests/domain/__init__.py +1 -0
  93. julee/docs/sphinx_hcd/tests/domain/models/__init__.py +1 -0
  94. julee/docs/sphinx_hcd/tests/domain/models/test_accelerator.py +266 -0
  95. julee/docs/sphinx_hcd/tests/domain/models/test_app.py +258 -0
  96. julee/docs/sphinx_hcd/tests/domain/models/test_code_info.py +231 -0
  97. julee/docs/sphinx_hcd/tests/domain/models/test_epic.py +163 -0
  98. julee/docs/sphinx_hcd/tests/domain/models/test_integration.py +327 -0
  99. julee/docs/sphinx_hcd/tests/domain/models/test_journey.py +249 -0
  100. julee/docs/sphinx_hcd/tests/domain/models/test_persona.py +172 -0
  101. julee/docs/sphinx_hcd/tests/domain/models/test_story.py +216 -0
  102. julee/docs/sphinx_hcd/tests/domain/use_cases/__init__.py +1 -0
  103. julee/docs/sphinx_hcd/tests/domain/use_cases/test_derive_personas.py +314 -0
  104. julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_accelerator_references.py +476 -0
  105. julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_app_references.py +265 -0
  106. julee/docs/sphinx_hcd/tests/domain/use_cases/test_resolve_story_references.py +229 -0
  107. julee/docs/sphinx_hcd/tests/integration/__init__.py +1 -0
  108. julee/docs/sphinx_hcd/tests/parsers/__init__.py +1 -0
  109. julee/docs/sphinx_hcd/tests/parsers/test_ast.py +298 -0
  110. julee/docs/sphinx_hcd/tests/parsers/test_gherkin.py +282 -0
  111. julee/docs/sphinx_hcd/tests/parsers/test_yaml.py +496 -0
  112. julee/docs/sphinx_hcd/tests/repositories/__init__.py +1 -0
  113. julee/docs/sphinx_hcd/tests/repositories/test_accelerator.py +298 -0
  114. julee/docs/sphinx_hcd/tests/repositories/test_app.py +218 -0
  115. julee/docs/sphinx_hcd/tests/repositories/test_base.py +151 -0
  116. julee/docs/sphinx_hcd/tests/repositories/test_code_info.py +253 -0
  117. julee/docs/sphinx_hcd/tests/repositories/test_epic.py +237 -0
  118. julee/docs/sphinx_hcd/tests/repositories/test_integration.py +268 -0
  119. julee/docs/sphinx_hcd/tests/repositories/test_journey.py +294 -0
  120. julee/docs/sphinx_hcd/tests/repositories/test_story.py +236 -0
  121. julee/docs/sphinx_hcd/tests/sphinx/__init__.py +1 -0
  122. julee/docs/sphinx_hcd/tests/sphinx/directives/__init__.py +1 -0
  123. julee/docs/sphinx_hcd/tests/sphinx/directives/test_base.py +160 -0
  124. julee/docs/sphinx_hcd/tests/sphinx/test_adapters.py +176 -0
  125. julee/docs/sphinx_hcd/tests/sphinx/test_context.py +257 -0
  126. julee/domain/models/assembly/tests/test_assembly.py +2 -0
  127. julee/domain/models/assembly_specification/tests/test_assembly_specification.py +2 -0
  128. julee/domain/models/assembly_specification/tests/test_knowledge_service_query.py +2 -0
  129. julee/domain/models/custom_fields/tests/test_custom_fields.py +2 -0
  130. julee/domain/models/document/tests/test_document.py +2 -0
  131. julee/domain/models/policy/tests/test_document_policy_validation.py +2 -0
  132. julee/domain/models/policy/tests/test_policy.py +2 -0
  133. julee/domain/use_cases/tests/test_extract_assemble_data.py +2 -0
  134. julee/domain/use_cases/tests/test_initialize_system_data.py +2 -0
  135. julee/domain/use_cases/tests/test_validate_document.py +2 -0
  136. julee/maintenance/release.py +10 -5
  137. julee/repositories/memory/tests/test_document.py +2 -0
  138. julee/repositories/memory/tests/test_document_policy_validation.py +2 -0
  139. julee/repositories/memory/tests/test_policy.py +2 -0
  140. julee/repositories/minio/tests/test_assembly.py +2 -0
  141. julee/repositories/minio/tests/test_assembly_specification.py +2 -0
  142. julee/repositories/minio/tests/test_client_protocol.py +3 -0
  143. julee/repositories/minio/tests/test_document.py +2 -0
  144. julee/repositories/minio/tests/test_document_policy_validation.py +2 -0
  145. julee/repositories/minio/tests/test_knowledge_service_config.py +2 -0
  146. julee/repositories/minio/tests/test_knowledge_service_query.py +2 -0
  147. julee/repositories/minio/tests/test_policy.py +2 -0
  148. julee/services/knowledge_service/anthropic/tests/test_knowledge_service.py +2 -0
  149. julee/services/knowledge_service/memory/test_knowledge_service.py +2 -0
  150. julee/services/knowledge_service/test_factory.py +2 -0
  151. julee/util/tests/test_decorators.py +2 -0
  152. julee-0.1.6.dist-info/METADATA +104 -0
  153. julee-0.1.6.dist-info/RECORD +288 -0
  154. julee/docs/sphinx_hcd/accelerators.py +0 -1175
  155. julee/docs/sphinx_hcd/apps.py +0 -518
  156. julee/docs/sphinx_hcd/epics.py +0 -453
  157. julee/docs/sphinx_hcd/integrations.py +0 -310
  158. julee/docs/sphinx_hcd/journeys.py +0 -797
  159. julee/docs/sphinx_hcd/personas.py +0 -457
  160. julee/docs/sphinx_hcd/stories.py +0 -960
  161. julee-0.1.4.dist-info/METADATA +0 -197
  162. julee-0.1.4.dist-info/RECORD +0 -196
  163. {julee-0.1.4.dist-info → julee-0.1.6.dist-info}/WHEEL +0 -0
  164. {julee-0.1.4.dist-info → julee-0.1.6.dist-info}/licenses/LICENSE +0 -0
  165. {julee-0.1.4.dist-info → julee-0.1.6.dist-info}/top_level.txt +0 -0
@@ -1,20 +1,20 @@
1
1
  """
2
- Temporal infrastructure for the polling contrib module.
2
+ Temporal integration for the polling contrib module.
3
3
 
4
- This module contains the temporal-specific implementations for the polling
5
- contrib module, including activity registrations, workflow proxies, and
4
+ This module provides the Temporal integration layer for polling operations,
5
+ including workflow proxies for calling polling activities from workflows and
6
6
  activity name constants.
7
7
 
8
8
  This keeps all polling-temporal integration within the contrib module,
9
9
  maintaining proper dependency direction (contrib imports from core, not vice versa).
10
- """
11
10
 
12
- from .activities import TemporalPollerService
13
- from .activity_names import POLLING_SERVICE_ACTIVITY_BASE
14
- from .proxies import WorkflowPollerServiceProxy
11
+ No re-exports to avoid import chains that pull non-deterministic code
12
+ into Temporal workflows. Import directly from specific modules:
13
+
14
+ - from julee.contrib.polling.infrastructure.temporal.activity_names import POLLING_SERVICE_ACTIVITY_BASE
15
+ - from julee.contrib.polling.infrastructure.temporal.manager import PollingManager
16
+ - from julee.contrib.polling.infrastructure.temporal.proxies import WorkflowPollerServiceProxy
17
+ - from julee.contrib.polling.infrastructure.temporal.activities import TemporalPollerService
18
+ """
15
19
 
16
- __all__ = [
17
- "TemporalPollerService",
18
- "POLLING_SERVICE_ACTIVITY_BASE",
19
- "WorkflowPollerServiceProxy",
20
- ]
20
+ __all__ = []
@@ -14,7 +14,7 @@ import logging
14
14
 
15
15
  from julee.util.temporal.decorators import temporal_activity_registration
16
16
 
17
- from ..services.polling.http import HttpPollerService
17
+ from ..services.polling.http.http_poller_service import HttpPollerService
18
18
  from .activity_names import POLLING_SERVICE_ACTIVITY_BASE
19
19
 
20
20
 
@@ -0,0 +1,291 @@
1
+ """
2
+ PollingManager for high-level HTTP endpoint polling operations.
3
+
4
+ This module provides a simple, framework-agnostic API for managing
5
+ HTTP endpoint polling with automatic change detection and pipeline
6
+ triggering. It abstracts away the underlying Temporal scheduling
7
+ implementation.
8
+ """
9
+
10
+ import logging
11
+ from datetime import timedelta
12
+ from typing import Any
13
+
14
+ from temporalio.client import (
15
+ Client,
16
+ Schedule,
17
+ ScheduleActionStartWorkflow,
18
+ ScheduleAlreadyRunningError,
19
+ ScheduleIntervalSpec,
20
+ ScheduleSpec,
21
+ ScheduleUpdate,
22
+ ScheduleUpdateInput,
23
+ )
24
+
25
+ from julee.contrib.polling.domain.models.polling_config import PollingConfig
26
+
27
+ logger = logging.getLogger(__name__)
28
+
29
+
30
+ class PollingManager:
31
+ """
32
+ High-level manager for HTTP endpoint polling operations.
33
+
34
+ This class provides a simple API for starting and stopping polling
35
+ operations using Temporal schedules for reliable execution. Users
36
+ must provide a Temporal client during initialization, following the
37
+ same pattern as other Julee infrastructure components.
38
+
39
+ The manager handles:
40
+ - Creating and managing Temporal schedules for polling
41
+ - Tracking active polling operations
42
+ - Providing status and control operations (pause/resume/stop)
43
+
44
+ Example:
45
+ # Using default task queue
46
+ manager = PollingManager(temporal_client)
47
+
48
+ # Using custom task queue
49
+ manager = PollingManager(temporal_client, task_queue="my-polling-queue")
50
+ """
51
+
52
+ def __init__(
53
+ self,
54
+ temporal_client: Client | None = None,
55
+ task_queue: str = "julee-polling-queue",
56
+ ) -> None:
57
+ """
58
+ Initialize the polling manager.
59
+
60
+ Args:
61
+ temporal_client: Temporal client for schedule management.
62
+ Typically created at application startup level
63
+ (worker, API) and passed to the manager.
64
+ task_queue: Task queue name for workflow execution.
65
+ Defaults to "julee-polling-queue".
66
+ """
67
+ self._temporal_client = temporal_client
68
+ self._task_queue = task_queue
69
+ self._active_polls: dict[str, dict[str, Any]] = {}
70
+
71
+ async def start_polling(
72
+ self,
73
+ endpoint_id: str,
74
+ config: PollingConfig,
75
+ interval_seconds: int,
76
+ downstream_pipeline: str | None = None,
77
+ ) -> str:
78
+ """
79
+ Start polling an HTTP endpoint at regular intervals.
80
+
81
+ Args:
82
+ endpoint_id: Unique identifier for this polling operation
83
+ config: Configuration for the polling operation
84
+ interval_seconds: How often to poll (in seconds)
85
+ downstream_pipeline: Optional pipeline to trigger when new data detected
86
+
87
+ Returns:
88
+ Schedule ID that was created
89
+
90
+ Raises:
91
+ ValueError: If endpoint_id is already being polled
92
+ RuntimeError: If Temporal client is not available
93
+ """
94
+ if endpoint_id in self._active_polls:
95
+ raise ValueError(f"Endpoint {endpoint_id} is already being polled")
96
+
97
+ if self._temporal_client is None:
98
+ raise RuntimeError("Temporal client not available")
99
+
100
+ schedule_id = f"poll-{endpoint_id}"
101
+
102
+ schedule = Schedule(
103
+ action=ScheduleActionStartWorkflow(
104
+ "NewDataDetectionPipeline",
105
+ args=[config, downstream_pipeline],
106
+ id=f"{schedule_id}-{{.timestamp}}",
107
+ task_queue=self._task_queue,
108
+ ),
109
+ spec=ScheduleSpec(
110
+ intervals=[
111
+ ScheduleIntervalSpec(every=timedelta(seconds=interval_seconds))
112
+ ]
113
+ ),
114
+ )
115
+
116
+ try:
117
+ await self._temporal_client.create_schedule(
118
+ id=schedule_id, schedule=schedule
119
+ )
120
+ logger.info(
121
+ f"Created new schedule {schedule_id} for endpoint {endpoint_id}"
122
+ )
123
+ except ScheduleAlreadyRunningError:
124
+ # Update existing schedule preserving history
125
+ logger.info(f"Updating existing schedule {schedule_id}")
126
+ schedule_handle = self._temporal_client.get_schedule_handle(schedule_id)
127
+
128
+ # Create update function that modifies the schedule
129
+ async def update_schedule_callback(
130
+ input: ScheduleUpdateInput,
131
+ ) -> ScheduleUpdate:
132
+ # Update the schedule with new configuration
133
+ updated_schedule = input.description.schedule
134
+ updated_schedule.action = schedule.action
135
+ updated_schedule.spec = schedule.spec
136
+ return ScheduleUpdate(schedule=updated_schedule)
137
+
138
+ await schedule_handle.update(update_schedule_callback)
139
+ logger.info(f"Updated schedule {schedule_id} for endpoint {endpoint_id}")
140
+
141
+ # Track the active polling operation
142
+ self._active_polls[endpoint_id] = {
143
+ "schedule_id": schedule_id,
144
+ "config": config,
145
+ "interval_seconds": interval_seconds,
146
+ "downstream_pipeline": downstream_pipeline,
147
+ }
148
+
149
+ return schedule_id
150
+
151
+ async def stop_polling(self, endpoint_id: str) -> bool:
152
+ """
153
+ Stop polling an endpoint.
154
+
155
+ Args:
156
+ endpoint_id: The endpoint ID to stop polling
157
+
158
+ Returns:
159
+ True if polling was stopped, False if not found
160
+
161
+ Raises:
162
+ RuntimeError: If Temporal client is not available
163
+ """
164
+ if endpoint_id not in self._active_polls:
165
+ return False
166
+
167
+ if self._temporal_client is None:
168
+ raise RuntimeError("Temporal client not available")
169
+
170
+ poll_info = self._active_polls[endpoint_id]
171
+ schedule_id = poll_info["schedule_id"]
172
+
173
+ # Delete the Temporal schedule
174
+ schedule_handle = self._temporal_client.get_schedule_handle(schedule_id)
175
+ await schedule_handle.delete()
176
+
177
+ # Remove from tracking
178
+ del self._active_polls[endpoint_id]
179
+
180
+ return True
181
+
182
+ async def list_active_polling(self) -> list[dict[str, Any]]:
183
+ """
184
+ List all active polling operations.
185
+
186
+ Returns:
187
+ List of dictionaries containing polling operation details
188
+ """
189
+ active_polls = []
190
+
191
+ for endpoint_id, poll_info in self._active_polls.items():
192
+ active_polls.append(
193
+ {
194
+ "endpoint_id": endpoint_id,
195
+ "schedule_id": poll_info["schedule_id"],
196
+ "interval_seconds": poll_info["interval_seconds"],
197
+ "endpoint_identifier": poll_info["config"].endpoint_identifier,
198
+ "polling_protocol": poll_info["config"].polling_protocol.value,
199
+ "downstream_pipeline": poll_info.get("downstream_pipeline"),
200
+ }
201
+ )
202
+
203
+ return active_polls
204
+
205
+ async def get_polling_status(self, endpoint_id: str) -> dict[str, Any] | None:
206
+ """
207
+ Get the status of a specific polling operation.
208
+
209
+ Args:
210
+ endpoint_id: The endpoint ID to check
211
+
212
+ Returns:
213
+ Dictionary with status information or None if not found
214
+
215
+ Raises:
216
+ RuntimeError: If Temporal client is not available
217
+ """
218
+ if endpoint_id not in self._active_polls:
219
+ return None
220
+
221
+ if self._temporal_client is None:
222
+ raise RuntimeError("Temporal client not available")
223
+
224
+ poll_info = self._active_polls[endpoint_id]
225
+ schedule_id = poll_info["schedule_id"]
226
+
227
+ # Get schedule information from Temporal
228
+ schedule_handle = self._temporal_client.get_schedule_handle(schedule_id)
229
+ schedule_description = await schedule_handle.describe()
230
+
231
+ return {
232
+ "endpoint_id": endpoint_id,
233
+ "schedule_id": schedule_id,
234
+ "interval_seconds": poll_info["interval_seconds"],
235
+ "is_paused": schedule_description.schedule.state.paused,
236
+ "downstream_pipeline": poll_info.get("downstream_pipeline"),
237
+ }
238
+
239
+ async def pause_polling(self, endpoint_id: str) -> bool:
240
+ """
241
+ Pause polling for an endpoint (without deleting the schedule).
242
+
243
+ Args:
244
+ endpoint_id: The endpoint ID to pause
245
+
246
+ Returns:
247
+ True if paused successfully, False if not found
248
+
249
+ Raises:
250
+ RuntimeError: If Temporal client is not available
251
+ """
252
+ if endpoint_id not in self._active_polls:
253
+ return False
254
+
255
+ if self._temporal_client is None:
256
+ raise RuntimeError("Temporal client not available")
257
+
258
+ poll_info = self._active_polls[endpoint_id]
259
+ schedule_id = poll_info["schedule_id"]
260
+
261
+ schedule_handle = self._temporal_client.get_schedule_handle(schedule_id)
262
+ await schedule_handle.pause()
263
+
264
+ return True
265
+
266
+ async def resume_polling(self, endpoint_id: str) -> bool:
267
+ """
268
+ Resume a paused polling operation.
269
+
270
+ Args:
271
+ endpoint_id: The endpoint ID to resume
272
+
273
+ Returns:
274
+ True if resumed successfully, False if not found
275
+
276
+ Raises:
277
+ RuntimeError: If Temporal client is not available
278
+ """
279
+ if endpoint_id not in self._active_polls:
280
+ return False
281
+
282
+ if self._temporal_client is None:
283
+ raise RuntimeError("Temporal client not available")
284
+
285
+ poll_info = self._active_polls[endpoint_id]
286
+ schedule_id = poll_info["schedule_id"]
287
+
288
+ schedule_handle = self._temporal_client.get_schedule_handle(schedule_id)
289
+ await schedule_handle.unpause()
290
+
291
+ return True
@@ -16,7 +16,7 @@ maintaining proper dependency direction (contrib imports from core, not vice ver
16
16
 
17
17
  from julee.util.temporal.decorators import temporal_workflow_proxy
18
18
 
19
- from ...domain.services import PollerService
19
+ from ...domain.services.poller import PollerService
20
20
  from .activity_names import POLLING_SERVICE_ACTIVITY_BASE
21
21
 
22
22