julee 0.1.2__py3-none-any.whl → 0.1.4__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 +11 -10
- 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 +76 -0
- julee/docs/sphinx_hcd/accelerators.py +1175 -0
- julee/docs/sphinx_hcd/apps.py +518 -0
- julee/docs/sphinx_hcd/config.py +148 -0
- julee/docs/sphinx_hcd/epics.py +453 -0
- julee/docs/sphinx_hcd/integrations.py +310 -0
- julee/docs/sphinx_hcd/journeys.py +797 -0
- julee/docs/sphinx_hcd/personas.py +457 -0
- julee/docs/sphinx_hcd/stories.py +960 -0
- julee/docs/sphinx_hcd/utils.py +185 -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 +23 -30
- julee/domain/models/document/tests/factories.py +3 -2
- julee/domain/models/document/tests/test_document.py +20 -37
- 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 +14 -13
- julee/domain/use_cases/initialize_system_data.py +88 -34
- 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/fixtures/documents.yaml +4 -43
- julee/fixtures/knowledge_service_queries.yaml +9 -0
- julee/maintenance/__init__.py +1 -0
- julee/maintenance/release.py +243 -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 +27 -20
- 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 +24 -22
- 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 +36 -33
- 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 +23 -22
- 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.4.dist-info}/METADATA +3 -3
- julee-0.1.4.dist-info/RECORD +196 -0
- julee/fixtures/assembly_specifications.yaml +0 -70
- julee-0.1.2.dist-info/RECORD +0 -161
- {julee-0.1.2.dist-info → julee-0.1.4.dist-info}/WHEEL +0 -0
- {julee-0.1.2.dist-info → julee-0.1.4.dist-info}/licenses/LICENSE +0 -0
- {julee-0.1.2.dist-info → julee-0.1.4.dist-info}/top_level.txt +0 -0
|
@@ -14,7 +14,6 @@ key.
|
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
import logging
|
|
17
|
-
from typing import Optional, List, Dict
|
|
18
17
|
|
|
19
18
|
from julee.domain.models.knowledge_service_config import (
|
|
20
19
|
KnowledgeServiceConfig,
|
|
@@ -22,6 +21,7 @@ from julee.domain.models.knowledge_service_config import (
|
|
|
22
21
|
from julee.domain.repositories.knowledge_service_config import (
|
|
23
22
|
KnowledgeServiceConfigRepository,
|
|
24
23
|
)
|
|
24
|
+
|
|
25
25
|
from .client import MinioClient, MinioRepositoryMixin
|
|
26
26
|
|
|
27
27
|
|
|
@@ -53,7 +53,7 @@ class MinioKnowledgeServiceConfigRepository(
|
|
|
53
53
|
self.bucket_name = "knowledge-service-configs"
|
|
54
54
|
self.ensure_buckets_exist(self.bucket_name)
|
|
55
55
|
|
|
56
|
-
async def get(self, knowledge_service_id: str) ->
|
|
56
|
+
async def get(self, knowledge_service_id: str) -> KnowledgeServiceConfig | None:
|
|
57
57
|
"""Retrieve a knowledge service configuration by ID.
|
|
58
58
|
|
|
59
59
|
Args:
|
|
@@ -98,8 +98,8 @@ class MinioKnowledgeServiceConfigRepository(
|
|
|
98
98
|
)
|
|
99
99
|
|
|
100
100
|
async def get_many(
|
|
101
|
-
self, knowledge_service_ids:
|
|
102
|
-
) ->
|
|
101
|
+
self, knowledge_service_ids: list[str]
|
|
102
|
+
) -> dict[str, KnowledgeServiceConfig | None]:
|
|
103
103
|
"""Retrieve multiple knowledge service configs by ID.
|
|
104
104
|
|
|
105
105
|
Args:
|
|
@@ -124,7 +124,7 @@ class MinioKnowledgeServiceConfigRepository(
|
|
|
124
124
|
)
|
|
125
125
|
|
|
126
126
|
# Convert object names back to knowledge service IDs for the result
|
|
127
|
-
result:
|
|
127
|
+
result: dict[str, KnowledgeServiceConfig | None] = {}
|
|
128
128
|
for i, service_id in enumerate(knowledge_service_ids):
|
|
129
129
|
object_name = object_names[i]
|
|
130
130
|
result[service_id] = object_results[object_name]
|
|
@@ -139,7 +139,7 @@ class MinioKnowledgeServiceConfigRepository(
|
|
|
139
139
|
"""
|
|
140
140
|
return self.generate_id_with_prefix("ks")
|
|
141
141
|
|
|
142
|
-
async def list_all(self) ->
|
|
142
|
+
async def list_all(self) -> list[KnowledgeServiceConfig]:
|
|
143
143
|
"""List all knowledge service configurations.
|
|
144
144
|
|
|
145
145
|
Returns:
|
|
@@ -16,17 +16,14 @@ Each query is stored as a separate object with the query ID as the key.
|
|
|
16
16
|
import logging
|
|
17
17
|
import uuid
|
|
18
18
|
|
|
19
|
-
from typing import Optional, List, Dict
|
|
20
|
-
|
|
21
|
-
|
|
22
19
|
from julee.domain.models.assembly_specification import (
|
|
23
20
|
KnowledgeServiceQuery,
|
|
24
21
|
)
|
|
25
|
-
from .client import MinioClient, MinioRepositoryMixin
|
|
26
22
|
from julee.domain.repositories.knowledge_service_query import (
|
|
27
23
|
KnowledgeServiceQueryRepository,
|
|
28
24
|
)
|
|
29
25
|
|
|
26
|
+
from .client import MinioClient, MinioRepositoryMixin
|
|
30
27
|
|
|
31
28
|
logger = logging.getLogger(__name__)
|
|
32
29
|
|
|
@@ -54,7 +51,7 @@ class MinioKnowledgeServiceQueryRepository(
|
|
|
54
51
|
self.bucket_name = "knowledge-service-queries"
|
|
55
52
|
self.ensure_buckets_exist(self.bucket_name)
|
|
56
53
|
|
|
57
|
-
async def get(self, query_id: str) ->
|
|
54
|
+
async def get(self, query_id: str) -> KnowledgeServiceQuery | None:
|
|
58
55
|
"""Retrieve a knowledge service query by ID.
|
|
59
56
|
|
|
60
57
|
Args:
|
|
@@ -124,8 +121,8 @@ class MinioKnowledgeServiceQueryRepository(
|
|
|
124
121
|
return query_id
|
|
125
122
|
|
|
126
123
|
async def get_many(
|
|
127
|
-
self, query_ids:
|
|
128
|
-
) ->
|
|
124
|
+
self, query_ids: list[str]
|
|
125
|
+
) -> dict[str, KnowledgeServiceQuery | None]:
|
|
129
126
|
"""Retrieve multiple knowledge service queries by ID.
|
|
130
127
|
|
|
131
128
|
Args:
|
|
@@ -159,14 +156,14 @@ class MinioKnowledgeServiceQueryRepository(
|
|
|
159
156
|
)
|
|
160
157
|
|
|
161
158
|
# Convert object names back to query IDs for the result
|
|
162
|
-
result:
|
|
159
|
+
result: dict[str, KnowledgeServiceQuery | None] = {}
|
|
163
160
|
for i, query_id in enumerate(query_ids):
|
|
164
161
|
object_name = object_names[i]
|
|
165
162
|
result[query_id] = object_results[object_name]
|
|
166
163
|
|
|
167
164
|
return result
|
|
168
165
|
|
|
169
|
-
async def list_all(self) ->
|
|
166
|
+
async def list_all(self) -> list[KnowledgeServiceQuery]:
|
|
170
167
|
"""List all knowledge service queries.
|
|
171
168
|
|
|
172
169
|
Returns:
|
|
@@ -13,10 +13,10 @@ and transformation queries.
|
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
import logging
|
|
16
|
-
from typing import Optional, List, Dict
|
|
17
16
|
|
|
18
17
|
from julee.domain.models.policy import Policy
|
|
19
18
|
from julee.domain.repositories.policy import PolicyRepository
|
|
19
|
+
|
|
20
20
|
from .client import MinioClient, MinioRepositoryMixin
|
|
21
21
|
|
|
22
22
|
|
|
@@ -40,7 +40,7 @@ class MinioPolicyRepository(PolicyRepository, MinioRepositoryMixin):
|
|
|
40
40
|
self.policies_bucket = "policies"
|
|
41
41
|
self.ensure_buckets_exist(self.policies_bucket)
|
|
42
42
|
|
|
43
|
-
async def get(self, policy_id: str) ->
|
|
43
|
+
async def get(self, policy_id: str) -> Policy | None:
|
|
44
44
|
"""Retrieve a policy by ID."""
|
|
45
45
|
return self.get_json_object(
|
|
46
46
|
bucket_name=self.policies_bucket,
|
|
@@ -72,7 +72,7 @@ class MinioPolicyRepository(PolicyRepository, MinioRepositoryMixin):
|
|
|
72
72
|
},
|
|
73
73
|
)
|
|
74
74
|
|
|
75
|
-
async def get_many(self, policy_ids:
|
|
75
|
+
async def get_many(self, policy_ids: list[str]) -> dict[str, Policy | None]:
|
|
76
76
|
"""Retrieve multiple policies by ID.
|
|
77
77
|
|
|
78
78
|
Args:
|
|
@@ -95,7 +95,7 @@ class MinioPolicyRepository(PolicyRepository, MinioRepositoryMixin):
|
|
|
95
95
|
)
|
|
96
96
|
|
|
97
97
|
# Convert object names back to policy IDs for the result
|
|
98
|
-
result:
|
|
98
|
+
result: dict[str, Policy | None] = {}
|
|
99
99
|
for policy_id in policy_ids:
|
|
100
100
|
result[policy_id] = object_results[policy_id]
|
|
101
101
|
|
|
@@ -7,15 +7,17 @@ state-based testing where you can verify actual storage state rather than
|
|
|
7
7
|
just mocking method calls.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
from
|
|
10
|
+
from collections.abc import Callable
|
|
11
|
+
from datetime import datetime, timezone
|
|
11
12
|
from functools import wraps
|
|
13
|
+
from typing import Any, BinaryIO
|
|
12
14
|
from unittest.mock import Mock
|
|
13
|
-
|
|
14
|
-
from minio.error import S3Error
|
|
15
|
-
from minio.datatypes import Object
|
|
15
|
+
|
|
16
16
|
from minio.api import ObjectWriteResult
|
|
17
|
-
from
|
|
17
|
+
from minio.datatypes import Object
|
|
18
|
+
from minio.error import S3Error
|
|
18
19
|
from urllib3 import HTTPHeaderDict
|
|
20
|
+
from urllib3.response import BaseHTTPResponse
|
|
19
21
|
|
|
20
22
|
from ..client import MinioClient
|
|
21
23
|
|
|
@@ -83,8 +85,8 @@ class FakeMinioClient(MinioClient):
|
|
|
83
85
|
"""
|
|
84
86
|
|
|
85
87
|
def __init__(self) -> None:
|
|
86
|
-
self._buckets:
|
|
87
|
-
self._objects:
|
|
88
|
+
self._buckets: dict[str, dict[str, Any]] = {}
|
|
89
|
+
self._objects: dict[str, dict[str, dict[str, Any]]] = {}
|
|
88
90
|
|
|
89
91
|
def bucket_exists(self, bucket_name: str) -> bool:
|
|
90
92
|
"""Check if a bucket exists."""
|
|
@@ -112,7 +114,7 @@ class FakeMinioClient(MinioClient):
|
|
|
112
114
|
data: BinaryIO,
|
|
113
115
|
length: int,
|
|
114
116
|
content_type: str = "application/octet-stream",
|
|
115
|
-
metadata:
|
|
117
|
+
metadata: dict[str, str | list[str] | tuple[str]] | None = None,
|
|
116
118
|
) -> ObjectWriteResult:
|
|
117
119
|
"""Store an object in the bucket."""
|
|
118
120
|
|
|
@@ -195,7 +197,7 @@ class FakeMinioClient(MinioClient):
|
|
|
195
197
|
del self._objects[bucket_name][object_name]
|
|
196
198
|
|
|
197
199
|
# Inspection methods for testing
|
|
198
|
-
def get_stored_objects(self, bucket_name: str) ->
|
|
200
|
+
def get_stored_objects(self, bucket_name: str) -> dict[str, dict[str, Any]]:
|
|
199
201
|
"""Get all stored objects in a bucket (for testing purposes)."""
|
|
200
202
|
return self._objects.get(bucket_name, {}).copy()
|
|
201
203
|
|
|
@@ -6,11 +6,13 @@ repository implementation, using the fake client to avoid external
|
|
|
6
6
|
dependencies during testing.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
import pytest
|
|
10
9
|
from datetime import datetime, timezone
|
|
11
10
|
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
12
13
|
from julee.domain.models.assembly import Assembly, AssemblyStatus
|
|
13
14
|
from julee.repositories.minio.assembly import MinioAssemblyRepository
|
|
15
|
+
|
|
14
16
|
from .fake_client import FakeMinioClient
|
|
15
17
|
|
|
16
18
|
|
|
@@ -6,9 +6,9 @@ specification repository implementation, using the fake client to avoid
|
|
|
6
6
|
external dependencies during testing.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
import pytest
|
|
10
9
|
from datetime import datetime, timezone
|
|
11
10
|
|
|
11
|
+
import pytest
|
|
12
12
|
|
|
13
13
|
from julee.domain.models.assembly_specification import (
|
|
14
14
|
AssemblySpecification,
|
|
@@ -17,6 +17,7 @@ from julee.domain.models.assembly_specification import (
|
|
|
17
17
|
from julee.repositories.minio.assembly_specification import (
|
|
18
18
|
MinioAssemblySpecificationRepository,
|
|
19
19
|
)
|
|
20
|
+
|
|
20
21
|
from .fake_client import FakeMinioClient
|
|
21
22
|
|
|
22
23
|
|
|
@@ -34,11 +34,11 @@ class TestMinioClientProtocol:
|
|
|
34
34
|
assert hasattr(real_client, "stat_object")
|
|
35
35
|
|
|
36
36
|
# Test that methods are callable
|
|
37
|
-
assert callable(
|
|
38
|
-
assert callable(
|
|
39
|
-
assert callable(
|
|
40
|
-
assert callable(
|
|
41
|
-
assert callable(
|
|
37
|
+
assert callable(real_client.bucket_exists)
|
|
38
|
+
assert callable(real_client.make_bucket)
|
|
39
|
+
assert callable(real_client.put_object)
|
|
40
|
+
assert callable(real_client.get_object)
|
|
41
|
+
assert callable(real_client.stat_object)
|
|
42
42
|
|
|
43
43
|
def test_protocol_accepts_real_minio_client(self) -> None:
|
|
44
44
|
"""Test that our protocol accepts a real Minio client instance."""
|
|
@@ -6,20 +6,21 @@ without requiring a real MinIO instance. They follow the Clean Architecture
|
|
|
6
6
|
testing patterns and verify idempotency, error handling, and content.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
import io
|
|
10
|
-
import pytest
|
|
11
9
|
import hashlib
|
|
12
|
-
import
|
|
10
|
+
import io
|
|
13
11
|
from typing import Any
|
|
14
12
|
from unittest.mock import Mock
|
|
15
|
-
from minio.error import S3Error
|
|
16
13
|
|
|
14
|
+
import multihash
|
|
15
|
+
import pytest
|
|
16
|
+
from minio.error import S3Error
|
|
17
17
|
|
|
18
|
-
from julee.repositories.minio.document import MinioDocumentRepository
|
|
19
|
-
from julee.domain.models.document import Document, DocumentStatus
|
|
20
18
|
from julee.domain.models.custom_fields.content_stream import (
|
|
21
19
|
ContentStream,
|
|
22
20
|
)
|
|
21
|
+
from julee.domain.models.document import Document, DocumentStatus
|
|
22
|
+
from julee.repositories.minio.document import MinioDocumentRepository
|
|
23
|
+
|
|
23
24
|
from .fake_client import FakeMinioClient
|
|
24
25
|
|
|
25
26
|
|
|
@@ -428,16 +429,16 @@ class TestMinioDocumentRepositoryMultihash:
|
|
|
428
429
|
assert len(multihash_result) > 0
|
|
429
430
|
|
|
430
431
|
|
|
431
|
-
class
|
|
432
|
-
"""Test
|
|
432
|
+
class TestMinioDocumentRepositoryContentBytes:
|
|
433
|
+
"""Test content_bytes functionality."""
|
|
433
434
|
|
|
434
|
-
async def
|
|
435
|
+
async def test_save_document_with_content_bytes(
|
|
435
436
|
self, repository: MinioDocumentRepository
|
|
436
437
|
) -> None:
|
|
437
|
-
"""Test saving document with
|
|
438
|
+
"""Test saving document with content_bytes (small content)."""
|
|
438
439
|
content = '{"assembled": "document", "data": "test"}'
|
|
439
440
|
|
|
440
|
-
# Create document with
|
|
441
|
+
# Create document with content_bytes
|
|
441
442
|
document = Document(
|
|
442
443
|
document_id="test-doc-content-string",
|
|
443
444
|
original_filename="assembled.json",
|
|
@@ -445,27 +446,27 @@ class TestMinioDocumentRepositoryContentString:
|
|
|
445
446
|
size_bytes=100, # Will be updated automatically
|
|
446
447
|
content_multihash="placeholder", # Will be updated automatically
|
|
447
448
|
status=DocumentStatus.CAPTURED,
|
|
448
|
-
|
|
449
|
+
content_bytes=content,
|
|
449
450
|
)
|
|
450
451
|
|
|
451
|
-
# Act - save should convert
|
|
452
|
+
# Act - save should convert content_bytes to ContentStream
|
|
452
453
|
await repository.save(document)
|
|
453
454
|
|
|
454
455
|
# Assert document was saved successfully
|
|
455
456
|
retrieved = await repository.get(document.document_id)
|
|
456
457
|
assert retrieved is not None
|
|
457
458
|
assert retrieved.content_multihash != "placeholder" # Hash was calculated
|
|
458
|
-
assert retrieved.size_bytes == len(content
|
|
459
|
+
assert retrieved.size_bytes == len(content)
|
|
459
460
|
|
|
460
461
|
# Verify content can be read
|
|
461
462
|
assert retrieved.content is not None
|
|
462
463
|
retrieved_content = retrieved.content.read().decode("utf-8")
|
|
463
464
|
assert retrieved_content == content
|
|
464
465
|
|
|
465
|
-
async def
|
|
466
|
+
async def test_save_document_with_content_bytes_unicode(
|
|
466
467
|
self, repository: MinioDocumentRepository
|
|
467
468
|
) -> None:
|
|
468
|
-
"""Test saving document with unicode
|
|
469
|
+
"""Test saving document with unicode content_bytes."""
|
|
469
470
|
content = '{"title": "测试文档", "emoji": "🚀", "content": "éñ"}'
|
|
470
471
|
|
|
471
472
|
document = Document(
|
|
@@ -475,7 +476,7 @@ class TestMinioDocumentRepositoryContentString:
|
|
|
475
476
|
size_bytes=100,
|
|
476
477
|
content_multihash="placeholder",
|
|
477
478
|
status=DocumentStatus.CAPTURED,
|
|
478
|
-
|
|
479
|
+
content_bytes=content,
|
|
479
480
|
)
|
|
480
481
|
|
|
481
482
|
await repository.save(document)
|
|
@@ -489,12 +490,12 @@ class TestMinioDocumentRepositoryContentString:
|
|
|
489
490
|
# Note: Empty content test removed because domain model requires
|
|
490
491
|
# size_bytes > 0
|
|
491
492
|
|
|
492
|
-
async def
|
|
493
|
+
async def test_save_excludes_content_bytes_from_metadata(
|
|
493
494
|
self,
|
|
494
495
|
repository: MinioDocumentRepository,
|
|
495
496
|
fake_minio_client: FakeMinioClient,
|
|
496
497
|
) -> None:
|
|
497
|
-
"""Test that
|
|
498
|
+
"""Test that content_bytes is not stored in metadata."""
|
|
498
499
|
content = '{"test": "data that should not be in metadata"}'
|
|
499
500
|
|
|
500
501
|
document = Document(
|
|
@@ -504,7 +505,7 @@ class TestMinioDocumentRepositoryContentString:
|
|
|
504
505
|
size_bytes=100,
|
|
505
506
|
content_multihash="placeholder",
|
|
506
507
|
status=DocumentStatus.CAPTURED,
|
|
507
|
-
|
|
508
|
+
content_bytes=content,
|
|
508
509
|
)
|
|
509
510
|
|
|
510
511
|
await repository.save(document)
|
|
@@ -520,8 +521,8 @@ class TestMinioDocumentRepositoryContentString:
|
|
|
520
521
|
|
|
521
522
|
metadata_dict = json.loads(metadata_json)
|
|
522
523
|
|
|
523
|
-
# Verify
|
|
524
|
-
assert "
|
|
524
|
+
# Verify content_bytes is not in stored metadata
|
|
525
|
+
assert "content_bytes" not in metadata_dict
|
|
525
526
|
assert "content" not in metadata_dict
|
|
526
527
|
|
|
527
528
|
# Verify essential fields are still present
|
|
@@ -7,9 +7,10 @@ repository that differs from the inherited mixins. Uses the fake client to
|
|
|
7
7
|
avoid external dependencies during testing.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
import pytest
|
|
11
10
|
from datetime import datetime, timezone
|
|
12
11
|
|
|
12
|
+
import pytest
|
|
13
|
+
|
|
13
14
|
from julee.domain.models.policy import (
|
|
14
15
|
DocumentPolicyValidation,
|
|
15
16
|
DocumentPolicyValidationStatus,
|
|
@@ -17,6 +18,7 @@ from julee.domain.models.policy import (
|
|
|
17
18
|
from julee.repositories.minio.document_policy_validation import (
|
|
18
19
|
MinioDocumentPolicyValidationRepository,
|
|
19
20
|
)
|
|
21
|
+
|
|
20
22
|
from .fake_client import FakeMinioClient
|
|
21
23
|
|
|
22
24
|
|
|
@@ -6,16 +6,18 @@ configuration repository implementation, using the fake client to avoid
|
|
|
6
6
|
external dependencies during testing.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
import pytest
|
|
10
9
|
from datetime import datetime, timezone
|
|
11
10
|
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
12
13
|
from julee.domain.models.knowledge_service_config import (
|
|
13
14
|
KnowledgeServiceConfig,
|
|
15
|
+
ServiceApi,
|
|
14
16
|
)
|
|
15
|
-
from julee.domain.models.knowledge_service_config import ServiceApi
|
|
16
17
|
from julee.repositories.minio.knowledge_service_config import (
|
|
17
18
|
MinioKnowledgeServiceConfigRepository,
|
|
18
19
|
)
|
|
20
|
+
|
|
19
21
|
from .fake_client import FakeMinioClient
|
|
20
22
|
|
|
21
23
|
|
|
@@ -6,16 +6,17 @@ query repository implementation, using the fake client to avoid external
|
|
|
6
6
|
dependencies during testing.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
import pytest
|
|
10
|
-
|
|
11
9
|
from datetime import datetime, timezone
|
|
12
10
|
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
13
13
|
from julee.domain.models.assembly_specification import (
|
|
14
14
|
KnowledgeServiceQuery,
|
|
15
15
|
)
|
|
16
16
|
from julee.repositories.minio.knowledge_service_query import (
|
|
17
17
|
MinioKnowledgeServiceQueryRepository,
|
|
18
18
|
)
|
|
19
|
+
|
|
19
20
|
from .fake_client import FakeMinioClient
|
|
20
21
|
|
|
21
22
|
|
|
@@ -6,11 +6,13 @@ implementation, using the fake client to avoid external dependencies during
|
|
|
6
6
|
testing.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
import pytest
|
|
10
9
|
from datetime import datetime, timezone
|
|
11
10
|
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
12
13
|
from julee.domain.models.policy import Policy, PolicyStatus
|
|
13
14
|
from julee.repositories.minio.policy import MinioPolicyRepository
|
|
15
|
+
|
|
14
16
|
from .fake_client import FakeMinioClient
|
|
15
17
|
|
|
16
18
|
|
|
@@ -10,12 +10,14 @@ The classes follow the naming pattern documented in systemPatterns.org:
|
|
|
10
10
|
- Each repository type gets its own activity prefix
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
from julee.util.temporal.decorators import temporal_activity_registration
|
|
14
13
|
from julee.repositories.minio.assembly import MinioAssemblyRepository
|
|
15
14
|
from julee.repositories.minio.assembly_specification import (
|
|
16
15
|
MinioAssemblySpecificationRepository,
|
|
17
16
|
)
|
|
18
17
|
from julee.repositories.minio.document import MinioDocumentRepository
|
|
18
|
+
from julee.repositories.minio.document_policy_validation import (
|
|
19
|
+
MinioDocumentPolicyValidationRepository,
|
|
20
|
+
)
|
|
19
21
|
from julee.repositories.minio.knowledge_service_config import (
|
|
20
22
|
MinioKnowledgeServiceConfigRepository,
|
|
21
23
|
)
|
|
@@ -25,20 +27,18 @@ from julee.repositories.minio.knowledge_service_query import (
|
|
|
25
27
|
from julee.repositories.minio.policy import (
|
|
26
28
|
MinioPolicyRepository,
|
|
27
29
|
)
|
|
28
|
-
from julee.repositories.minio.document_policy_validation import (
|
|
29
|
-
MinioDocumentPolicyValidationRepository,
|
|
30
|
-
)
|
|
31
30
|
|
|
32
31
|
# Import activity name bases from shared module
|
|
33
32
|
from julee.repositories.temporal.activity_names import (
|
|
34
33
|
ASSEMBLY_ACTIVITY_BASE,
|
|
35
34
|
ASSEMBLY_SPECIFICATION_ACTIVITY_BASE,
|
|
36
35
|
DOCUMENT_ACTIVITY_BASE,
|
|
36
|
+
DOCUMENT_POLICY_VALIDATION_ACTIVITY_BASE,
|
|
37
37
|
KNOWLEDGE_SERVICE_CONFIG_ACTIVITY_BASE,
|
|
38
38
|
KNOWLEDGE_SERVICE_QUERY_ACTIVITY_BASE,
|
|
39
39
|
POLICY_ACTIVITY_BASE,
|
|
40
|
-
DOCUMENT_POLICY_VALIDATION_ACTIVITY_BASE,
|
|
41
40
|
)
|
|
41
|
+
from julee.util.temporal.decorators import temporal_activity_registration
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
@temporal_activity_registration(ASSEMBLY_ACTIVITY_BASE)
|
|
@@ -11,12 +11,14 @@ workflow.execute_activity() with the appropriate activity names, timeouts,
|
|
|
11
11
|
and retry policies.
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
from julee.util.temporal.decorators import temporal_workflow_proxy
|
|
15
14
|
from julee.domain.repositories.assembly import AssemblyRepository
|
|
16
15
|
from julee.domain.repositories.assembly_specification import (
|
|
17
16
|
AssemblySpecificationRepository,
|
|
18
17
|
)
|
|
19
18
|
from julee.domain.repositories.document import DocumentRepository
|
|
19
|
+
from julee.domain.repositories.document_policy_validation import (
|
|
20
|
+
DocumentPolicyValidationRepository,
|
|
21
|
+
)
|
|
20
22
|
from julee.domain.repositories.knowledge_service_config import (
|
|
21
23
|
KnowledgeServiceConfigRepository,
|
|
22
24
|
)
|
|
@@ -24,20 +26,18 @@ from julee.domain.repositories.knowledge_service_query import (
|
|
|
24
26
|
KnowledgeServiceQueryRepository,
|
|
25
27
|
)
|
|
26
28
|
from julee.domain.repositories.policy import PolicyRepository
|
|
27
|
-
from julee.domain.repositories.document_policy_validation import (
|
|
28
|
-
DocumentPolicyValidationRepository,
|
|
29
|
-
)
|
|
30
29
|
|
|
31
30
|
# Import activity name bases from shared module
|
|
32
31
|
from julee.repositories.temporal.activity_names import (
|
|
33
32
|
ASSEMBLY_ACTIVITY_BASE,
|
|
34
33
|
ASSEMBLY_SPECIFICATION_ACTIVITY_BASE,
|
|
35
34
|
DOCUMENT_ACTIVITY_BASE,
|
|
35
|
+
DOCUMENT_POLICY_VALIDATION_ACTIVITY_BASE,
|
|
36
36
|
KNOWLEDGE_SERVICE_CONFIG_ACTIVITY_BASE,
|
|
37
37
|
KNOWLEDGE_SERVICE_QUERY_ACTIVITY_BASE,
|
|
38
38
|
POLICY_ACTIVITY_BASE,
|
|
39
|
-
DOCUMENT_POLICY_VALIDATION_ACTIVITY_BASE,
|
|
40
39
|
)
|
|
40
|
+
from julee.util.temporal.decorators import temporal_workflow_proxy
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
@temporal_workflow_proxy(
|
|
@@ -9,12 +9,11 @@ appropriate implementation based on the service_api configuration.
|
|
|
9
9
|
import logging
|
|
10
10
|
|
|
11
11
|
from .knowledge_service import (
|
|
12
|
+
FileRegistrationResult,
|
|
12
13
|
KnowledgeService,
|
|
13
14
|
QueryResult,
|
|
14
|
-
FileRegistrationResult,
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
-
|
|
18
17
|
logger = logging.getLogger(__name__)
|
|
19
18
|
|
|
20
19
|
|
|
@@ -10,23 +10,24 @@ Requirements:
|
|
|
10
10
|
- ANTHROPIC_API_KEY environment variable must be set
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
import os
|
|
14
13
|
import logging
|
|
14
|
+
import os
|
|
15
15
|
import time
|
|
16
16
|
import uuid
|
|
17
|
-
from typing import Optional, List, Dict, Any
|
|
18
17
|
from datetime import datetime, timezone
|
|
18
|
+
from typing import Any
|
|
19
19
|
|
|
20
20
|
from anthropic import AsyncAnthropic
|
|
21
21
|
|
|
22
|
+
from julee.domain.models.document import Document
|
|
22
23
|
from julee.domain.models.knowledge_service_config import (
|
|
23
24
|
KnowledgeServiceConfig,
|
|
24
25
|
)
|
|
25
|
-
|
|
26
|
+
|
|
26
27
|
from ..knowledge_service import (
|
|
28
|
+
FileRegistrationResult,
|
|
27
29
|
KnowledgeService,
|
|
28
30
|
QueryResult,
|
|
29
|
-
FileRegistrationResult,
|
|
30
31
|
)
|
|
31
32
|
|
|
32
33
|
logger = logging.getLogger(__name__)
|
|
@@ -171,9 +172,9 @@ class AnthropicKnowledgeService(KnowledgeService):
|
|
|
171
172
|
self,
|
|
172
173
|
config: KnowledgeServiceConfig,
|
|
173
174
|
query_text: str,
|
|
174
|
-
service_file_ids:
|
|
175
|
-
query_metadata:
|
|
176
|
-
assistant_prompt:
|
|
175
|
+
service_file_ids: list[str] | None = None,
|
|
176
|
+
query_metadata: dict[str, Any] | None = None,
|
|
177
|
+
assistant_prompt: str | None = None,
|
|
177
178
|
) -> QueryResult:
|
|
178
179
|
"""Execute a query against Anthropic.
|
|
179
180
|
|
|
@@ -6,19 +6,20 @@ KnowledgeService protocol, verifying file registration and query
|
|
|
6
6
|
execution functionality.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
import pytest
|
|
10
|
-
from unittest.mock import AsyncMock, MagicMock, patch
|
|
11
|
-
from datetime import datetime, timezone
|
|
12
9
|
import io
|
|
10
|
+
from datetime import datetime, timezone
|
|
11
|
+
from unittest.mock import AsyncMock, MagicMock, patch
|
|
12
|
+
|
|
13
|
+
import pytest
|
|
13
14
|
|
|
14
|
-
from julee.domain.models.knowledge_service_config import (
|
|
15
|
-
KnowledgeServiceConfig,
|
|
16
|
-
)
|
|
17
|
-
from julee.domain.models.document import Document, DocumentStatus
|
|
18
|
-
from julee.domain.models.knowledge_service_config import ServiceApi
|
|
19
15
|
from julee.domain.models.custom_fields.content_stream import (
|
|
20
16
|
ContentStream,
|
|
21
17
|
)
|
|
18
|
+
from julee.domain.models.document import Document, DocumentStatus
|
|
19
|
+
from julee.domain.models.knowledge_service_config import (
|
|
20
|
+
KnowledgeServiceConfig,
|
|
21
|
+
ServiceApi,
|
|
22
|
+
)
|
|
22
23
|
from julee.services.knowledge_service.anthropic import (
|
|
23
24
|
knowledge_service as anthropic_ks,
|
|
24
25
|
)
|
|
@@ -184,7 +185,7 @@ class TestAnthropicKnowledgeService:
|
|
|
184
185
|
) -> None:
|
|
185
186
|
"""Test execute_query handles API errors gracefully."""
|
|
186
187
|
mock_client = MagicMock()
|
|
187
|
-
mock_client.messages.create = AsyncMock(side_effect=
|
|
188
|
+
mock_client.messages.create = AsyncMock(side_effect=RuntimeError("API Error"))
|
|
188
189
|
|
|
189
190
|
with patch(
|
|
190
191
|
"julee.services.knowledge_service.anthropic.knowledge_service.AsyncAnthropic"
|
|
@@ -193,7 +194,7 @@ class TestAnthropicKnowledgeService:
|
|
|
193
194
|
|
|
194
195
|
service = anthropic_ks.AnthropicKnowledgeService()
|
|
195
196
|
|
|
196
|
-
with pytest.raises(
|
|
197
|
+
with pytest.raises(RuntimeError):
|
|
197
198
|
await service.execute_query(knowledge_service_config, "Test query")
|
|
198
199
|
|
|
199
200
|
@patch.dict("os.environ", {"ANTHROPIC_API_KEY": "test-key"})
|