julee 0.1.2__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 (155) 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 +7 -6
  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 +10 -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 +5 -4
  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 +13 -12
  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 +14 -14
  93. julee/maintenance/__init__.py +1 -0
  94. julee/maintenance/release.py +188 -0
  95. julee/repositories/memory/assembly.py +6 -5
  96. julee/repositories/memory/assembly_specification.py +8 -9
  97. julee/repositories/memory/base.py +12 -11
  98. julee/repositories/memory/document.py +8 -7
  99. julee/repositories/memory/document_policy_validation.py +7 -6
  100. julee/repositories/memory/knowledge_service_config.py +8 -7
  101. julee/repositories/memory/knowledge_service_query.py +8 -7
  102. julee/repositories/memory/policy.py +6 -5
  103. julee/repositories/memory/tests/test_document.py +6 -4
  104. julee/repositories/memory/tests/test_document_policy_validation.py +2 -1
  105. julee/repositories/memory/tests/test_policy.py +2 -1
  106. julee/repositories/minio/assembly.py +4 -4
  107. julee/repositories/minio/assembly_specification.py +6 -8
  108. julee/repositories/minio/client.py +22 -25
  109. julee/repositories/minio/document.py +11 -11
  110. julee/repositories/minio/document_policy_validation.py +5 -5
  111. julee/repositories/minio/knowledge_service_config.py +6 -6
  112. julee/repositories/minio/knowledge_service_query.py +6 -9
  113. julee/repositories/minio/policy.py +4 -4
  114. julee/repositories/minio/tests/fake_client.py +11 -9
  115. julee/repositories/minio/tests/test_assembly.py +3 -1
  116. julee/repositories/minio/tests/test_assembly_specification.py +2 -1
  117. julee/repositories/minio/tests/test_client_protocol.py +5 -5
  118. julee/repositories/minio/tests/test_document.py +7 -6
  119. julee/repositories/minio/tests/test_document_policy_validation.py +3 -1
  120. julee/repositories/minio/tests/test_knowledge_service_config.py +4 -2
  121. julee/repositories/minio/tests/test_knowledge_service_query.py +3 -2
  122. julee/repositories/minio/tests/test_policy.py +3 -1
  123. julee/repositories/temporal/activities.py +5 -5
  124. julee/repositories/temporal/proxies.py +5 -5
  125. julee/services/knowledge_service/__init__.py +1 -2
  126. julee/services/knowledge_service/anthropic/knowledge_service.py +8 -7
  127. julee/services/knowledge_service/anthropic/tests/test_knowledge_service.py +11 -10
  128. julee/services/knowledge_service/factory.py +8 -8
  129. julee/services/knowledge_service/knowledge_service.py +12 -14
  130. julee/services/knowledge_service/memory/knowledge_service.py +13 -12
  131. julee/services/knowledge_service/memory/test_knowledge_service.py +10 -7
  132. julee/services/knowledge_service/test_factory.py +11 -10
  133. julee/services/temporal/activities.py +10 -10
  134. julee/services/temporal/proxies.py +2 -2
  135. julee/util/domain.py +6 -6
  136. julee/util/repos/minio/file_storage.py +8 -9
  137. julee/util/repos/temporal/client_proxies/file_storage.py +3 -4
  138. julee/util/repos/temporal/data_converter.py +6 -6
  139. julee/util/repos/temporal/minio_file_storage.py +1 -1
  140. julee/util/repos/temporal/proxies/file_storage.py +2 -3
  141. julee/util/repositories.py +4 -3
  142. julee/util/temporal/decorators.py +20 -18
  143. julee/util/tests/test_decorators.py +13 -15
  144. julee/util/validation/repository.py +3 -3
  145. julee/util/validation/type_guards.py +12 -11
  146. julee/worker.py +9 -8
  147. julee/workflows/__init__.py +2 -2
  148. julee/workflows/extract_assemble.py +2 -1
  149. julee/workflows/validate_document.py +3 -2
  150. {julee-0.1.2.dist-info → julee-0.1.3.dist-info}/METADATA +2 -1
  151. julee-0.1.3.dist-info/RECORD +197 -0
  152. julee-0.1.2.dist-info/RECORD +0 -161
  153. {julee-0.1.2.dist-info → julee-0.1.3.dist-info}/WHEEL +0 -0
  154. {julee-0.1.2.dist-info → julee-0.1.3.dist-info}/licenses/LICENSE +0 -0
  155. {julee-0.1.2.dist-info → julee-0.1.3.dist-info}/top_level.txt +0 -0
