julee 0.1.0__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 (161) hide show
  1. julee/__init__.py +3 -0
  2. julee/api/__init__.py +20 -0
  3. julee/api/app.py +180 -0
  4. julee/api/dependencies.py +257 -0
  5. julee/api/requests.py +175 -0
  6. julee/api/responses.py +43 -0
  7. julee/api/routers/__init__.py +43 -0
  8. julee/api/routers/assembly_specifications.py +212 -0
  9. julee/api/routers/documents.py +182 -0
  10. julee/api/routers/knowledge_service_configs.py +79 -0
  11. julee/api/routers/knowledge_service_queries.py +293 -0
  12. julee/api/routers/system.py +137 -0
  13. julee/api/routers/workflows.py +234 -0
  14. julee/api/services/__init__.py +20 -0
  15. julee/api/services/system_initialization.py +214 -0
  16. julee/api/tests/__init__.py +14 -0
  17. julee/api/tests/routers/__init__.py +17 -0
  18. julee/api/tests/routers/test_assembly_specifications.py +749 -0
  19. julee/api/tests/routers/test_documents.py +301 -0
  20. julee/api/tests/routers/test_knowledge_service_configs.py +234 -0
  21. julee/api/tests/routers/test_knowledge_service_queries.py +738 -0
  22. julee/api/tests/routers/test_system.py +179 -0
  23. julee/api/tests/routers/test_workflows.py +393 -0
  24. julee/api/tests/test_app.py +285 -0
  25. julee/api/tests/test_dependencies.py +245 -0
  26. julee/api/tests/test_requests.py +250 -0
  27. julee/domain/__init__.py +22 -0
  28. julee/domain/models/__init__.py +49 -0
  29. julee/domain/models/assembly/__init__.py +17 -0
  30. julee/domain/models/assembly/assembly.py +103 -0
  31. julee/domain/models/assembly/tests/__init__.py +0 -0
  32. julee/domain/models/assembly/tests/factories.py +37 -0
  33. julee/domain/models/assembly/tests/test_assembly.py +430 -0
  34. julee/domain/models/assembly_specification/__init__.py +24 -0
  35. julee/domain/models/assembly_specification/assembly_specification.py +172 -0
  36. julee/domain/models/assembly_specification/knowledge_service_query.py +123 -0
  37. julee/domain/models/assembly_specification/tests/__init__.py +0 -0
  38. julee/domain/models/assembly_specification/tests/factories.py +78 -0
  39. julee/domain/models/assembly_specification/tests/test_assembly_specification.py +490 -0
  40. julee/domain/models/assembly_specification/tests/test_knowledge_service_query.py +310 -0
  41. julee/domain/models/custom_fields/__init__.py +0 -0
  42. julee/domain/models/custom_fields/content_stream.py +68 -0
  43. julee/domain/models/custom_fields/tests/__init__.py +0 -0
  44. julee/domain/models/custom_fields/tests/test_custom_fields.py +53 -0
  45. julee/domain/models/document/__init__.py +17 -0
  46. julee/domain/models/document/document.py +150 -0
  47. julee/domain/models/document/tests/__init__.py +0 -0
  48. julee/domain/models/document/tests/factories.py +76 -0
  49. julee/domain/models/document/tests/test_document.py +297 -0
  50. julee/domain/models/knowledge_service_config/__init__.py +17 -0
  51. julee/domain/models/knowledge_service_config/knowledge_service_config.py +86 -0
  52. julee/domain/models/policy/__init__.py +15 -0
  53. julee/domain/models/policy/document_policy_validation.py +220 -0
  54. julee/domain/models/policy/policy.py +203 -0
  55. julee/domain/models/policy/tests/__init__.py +0 -0
  56. julee/domain/models/policy/tests/factories.py +47 -0
  57. julee/domain/models/policy/tests/test_document_policy_validation.py +420 -0
  58. julee/domain/models/policy/tests/test_policy.py +546 -0
  59. julee/domain/repositories/__init__.py +27 -0
  60. julee/domain/repositories/assembly.py +45 -0
  61. julee/domain/repositories/assembly_specification.py +52 -0
  62. julee/domain/repositories/base.py +146 -0
  63. julee/domain/repositories/document.py +49 -0
  64. julee/domain/repositories/document_policy_validation.py +52 -0
  65. julee/domain/repositories/knowledge_service_config.py +54 -0
  66. julee/domain/repositories/knowledge_service_query.py +44 -0
  67. julee/domain/repositories/policy.py +49 -0
  68. julee/domain/use_cases/__init__.py +17 -0
  69. julee/domain/use_cases/decorators.py +107 -0
  70. julee/domain/use_cases/extract_assemble_data.py +649 -0
  71. julee/domain/use_cases/initialize_system_data.py +842 -0
  72. julee/domain/use_cases/tests/__init__.py +7 -0
  73. julee/domain/use_cases/tests/test_extract_assemble_data.py +548 -0
  74. julee/domain/use_cases/tests/test_initialize_system_data.py +455 -0
  75. julee/domain/use_cases/tests/test_validate_document.py +1228 -0
  76. julee/domain/use_cases/validate_document.py +736 -0
  77. julee/fixtures/assembly_specifications.yaml +70 -0
  78. julee/fixtures/documents.yaml +178 -0
  79. julee/fixtures/knowledge_service_configs.yaml +37 -0
  80. julee/fixtures/knowledge_service_queries.yaml +27 -0
  81. julee/repositories/__init__.py +17 -0
  82. julee/repositories/memory/__init__.py +31 -0
  83. julee/repositories/memory/assembly.py +84 -0
  84. julee/repositories/memory/assembly_specification.py +125 -0
  85. julee/repositories/memory/base.py +227 -0
  86. julee/repositories/memory/document.py +149 -0
  87. julee/repositories/memory/document_policy_validation.py +104 -0
  88. julee/repositories/memory/knowledge_service_config.py +123 -0
  89. julee/repositories/memory/knowledge_service_query.py +120 -0
  90. julee/repositories/memory/policy.py +87 -0
  91. julee/repositories/memory/tests/__init__.py +0 -0
  92. julee/repositories/memory/tests/test_document.py +212 -0
  93. julee/repositories/memory/tests/test_document_policy_validation.py +161 -0
  94. julee/repositories/memory/tests/test_policy.py +443 -0
  95. julee/repositories/minio/__init__.py +31 -0
  96. julee/repositories/minio/assembly.py +103 -0
  97. julee/repositories/minio/assembly_specification.py +170 -0
  98. julee/repositories/minio/client.py +570 -0
  99. julee/repositories/minio/document.py +530 -0
  100. julee/repositories/minio/document_policy_validation.py +120 -0
  101. julee/repositories/minio/knowledge_service_config.py +187 -0
  102. julee/repositories/minio/knowledge_service_query.py +211 -0
  103. julee/repositories/minio/policy.py +106 -0
  104. julee/repositories/minio/tests/__init__.py +0 -0
  105. julee/repositories/minio/tests/fake_client.py +213 -0
  106. julee/repositories/minio/tests/test_assembly.py +374 -0
  107. julee/repositories/minio/tests/test_assembly_specification.py +391 -0
  108. julee/repositories/minio/tests/test_client_protocol.py +57 -0
  109. julee/repositories/minio/tests/test_document.py +591 -0
  110. julee/repositories/minio/tests/test_document_policy_validation.py +192 -0
  111. julee/repositories/minio/tests/test_knowledge_service_config.py +374 -0
  112. julee/repositories/minio/tests/test_knowledge_service_query.py +438 -0
  113. julee/repositories/minio/tests/test_policy.py +559 -0
  114. julee/repositories/temporal/__init__.py +38 -0
  115. julee/repositories/temporal/activities.py +114 -0
  116. julee/repositories/temporal/activity_names.py +34 -0
  117. julee/repositories/temporal/proxies.py +159 -0
  118. julee/services/__init__.py +18 -0
  119. julee/services/knowledge_service/__init__.py +48 -0
  120. julee/services/knowledge_service/anthropic/__init__.py +12 -0
  121. julee/services/knowledge_service/anthropic/knowledge_service.py +331 -0
  122. julee/services/knowledge_service/anthropic/tests/test_knowledge_service.py +318 -0
  123. julee/services/knowledge_service/factory.py +138 -0
  124. julee/services/knowledge_service/knowledge_service.py +160 -0
  125. julee/services/knowledge_service/memory/__init__.py +13 -0
  126. julee/services/knowledge_service/memory/knowledge_service.py +278 -0
  127. julee/services/knowledge_service/memory/test_knowledge_service.py +345 -0
  128. julee/services/knowledge_service/test_factory.py +112 -0
  129. julee/services/temporal/__init__.py +38 -0
  130. julee/services/temporal/activities.py +86 -0
  131. julee/services/temporal/activity_names.py +22 -0
  132. julee/services/temporal/proxies.py +41 -0
  133. julee/util/__init__.py +0 -0
  134. julee/util/domain.py +119 -0
  135. julee/util/repos/__init__.py +0 -0
  136. julee/util/repos/minio/__init__.py +0 -0
  137. julee/util/repos/minio/file_storage.py +213 -0
  138. julee/util/repos/temporal/__init__.py +11 -0
  139. julee/util/repos/temporal/client_proxies/file_storage.py +68 -0
  140. julee/util/repos/temporal/data_converter.py +123 -0
  141. julee/util/repos/temporal/minio_file_storage.py +12 -0
  142. julee/util/repos/temporal/proxies/__init__.py +0 -0
  143. julee/util/repos/temporal/proxies/file_storage.py +58 -0
  144. julee/util/repositories.py +55 -0
  145. julee/util/temporal/__init__.py +22 -0
  146. julee/util/temporal/activities.py +123 -0
  147. julee/util/temporal/decorators.py +473 -0
  148. julee/util/tests/__init__.py +1 -0
  149. julee/util/tests/test_decorators.py +770 -0
  150. julee/util/validation/__init__.py +29 -0
  151. julee/util/validation/repository.py +100 -0
  152. julee/util/validation/type_guards.py +369 -0
  153. julee/worker.py +211 -0
  154. julee/workflows/__init__.py +26 -0
  155. julee/workflows/extract_assemble.py +215 -0
  156. julee/workflows/validate_document.py +228 -0
  157. julee-0.1.0.dist-info/METADATA +195 -0
  158. julee-0.1.0.dist-info/RECORD +161 -0
  159. julee-0.1.0.dist-info/WHEEL +5 -0
  160. julee-0.1.0.dist-info/licenses/LICENSE +674 -0
  161. julee-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,170 @@
