Skip to content

Commit

Permalink
client options and doc classes, proto generated schema code
Browse files Browse the repository at this point in the history
  • Loading branch information
pushkarmoi committed Mar 20, 2024
1 parent b1fceb9 commit 5ec4a17
Show file tree
Hide file tree
Showing 14 changed files with 979 additions and 4 deletions.
8 changes: 8 additions & 0 deletions ikv-python-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Generating python code from proto:

$> python3 -m pip install grpcio-tools

$> pwd
/Users/pushkar/projects/ikv-store/ikv-python-client/ikv-py

$> python3 -m grpc_tools.protoc -I../../ikv-cloud/src/main/proto --python_out=./schemas --pyi_out=./schemas --grpc_python_out=./schemas ../../ikv-cloud/src/main/proto/*.proto
1 change: 1 addition & 0 deletions ikv-python-client/ikv-py/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from clientoptions import ClientOptions
from document import IKVDocument
from typing import List, Tuple
from schemas.services_pb2 import HelloWorldRequest

class IKVReader(ABC):
"""
Expand Down
63 changes: 61 additions & 2 deletions ikv-python-client/ikv-py/clientoptions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,62 @@
# todo
from schemas.common_pb2 import IKVStoreConfig
import utils as ikvutils

class ClientOptions:
pass
_VALID_LOG_LEVELS = {"error", "warn", "info", "debug", "trace"}

def __init__(self, ikv_config: IKVStoreConfig):
self.ikv_config = ikv_config

class ClientOptionsBuilder:
def __init__(self):
# initialize ikvconfig proto object
ikv_config = IKVStoreConfig()
ikv_config.stringConfigs = {}
ikv_config.intConfigs = {}
ikv_config.floatConfigs = {}
ikv_config.bytesConfigs = {}
ikv_config.booleanConfigs = {}

# default logging options
ikv_config.stringConfigs["rust_client_log_level"] = "info"
ikv_config.booleanConfigs["rust_client_log_to_console"] = True

self.ikv_config: IKVStoreConfig = ikv_config

def with_mount_directory(self, dir: str) -> 'ClientOptionsBuilder':
self.ikv_config.stringConfigs["mount_directory"] = ikvutils.is_valid_str_or_raise(dir)
return self

def with_store_name(self, name: str) -> 'ClientOptionsBuilder':
self.ikv_config.stringConfigs["store_name"] = ikvutils.is_valid_str_or_raise(name)
return self

def with_account_id(self, id: str) -> 'ClientOptionsBuilder':
self.ikv_config.stringConfigs["account_id"] = ikvutils.is_valid_str_or_raise(id)
return self

def with_account_passkey(self, passkey: str) -> 'ClientOptionsBuilder':
self.ikv_config.stringConfigs["account_passkey"] = ikvutils.is_valid_str_or_raise(passkey)
return self

def with_console_logging(self, level: str) -> 'ClientOptionsBuilder':
level = ikvutils.is_valid_str_or_raise(level).lower()
if not level in ClientOptions._VALID_LOG_LEVELS:
raise ValueError("not a valid log level, valid levels: " + ", ".join(ClientOptions._VALID_LOG_LEVELS))

self.ikv_config.stringConfigs["rust_client_log_level"] = level
self.ikv_config.booleanConfigs["rust_client_log_to_console"] = True
return self

def with_file_logging(self, level: str, filepath: str) -> 'ClientOptionsBuilder':
level = ikvutils.is_valid_str_or_raise(level).lower()
if not level in ClientOptions._VALID_LOG_LEVELS:
raise ValueError("not a valid log level, valid levels: " + ", ".join(ClientOptions._VALID_LOG_LEVELS))

self.ikv_config.stringConfigs["rust_client_log_level"] = level
self.ikv_config.booleanConfigs["rust_client_log_to_console"] = False
self.ikv_config.stringConfigs["rust_client_log_file"] = ikvutils.is_valid_str_or_raise(filepath)
return self

def build(self) -> ClientOptions:
return ClientOptions(self.ikv_config)
35 changes: 33 additions & 2 deletions ikv-python-client/ikv-py/document.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
# todo
from typing import Dict
from schemas.common_pb2 import FieldValue
from schemas.common_pb2 import STRING as FieldValueString
from schemas.common_pb2 import BYTES as FieldValueBytes
import utils as ikvutils

class IKVDocument:
pass
def __init__(self, fields: Dict[str, FieldValue]):
self.fields: Dict[str, FieldValue] = fields

class IKVDocumentBuilder:
def __init__(self):
self.fields: Dict[str, FieldValue] = {}

def put_string_field(self, name: str, value: str) -> 'IKVDocumentBuilder':
name: str = ikvutils.is_valid_str_or_raise(name)
value: bytes = ikvutils.is_valid_str_or_raise(value).encode('utf-8')

field_value: FieldValue = FieldValue(fieldType=FieldValueString, value=value)
self.fields[name] = field_value

return self

def put_bytes_field(self, name: str, value: bytes) -> 'IKVDocumentBuilder':
name: str = ikvutils.is_valid_str_or_raise(name)
value: bytes = ikvutils.is_valid_bytes_or_raise(value)

field_value: FieldValue = FieldValue(fieldType=FieldValueBytes, value=value)
self.fields[name] = field_value

return self

def build(self) -> IKVDocument:
return IKVDocument(fields=self.fields)
57 changes: 57 additions & 0 deletions ikv-python-client/ikv-py/schemas/common_pb2.py

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

96 changes: 96 additions & 0 deletions ikv-python-client/ikv-py/schemas/common_pb2.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
from google.protobuf.internal import containers as _containers
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union

DESCRIPTOR: _descriptor.FileDescriptor

class FieldType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = ()
UNKNOWN: _ClassVar[FieldType]
INT32: _ClassVar[FieldType]
INT64: _ClassVar[FieldType]
FLOAT32: _ClassVar[FieldType]
FLOAT64: _ClassVar[FieldType]
STRING: _ClassVar[FieldType]
BYTES: _ClassVar[FieldType]
BOOLEAN: _ClassVar[FieldType]
UNKNOWN: FieldType
INT32: FieldType
INT64: FieldType
FLOAT32: FieldType
FLOAT64: FieldType
STRING: FieldType
BYTES: FieldType
BOOLEAN: FieldType

class IKVDocumentOnWire(_message.Message):
__slots__ = ("document",)
class DocumentEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: FieldValue
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[FieldValue, _Mapping]] = ...) -> None: ...
DOCUMENT_FIELD_NUMBER: _ClassVar[int]
document: _containers.MessageMap[str, FieldValue]
def __init__(self, document: _Optional[_Mapping[str, FieldValue]] = ...) -> None: ...

class FieldValue(_message.Message):
__slots__ = ("fieldType", "value")
FIELDTYPE_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
fieldType: FieldType
value: bytes
def __init__(self, fieldType: _Optional[_Union[FieldType, str]] = ..., value: _Optional[bytes] = ...) -> None: ...

class IKVStoreConfig(_message.Message):
__slots__ = ("stringConfigs", "intConfigs", "floatConfigs", "bytesConfigs", "booleanConfigs")
class StringConfigsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: str
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
class IntConfigsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: int
def __init__(self, key: _Optional[str] = ..., value: _Optional[int] = ...) -> None: ...
class FloatConfigsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: float
def __init__(self, key: _Optional[str] = ..., value: _Optional[float] = ...) -> None: ...
class BytesConfigsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: bytes
def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ...
class BooleanConfigsEntry(_message.Message):
__slots__ = ("key", "value")
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: bool
def __init__(self, key: _Optional[str] = ..., value: bool = ...) -> None: ...
STRINGCONFIGS_FIELD_NUMBER: _ClassVar[int]
INTCONFIGS_FIELD_NUMBER: _ClassVar[int]
FLOATCONFIGS_FIELD_NUMBER: _ClassVar[int]
BYTESCONFIGS_FIELD_NUMBER: _ClassVar[int]
BOOLEANCONFIGS_FIELD_NUMBER: _ClassVar[int]
stringConfigs: _containers.ScalarMap[str, str]
intConfigs: _containers.ScalarMap[str, int]
floatConfigs: _containers.ScalarMap[str, float]
bytesConfigs: _containers.ScalarMap[str, bytes]
booleanConfigs: _containers.ScalarMap[str, bool]
def __init__(self, stringConfigs: _Optional[_Mapping[str, str]] = ..., intConfigs: _Optional[_Mapping[str, int]] = ..., floatConfigs: _Optional[_Mapping[str, float]] = ..., bytesConfigs: _Optional[_Mapping[str, bytes]] = ..., booleanConfigs: _Optional[_Mapping[str, bool]] = ...) -> None: ...
4 changes: 4 additions & 0 deletions ikv-python-client/ikv-py/schemas/common_pb2_grpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc

Loading

0 comments on commit 5ec4a17

Please sign in to comment.