julee 0.1.1__py3-none-any.whl → 0.1.3__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 (157) hide show
  1. julee/api/app.py +9 -8
  2. julee/api/dependencies.py +15 -15
  3. julee/api/requests.py +10 -9
  4. julee/api/responses.py +2 -1
  5. julee/api/routers/__init__.py +5 -5
  6. julee/api/routers/assembly_specifications.py +5 -4
  7. julee/api/routers/documents.py +1 -1
  8. julee/api/routers/knowledge_service_configs.py +4 -3
  9. julee/api/routers/knowledge_service_queries.py +7 -6
  10. julee/api/routers/system.py +4 -3
  11. julee/api/routers/workflows.py +4 -5
  12. julee/api/services/system_initialization.py +6 -6
  13. julee/api/tests/routers/test_assembly_specifications.py +4 -3
  14. julee/api/tests/routers/test_documents.py +5 -4
  15. julee/api/tests/routers/test_knowledge_service_configs.py +7 -6
  16. julee/api/tests/routers/test_knowledge_service_queries.py +4 -3
  17. julee/api/tests/routers/test_system.py +5 -4
  18. julee/api/tests/routers/test_workflows.py +5 -4
  19. julee/api/tests/test_app.py +5 -4
  20. julee/api/tests/test_dependencies.py +3 -2
  21. julee/api/tests/test_requests.py +2 -1
  22. julee/contrib/__init__.py +15 -0
  23. julee/contrib/polling/__init__.py +47 -0
  24. julee/contrib/polling/domain/__init__.py +17 -0
  25. julee/contrib/polling/domain/models/__init__.py +13 -0
  26. julee/contrib/polling/domain/models/polling_config.py +39 -0
  27. julee/contrib/polling/domain/services/__init__.py +11 -0
  28. julee/contrib/polling/domain/services/poller.py +39 -0
  29. julee/contrib/polling/infrastructure/__init__.py +15 -0
  30. julee/contrib/polling/infrastructure/services/__init__.py +12 -0
  31. julee/contrib/polling/infrastructure/services/polling/__init__.py +12 -0
  32. julee/contrib/polling/infrastructure/services/polling/http/__init__.py +12 -0
  33. julee/contrib/polling/infrastructure/services/polling/http/http_poller_service.py +80 -0
  34. julee/contrib/polling/infrastructure/temporal/__init__.py +20 -0
  35. julee/contrib/polling/infrastructure/temporal/activities.py +42 -0
  36. julee/contrib/polling/infrastructure/temporal/activity_names.py +20 -0
  37. julee/contrib/polling/infrastructure/temporal/proxies.py +45 -0
  38. julee/contrib/polling/tests/__init__.py +6 -0
  39. julee/contrib/polling/tests/unit/__init__.py +6 -0
  40. julee/contrib/polling/tests/unit/infrastructure/__init__.py +7 -0
  41. julee/contrib/polling/tests/unit/infrastructure/services/__init__.py +6 -0
  42. julee/contrib/polling/tests/unit/infrastructure/services/polling/__init__.py +6 -0
  43. julee/contrib/polling/tests/unit/infrastructure/services/polling/http/__init__.py +7 -0
  44. julee/contrib/polling/tests/unit/infrastructure/services/polling/http/test_http_poller_service.py +163 -0
  45. julee/docs/__init__.py +5 -0
  46. julee/docs/sphinx_hcd/__init__.py +82 -0
  47. julee/docs/sphinx_hcd/accelerators.py +1078 -0
  48. julee/docs/sphinx_hcd/apps.py +499 -0
  49. julee/docs/sphinx_hcd/config.py +148 -0
  50. julee/docs/sphinx_hcd/epics.py +448 -0
  51. julee/docs/sphinx_hcd/integrations.py +306 -0
  52. julee/docs/sphinx_hcd/journeys.py +783 -0
  53. julee/docs/sphinx_hcd/personas.py +435 -0
  54. julee/docs/sphinx_hcd/stories.py +932 -0
  55. julee/docs/sphinx_hcd/utils.py +180 -0
  56. julee/domain/models/__init__.py +5 -6
  57. julee/domain/models/assembly/assembly.py +7 -7
  58. julee/domain/models/assembly/tests/factories.py +2 -1
  59. julee/domain/models/assembly/tests/test_assembly.py +16 -13
  60. julee/domain/models/assembly_specification/assembly_specification.py +11 -10
  61. julee/domain/models/assembly_specification/knowledge_service_query.py +14 -9
  62. julee/domain/models/assembly_specification/tests/factories.py +2 -1
  63. julee/domain/models/assembly_specification/tests/test_assembly_specification.py +9 -6
  64. julee/domain/models/assembly_specification/tests/test_knowledge_service_query.py +3 -1
  65. julee/domain/models/custom_fields/content_stream.py +3 -2
  66. julee/domain/models/custom_fields/tests/test_custom_fields.py +2 -1
  67. julee/domain/models/document/document.py +12 -10
  68. julee/domain/models/document/tests/factories.py +3 -2
  69. julee/domain/models/document/tests/test_document.py +6 -3
  70. julee/domain/models/knowledge_service_config/knowledge_service_config.py +4 -4
  71. julee/domain/models/policy/__init__.py +4 -4
  72. julee/domain/models/policy/document_policy_validation.py +17 -17
  73. julee/domain/models/policy/policy.py +12 -10
  74. julee/domain/models/policy/tests/factories.py +2 -1
  75. julee/domain/models/policy/tests/test_document_policy_validation.py +3 -1
  76. julee/domain/models/policy/tests/test_policy.py +2 -1
  77. julee/domain/repositories/__init__.py +3 -3
  78. julee/domain/repositories/assembly.py +3 -1
  79. julee/domain/repositories/assembly_specification.py +2 -0
  80. julee/domain/repositories/base.py +33 -16
  81. julee/domain/repositories/document.py +3 -1
  82. julee/domain/repositories/document_policy_validation.py +3 -1
  83. julee/domain/repositories/knowledge_service_config.py +2 -0
  84. julee/domain/repositories/knowledge_service_query.py +1 -0
  85. julee/domain/repositories/policy.py +3 -1
  86. julee/domain/use_cases/decorators.py +3 -2
  87. julee/domain/use_cases/extract_assemble_data.py +23 -13
  88. julee/domain/use_cases/initialize_system_data.py +13 -13
  89. julee/domain/use_cases/tests/test_extract_assemble_data.py +10 -10
  90. julee/domain/use_cases/tests/test_initialize_system_data.py +2 -2
  91. julee/domain/use_cases/tests/test_validate_document.py +11 -11
  92. julee/domain/use_cases/validate_document.py +26 -15
  93. julee/maintenance/__init__.py +1 -0
  94. julee/maintenance/release.py +188 -0
  95. julee/repositories/__init__.py +4 -1
  96. julee/repositories/memory/assembly.py +6 -5
  97. julee/repositories/memory/assembly_specification.py +9 -9
  98. julee/repositories/memory/base.py +12 -11
  99. julee/repositories/memory/document.py +8 -7
  100. julee/repositories/memory/document_policy_validation.py +7 -6
  101. julee/repositories/memory/knowledge_service_config.py +9 -7
  102. julee/repositories/memory/knowledge_service_query.py +9 -7
  103. julee/repositories/memory/policy.py +6 -5
  104. julee/repositories/memory/tests/test_document.py +6 -4
  105. julee/repositories/memory/tests/test_document_policy_validation.py +2 -1
  106. julee/repositories/memory/tests/test_policy.py +2 -1
  107. julee/repositories/minio/assembly.py +4 -4
  108. julee/repositories/minio/assembly_specification.py +6 -8
  109. julee/repositories/minio/client.py +22 -25
  110. julee/repositories/minio/document.py +11 -11
  111. julee/repositories/minio/document_policy_validation.py +5 -5
  112. julee/repositories/minio/knowledge_service_config.py +8 -8
  113. julee/repositories/minio/knowledge_service_query.py +6 -9
  114. julee/repositories/minio/policy.py +4 -4
  115. julee/repositories/minio/tests/fake_client.py +11 -9
  116. julee/repositories/minio/tests/test_assembly.py +3 -1
  117. julee/repositories/minio/tests/test_assembly_specification.py +2 -1
  118. julee/repositories/minio/tests/test_client_protocol.py +5 -5
  119. julee/repositories/minio/tests/test_document.py +7 -6
  120. julee/repositories/minio/tests/test_document_policy_validation.py +3 -1
  121. julee/repositories/minio/tests/test_knowledge_service_config.py +4 -2
  122. julee/repositories/minio/tests/test_knowledge_service_query.py +3 -2
  123. julee/repositories/minio/tests/test_policy.py +3 -1
  124. julee/repositories/temporal/activities.py +5 -5
  125. julee/repositories/temporal/proxies.py +5 -5
  126. julee/services/knowledge_service/__init__.py +1 -2
  127. julee/services/knowledge_service/anthropic/knowledge_service.py +8 -7
  128. julee/services/knowledge_service/anthropic/tests/test_knowledge_service.py +11 -10
  129. julee/services/knowledge_service/factory.py +8 -8
  130. julee/services/knowledge_service/knowledge_service.py +22 -18
  131. julee/services/knowledge_service/memory/knowledge_service.py +13 -12
  132. julee/services/knowledge_service/memory/test_knowledge_service.py +10 -7
  133. julee/services/knowledge_service/test_factory.py +11 -10
  134. julee/services/temporal/activities.py +10 -10
  135. julee/services/temporal/proxies.py +2 -2
  136. julee/util/domain.py +6 -6
  137. julee/util/repos/minio/file_storage.py +8 -9
  138. julee/util/repos/temporal/client_proxies/file_storage.py +3 -4
  139. julee/util/repos/temporal/data_converter.py +6 -6
  140. julee/util/repos/temporal/minio_file_storage.py +1 -1
  141. julee/util/repos/temporal/proxies/file_storage.py +2 -3
  142. julee/util/repositories.py +6 -7
  143. julee/util/temporal/activities.py +1 -1
  144. julee/util/temporal/decorators.py +28 -33
  145. julee/util/tests/test_decorators.py +13 -15
  146. julee/util/validation/repository.py +3 -3
  147. julee/util/validation/type_guards.py +12 -11
  148. julee/worker.py +9 -8
  149. julee/workflows/__init__.py +2 -2
  150. julee/workflows/extract_assemble.py +2 -1
  151. julee/workflows/validate_document.py +3 -2
  152. {julee-0.1.1.dist-info → julee-0.1.3.dist-info}/METADATA +4 -1
  153. julee-0.1.3.dist-info/RECORD +197 -0
  154. julee-0.1.1.dist-info/RECORD +0 -161
  155. {julee-0.1.1.dist-info → julee-0.1.3.dist-info}/WHEEL +0 -0
  156. {julee-0.1.1.dist-info → julee-0.1.3.dist-info}/licenses/LICENSE +0 -0
  157. {julee-0.1.1.dist-info → julee-0.1.3.dist-info}/top_level.txt +0 -0
@@ -10,8 +10,9 @@ instances following the Clean Architecture principles.
10
10
  import hashlib
11
11
  import json
12
12
  import logging
13
+ from collections.abc import Callable
13
14
  from datetime import datetime, timezone
14
- from typing import Any, Callable, Dict
15
+ from typing import Any
15
16
 
16
17
  import jsonpointer # type: ignore
17
18
  import jsonschema
@@ -57,6 +58,7 @@ class ExtractAssembleDataUseCase:
57
58
  methods and expects them to work correctly.
58
59
 
59
60
  Architectural Notes:
61
+
60
62
  - This class contains pure business logic with no framework dependencies
61
63
  - Repository dependencies are injected via constructor
62
64
  (dependency inversion)
@@ -64,6 +66,7 @@ class ExtractAssembleDataUseCase:
64
66
  - The use case works with domain objects exclusively
65
67
  - Deterministic execution is guaranteed by avoiding
66
68
  non-deterministic operations
69
+
67
70
  """
68
71
 
69
72
  def __init__(
@@ -91,7 +94,8 @@ class ExtractAssembleDataUseCase:
91
94
  operations
92
95
  now_fn: Function to get current time (for workflow compatibility)
93
96
 
94
- Note:
97
+ .. note::
98
+
95
99
  The repositories passed here may be concrete implementations
96
100
  (for testing or direct execution) or workflow stubs (for
97
101
  Temporal workflow execution). The use case doesn't know or care
@@ -99,6 +103,7 @@ class ExtractAssembleDataUseCase:
99
103
 
100
104
  Repositories are validated at construction time to catch
101
105
  configuration errors early in the application lifecycle.
106
+
102
107
  """
