agentscope-runtime 0.1.5b2__py3-none-any.whl → 0.1.6__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.
- agentscope_runtime/engine/agents/agentscope_agent.py +447 -0
- agentscope_runtime/engine/agents/agno_agent.py +19 -18
- agentscope_runtime/engine/agents/autogen_agent.py +13 -8
- agentscope_runtime/engine/agents/utils.py +53 -0
- agentscope_runtime/engine/deployers/__init__.py +0 -13
- agentscope_runtime/engine/deployers/local_deployer.py +501 -356
- agentscope_runtime/engine/helpers/helper.py +60 -41
- agentscope_runtime/engine/runner.py +11 -36
- agentscope_runtime/engine/schemas/agent_schemas.py +2 -70
- agentscope_runtime/engine/services/sandbox_service.py +62 -70
- agentscope_runtime/engine/services/tablestore_memory_service.py +304 -0
- agentscope_runtime/engine/services/tablestore_rag_service.py +143 -0
- agentscope_runtime/engine/services/tablestore_session_history_service.py +293 -0
- agentscope_runtime/engine/services/utils/tablestore_service_utils.py +352 -0
- agentscope_runtime/sandbox/__init__.py +2 -0
- agentscope_runtime/sandbox/box/base/__init__.py +4 -0
- agentscope_runtime/sandbox/box/base/base_sandbox.py +4 -3
- agentscope_runtime/sandbox/box/browser/__init__.py +4 -0
- agentscope_runtime/sandbox/box/browser/browser_sandbox.py +8 -13
- agentscope_runtime/sandbox/box/dummy/__init__.py +4 -0
- agentscope_runtime/sandbox/box/filesystem/__init__.py +4 -0
- agentscope_runtime/sandbox/box/filesystem/filesystem_sandbox.py +8 -6
- agentscope_runtime/sandbox/box/gui/__init__.py +4 -0
- agentscope_runtime/sandbox/box/gui/gui_sandbox.py +80 -0
- agentscope_runtime/sandbox/box/sandbox.py +5 -2
- agentscope_runtime/sandbox/box/shared/routers/generic.py +20 -1
- agentscope_runtime/sandbox/box/training_box/__init__.py +4 -0
- agentscope_runtime/sandbox/box/training_box/training_box.py +10 -15
- agentscope_runtime/sandbox/build.py +143 -58
- agentscope_runtime/sandbox/client/http_client.py +43 -49
- agentscope_runtime/sandbox/client/training_client.py +0 -1
- agentscope_runtime/sandbox/constant.py +24 -1
- agentscope_runtime/sandbox/custom/custom_sandbox.py +5 -5
- agentscope_runtime/sandbox/custom/example.py +2 -2
- agentscope_runtime/sandbox/enums.py +1 -0
- agentscope_runtime/sandbox/manager/collections/in_memory_mapping.py +11 -6
- agentscope_runtime/sandbox/manager/collections/redis_mapping.py +25 -9
- agentscope_runtime/sandbox/manager/container_clients/__init__.py +0 -10
- agentscope_runtime/sandbox/manager/container_clients/agentrun_client.py +1098 -0
- agentscope_runtime/sandbox/manager/container_clients/docker_client.py +33 -205
- agentscope_runtime/sandbox/manager/container_clients/kubernetes_client.py +8 -555
- agentscope_runtime/sandbox/manager/sandbox_manager.py +187 -88
- agentscope_runtime/sandbox/manager/server/app.py +82 -14
- agentscope_runtime/sandbox/manager/server/config.py +50 -3
- agentscope_runtime/sandbox/model/container.py +6 -23
- agentscope_runtime/sandbox/model/manager_config.py +93 -5
- agentscope_runtime/sandbox/tools/gui/__init__.py +7 -0
- agentscope_runtime/sandbox/tools/gui/tool.py +77 -0
- agentscope_runtime/sandbox/tools/mcp_tool.py +6 -2
- agentscope_runtime/sandbox/utils.py +124 -0
- agentscope_runtime/version.py +1 -1
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/METADATA +168 -77
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/RECORD +59 -78
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/entry_points.txt +0 -1
- agentscope_runtime/engine/agents/agentscope_agent/__init__.py +0 -6
- agentscope_runtime/engine/agents/agentscope_agent/agent.py +0 -401
- agentscope_runtime/engine/agents/agentscope_agent/hooks.py +0 -169
- agentscope_runtime/engine/agents/llm_agent.py +0 -51
- agentscope_runtime/engine/deployers/adapter/responses/response_api_adapter_utils.py +0 -2886
- agentscope_runtime/engine/deployers/adapter/responses/response_api_agent_adapter.py +0 -51
- agentscope_runtime/engine/deployers/adapter/responses/response_api_protocol_adapter.py +0 -314
- agentscope_runtime/engine/deployers/cli_fc_deploy.py +0 -184
- agentscope_runtime/engine/deployers/kubernetes_deployer.py +0 -265
- agentscope_runtime/engine/deployers/modelstudio_deployer.py +0 -677
- agentscope_runtime/engine/deployers/utils/deployment_modes.py +0 -14
- agentscope_runtime/engine/deployers/utils/docker_image_utils/__init__.py +0 -8
- agentscope_runtime/engine/deployers/utils/docker_image_utils/docker_image_builder.py +0 -429
- agentscope_runtime/engine/deployers/utils/docker_image_utils/dockerfile_generator.py +0 -240
- agentscope_runtime/engine/deployers/utils/docker_image_utils/runner_image_factory.py +0 -297
- agentscope_runtime/engine/deployers/utils/package_project_utils.py +0 -932
- agentscope_runtime/engine/deployers/utils/service_utils/__init__.py +0 -9
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_factory.py +0 -504
- agentscope_runtime/engine/deployers/utils/service_utils/fastapi_templates.py +0 -157
- agentscope_runtime/engine/deployers/utils/service_utils/process_manager.py +0 -268
- agentscope_runtime/engine/deployers/utils/service_utils/service_config.py +0 -75
- agentscope_runtime/engine/deployers/utils/service_utils/service_factory.py +0 -220
- agentscope_runtime/engine/deployers/utils/wheel_packager.py +0 -389
- agentscope_runtime/engine/helpers/agent_api_builder.py +0 -651
- agentscope_runtime/engine/llms/__init__.py +0 -3
- agentscope_runtime/engine/llms/base_llm.py +0 -60
- agentscope_runtime/engine/llms/qwen_llm.py +0 -47
- agentscope_runtime/engine/schemas/embedding.py +0 -37
- agentscope_runtime/engine/schemas/modelstudio_llm.py +0 -310
- agentscope_runtime/engine/schemas/oai_llm.py +0 -538
- agentscope_runtime/engine/schemas/realtime.py +0 -254
- /agentscope_runtime/engine/{deployers/adapter/responses → services/utils}/__init__.py +0 -0
- /agentscope_runtime/{engine/deployers/utils → sandbox/box/gui/box}/__init__.py +0 -0
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/WHEEL +0 -0
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {agentscope_runtime-0.1.5b2.dist-info → agentscope_runtime-0.1.6.dist-info}/top_level.txt +0 -0
|
@@ -3,13 +3,12 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
import time
|
|
5
5
|
from typing import Any, Optional
|
|
6
|
+
from urllib.parse import urljoin
|
|
6
7
|
|
|
7
8
|
import requests
|
|
8
9
|
from pydantic import Field
|
|
9
|
-
from steel import Steel
|
|
10
10
|
|
|
11
11
|
from ..model import ContainerModel
|
|
12
|
-
from ..constant import BROWSER_SESSION_ID
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
logging.getLogger("httpx").setLevel(logging.CRITICAL)
|
|
@@ -69,8 +68,7 @@ class SandboxHttpClient:
|
|
|
69
68
|
def __init__(
|
|
70
69
|
self,
|
|
71
70
|
model: Optional[ContainerModel] = None,
|
|
72
|
-
timeout: int =
|
|
73
|
-
enable_browser: bool = True,
|
|
71
|
+
timeout: int = 60,
|
|
74
72
|
domain: str = "localhost",
|
|
75
73
|
) -> None:
|
|
76
74
|
"""
|
|
@@ -81,49 +79,28 @@ class SandboxHttpClient:
|
|
|
81
79
|
runtime sandbox.
|
|
82
80
|
"""
|
|
83
81
|
self.session_id = model.session_id
|
|
84
|
-
self.base_url =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
"localhost",
|
|
88
|
-
domain,
|
|
82
|
+
self.base_url = urljoin(
|
|
83
|
+
model.url.replace("localhost", domain),
|
|
84
|
+
"fastapi",
|
|
89
85
|
)
|
|
90
86
|
|
|
91
|
-
self.enable_browser = enable_browser
|
|
92
87
|
self.timeout = timeout
|
|
93
88
|
self.session = requests.Session()
|
|
94
89
|
self.built_in_tools = []
|
|
95
90
|
self.secret = model.runtime_token
|
|
96
91
|
|
|
97
92
|
# Update headers with secret if provided
|
|
98
|
-
headers = {
|
|
93
|
+
headers = {
|
|
94
|
+
"Content-Type": "application/json",
|
|
95
|
+
"x-agentrun-session-id": "s" + self.session_id,
|
|
96
|
+
}
|
|
99
97
|
if self.secret:
|
|
100
98
|
headers["Authorization"] = f"Bearer {self.secret}"
|
|
101
99
|
self.session.headers.update(headers)
|
|
102
100
|
|
|
103
|
-
self.steel_client = None
|
|
104
|
-
|
|
105
101
|
def __enter__(self):
|
|
106
102
|
# Wait for the runtime api server to be healthy
|
|
107
103
|
self.wait_until_healthy()
|
|
108
|
-
|
|
109
|
-
if self.enable_browser:
|
|
110
|
-
self.steel_client = Steel(
|
|
111
|
-
steel_api_key="dummy",
|
|
112
|
-
base_url=self.browser_url,
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
# Create a new browser session if it doesn't exist
|
|
116
|
-
try:
|
|
117
|
-
# Try to connet to existing session
|
|
118
|
-
self.steel_client.sessions.retrieve(
|
|
119
|
-
BROWSER_SESSION_ID,
|
|
120
|
-
)
|
|
121
|
-
except Exception:
|
|
122
|
-
# Session not found, create a new one
|
|
123
|
-
self.steel_client.sessions.create(
|
|
124
|
-
session_id=BROWSER_SESSION_ID,
|
|
125
|
-
)
|
|
126
|
-
|
|
127
104
|
return self
|
|
128
105
|
|
|
129
106
|
def __exit__(self, exc_type, exc_value, traceback):
|
|
@@ -138,17 +115,9 @@ class SandboxHttpClient:
|
|
|
138
115
|
bool: True if the service is reachable, False otherwise
|
|
139
116
|
"""
|
|
140
117
|
endpoint = f"{self.base_url}/healthz"
|
|
141
|
-
browser_endpoint = f"{self.browser_url}/v1/health"
|
|
142
118
|
try:
|
|
143
119
|
response_api = self.session.get(endpoint)
|
|
144
|
-
|
|
145
|
-
response_browser = self.session.get(browser_endpoint)
|
|
146
|
-
return (
|
|
147
|
-
response_api.status_code == 200
|
|
148
|
-
and response_browser.status_code == 200
|
|
149
|
-
)
|
|
150
|
-
else:
|
|
151
|
-
return response_api.status_code == 200
|
|
120
|
+
return response_api.status_code == 200
|
|
152
121
|
except requests.RequestException:
|
|
153
122
|
return False
|
|
154
123
|
|
|
@@ -246,7 +215,10 @@ class SandboxHttpClient:
|
|
|
246
215
|
"""Run an IPython cell."""
|
|
247
216
|
try:
|
|
248
217
|
endpoint = f"{self.base_url}/tools/run_ipython_cell"
|
|
249
|
-
response = self.session.post(
|
|
218
|
+
response = self.session.post(
|
|
219
|
+
endpoint,
|
|
220
|
+
json={"code": code},
|
|
221
|
+
)
|
|
250
222
|
response.raise_for_status()
|
|
251
223
|
return response.json()
|
|
252
224
|
except requests.exceptions.RequestException as e:
|
|
@@ -379,7 +351,11 @@ class SandboxHttpClient:
|
|
|
379
351
|
endpoint = f"{self.base_url}/workspace/files"
|
|
380
352
|
params = {"file_path": file_path}
|
|
381
353
|
data = {"content": content}
|
|
382
|
-
response = self.session.post(
|
|
354
|
+
response = self.session.post(
|
|
355
|
+
endpoint,
|
|
356
|
+
params=params,
|
|
357
|
+
json=data,
|
|
358
|
+
)
|
|
383
359
|
response.raise_for_status()
|
|
384
360
|
return response.json()
|
|
385
361
|
except requests.exceptions.RequestException as e:
|
|
@@ -402,7 +378,10 @@ class SandboxHttpClient:
|
|
|
402
378
|
try:
|
|
403
379
|
endpoint = f"{self.base_url}/workspace/list-directories"
|
|
404
380
|
params = {"directory": directory}
|
|
405
|
-
response = self.session.get(
|
|
381
|
+
response = self.session.get(
|
|
382
|
+
endpoint,
|
|
383
|
+
params=params,
|
|
384
|
+
)
|
|
406
385
|
response.raise_for_status()
|
|
407
386
|
return response.json()
|
|
408
387
|
except requests.exceptions.RequestException as e:
|
|
@@ -419,7 +398,10 @@ class SandboxHttpClient:
|
|
|
419
398
|
try:
|
|
420
399
|
endpoint = f"{self.base_url}/workspace/directories"
|
|
421
400
|
params = {"directory_path": directory_path}
|
|
422
|
-
response = self.session.post(
|
|
401
|
+
response = self.session.post(
|
|
402
|
+
endpoint,
|
|
403
|
+
params=params,
|
|
404
|
+
)
|
|
423
405
|
response.raise_for_status()
|
|
424
406
|
return response.json()
|
|
425
407
|
except requests.exceptions.RequestException as e:
|
|
@@ -438,7 +420,10 @@ class SandboxHttpClient:
|
|
|
438
420
|
try:
|
|
439
421
|
endpoint = f"{self.base_url}/workspace/files"
|
|
440
422
|
params = {"file_path": file_path}
|
|
441
|
-
response = self.session.delete(
|
|
423
|
+
response = self.session.delete(
|
|
424
|
+
endpoint,
|
|
425
|
+
params=params,
|
|
426
|
+
)
|
|
442
427
|
response.raise_for_status()
|
|
443
428
|
return response.json()
|
|
444
429
|
except requests.exceptions.RequestException as e:
|
|
@@ -461,7 +446,10 @@ class SandboxHttpClient:
|
|
|
461
446
|
try:
|
|
462
447
|
endpoint = f"{self.base_url}/workspace/directories"
|
|
463
448
|
params = {"directory_path": directory_path, "recursive": recursive}
|
|
464
|
-
response = self.session.delete(
|
|
449
|
+
response = self.session.delete(
|
|
450
|
+
endpoint,
|
|
451
|
+
params=params,
|
|
452
|
+
)
|
|
465
453
|
response.raise_for_status()
|
|
466
454
|
return response.json()
|
|
467
455
|
except requests.exceptions.RequestException as e:
|
|
@@ -487,7 +475,10 @@ class SandboxHttpClient:
|
|
|
487
475
|
"source_path": source_path,
|
|
488
476
|
"destination_path": destination_path,
|
|
489
477
|
}
|
|
490
|
-
response = self.session.put(
|
|
478
|
+
response = self.session.put(
|
|
479
|
+
endpoint,
|
|
480
|
+
params=params,
|
|
481
|
+
)
|
|
491
482
|
response.raise_for_status()
|
|
492
483
|
return response.json()
|
|
493
484
|
except requests.exceptions.RequestException as e:
|
|
@@ -514,7 +505,10 @@ class SandboxHttpClient:
|
|
|
514
505
|
"source_path": source_path,
|
|
515
506
|
"destination_path": destination_path,
|
|
516
507
|
}
|
|
517
|
-
response = self.session.post(
|
|
508
|
+
response = self.session.post(
|
|
509
|
+
endpoint,
|
|
510
|
+
params=params,
|
|
511
|
+
)
|
|
518
512
|
response.raise_for_status()
|
|
519
513
|
return response.json()
|
|
520
514
|
except requests.exceptions.RequestException as e:
|
|
@@ -212,7 +212,6 @@ class TrainingSandboxClient:
|
|
|
212
212
|
def list_tools(self, **kwargs):
|
|
213
213
|
"""list tools"""
|
|
214
214
|
if "instance_id" in kwargs:
|
|
215
|
-
# 只传get_tools_info的方法参数
|
|
216
215
|
return self.get_tools_info(
|
|
217
216
|
instance_id=kwargs.get("instance_id"),
|
|
218
217
|
messages=kwargs.get("messages", {}),
|
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import os
|
|
3
|
+
import sys
|
|
4
|
+
import logging
|
|
3
5
|
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
# Image Registry: default "", means using Docker Hub.
|
|
9
|
+
# For AgentScope official registry, use
|
|
10
|
+
# "agentscope-registry.ap-southeast-1.cr.aliyuncs.com"
|
|
11
|
+
REGISTRY = os.getenv("RUNTIME_SANDBOX_REGISTRY", "")
|
|
12
|
+
if REGISTRY == "":
|
|
13
|
+
agentscope_acr = "agentscope-registry.ap-southeast-1.cr.aliyuncs.com"
|
|
14
|
+
if sys.platform.startswith("win"):
|
|
15
|
+
cmd = f"set RUNTIME_SANDBOX_REGISTRY={agentscope_acr}"
|
|
16
|
+
else:
|
|
17
|
+
cmd = f"export RUNTIME_SANDBOX_REGISTRY={agentscope_acr}"
|
|
18
|
+
logger.warning(
|
|
19
|
+
"Using Docker Hub as image registry. If pulling is slow or fails, "
|
|
20
|
+
f"you can switch to the AgentScope official registry by running:\n "
|
|
21
|
+
f"{cmd}\n",
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# Image Namespace
|
|
25
|
+
IMAGE_NAMESPACE = os.getenv("RUNTIME_SANDBOX_IMAGE_NAMESPACE", "agentscope")
|
|
26
|
+
|
|
27
|
+
# Image Tag
|
|
4
28
|
IMAGE_TAG = os.getenv("RUNTIME_SANDBOX_IMAGE_TAG", "latest")
|
|
5
|
-
BROWSER_SESSION_ID = "123e4567-e89b-12d3-a456-426614174000"
|
|
@@ -3,17 +3,17 @@ import os
|
|
|
3
3
|
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
|
-
from ..
|
|
6
|
+
from ..utils import build_image_uri
|
|
7
7
|
from ..registry import SandboxRegistry
|
|
8
8
|
from ..enums import SandboxType
|
|
9
9
|
from ..box.sandbox import Sandbox
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
SANDBOX_TYPE = "custom_sandbox"
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
@SandboxRegistry.register(
|
|
15
|
-
f"
|
|
16
|
-
sandbox_type=
|
|
15
|
+
build_image_uri(f"runtime-sandbox-{SANDBOX_TYPE}"),
|
|
16
|
+
sandbox_type=SANDBOX_TYPE,
|
|
17
17
|
security_level="medium",
|
|
18
18
|
timeout=60,
|
|
19
19
|
description="my sandbox",
|
|
@@ -35,5 +35,5 @@ class CustomSandbox(Sandbox):
|
|
|
35
35
|
timeout,
|
|
36
36
|
base_url,
|
|
37
37
|
bearer_token,
|
|
38
|
-
SandboxType(
|
|
38
|
+
SandboxType(SANDBOX_TYPE),
|
|
39
39
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
from typing import Optional
|
|
3
3
|
|
|
4
|
-
from ..
|
|
4
|
+
from ..utils import build_image_uri
|
|
5
5
|
from ..registry import SandboxRegistry
|
|
6
6
|
from ..enums import SandboxType
|
|
7
7
|
from ..box.sandbox import Sandbox
|
|
@@ -10,7 +10,7 @@ SANDBOX_TYPE = "example"
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@SandboxRegistry.register(
|
|
13
|
-
f"
|
|
13
|
+
build_image_uri(f"runtime-sandbox-{SANDBOX_TYPE}"),
|
|
14
14
|
sandbox_type=SANDBOX_TYPE,
|
|
15
15
|
security_level="medium",
|
|
16
16
|
timeout=60,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
2
4
|
from .base_mapping import Mapping
|
|
3
5
|
|
|
4
6
|
|
|
@@ -6,17 +8,20 @@ class InMemoryMapping(Mapping):
|
|
|
6
8
|
def __init__(self):
|
|
7
9
|
self.store = {}
|
|
8
10
|
|
|
9
|
-
def set(self, key: str, value:
|
|
11
|
+
def set(self, key: str, value: Any):
|
|
10
12
|
self.store[key] = value
|
|
11
13
|
|
|
12
|
-
def get(self, key: str) ->
|
|
14
|
+
def get(self, key: str) -> Any:
|
|
13
15
|
return self.store.get(key)
|
|
14
16
|
|
|
15
17
|
def delete(self, key: str):
|
|
16
18
|
if key in self.store:
|
|
17
19
|
del self.store[key]
|
|
18
20
|
|
|
19
|
-
def scan(self, prefix: str):
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
def scan(self, prefix: str = None):
|
|
22
|
+
if prefix is None:
|
|
23
|
+
yield from list(self.store.keys())
|
|
24
|
+
else:
|
|
25
|
+
yield from list(
|
|
26
|
+
key for key in self.store if key.startswith(prefix)
|
|
27
|
+
)
|
|
@@ -1,26 +1,42 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
import json
|
|
3
3
|
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
4
6
|
from .base_mapping import Mapping
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
class RedisMapping(Mapping):
|
|
8
|
-
def __init__(self, redis_client):
|
|
10
|
+
def __init__(self, redis_client, prefix: str = ""):
|
|
9
11
|
self.client = redis_client
|
|
12
|
+
self.prefix = prefix.rstrip(":") + ":" if prefix else ""
|
|
13
|
+
|
|
14
|
+
def _get_full_key(self, key: str) -> str:
|
|
15
|
+
return f"{self.prefix}{key}"
|
|
16
|
+
|
|
17
|
+
def _strip_prefix(self, full_key: str) -> str:
|
|
18
|
+
if self.prefix and full_key.startswith(self.prefix):
|
|
19
|
+
return full_key[len(self.prefix) :]
|
|
20
|
+
return full_key
|
|
10
21
|
|
|
11
|
-
def set(self, key: str, value:
|
|
12
|
-
self.client.set(key, json.dumps(value))
|
|
22
|
+
def set(self, key: str, value: Any):
|
|
23
|
+
self.client.set(self._get_full_key(key), json.dumps(value))
|
|
13
24
|
|
|
14
|
-
def get(self, key: str) ->
|
|
15
|
-
value = self.client.get(key)
|
|
25
|
+
def get(self, key: str) -> Any:
|
|
26
|
+
value = self.client.get(self._get_full_key(key))
|
|
16
27
|
return json.loads(value) if value else None
|
|
17
28
|
|
|
18
29
|
def delete(self, key: str):
|
|
19
|
-
self.client.delete(key)
|
|
30
|
+
self.client.delete(self._get_full_key(key))
|
|
20
31
|
|
|
21
|
-
def scan(self, prefix: str):
|
|
32
|
+
def scan(self, prefix: str = ""):
|
|
33
|
+
search_pattern = f"{self._get_full_key(prefix)}*"
|
|
22
34
|
cursor = 0
|
|
23
35
|
while cursor != 0:
|
|
24
|
-
cursor, keys = self.client.scan(
|
|
36
|
+
cursor, keys = self.client.scan(
|
|
37
|
+
cursor=cursor,
|
|
38
|
+
match=search_pattern,
|
|
39
|
+
)
|
|
25
40
|
for key in keys:
|
|
26
|
-
|
|
41
|
+
decoded_key = key.decode("utf-8")
|
|
42
|
+
yield self._strip_prefix(decoded_key)
|