@@ -19,11 +19,14 @@ Design decisions documented:
19
19
  - Documents act as readable streams with standard methods
20
20
  """
21
21
 
22
- import pytest
23
22
  import json
24
23
 
24
+ import pytest
25
+ from pydantic import ValidationError
26
+
25
27
  from julee.domain.models.document import Document
26
- from .factories import DocumentFactory, ContentStreamFactory
28
+
29
+ from .factories import ContentStreamFactory, DocumentFactory
27
30
 
28
31
 
29
32
  class TestDocumentInstantiation:
@@ -164,7 +167,7 @@ class TestDocumentInstantiation:
164
167
  assert doc.content_multihash.strip() == multihash.strip()
165
168
  else:
166
169
  # Should raise validation error
167
- with pytest.raises(Exception): # Could be ValueError or ValidationError
170
+ with pytest.raises((ValueError, ValidationError)):
168
171
  Document(
169
172
  document_id=document_id,
170
173
  original_filename=original_filename,
@@ -13,11 +13,11 @@ All domain models use Pydantic BaseModel for validation, serialization,
13
13
  and type safety, following the patterns established in the sample project.
14
14
  """
15
15
 
16
- from pydantic import BaseModel, Field, field_validator
17
- from typing import Optional
18
16
  from datetime import datetime, timezone
19
17
  from enum import Enum
20
18
 
19
+ from pydantic import BaseModel, Field, field_validator
20
+
21
21
 
22
22
  class ServiceApi(str, Enum):
23
23
  """Supported knowledge service APIs."""
@@ -48,10 +48,10 @@ class KnowledgeServiceConfig(BaseModel):
48
48
  )
49
49
 
50
50
  # Timestamps
51
- created_at: Optional[datetime] = Field(
51
+ created_at: datetime | None = Field(
52
52
  default_factory=lambda: datetime.now(timezone.utc)
53
53
  )
54
- updated_at: Optional[datetime] = Field(
54
+ updated_at: datetime | None = Field(
55
55
  default_factory=lambda: datetime.now(timezone.utc)
56
56
  )
57
57
 
@@ -1,11 +1,11 @@
1
- from .policy import (
2
- Policy,
3
- PolicyStatus,
4
- )
5
1
  from .document_policy_validation import (
6
2
  DocumentPolicyValidation,
7
3
  DocumentPolicyValidationStatus,
8
4
  )
5
+ from .policy import (
6
+ Policy,
7
+ PolicyStatus,
8
+ )
9
9
 
10
10
  __all__ = [
11
11
  "Policy",
@@ -17,11 +17,11 @@ All domain models use Pydantic BaseModel for validation, serialization,
17
17
  and type safety, following the patterns established in the sample project.
18
18
  """
19
19
 
20
- from pydantic import BaseModel, Field, field_validator
21
- from typing import Optional, List, Tuple
22
20
  from datetime import datetime, timezone
23
21
  from enum import Enum
24
22
 
23
+ from pydantic import BaseModel, Field, field_validator
24
+
25
25
 
26
26
  class DocumentPolicyValidationStatus(str, Enum):
27
27
  """Status of a document policy validation process."""
@@ -70,7 +70,7 @@ class DocumentPolicyValidation(BaseModel):
70
70
  status: DocumentPolicyValidationStatus = DocumentPolicyValidationStatus.PENDING
71
71
 
72
72
  # Initial validation results
73
- validation_scores: List[Tuple[str, int]] = Field(
73
+ validation_scores: list[tuple[str, int]] = Field(
74
74
  default_factory=list,
75
75
  description="List of (knowledge_service_query_id, actual_score) "
76
76
  "tuples representing the scores achieved during initial validation. "
@@ -78,13 +78,13 @@ class DocumentPolicyValidation(BaseModel):
78
78
  )
79
79
 
80
80
  # Transformation results (if applicable)
81
- transformed_document_id: Optional[str] = Field(
81
+ transformed_document_id: str | None = Field(
82
82
  default=None,
83
83
  description="ID of the document after transformations have been "
84
84
  "applied. Only present if the policy includes transformation queries "
85
85
  "and they were executed",
86
86
  )
87
- post_transform_validation_scores: Optional[List[Tuple[str, int]]] = Field(
87
+ post_transform_validation_scores: list[tuple[str, int]] | None = Field(
88
88
  default=None,
89
89
  description="List of (knowledge_service_query_id, actual_score) "
90
90
  "tuples representing scores achieved after transformation. "
@@ -93,19 +93,19 @@ class DocumentPolicyValidation(BaseModel):
93
93
  )
94
94
 
95
95
  # Validation metadata
96
- started_at: Optional[datetime] = Field(
96
+ started_at: datetime | None = Field(
97
97
  default_factory=lambda: datetime.now(timezone.utc),
98
98
  description="When the validation process was initiated",
99
99
  )
100
- completed_at: Optional[datetime] = Field(
100
+ completed_at: datetime | None = Field(
101
101
  default=None, description="When the validation process completed"
102
102
  )
103
- error_message: Optional[str] = Field(
103
+ error_message: str | None = Field(
104
104
  default=None, description="Error message if validation process failed"
105
105
  )
106
106
 
107
107
  # Results summary
108
- passed: Optional[bool] = Field(
108
+ passed: bool | None = Field(
109
109
  default=None,
110
110
  description="Whether the document passed policy validation. "
111
111
  "None while validation is in progress, True/False when complete",
@@ -128,8 +128,8 @@ class DocumentPolicyValidation(BaseModel):
128
128
  @field_validator("validation_scores")
129
129
  @classmethod
130
130
  def validation_scores_must_be_valid(
131
- cls, v: List[Tuple[str, int]]
132
- ) -> List[Tuple[str, int]]:
131
+ cls, v: list[tuple[str, int]]
132
+ ) -> list[tuple[str, int]]:
133
133
  if not isinstance(v, list):
134
134
  raise ValueError("Validation scores must be a list")
135
135
 
@@ -142,8 +142,8 @@ class DocumentPolicyValidation(BaseModel):
142
142
  @field_validator("post_transform_validation_scores")
143
143
  @classmethod
144
144
  def post_transform_scores_must_be_valid(
145
- cls, v: Optional[List[Tuple[str, int]]]
146
- ) -> Optional[List[Tuple[str, int]]]:
145
+ cls, v: list[tuple[str, int]] | None
146
+ ) -> list[tuple[str, int]] | None:
147
147
  if v is None:
148
148
  return v
149
149
 
@@ -158,7 +158,7 @@ class DocumentPolicyValidation(BaseModel):
158
158
 
159
159
  @field_validator("error_message")
160
160
  @classmethod
161
- def error_message_must_be_valid(cls, v: Optional[str]) -> Optional[str]:
161
+ def error_message_must_be_valid(cls, v: str | None) -> str | None:
162
162
  if v is None:
163
163
  return v
164
164
  if not isinstance(v, str):
@@ -167,7 +167,7 @@ class DocumentPolicyValidation(BaseModel):
167
167
 
168
168
  @field_validator("transformed_document_id")
169
169
  @classmethod
170
- def transformed_document_id_must_be_valid(cls, v: Optional[str]) -> Optional[str]:
170
+ def transformed_document_id_must_be_valid(cls, v: str | None) -> str | None:
171
171
  if v is None:
172
172
  return v
173
173
  if not isinstance(v, str) or not v.strip():
@@ -178,8 +178,8 @@ class DocumentPolicyValidation(BaseModel):
178
178
 
179
179
  @classmethod
180
180
  def _validate_score_tuples(
181
- cls, scores: List[Tuple[str, int]], field_name: str
182
- ) -> List[Tuple[str, int]]:
181
+ cls, scores: list[tuple[str, int]], field_name: str
182
+ ) -> list[tuple[str, int]]:
183
183
  """Helper method to validate score tuple lists."""
184
184
  validated_scores = []
185
185
  query_ids_seen = set()
@@ -13,11 +13,11 @@ All domain models use Pydantic BaseModel for validation, serialization,
13
13
  and type safety, following the patterns established in the sample project.
14
14
  """
15
15
 
16
- from pydantic import BaseModel, Field, field_validator
17
- from typing import Optional, List, Tuple
18
16
  from datetime import datetime, timezone
19
17
  from enum import Enum
20
18
 
19
+ from pydantic import BaseModel, Field, field_validator
20
+
21
21
 
22
22
  class PolicyStatus(str, Enum):
23
23
  """Status of a policy configuration."""
@@ -55,12 +55,12 @@ class Policy(BaseModel):
55
55
 
56
56
  # Policy configuration
57
57
  status: PolicyStatus = PolicyStatus.ACTIVE
58
- validation_scores: List[Tuple[str, int]] = Field(
58
+ validation_scores: list[tuple[str, int]] = Field(
59
59
  description="List of (knowledge_service_query_id, required_score) "
60
60
  "tuples where required_score is between 0 and 100. All scores "
61
61
  "must be met or exceeded for the policy to pass"
62
62
  )
63
- transformation_queries: Optional[List[str]] = Field(
63
+ transformation_queries: list[str] | None = Field(
64
64
  default=None,
65
65
  description="Optional list of knowledge service query IDs for "
66
66
  "transformations to apply before re-validation. If not provided "
@@ -69,10 +69,10 @@ class Policy(BaseModel):
69
69
 
70
70
  # Policy metadata
71
71
  version: str = Field(default="0.1.0", description="Policy version")
72
- created_at: Optional[datetime] = Field(
72
+ created_at: datetime | None = Field(
73
73
  default_factory=lambda: datetime.now(timezone.utc)
74
74
  )
75
- updated_at: Optional[datetime] = Field(default=None)
75
+ updated_at: datetime | None = Field(default=None)
76
76
 
77
77
  @field_validator("policy_id")
78
78
  @classmethod
@@ -98,8 +98,8 @@ class Policy(BaseModel):
98
98
  @field_validator("validation_scores")
99
99
  @classmethod
100
100
  def validation_scores_must_be_valid(
101
- cls, v: List[Tuple[str, int]]
102
- ) -> List[Tuple[str, int]]:
101
+ cls, v: list[tuple[str, int]]
102
+ ) -> list[tuple[str, int]]:
103
103
  if not isinstance(v, list):
104
104
  raise ValueError("Validation scores must be a list")
105
105
 
@@ -147,8 +147,8 @@ class Policy(BaseModel):
147
147
  @field_validator("transformation_queries")
148
148
  @classmethod
149
149
  def transformation_queries_must_be_valid(
150
- cls, v: Optional[List[str]]
151
- ) -> Optional[List[str]]:
150
+ cls, v: list[str] | None
151
+ ) -> list[str] | None:
152
152
  if v is None:
153
153
  return v
154
154
 
@@ -6,9 +6,10 @@ Policy domain objects with sensible defaults.
6
6
  """
7
7
 
8
8
  from datetime import datetime, timezone
9
+
9
10
  from factory.base import Factory
10
- from factory.faker import Faker
11
11
  from factory.declarations import LazyFunction
12
+ from factory.faker import Faker
12
13
 
13
14
  from julee.domain.models.policy import (
14
15
  DocumentPolicyValidation,
@@ -13,14 +13,16 @@ Tests focus on:
13
13
  - Edge cases and error conditions
14
14
  """
15
15
 
16
- import pytest
17
16
  from datetime import datetime, timezone
17
+
18
+ import pytest
18
19
  from pydantic import ValidationError
19
20
 
20
21
  from julee.domain.models.policy import (
21
22
  DocumentPolicyValidation,
22
23
  DocumentPolicyValidationStatus,
23
24
  )
25
+
24
26
  from .factories import DocumentPolicyValidationFactory
25
27
 
26
28
 
@@ -5,8 +5,9 @@ These tests verify the behavior of Policy domain objects,
5
5
  including validation, serialization, and business logic.
6
6
  """
7
7
 
8
- import pytest
9
8
  from datetime import datetime, timezone
9
+
10
+ import pytest
10
11
  from pydantic import ValidationError
11
12
 
12
13
  from julee.domain.models.policy import (
@@ -6,14 +6,14 @@ Extract, Assemble, Publish workflow, following the Clean Architecture
6
6
  patterns established in the Fun-Police framework.
7
7
  """
8
8
 
9
- from .base import BaseRepository
10
- from .document import DocumentRepository
11
9
  from .assembly import AssemblyRepository
12
10
  from .assembly_specification import AssemblySpecificationRepository
11
+ from .base import BaseRepository
12
+ from .document import DocumentRepository
13
+ from .document_policy_validation import DocumentPolicyValidationRepository
13
14
  from .knowledge_service_config import KnowledgeServiceConfigRepository
14
15
  from .knowledge_service_query import KnowledgeServiceQueryRepository
15
16
  from .policy import PolicyRepository
16
- from .document_policy_validation import DocumentPolicyValidationRepository
17
17
 
18
18
  __all__ = [
19
19
  "BaseRepository",
@@ -27,8 +27,10 @@ In Temporal workflow contexts, these protocols are implemented by workflow
27
27
  stubs that delegate to activities for durability and proper error handling.
28
28
  """
29
29
 
30
- from typing import runtime_checkable, Protocol
30
+ from typing import Protocol, runtime_checkable
31
+
31
32
  from julee.domain.models import Assembly
33
+
32
34
  from .base import BaseRepository
33
35
 
34
36
 
@@ -30,9 +30,11 @@ stubs that delegate to activities for durability and proper error handling.
30
30
  """
31
31
 
32
32
  from typing import Protocol, runtime_checkable
33
+
33
34
  from julee.domain.models.assembly_specification import (
34
35
  AssemblySpecification,
35
36
  )
37
+
36
38
  from .base import BaseRepository
37
39
 
38
40
 
@@ -23,7 +23,8 @@ In Temporal workflow contexts, these protocols are implemented by workflow
23
23
  stubs that delegate to activities for durability and proper error handling.
24
24
  """
25
25
 
26
- from typing import Protocol, Optional, runtime_checkable, TypeVar, List, Dict
26
+ from typing import Protocol, TypeVar, runtime_checkable
27
+
27
28
  from pydantic import BaseModel
28
29
 
29
30
  # Type variable bound to Pydantic BaseModel for domain entities
@@ -42,7 +43,7 @@ class BaseRepository(Protocol[T]):
42
43
  T: The domain entity type (must extend Pydantic BaseModel)
43
44
  """
44
45
 
45
- async def get(self, entity_id: str) -> Optional[T]:
46
+ async def get(self, entity_id: str) -> T | None:
46
47
  """Retrieve an entity by ID.
47
48
 
48
49
  Args:
@@ -60,7 +61,7 @@ class BaseRepository(Protocol[T]):
60
61
  """
61
62
  ...
62
63
 
63
- async def get_many(self, entity_ids: List[str]) -> Dict[str, Optional[T]]:
64
+ async def get_many(self, entity_ids: list[str]) -> dict[str, T | None]:
64
65
  """Retrieve multiple entities by ID.
65
66
 
66
67
  Args:
@@ -103,7 +104,7 @@ class BaseRepository(Protocol[T]):
103
104
  """
104
105
  ...
105
106
 
106
- async def list_all(self) -> List[T]:
107
+ async def list_all(self) -> list[T]:
107
108
  """List all entities.
108
109
 
109
110
  Returns:
@@ -29,8 +29,10 @@ In Temporal workflow contexts, these protocols are implemented by workflow
29
29
  stubs that delegate to activities for durability and proper error handling.
30
30
  """
31
31
 
32
- from typing import runtime_checkable, Protocol
32
+ from typing import Protocol, runtime_checkable
33
+
33
34
  from julee.domain.models import Document
35
+
34
36
  from .base import BaseRepository
35
37
 
36
38
 
@@ -29,8 +29,10 @@ In Temporal workflow contexts, these protocols are implemented by workflow
29
29
  stubs that delegate to activities for durability and proper error handling.
30
30
  """
31
31
 
32
- from typing import runtime_checkable, Protocol
32
+ from typing import Protocol, runtime_checkable
33
+
33
34
  from julee.domain.models.policy import DocumentPolicyValidation
35
+
34
36
  from .base import BaseRepository
35
37
 
36
38
 
@@ -31,9 +31,11 @@ stubs that delegate to activities for durability and proper error handling.
31
31
  """
32
32
 
33
33
  from typing import Protocol, runtime_checkable
34
+
34
35
  from julee.domain.models.knowledge_service_config import (
35
36
  KnowledgeServiceConfig,
36
37
  )
38
+
37
39
  from .base import BaseRepository
38
40
 
39
41
 
@@ -25,6 +25,7 @@ from typing import Protocol, runtime_checkable
25
25
  from julee.domain.models.assembly_specification import (
26
26
  KnowledgeServiceQuery,
27
27
  )
28
+
28
29
  from .base import BaseRepository
29
30
 
30
31
 
@@ -29,8 +29,10 @@ In Temporal workflow contexts, these protocols are implemented by workflow
29
29
  stubs that delegate to activities for durability and proper error handling.
30
30
  """
31
31
 
32
- from typing import runtime_checkable, Protocol
32
+ from typing import Protocol, runtime_checkable
33
+
33
34
  from julee.domain.models import Policy
35
+
34
36
  from .base import BaseRepository
35
37
 
36
38
 
@@ -7,8 +7,9 @@ following the patterns established in the sample use cases.
7
7
  """
8
8
 
9
9
  import logging
10
+ from collections.abc import Awaitable, Callable
10
11
  from functools import wraps
11
- from typing import Any, Callable, Dict, Optional, TypeVar, Awaitable
12
+ from typing import Any, TypeVar
12
13
 
13
14
  logger = logging.getLogger(__name__)
14
15
 
@@ -17,7 +18,7 @@ F = TypeVar("F", bound=Callable[..., Awaitable[Any]])
17
18
 
18
19
  def try_use_case_step(
19
20
  step_name: str,
20
- extra_context: Optional[Dict[str, Any]] = None,
21
+ extra_context: dict[str, Any] | None = None,
21
22
  ) -> Callable[[F], F]:
22
23
  """
23
24
  Decorator that wraps use case steps with consistent error handling and
@@ -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
@@ -256,8 +257,8 @@ class ExtractAssembleDataUseCase:
256
257
  async def _register_document_with_services(
257
258
  self,
258
259
  document: Document,
259
- queries: Dict[str, KnowledgeServiceQuery],
260
- ) -> Dict[str, str]:
260
+ queries: dict[str, KnowledgeServiceQuery],
261
+ ) -> dict[str, str]:
261
262
  """
262
263
  Register the document with all knowledge services needed for assembly.
263
264
 
@@ -301,7 +302,7 @@ class ExtractAssembleDataUseCase:
301
302
  @try_use_case_step("queries_retrieval")
302
303
  async def _retrieve_all_queries(
303
304
  self, assembly_specification: AssemblySpecification
304
- ) -> Dict[str, KnowledgeServiceQuery]:
305
+ ) -> dict[str, KnowledgeServiceQuery]:
305
306
  """Retrieve all knowledge service queries needed for this assembly."""
306
307
  query_ids = list(assembly_specification.knowledge_service_queries.values())
307
308
 
@@ -351,8 +352,8 @@ class ExtractAssembleDataUseCase:
351
352
  self,
352
353
  document: Document,
353
354
  assembly_specification: AssemblySpecification,
354
- document_registrations: Dict[str, str],
355
- queries: Dict[str, KnowledgeServiceQuery],
355
+ document_registrations: dict[str, str],
356
+ queries: dict[str, KnowledgeServiceQuery],
356
357
  ) -> str:
357
358
  """
358
359
  Perform a single assembly iteration using knowledge services.
@@ -379,7 +380,7 @@ class ExtractAssembleDataUseCase:
379
380
 
380
381
  """
381
382
  # Initialize the result data structure
382
- assembled_data: Dict[str, Any] = {}
383
+ assembled_data: dict[str, Any] = {}
383
384
 
384
385
  # Process each knowledge service query
385
386
  # TODO: This is where we may want to fan-out/fan-in to do these
@@ -470,7 +471,7 @@ class ExtractAssembleDataUseCase:
470
471
  return document
471
472
 
472
473
  def _extract_schema_section(
473
- self, jsonschema: Dict[str, Any], schema_pointer: str
474
+ self, jsonschema: dict[str, Any], schema_pointer: str
474
475
  ) -> Any:
475
476
  """Extract relevant section of JSON schema using JSON Pointer."""
476
477
  if not schema_pointer:
@@ -495,7 +496,7 @@ Please structure your response according to this JSON schema:
495
496
  Return only valid JSON that conforms to this schema, without any surrounding
496
497
  text or markdown formatting."""
497
498
 
498
- def _parse_query_result(self, result_data: Dict[str, Any]) -> Any:
499
+ def _parse_query_result(self, result_data: dict[str, Any]) -> Any:
499
500
  """Parse the query result to extract the JSON response."""
500
501
  response_text = result_data.get("response", "")
501
502
  if not response_text:
@@ -514,7 +515,7 @@ text or markdown formatting."""
514
515
 
515
516
  def _store_result_in_assembled_data(
516
517
  self,
517
- assembled_data: Dict[str, Any],
518
+ assembled_data: dict[str, Any],
518
519
  schema_pointer: str,
519
520
  result_data: Any,
520
521
  ) -> None:
@@ -572,7 +573,7 @@ text or markdown formatting."""
572
573
  @try_use_case_step("assembled_document_creation")
573
574
  async def _create_assembled_document(
574
575
  self,
575
- assembled_data: Dict[str, Any],
576
+ assembled_data: dict[str, Any],
576
577
  assembly_specification: AssemblySpecification,
577
578
  ) -> str:
578
579
  """Create and store the assembled document."""
@@ -605,7 +606,7 @@ text or markdown formatting."""
605
606
 
606
607
  def _validate_assembled_data(
607
608
  self,
608
- assembled_data: Dict[str, Any],
609
+ assembled_data: dict[str, Any],
609
610
  assembly_specification: AssemblySpecification,
610
611
  ) -> None:
611
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