103
108
  # Validate at construction time for early error detection
104
109
  self.document_repo = ensure_repository_protocol(
@@ -135,6 +140,7 @@ class ExtractAssembleDataUseCase:
135
140
  assembly.
136
141
 
137
142
  This method orchestrates the core assembly workflow:
143
+
138
144
  1. Generates a unique assembly ID
139
145
  2. Retrieves the assembly specification
140
146
  3. Stores the initial assembly in the repository
@@ -156,6 +162,7 @@ class ExtractAssembleDataUseCase:
156
162
  Raises:
157
163
  ValueError: If required entities are not found or invalid
158
164
  RuntimeError: If assembly processing fails
165
+
159
166
  """
160
167
  logger.debug(
161
168
  "Starting data assembly use case",
@@ -250,8 +257,8 @@ class ExtractAssembleDataUseCase:
250
257
  async def _register_document_with_services(
251
258
  self,
252
259
  document: Document,
253
- queries: Dict[str, KnowledgeServiceQuery],
254
- ) -> Dict[str, str]:
260
+ queries: dict[str, KnowledgeServiceQuery],
261
+ ) -> dict[str, str]:
255
262
  """
256
263
  Register the document with all knowledge services needed for assembly.
257
264
 
@@ -267,6 +274,7 @@ class ExtractAssembleDataUseCase:
267
274
 
268
275
  Raises:
269
276
  RuntimeError: If registration fails
277
+
270
278
  """
271
279
  registrations = {}
272
280
 
@@ -294,7 +302,7 @@ class ExtractAssembleDataUseCase:
294
302
  @try_use_case_step("queries_retrieval")
295
303
  async def _retrieve_all_queries(
296
304
  self, assembly_specification: AssemblySpecification
297
- ) -> Dict[str, KnowledgeServiceQuery]:
305
+ ) -> dict[str, KnowledgeServiceQuery]:
298
306
  """Retrieve all knowledge service queries needed for this assembly."""
299
307
  query_ids = list(assembly_specification.knowledge_service_queries.values())
300
308
 
@@ -344,13 +352,14 @@ class ExtractAssembleDataUseCase:
344
352
  self,
345
353
  document: Document,
346
354
  assembly_specification: AssemblySpecification,
347
- document_registrations: Dict[str, str],
348
- queries: Dict[str, KnowledgeServiceQuery],
355
+ document_registrations: dict[str, str],
356
+ queries: dict[str, KnowledgeServiceQuery],
349
357
  ) -> str:
350
358
  """
351
359
  Perform a single assembly iteration using knowledge services.
352
360
 
353
361
  This method:
362
+
354
363
  1. Executes all knowledge service queries defined in the specification
355
364
  2. Stitches together the query results into a complete JSON document
356
365
  3. Creates and stores the assembled document
@@ -368,9 +377,10 @@ class ExtractAssembleDataUseCase:
368
377
  Raises:
369
378
  ValueError: If required entities are not found
370
379
  RuntimeError: If knowledge service operations fail
380
+
371
381
  """
372
382
  # Initialize the result data structure
373
- assembled_data: Dict[str, Any] = {}
383
+ assembled_data: dict[str, Any] = {}
374
384
 
375
385
  # Process each knowledge service query
376
386
  # TODO: This is where we may want to fan-out/fan-in to do these
@@ -461,7 +471,7 @@ class ExtractAssembleDataUseCase:
461
471
  return document
462
472
 
463
473
  def _extract_schema_section(
464
- self, jsonschema: Dict[str, Any], schema_pointer: str
474
+ self, jsonschema: dict[str, Any], schema_pointer: str
465
475
  ) -> Any:
466
476
  """Extract relevant section of JSON schema using JSON Pointer."""
467
477
  if not schema_pointer:
@@ -486,7 +496,7 @@ Please structure your response according to this JSON schema:
486
496
  Return only valid JSON that conforms to this schema, without any surrounding
487
497
  text or markdown formatting."""
488
498
 
489
- def _parse_query_result(self, result_data: Dict[str, Any]) -> Any:
499
+ def _parse_query_result(self, result_data: dict[str, Any]) -> Any:
490
500
  """Parse the query result to extract the JSON response."""
491
501
  response_text = result_data.get("response", "")
492
502
  if not response_text:
@@ -505,7 +515,7 @@ text or markdown formatting."""
505
515
 
506
516
  def _store_result_in_assembled_data(
507
517
  self,
508
- assembled_data: Dict[str, Any],
518
+ assembled_data: dict[str, Any],
509
519
  schema_pointer: str,
510
520
  result_data: Any,
511
521
  ) -> None:
@@ -563,7 +573,7 @@ text or markdown formatting."""
563
573
  @try_use_case_step("assembled_document_creation")
564
574
  async def _create_assembled_document(
565
575
  self,
566
- assembled_data: Dict[str, Any],
576
+ assembled_data: dict[str, Any],
567
577
  assembly_specification: AssemblySpecification,
568
578
  ) -> str:
569
579
  """Create and store the assembled document."""
@@ -596,7 +606,7 @@ text or markdown formatting."""
596
606
 
597
607
  def _validate_assembled_data(
598
608
  self,
599
- assembled_data: Dict[str, Any],
609
+ assembled_data: dict[str, Any],
600
610
  assembly_specification: AssemblySpecification,
601
611
  ) -> None:
602
612
  """Validate that the assembled data conforms to the JSON schema."""
@@ -16,7 +16,7 @@ import hashlib
16
16
  import logging
17
17
  from datetime import datetime, timezone
18
18
  from pathlib import Path
19
- from typing import Any, Dict, List
19
+ from typing import Any
20
20
 
21
21
  import yaml
22
22
 
@@ -192,7 +192,7 @@ class InitializeSystemDataUseCase:
192
192
  )
193
193
  raise
194
194
 
195
- def _load_fixture_configurations(self) -> List[Dict[str, Any]]:
195
+ def _load_fixture_configurations(self) -> list[dict[str, Any]]:
196
196
  """
197
197
  Load knowledge service configurations from the YAML fixture file.
198
198
 
@@ -217,7 +217,7 @@ class InitializeSystemDataUseCase:
217
217
  )
