Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,5 @@ cython_debug/
#.idea/

.vscode
.ruff_cache
.ruff_cache
examples/test*
39 changes: 38 additions & 1 deletion bk_bscp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.
"""The client for bscp feed-server"""

import json
import logging
import random
Expand All @@ -36,7 +37,7 @@
)
from bk_bscp.grpc_lib.core.base import base_pb2
from bk_bscp.grpc_lib.feed_server import feed_server_pb2, feed_server_pb2_grpc
from bk_bscp.models import KeyValuePair, KeyValueUpdatedEvent, WatchAppInputParams
from bk_bscp.models import AppOptions, KeyValuePair, KeyValueUpdatedEvent, Release, WatchAppInputParams
from bk_bscp.utils import get_fingerprint

logger = logging.getLogger("bk_bscp")
Expand Down Expand Up @@ -153,6 +154,42 @@ def do_handshake(self):
raise BscpClientHandshakeError("Unable to handshake", e) from e
logger.debug("Handshake success, api_version: %s", response.api_version)

def pull_kvs(self, app: str, match: List[str], app_options: Optional[AppOptions] = None) -> Release:
"""Pull key-value Release from the server.
:param app: The app name.
:param match: The key.
:param app_options: the app option params.
:return: A kv Release.
:raises BscpClientGetError: If get failed.
"""
total_labels = {**self.labels}
uid = self._fingerprint

if app_options is not None:
uid = app_options.uid or self._fingerprint
total_labels = {**self.labels, **(app_options.labels or {})}
match = [*match, *(app_options.match or [])]

msg = feed_server_pb2.PullKvMetaReq(
match=match,
biz_id=self.biz_id,
app_meta=feed_server_pb2.AppMeta(
uid=uid,
app=app,
labels=total_labels,
),
)
try:
response = self.stub.PullKvMeta(msg, metadata=self._get_req_metadata())
except grpc.RpcError as e:
raise BscpClientGetError(f'Unable to get "{app}" release, details: {e.details()}', e) from e

r = Release(
release_id=response.release_id,
kvs=response.kv_metas,
)
return r

def get(self, app: str, key: str, labels: Optional[dict] = None) -> KeyValuePair:
"""Get a key-value pair from the server.

Expand Down
18 changes: 18 additions & 0 deletions bk_bscp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from dataclasses import dataclass
from typing import Any, Dict, List

from bk_bscp.grpc_lib.feed_server import feed_server_pb2
from bk_bscp.utils import dict_to_dataclass


Expand Down Expand Up @@ -73,3 +74,20 @@ class KeyValuePair:
key: str
type: str
value: Any


@dataclass
class AppOptions:
"""AppOptions options for app pull and watch"""

match: List[str] # Match matches config items
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:考虑直接在类的 docstring 里面写字段说明

labels: Dict[str, str] # Labels instance labels
uid: str # UID instance unique uid


@dataclass
class Release:
"""Release info returned by the bscp server."""

release_id: int
kvs: List[feed_server_pb2.KvMeta]
19 changes: 17 additions & 2 deletions examples/get_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.
"""Get a key."""
from bk_bscp.client import BscpClient

from bk_bscp.client import AppOptions, BscpClient

SERVER_ADDRS = ["example.com:9090"]
TOKEN = "your_token"
Expand All @@ -27,6 +28,20 @@ def get_key():
print(pair)


def get_all_keys():
app = AppOptions(
match=[],
labels={},
uid="",
)

with BscpClient(SERVER_ADDRS, TOKEN, BIZ_ID) as client:
release = client.pull_kvs("app1", ["key1"], app)
for kv in release.kvs:
pair = client.get("app1", kv.key)
print(pair)


def get_key_with_labels():
"""Get a key with labels specified."""
#
Expand All @@ -42,7 +57,7 @@ def get_key_with_labels():


def main():
get_key()
get_all_keys()


if __name__ == "__main__":
Expand Down
13 changes: 13 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ with BscpClient(server_addrs, token, biz_id) as client:

### 开发指南

安装环境

```bash
# 安装版本, 修改{version}为版本号, 如3.18, 如果已经有版本,步骤忽略
uv python install {version}

# 创建环境, 修改{path}为python真实路径
uv venv -p {path}/python

# 安装依赖
uv sync --frozen
```

执行单元测试:

```bash
Expand Down
14 changes: 14 additions & 0 deletions readme_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ For more sample code, please refer to the examples/ directory.

### Development Guide

Installation environment
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:英文翻译不太准确


```bash
# Install version, modify {version} to real version, such as 3.18. If there is already a version, ignore this step
uv python install {version}

# Create environment, modify {path} to the real path of python

uv venv -p {path}/python

# Install dependencies
uv sync --frozen
```

Execute unit tests:

```bash
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading