Skip to content

Commit 37edf18

Browse files
Merge pull request #1191 from writer/vlad/AB-683-pt2
feat: expose API for KV access
2 parents e649366 + 5295115 commit 37edf18

3 files changed

Lines changed: 52 additions & 1 deletion

File tree

src/writer/keyvalue_storage.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22
import os
33
from functools import partial
4-
from typing import Any, Dict, Literal, Optional, Protocol
4+
from typing import Any, Dict, List, Literal, Optional, Protocol
55

66
import httpx
77

@@ -42,6 +42,9 @@ def _get_agent_ids(self):
4242

4343
def get(self, key: str, type_: Literal["data", "secret"]) -> Dict[str, Any]:
4444
return self._request(partial(self._client.get, url=f"{self.api_url}/agent_{type_}/{key}")).json()
45+
46+
def get_data_keys(self) -> List[str]:
47+
return self._request(partial(self._client.get, url=f"{self.api_url}/agent_data")).json()["keys"]
4548

4649
def save(self, key: str, data: Any) -> Dict[str, Any]:
4750
try:

src/writer/serve.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
AppProcessServerResponse,
4848
AutogenRequestBody,
4949
ComponentUpdateRequestPayload,
50+
DeleteDataRequestBody,
5051
EventResponsePayload,
5152
HashRequestPayload,
5253
HashRequestResponsePayload,
@@ -55,6 +56,8 @@
5556
InitResponseBodyRun,
5657
InitSessionRequestPayload,
5758
InitSessionResponsePayload,
59+
RetrieveDataRequestBody,
60+
RetrieveDataResponseBody,
5861
ServeMode,
5962
StateEnquiryResponsePayload,
6063
WriterEvent,
@@ -290,6 +293,38 @@ async def autogen(requestBody: AutogenRequestBody, request: Request):
290293
agent_token_header
291294
)
292295

296+
@app.post("/api/data/retrieve")
297+
async def retrieve_data(requestBody: RetrieveDataRequestBody) -> RetrieveDataResponseBody:
298+
from writer.keyvalue_storage import writer_kv_storage
299+
300+
all_keys = writer_kv_storage.get_data_keys()
301+
302+
keys_to_fetch = []
303+
for key in all_keys:
304+
if key in requestBody.skip_keys:
305+
continue
306+
if requestBody.key_contains and requestBody.key_contains not in key:
307+
continue
308+
keys_to_fetch.append(key)
309+
310+
async def fetch_value(key: str):
311+
return key, await asyncio.to_thread(writer_kv_storage.get, key, "data")
312+
313+
kv_pairs = await asyncio.gather(*(fetch_value(key) for key in keys_to_fetch))
314+
315+
return RetrieveDataResponseBody(result={k: v["data"] for k, v in kv_pairs})
316+
317+
@app.post("/api/data/delete")
318+
async def delete_data(requestBody: DeleteDataRequestBody) -> None:
319+
from writer.keyvalue_storage import writer_kv_storage
320+
321+
async def delete_key(key: str):
322+
return key, await asyncio.to_thread(writer_kv_storage.delete, key)
323+
324+
await asyncio.gather(*(delete_key(key) for key in requestBody.keys))
325+
326+
return None
327+
293328
@app.post("/api/init")
294329
async def init(
295330
initBody: InitRequestBody, request: Request, response: Response

src/writer/ss_types.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ class AutogenRequestBody(BaseModel):
7979
description: str
8080

8181

82+
class RetrieveDataRequestBody(BaseModel):
83+
skip_keys: List[str] = []
84+
key_contains: Optional[str] = None
85+
86+
87+
class RetrieveDataResponseBody(BaseModel):
88+
result: Dict[str, Any]
89+
90+
91+
class DeleteDataRequestBody(BaseModel):
92+
keys: List[str]
93+
94+
8295
class InitRequestBody(BaseModel):
8396
proposedSessionId: Optional[str] = None
8497

0 commit comments

Comments
 (0)