218
218
 
219
219
  try:
220
- with open(fixture_path, "r", encoding="utf-8") as f:
220
+ with open(fixture_path, encoding="utf-8") as f:
221
221
  fixture_data = yaml.safe_load(f)
222
222
 
223
223
  if not fixture_data or "knowledge_services" not in fixture_data:
@@ -240,7 +240,7 @@ class InitializeSystemDataUseCase:
240
240
  raise yaml.YAMLError(f"Invalid YAML in fixture file: {e}")
241
241
 
242
242
  def _create_config_from_fixture_data(
243
- self, config_data: Dict[str, Any]
243
+ self, config_data: dict[str, Any]
244
244
  ) -> KnowledgeServiceConfig:
245
245
  """
246
246
  Create a KnowledgeServiceConfig from fixture data.
@@ -363,7 +363,7 @@ class InitializeSystemDataUseCase:
363
363
  )
364
364
  raise
365
365
 
366
- def _load_fixture_queries(self) -> List[Dict[str, Any]]:
366
+ def _load_fixture_queries(self) -> list[dict[str, Any]]:
367
367
  """
368
368
  Load knowledge service queries from the YAML fixture file.
369
369
 
@@ -388,7 +388,7 @@ class InitializeSystemDataUseCase:
388
388
  )
389
389
 
390
390
  try:
391
- with open(fixture_path, "r", encoding="utf-8") as f:
391
+ with open(fixture_path, encoding="utf-8") as f:
392
392
  fixture_data = yaml.safe_load(f)
393
393
 
394
394
  if not fixture_data or "knowledge_service_queries" not in fixture_data:
@@ -413,7 +413,7 @@ class InitializeSystemDataUseCase:
413
413
  raise yaml.YAMLError(f"Invalid YAML in queries fixture file: {e}")
414
414
 
415
415
  def _create_query_from_fixture_data(
416
- self, query_data: Dict[str, Any]
416
+ self, query_data: dict[str, Any]
417
417
  ) -> KnowledgeServiceQuery:
418
418
  """
419
419
  Create a KnowledgeServiceQuery from fixture data.
@@ -533,7 +533,7 @@ class InitializeSystemDataUseCase:
533
533
  )
534
534
  raise
535
535
 
536
- def _load_fixture_assembly_specifications(self) -> List[Dict[str, Any]]:
536
+ def _load_fixture_assembly_specifications(self) -> list[dict[str, Any]]:
537
537
  """
538
538
  Load assembly specifications from the YAML fixture file.
539
539
 
@@ -558,7 +558,7 @@ class InitializeSystemDataUseCase:
558
558
  )
559
559
 
560
560
  try:
561
- with open(fixture_path, "r", encoding="utf-8") as f:
561
+ with open(fixture_path, encoding="utf-8") as f:
562
562
  fixture_data = yaml.safe_load(f)
563
563
 
564
564
  if not fixture_data or "assembly_specifications" not in fixture_data:
@@ -586,7 +586,7 @@ class InitializeSystemDataUseCase:
586
586
  )
587
587
 
588
588
  def _create_assembly_spec_from_fixture_data(
589
- self, spec_data: Dict[str, Any]
589
+ self, spec_data: dict[str, Any]
590
590
  ) -> AssemblySpecification:
591
591
  """
592
592
  Create an AssemblySpecification from fixture data.
@@ -719,7 +719,7 @@ class InitializeSystemDataUseCase:
719
719
  )
720
720
  raise
721
721
 
722
- def _load_fixture_documents(self) -> List[Dict[str, Any]]:
722
+ def _load_fixture_documents(self) -> list[dict[str, Any]]:
723
723
  """
