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.

@@ -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
- result = conn.execute(
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 ? DAYS
94
- """,
95
- (self.ttl_days,),
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)