1
+ """
2
+ Minio implementation of AssemblySpecificationRepository.
3
+
4
+ This module provides a Minio-based implementation of the
5
+ AssemblySpecificationRepository protocol that follows the Clean Architecture
6
+ patterns defined in the Fun-Police Framework. It handles assembly
7
+ specification storage with complete JSON schemas and knowledge service query
8
+ configurations, ensuring idempotency and proper error handling.
9
+
10
+ The implementation stores assembly specifications as JSON objects in Minio,
11
+ following the large payload handling pattern from the architectural
12
+ guidelines. Each specification is stored as a complete JSON document with its
13
+ schema and query mappings.
14
+ """
15
+
16
+ import logging
17
+ from typing import Optional, List, Dict
18
+
19
+ from julee.domain.models.assembly_specification import (
20
+ AssemblySpecification,
21
+ )
22
+ from julee.domain.repositories.assembly_specification import (
23
+ AssemblySpecificationRepository,
24
+ )
25
+ from .client import MinioClient, MinioRepositoryMixin
26
+
27
+
28
+ class MinioAssemblySpecificationRepository(
29
+ AssemblySpecificationRepository, MinioRepositoryMixin
30
+ ):
31
+ """
32
+ Minio implementation of AssemblySpecificationRepository using Minio for
33
+ persistence.
34
+
35
+ This implementation stores assembly specifications as JSON objects in the
36
+ "assembly-specifications" bucket. Each specification includes its complete
37
+ JSON schema definition and knowledge service query mappings.
38
+ """
39
+
40
+ def __init__(self, client: MinioClient) -> None:
41
+ """Initialize repository with Minio client.
42
+
43
+ Args:
44
+ client: MinioClient protocol implementation (real or fake)
45
+ """
46
+ self.client = client
47
+ self.logger = logging.getLogger("MinioAssemblySpecificationRepository")
48
+ self.specifications_bucket = "assembly-specifications"
49
+ self.ensure_buckets_exist(self.specifications_bucket)
50
+
51
+ async def get(
52
+ self, assembly_specification_id: str
53
+ ) -> Optional[AssemblySpecification]:
54
+ """Retrieve an assembly specification by ID."""
55
+ object_name = f"spec/{assembly_specification_id}"
56
+
57
+ return self.get_json_object(
58
+ bucket_name=self.specifications_bucket,
59
+ object_name=object_name,
60
+ model_class=AssemblySpecification,
61
+ not_found_log_message="Specification not found",
62
+ error_log_message="Error retrieving specification",
63
+ extra_log_data={"assembly_specification_id": assembly_specification_id},
64
+ )
65
+
66
+ async def save(self, assembly_specification: AssemblySpecification) -> None:
67
+ """Save an assembly specification to Minio."""
68
+ # Update timestamps
69
+ self.update_timestamps(assembly_specification)
70
+
71
+ object_name = f"spec/{assembly_specification.assembly_specification_id}"
72
+
73
+ self.put_json_object(
74
+ bucket_name=self.specifications_bucket,
75
+ object_name=object_name,
76
+ model=assembly_specification,
77
+ success_log_message="Specification saved successfully",
78
+ error_log_message="Error saving specification",
79
+ extra_log_data={
80
+ "assembly_specification_id": (
81
+ assembly_specification.assembly_specification_id
82
+ ),
83
+ "spec_name": assembly_specification.name,
84
+ "status": assembly_specification.status.value,
85
+ "version": assembly_specification.version,
86
+ },
87
+ )
88
+
89
+ async def get_many(
90
+ self, assembly_specification_ids: List[str]
91
+ ) -> Dict[str, Optional[AssemblySpecification]]:
92
+ """Retrieve multiple assembly specifications by ID.
93
+
94
+ Args:
95
+ assembly_specification_ids: List of unique specification
96
+ identifiers
97
+
98
+ Returns:
99
+ Dict mapping specification_id to AssemblySpecification (or None if
100
+ not found)
101
+ """
102
+ # Convert specification IDs to object names
103
+ object_names = [f"spec/{spec_id}" for spec_id in assembly_specification_ids]
104
+
105
+ # Get objects from Minio using batch method
106
+ object_results = self.get_many_json_objects(
107
+ bucket_name=self.specifications_bucket,
108
+ object_names=object_names,
109
+ model_class=AssemblySpecification,
110
+ not_found_log_message="Specification not found",
111
+ error_log_message="Error retrieving specification",
112
+ extra_log_data={"assembly_specification_ids": assembly_specification_ids},
113
+ )
114
+
115
+ # Convert object names back to specification IDs for the result
116
+ result: Dict[str, Optional[AssemblySpecification]] = {}
117
+ for i, spec_id in enumerate(assembly_specification_ids):
118
+ object_name = object_names[i]
119
+ result[spec_id] = object_results[object_name]
120
+
121
+ return result
122
+
123
+ async def generate_id(self) -> str:
124
+ """Generate a unique assembly specification identifier."""
125
+ return self.generate_id_with_prefix("spec")
126
+
127
+ async def list_all(self) -> List[AssemblySpecification]:
128
+ """List all assembly specifications.
129
+
130
+ Returns:
131
+ List of all assembly specifications, sorted by
132
+ assembly_specification_id
133
+ """
134
+ try:
135
+ # Extract specification IDs from objects with the spec/ prefix
136
+ spec_ids = self.list_objects_with_prefix_extract_ids(
137
+ bucket_name=self.specifications_bucket,
138
+ prefix="spec/",
139
+ entity_type_name="specs",
140
+ )
141
+
142
+ if not spec_ids:
143
+ return []
144
+
145
+ # Get all specifications using the existing get_many method
146
+ spec_results = await self.get_many(spec_ids)
147
+
148
+ # Filter out None results and sort by assembly_specification_id
149
+ specs = [spec for spec in spec_results.values() if spec is not None]
150
+ specs.sort(key=lambda x: x.assembly_specification_id)
151
+
152
+ self.logger.debug(
153
+ "Retrieved specs",
154
+ extra={"count": len(specs)},
155
+ )
156
+
157
+ return specs
158
+
159
+ except Exception as e:
160
+ self.logger.error(
161
+ "Error listing specs",
162
+ exc_info=True,
163
+ extra={
164
+ "error_type": type(e).__name__,
165
+ "error_message": str(e),
166
+ "bucket": self.specifications_bucket,
167
+ },
168
+ )
169
+ # Return empty list on error to avoid breaking the API
170
+ return []