724
724
  Load documents from the YAML fixture file.
725
725
 
@@ -742,7 +742,7 @@ class InitializeSystemDataUseCase:
742
742
  raise FileNotFoundError(f"Documents fixture file not found: {fixture_path}")
743
743
 
744
744
  try:
745
- with open(fixture_path, "r", encoding="utf-8") as f:
745
+ with open(fixture_path, encoding="utf-8") as f:
746
746
  fixture_data = yaml.safe_load(f)
747
747
 
748
748
  if not fixture_data or "documents" not in fixture_data:
@@ -764,7 +764,7 @@ class InitializeSystemDataUseCase:
764
764
  except yaml.YAMLError as e:
765
765
  raise yaml.YAMLError(f"Invalid YAML in documents fixture file: {e}")
766
766
 
767
- def _create_document_from_fixture_data(self, doc_data: Dict[str, Any]) -> Document:
767
+ def _create_document_from_fixture_data(self, doc_data: dict[str, Any]) -> Document:
768
768
  """
769
769
  Create a Document from fixture data.
770
770
 
@@ -8,35 +8,35 @@ following the Clean Architecture principles.
8
8
 
9
9
  import io
10
10
  import json
11
- import pytest
12
-
13
- from unittest.mock import AsyncMock
14
11
  from datetime import datetime, timezone
12
+ from unittest.mock import AsyncMock
13
+
14
+ import pytest
15
15
 
16
- from julee.domain.use_cases import ExtractAssembleDataUseCase
17
16
  from julee.domain.models import (
18
17
  Assembly,
18
+ AssemblySpecification,
19
+ AssemblySpecificationStatus,
19
20
  AssemblyStatus,
21
+ ContentStream,
20
22
  Document,
21
23
  DocumentStatus,
22
- ContentStream,
23
- AssemblySpecification,
24
- AssemblySpecificationStatus,
25
- KnowledgeServiceQuery,
26
24
  KnowledgeServiceConfig,
25
+ KnowledgeServiceQuery,
27
26
  )
28
27
  from julee.domain.models.knowledge_service_config import ServiceApi
28
+ from julee.domain.use_cases import ExtractAssembleDataUseCase
29
29
  from julee.repositories.memory import (
30
- MemoryDocumentRepository,
31
30
  MemoryAssemblyRepository,
32
31
  MemoryAssemblySpecificationRepository,
32
+ MemoryDocumentRepository,
33
33
  MemoryKnowledgeServiceConfigRepository,
34
34
  MemoryKnowledgeServiceQueryRepository,
35
35
  )
36
+ from julee.services.knowledge_service import QueryResult
36
37
  from julee.services.knowledge_service.memory import (
37
38
  MemoryKnowledgeService,
38
39
  )
39
- from julee.services.knowledge_service import QueryResult
40
40
 
41
41
 
42
42
  class TestExtractAssembleDataUseCase:
@@ -86,7 +86,7 @@ def fixture_configs() -> list[dict]:
86
86
 
87
87
  assert fixture_path.exists(), f"Fixture file not found: {fixture_path}"
88
88
 
89
- with open(fixture_path, "r", encoding="utf-8") as f:
89
+ with open(fixture_path, encoding="utf-8") as f:
90
90
  fixture_data = yaml.safe_load(f)
91
91
 
92
92
  assert "knowledge_services" in fixture_data
@@ -320,7 +320,7 @@ class TestYamlFixtureIntegration:
320
320
  assert fixture_path.exists(), f"Fixture file not found: {fixture_path}"
321
321
 
322
322
  # Verify file can be parsed
323
- with open(fixture_path, "r", encoding="utf-8") as f:
323
+ with open(fixture_path, encoding="utf-8") as f:
324
324
  fixture_data = yaml.safe_load(f)
325
325
 
326
326
  # Verify structure
@@ -7,38 +7,38 @@ following the Clean Architecture principles.
7
7
  """
8
8
 
9
9
  import io
10
- import pytest
11
- from unittest.mock import AsyncMock
12
10
  from datetime import datetime, timezone
13
- from pydantic import ValidationError
11
+ from unittest.mock import AsyncMock
14
12
 
15
- from julee.domain.use_cases import ValidateDocumentUseCase
13
+ import pytest
14
+ from pydantic import ValidationError
16
15
 
17
16
  from julee.domain.models import (
17
+ ContentStream,
18
18
  Document,
19
19
  DocumentStatus,
20
- ContentStream,
21
20
  KnowledgeServiceConfig,
22
21
  KnowledgeServiceQuery,
23
22
  )
23
+ from julee.domain.models.knowledge_service_config import ServiceApi
24
24
  from julee.domain.models.policy import (
25
- Policy,
26
- PolicyStatus,
27
25
  DocumentPolicyValidation,
28
26
  DocumentPolicyValidationStatus,
27
+ Policy,
28
+ PolicyStatus,
29
29
  )
30
- from julee.domain.models.knowledge_service_config import ServiceApi
30
+ from julee.domain.use_cases import ValidateDocumentUseCase
31
31
  from julee.repositories.memory import (
32
+ MemoryDocumentPolicyValidationRepository,
32
33
  MemoryDocumentRepository,
33
- MemoryKnowledgeServiceQueryRepository,
34
34
  MemoryKnowledgeServiceConfigRepository,
35
+ MemoryKnowledgeServiceQueryRepository,
35
36
  MemoryPolicyRepository,
36
- MemoryDocumentPolicyValidationRepository,
37
37
  )
38
+ from julee.services.knowledge_service import QueryResult
38
39
  from julee.services.knowledge_service.memory import (
39
40
  MemoryKnowledgeService,
40
41
  )
41
- from julee.services.knowledge_service import QueryResult
42
42
 
43
43
 
44
44
  class TestValidateDocumentUseCase:
@@ -11,8 +11,8 @@ import hashlib
11
11
  import io
12
12
  import json
13
13
  import logging
14
+ from collections.abc import Callable
14
15
  from datetime import datetime
15
- from typing import Callable, Dict, List, Tuple
16
16
 
17
17
  import multihash
18
18
 
@@ -58,6 +58,7 @@ class ValidateDocumentUseCase:
58
58
  methods and expects them to work correctly.
59
59
 
60
60
  Architectural Notes:
61
+
61
62
  - This class contains pure business logic with no framework dependencies
62
63
  - Repository dependencies are injected via constructor
63
64
  (dependency inversion)
@@ -65,6 +66,7 @@ class ValidateDocumentUseCase:
65
66
  - The use case works with domain objects exclusively
66
67
  - Deterministic execution is guaranteed by avoiding
67
68
  non-deterministic operations
69
+
68
70
  """
69
71
 
70
72
  def __init__(
@@ -93,7 +95,8 @@ class ValidateDocumentUseCase:
93
95
  now_fn: Function to get current time (e.g., workflow.now for
94
96
  Temporal workflows)
95
97
 
96
- Note:
98
+ .. note::
99
+
97
100
  The repositories passed here may be concrete implementations
98
101
  (for testing or direct execution) or workflow stubs (for
99
102
  Temporal workflow execution). The use case doesn't know or care
@@ -101,6 +104,7 @@ class ValidateDocumentUseCase:
101
104
 
102
105
  Repositories are validated at construction time to catch
103
106
  configuration errors early in the application lifecycle.
107
+
104
108
  """
105
109
  # Validate at construction time for early error detection
