flock-core 0.5.0b54__py3-none-any.whl → 0.5.0b56__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.
Potentially problematic release.
This version of flock-core might be problematic. Click here for more details.
- flock/logging/telemetry_exporter/duckdb_exporter.py +6 -6
- flock/store.py +34 -1
- flock_core-0.5.0b56.dist-info/METADATA +943 -0
- {flock_core-0.5.0b54.dist-info → flock_core-0.5.0b56.dist-info}/RECORD +7 -7
- flock_core-0.5.0b54.dist-info/METADATA +0 -916
- {flock_core-0.5.0b54.dist-info → flock_core-0.5.0b56.dist-info}/WHEEL +0 -0
- {flock_core-0.5.0b54.dist-info → flock_core-0.5.0b56.dist-info}/entry_points.txt +0 -0
- {flock_core-0.5.0b54.dist-info → flock_core-0.5.0b56.dist-info}/licenses/LICENSE +0 -0
|
@@ -87,13 +87,13 @@ class DuckDBSpanExporter(TelemetryExporter):
|
|
|
87
87
|
try:
|
|
88
88
|
with duckdb.connect(str(self.db_path)) as conn:
|
|
89
89
|
# Delete spans older than TTL
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
# Note: DuckDB doesn't support ? placeholders inside INTERVAL expressions
|
|
91
|
+
# Safe: ttl_days is guaranteed to be an int, no injection risk
|
|
92
|
+
query = f"""
|
|
92
93
|
DELETE FROM spans
|
|
93
|
-
WHERE created_at < CURRENT_TIMESTAMP - INTERVAL
|
|
94
|
-
"""
|
|
95
|
-
|
|
96
|
-
)
|
|
94
|
+
WHERE created_at < CURRENT_TIMESTAMP - INTERVAL '{self.ttl_days} DAYS'
|
|
95
|
+
""" # nosec B608
|
|
96
|
+
result = conn.execute(query)
|
|
97
97
|
|
|
98
98
|
deleted_count = result.fetchall()[0][0] if result else 0
|
|
99
99
|
|
flock/store.py
CHANGED
|
@@ -5,7 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
|
|
6
6
|
from asyncio import Lock
|
|
7
7
|
from collections import defaultdict
|
|
8
|
-
from typing import TYPE_CHECKING
|
|
8
|
+
from typing import TYPE_CHECKING, TypeVar
|
|
9
9
|
|
|
10
10
|
from flock.registry import type_registry
|
|
11
11
|
|
|
@@ -17,6 +17,8 @@ if TYPE_CHECKING:
|
|
|
17
17
|
|
|
18
18
|
from flock.artifacts import Artifact
|
|
19
19
|
|
|
20
|
+
T = TypeVar("T")
|
|
21
|
+
|
|
20
22
|
|
|
21
23
|
class BlackboardStore:
|
|
22
24
|
async def publish(self, artifact: Artifact) -> None:
|
|
@@ -31,6 +33,21 @@ class BlackboardStore:
|
|
|
31
33
|
async def list_by_type(self, type_name: str) -> builtins.list[Artifact]:
|
|
32
34
|
raise NotImplementedError
|
|
33
35
|
|
|
36
|
+
async def get_by_type(self, artifact_type: type[T]) -> builtins.list[T]:
|
|
37
|
+
"""Get artifacts by Pydantic type, returning data already cast.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
artifact_type: The Pydantic model class (e.g., BugAnalysis)
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
List of data objects of the specified type (not Artifact wrappers)
|
|
44
|
+
|
|
45
|
+
Example:
|
|
46
|
+
bug_analyses = await store.get_by_type(BugAnalysis)
|
|
47
|
+
# Returns list[BugAnalysis] directly, no .data access needed
|
|
48
|
+
"""
|
|
49
|
+
raise NotImplementedError
|
|
50
|
+
|
|
34
51
|
|
|
35
52
|
class InMemoryBlackboardStore(BlackboardStore):
|
|
36
53
|
"""Simple in-memory implementation suitable for local dev and tests."""
|
|
@@ -58,6 +75,22 @@ class InMemoryBlackboardStore(BlackboardStore):
|
|
|
58
75
|
canonical = type_registry.resolve_name(type_name)
|
|
59
76
|
return list(self._by_type.get(canonical, []))
|
|
60
77
|
|
|
78
|
+
async def get_by_type(self, artifact_type: type[T]) -> builtins.list[T]:
|
|
79
|
+
"""Get artifacts by Pydantic type, returning data already cast.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
artifact_type: The Pydantic model class (e.g., BugAnalysis)
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
List of data objects of the specified type (not Artifact wrappers)
|
|
86
|
+
"""
|
|
87
|
+
async with self._lock:
|
|
88
|
+
# Get canonical name from the type
|
|
89
|
+
canonical = type_registry.resolve_name(artifact_type.__name__)
|
|
90
|
+
artifacts = self._by_type.get(canonical, [])
|
|
91
|
+
# Reconstruct Pydantic models from payload dictionaries
|
|
92
|
+
return [artifact_type(**artifact.payload) for artifact in artifacts] # type: ignore
|
|
93
|
+
|
|
61
94
|
async def extend(self, artifacts: Iterable[Artifact]) -> None: # pragma: no cover - helper
|
|
62
95
|
for artifact in artifacts:
|
|
63
96
|
await self.publish(artifact)
|