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.
- julee/api/app.py +9 -8
- julee/api/dependencies.py +15 -15
- julee/api/requests.py +10 -9
- julee/api/responses.py +2 -1
- julee/api/routers/__init__.py +5 -5
- julee/api/routers/assembly_specifications.py +5 -4
- julee/api/routers/documents.py +1 -1
- julee/api/routers/knowledge_service_configs.py +4 -3
- julee/api/routers/knowledge_service_queries.py +7 -6
- julee/api/routers/system.py +4 -3
- julee/api/routers/workflows.py +4 -5
- julee/api/services/system_initialization.py +6 -6
- julee/api/tests/routers/test_assembly_specifications.py +4 -3
- julee/api/tests/routers/test_documents.py +5 -4
- julee/api/tests/routers/test_knowledge_service_configs.py +7 -6
- julee/api/tests/routers/test_knowledge_service_queries.py +4 -3
- julee/api/tests/routers/test_system.py +5 -4
- julee/api/tests/routers/test_workflows.py +5 -4
- julee/api/tests/test_app.py +5 -4
- julee/api/tests/test_dependencies.py +3 -2
- julee/api/tests/test_requests.py +2 -1
- julee/contrib/__init__.py +15 -0
- julee/contrib/polling/__init__.py +47 -0
- julee/contrib/polling/domain/__init__.py +17 -0
- julee/contrib/polling/domain/models/__init__.py +13 -0
- julee/contrib/polling/domain/models/polling_config.py +39 -0
- julee/contrib/polling/domain/services/__init__.py +11 -0
- julee/contrib/polling/domain/services/poller.py +39 -0
- julee/contrib/polling/infrastructure/__init__.py +15 -0
- julee/contrib/polling/infrastructure/services/__init__.py +12 -0
- julee/contrib/polling/infrastructure/services/polling/__init__.py +12 -0
- julee/contrib/polling/infrastructure/services/polling/http/__init__.py +12 -0
- julee/contrib/polling/infrastructure/services/polling/http/http_poller_service.py +80 -0
- julee/contrib/polling/infrastructure/temporal/__init__.py +20 -0
- julee/contrib/polling/infrastructure/temporal/activities.py +42 -0
- julee/contrib/polling/infrastructure/temporal/activity_names.py +20 -0
- julee/contrib/polling/infrastructure/temporal/proxies.py +45 -0
- julee/contrib/polling/tests/__init__.py +6 -0
- julee/contrib/polling/tests/unit/__init__.py +6 -0
- julee/contrib/polling/tests/unit/infrastructure/__init__.py +7 -0
- julee/contrib/polling/tests/unit/infrastructure/services/__init__.py +6 -0
- julee/contrib/polling/tests/unit/infrastructure/services/polling/__init__.py +6 -0
- julee/contrib/polling/tests/unit/infrastructure/services/polling/http/__init__.py +7 -0
- julee/contrib/polling/tests/unit/infrastructure/services/polling/http/test_http_poller_service.py +163 -0
- julee/docs/__init__.py +5 -0
- julee/docs/sphinx_hcd/__init__.py +82 -0
- julee/docs/sphinx_hcd/accelerators.py +1078 -0
- julee/docs/sphinx_hcd/apps.py +499 -0
- julee/docs/sphinx_hcd/config.py +148 -0
- julee/docs/sphinx_hcd/epics.py +448 -0
- julee/docs/sphinx_hcd/integrations.py +306 -0
- julee/docs/sphinx_hcd/journeys.py +783 -0
- julee/docs/sphinx_hcd/personas.py +435 -0
- julee/docs/sphinx_hcd/stories.py +932 -0
- julee/docs/sphinx_hcd/utils.py +180 -0
- julee/domain/models/__init__.py +5 -6
- julee/domain/models/assembly/assembly.py +7 -7
- julee/domain/models/assembly/tests/factories.py +2 -1
- julee/domain/models/assembly/tests/test_assembly.py +16 -13
- julee/domain/models/assembly_specification/assembly_specification.py +11 -10
- julee/domain/models/assembly_specification/knowledge_service_query.py +7 -6
- julee/domain/models/assembly_specification/tests/factories.py +2 -1
- julee/domain/models/assembly_specification/tests/test_assembly_specification.py +9 -6
- julee/domain/models/assembly_specification/tests/test_knowledge_service_query.py +3 -1
- julee/domain/models/custom_fields/content_stream.py +3 -2
- julee/domain/models/custom_fields/tests/test_custom_fields.py +2 -1
- julee/domain/models/document/document.py +12 -10
- julee/domain/models/document/tests/factories.py +3 -2
- julee/domain/models/document/tests/test_document.py +6 -3
- julee/domain/models/knowledge_service_config/knowledge_service_config.py +4 -4
- julee/domain/models/policy/__init__.py +4 -4
- julee/domain/models/policy/document_policy_validation.py +17 -17
- julee/domain/models/policy/policy.py +10 -10
- julee/domain/models/policy/tests/factories.py +2 -1
- julee/domain/models/policy/tests/test_document_policy_validation.py +3 -1
- julee/domain/models/policy/tests/test_policy.py +2 -1
- julee/domain/repositories/__init__.py +3 -3
- julee/domain/repositories/assembly.py +3 -1
- julee/domain/repositories/assembly_specification.py +2 -0
- julee/domain/repositories/base.py +5 -4
- julee/domain/repositories/document.py +3 -1
- julee/domain/repositories/document_policy_validation.py +3 -1
- julee/domain/repositories/knowledge_service_config.py +2 -0
- julee/domain/repositories/knowledge_service_query.py +1 -0
- julee/domain/repositories/policy.py +3 -1
- julee/domain/use_cases/decorators.py +3 -2
- julee/domain/use_cases/extract_assemble_data.py +13 -12
- julee/domain/use_cases/initialize_system_data.py +13 -13
- julee/domain/use_cases/tests/test_extract_assemble_data.py +10 -10
- julee/domain/use_cases/tests/test_initialize_system_data.py +2 -2
- julee/domain/use_cases/tests/test_validate_document.py +11 -11
- julee/domain/use_cases/validate_document.py +14 -14
- julee/maintenance/__init__.py +1 -0
- julee/maintenance/release.py +188 -0
- julee/repositories/memory/assembly.py +6 -5
- julee/repositories/memory/assembly_specification.py +8 -9
- julee/repositories/memory/base.py +12 -11
- julee/repositories/memory/document.py +8 -7
- julee/repositories/memory/document_policy_validation.py +7 -6
- julee/repositories/memory/knowledge_service_config.py +8 -7
- julee/repositories/memory/knowledge_service_query.py +8 -7
- julee/repositories/memory/policy.py +6 -5
- julee/repositories/memory/tests/test_document.py +6 -4
- julee/repositories/memory/tests/test_document_policy_validation.py +2 -1
- julee/repositories/memory/tests/test_policy.py +2 -1
- julee/repositories/minio/assembly.py +4 -4
- julee/repositories/minio/assembly_specification.py +6 -8
- julee/repositories/minio/client.py +22 -25
- julee/repositories/minio/document.py +11 -11
- julee/repositories/minio/document_policy_validation.py +5 -5
- julee/repositories/minio/knowledge_service_config.py +6 -6
- julee/repositories/minio/knowledge_service_query.py +6 -9
- julee/repositories/minio/policy.py +4 -4
- julee/repositories/minio/tests/fake_client.py +11 -9
- julee/repositories/minio/tests/test_assembly.py +3 -1
- julee/repositories/minio/tests/test_assembly_specification.py +2 -1
- julee/repositories/minio/tests/test_client_protocol.py +5 -5
- julee/repositories/minio/tests/test_document.py +7 -6
- julee/repositories/minio/tests/test_document_policy_validation.py +3 -1
- julee/repositories/minio/tests/test_knowledge_service_config.py +4 -2
- julee/repositories/minio/tests/test_knowledge_service_query.py +3 -2
- julee/repositories/minio/tests/test_policy.py +3 -1
- julee/repositories/temporal/activities.py +5 -5
- julee/repositories/temporal/proxies.py +5 -5
- julee/services/knowledge_service/__init__.py +1 -2
- julee/services/knowledge_service/anthropic/knowledge_service.py +8 -7
- julee/services/knowledge_service/anthropic/tests/test_knowledge_service.py +11 -10
- julee/services/knowledge_service/factory.py +8 -8
- julee/services/knowledge_service/knowledge_service.py +12 -14
- julee/services/knowledge_service/memory/knowledge_service.py +13 -12
- julee/services/knowledge_service/memory/test_knowledge_service.py +10 -7
- julee/services/knowledge_service/test_factory.py +11 -10
- julee/services/temporal/activities.py +10 -10
- julee/services/temporal/proxies.py +2 -2
- julee/util/domain.py +6 -6
- julee/util/repos/minio/file_storage.py +8 -9
- julee/util/repos/temporal/client_proxies/file_storage.py +3 -4
- julee/util/repos/temporal/data_converter.py +6 -6
- julee/util/repos/temporal/minio_file_storage.py +1 -1
- julee/util/repos/temporal/proxies/file_storage.py +2 -3
- julee/util/repositories.py +4 -3
- julee/util/temporal/decorators.py +20 -18
- julee/util/tests/test_decorators.py +13 -15
- julee/util/validation/repository.py +3 -3
- julee/util/validation/type_guards.py +12 -11
- julee/worker.py +9 -8
- julee/workflows/__init__.py +2 -2
- julee/workflows/extract_assemble.py +2 -1
- julee/workflows/validate_document.py +3 -2
- {julee-0.1.2.dist-info → julee-0.1.3.dist-info}/METADATA +2 -1
- julee-0.1.3.dist-info/RECORD +197 -0
- julee-0.1.2.dist-info/RECORD +0 -161
- {julee-0.1.2.dist-info → julee-0.1.3.dist-info}/WHEEL +0 -0
- {julee-0.1.2.dist-info → julee-0.1.3.dist-info}/licenses/LICENSE +0 -0
- {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
|
-
|
|
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(
|
|
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:
|
|
51
|
+
created_at: datetime | None = Field(
|
|
52
52
|
default_factory=lambda: datetime.now(timezone.utc)
|
|
53
53
|
)
|
|
54
|
-
updated_at:
|
|
54
|
+
updated_at: datetime | None = Field(
|
|
55
55
|
default_factory=lambda: datetime.now(timezone.utc)
|
|
56
56
|
)
|
|
57
57
|
|
|
@@ -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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
100
|
+
completed_at: datetime | None = Field(
|
|
101
101
|
default=None, description="When the validation process completed"
|
|
102
102
|
)
|
|
103
|
-
error_message:
|
|
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:
|
|
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:
|
|
132
|
-
) ->
|
|
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:
|
|
146
|
-
) ->
|
|
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:
|
|
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:
|
|
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:
|
|
182
|
-
) ->
|
|
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:
|
|
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:
|
|
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:
|
|
72
|
+
created_at: datetime | None = Field(
|
|
73
73
|
default_factory=lambda: datetime.now(timezone.utc)
|
|
74
74
|
)
|
|
75
|
-
updated_at:
|
|
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:
|
|
102
|
-
) ->
|
|
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:
|
|
151
|
-
) ->
|
|
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
|
|
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,
|
|
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) ->
|
|
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:
|
|
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) ->
|
|
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
|
|
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
|
|
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
|
|
|
@@ -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
|
|
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,
|
|
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:
|
|
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
|
|
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:
|
|
260
|
-
) ->
|
|
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
|
-
) ->
|
|
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:
|
|
355
|
-
queries:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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) ->
|
|
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,
|
|
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:
|
|
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) ->
|
|
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,
|
|
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:
|
|
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) ->
|
|
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,
|
|
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:
|
|
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) ->
|
|
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,
|
|
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:
|
|
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
|
|