106
110
  self.document_repo = ensure_repository_protocol(
@@ -133,6 +137,7 @@ class ValidateDocumentUseCase:
133
137
  Validate a document against a policy and return the validation result.
134
138
 
135
139
  This method orchestrates the core validation workflow:
140
+
136
141
  1. Generates a unique validation ID
137
142
  2. Retrieves the document and policy
138
143
  3. Creates and stores the initial validation record
@@ -152,6 +157,7 @@ class ValidateDocumentUseCase:
152
157
  Raises:
153
158
  ValueError: If required entities are not found or invalid
154
159
  RuntimeError: If validation processing fails
160
+
155
161
  """
156
162
  logger.debug(
157
163
  "Starting document validation use case",
@@ -391,13 +397,13 @@ class ValidateDocumentUseCase:
391
397
  @try_use_case_step("all_queries_retrieval")
392
398
  async def _retrieve_all_queries(
393
399
  self, policy: Policy
394
- ) -> Dict[str, KnowledgeServiceQuery]:
400
+ ) -> dict[str, KnowledgeServiceQuery]:
395
401
  """Retrieve all knowledge service queries needed for validation and
396
402
  transformation."""
397
403
  all_queries = {}
398
404
 
399
405
  # Get validation queries
400
- for query_id, required_score in policy.validation_scores:
406
+ for query_id, _required_score in policy.validation_scores:
401
407
  query = await self.knowledge_service_query_repo.get(query_id)
402
408
  if not query:
403
409
  raise ValueError(f"Validation query not found: {query_id}")
@@ -417,8 +423,8 @@ class ValidateDocumentUseCase:
417
423
  async def _register_document_with_services(
418
424
  self,
419
425
  document: Document,
420
- queries: Dict[str, KnowledgeServiceQuery],
421
- ) -> Dict[str, str]:
426
+ queries: dict[str, KnowledgeServiceQuery],
427
+ ) -> dict[str, str]:
422
428
  """
423
429
  Register the document with all knowledge services needed for
424
430
  validation.
@@ -429,6 +435,7 @@ class ValidateDocumentUseCase:
429
435
 
430
436
  Returns:
431
437
  Dict mapping knowledge_service_id to service_file_id
438
+
432
439
  """
433
440
  registrations = {}
434
441
  required_service_ids = {
@@ -457,9 +464,9 @@ class ValidateDocumentUseCase:
457
464
  self,
458
465
  document: Document,
459
466
  policy: Policy,
460
- document_registrations: Dict[str, str],
461
- queries: Dict[str, KnowledgeServiceQuery],
462
- ) -> List[Tuple[str, int]]:
467
+ document_registrations: dict[str, str],
468
+ queries: dict[str, KnowledgeServiceQuery],
469
+ ) -> list[tuple[str, int]]:
463
470
  """
464
471
  Execute all validation queries and return the actual scores achieved.
465
472
 
@@ -471,6 +478,7 @@ class ValidateDocumentUseCase:
471
478
 
472
479
  Returns:
473
480
  List of (query_id, actual_score) tuples
481
+
474
482
  """
475
483
  validation_scores = []
476
484
 
@@ -520,7 +528,7 @@ class ValidateDocumentUseCase:
520
528
 
521
529
  return validation_scores
522
530
 
523
- def _extract_score_from_result(self, result_data: Dict) -> int:
531
+ def _extract_score_from_result(self, result_data: dict) -> int:
524
532
  """
525
533
  Extract a numeric score from the knowledge service query result.
526
534
 
@@ -543,8 +551,8 @@ class ValidateDocumentUseCase:
543
551
 
544
552
  def _determine_validation_result(
545
553
  self,
546
- actual_scores: List[Tuple[str, int]],
547
- required_scores: List[Tuple[str, int]],
554
+ actual_scores: list[tuple[str, int]],
555
+ required_scores: list[tuple[str, int]],
548
556
  ) -> bool:
549
557
  """
550
558
  Determine if validation passed based on actual vs required scores.
@@ -556,6 +564,7 @@ class ValidateDocumentUseCase:
556
564
 
557
565
  Returns:
558
566
  True if all required scores were met or exceeded, False otherwise
567
+
559
568
  """
560
569
  # Convert to dictionaries for easier lookup
561
570
  actual_scores_dict = dict(actual_scores)
@@ -582,8 +591,8 @@ class ValidateDocumentUseCase:
582
591
  self,
583
592
  document: Document,
584
593
  policy: Policy,
585
- all_queries: Dict[str, KnowledgeServiceQuery],
586
- document_registrations: Dict[str, str],
594
+ all_queries: dict[str, KnowledgeServiceQuery],
595
+ document_registrations: dict[str, str],
587
596
  ) -> Document:
588
597
  """
589
598
  Apply transformation queries to a document and return the
@@ -601,6 +610,7 @@ class ValidateDocumentUseCase:
601
610
  Raises:
602
611
  ValueError: If transformation queries are not found or fail
603
612
  RuntimeError: If document transformation fails
613
+
604
614
  """
605
615
  if not policy.transformation_queries:
606
616
  raise ValueError("No transformation queries provided")
@@ -704,7 +714,7 @@ class ValidateDocumentUseCase:
704
714
 
705
715
  return transformed_document
706
716
 
707
- def _extract_transformed_content(self, result_data: Dict) -> str:
717
+ def _extract_transformed_content(self, result_data: dict) -> str:
708
718
  """
709
719
  Extract transformed document content from knowledge service result.
710
720
 
@@ -717,6 +727,7 @@ class ValidateDocumentUseCase:
717
727
 
718
728
  Raises:
719
729
  ValueError: If no valid JSON content can be extracted from result
730
+
720
731
  """
721
732
  response_text = result_data.get("response", "")
722
733
  if not response_text:
@@ -0,0 +1 @@
1
+ """Maintenance utilities for julee and julee-based solutions."""