digitalkin 0.2.4__py3-none-any.whl → 0.2.5__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.
- digitalkin/__version__.py +1 -1
- digitalkin/grpc_servers/module_server.py +65 -30
- digitalkin/grpc_servers/module_servicer.py +2 -1
- digitalkin/grpc_servers/utils/grpc_client_wrapper.py +18 -12
- digitalkin/grpc_servers/utils/models.py +124 -32
- digitalkin/services/setup/grpc_setup.py +2 -2
- {digitalkin-0.2.4.dist-info → digitalkin-0.2.5.dist-info}/METADATA +2 -1
- {digitalkin-0.2.4.dist-info → digitalkin-0.2.5.dist-info}/RECORD +11 -11
- {digitalkin-0.2.4.dist-info → digitalkin-0.2.5.dist-info}/WHEEL +0 -0
- {digitalkin-0.2.4.dist-info → digitalkin-0.2.5.dist-info}/licenses/LICENSE +0 -0
- {digitalkin-0.2.4.dist-info → digitalkin-0.2.5.dist-info}/top_level.txt +0 -0
digitalkin/__version__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Module gRPC server implementation for DigitalKin."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
from pathlib import Path
|
|
4
5
|
import uuid
|
|
5
6
|
|
|
6
7
|
import grpc
|
|
@@ -8,7 +9,11 @@ import grpc
|
|
|
8
9
|
from digitalkin.grpc_servers._base_server import BaseServer
|
|
9
10
|
from digitalkin.grpc_servers.module_servicer import ModuleServicer
|
|
10
11
|
from digitalkin.grpc_servers.utils.exceptions import ServerError
|
|
11
|
-
from digitalkin.grpc_servers.utils.models import
|
|
12
|
+
from digitalkin.grpc_servers.utils.models import (
|
|
13
|
+
ClientConfig,
|
|
14
|
+
ModuleServerConfig,
|
|
15
|
+
SecurityMode,
|
|
16
|
+
)
|
|
12
17
|
from digitalkin.modules._base_module import BaseModule
|
|
13
18
|
|
|
14
19
|
from digitalkin_proto.digitalkin.module.v2 import (
|
|
@@ -32,14 +37,16 @@ class ModuleServer(BaseServer):
|
|
|
32
37
|
|
|
33
38
|
Attributes:
|
|
34
39
|
module: The module instance being served.
|
|
35
|
-
|
|
40
|
+
server_config: Server configuration.
|
|
41
|
+
client_config: Setup client configuration.
|
|
36
42
|
module_servicer: The gRPC servicer handling module requests.
|
|
37
43
|
"""
|
|
38
44
|
|
|
39
45
|
def __init__(
|
|
40
46
|
self,
|
|
41
47
|
module_class: type[BaseModule],
|
|
42
|
-
|
|
48
|
+
server_config: ModuleServerConfig,
|
|
49
|
+
client_config: ClientConfig | None = None,
|
|
43
50
|
) -> None:
|
|
44
51
|
"""Initialize the module server.
|
|
45
52
|
|
|
@@ -47,9 +54,10 @@ class ModuleServer(BaseServer):
|
|
|
47
54
|
module_class: The module instance to be served.
|
|
48
55
|
config: Server configuration including registry address if auto-registration is desired.
|
|
49
56
|
"""
|
|
50
|
-
super().__init__(
|
|
57
|
+
super().__init__(server_config)
|
|
51
58
|
self.module_class = module_class
|
|
52
|
-
self.
|
|
59
|
+
self.server_config = server_config
|
|
60
|
+
self.client_config = client_config
|
|
53
61
|
self.module_servicer: ModuleServicer | None = None
|
|
54
62
|
|
|
55
63
|
def _register_servicers(self) -> None:
|
|
@@ -73,34 +81,46 @@ class ModuleServer(BaseServer):
|
|
|
73
81
|
|
|
74
82
|
def start(self) -> None:
|
|
75
83
|
"""Start the module server and register with the registry if configured."""
|
|
76
|
-
logger.critical(self.
|
|
84
|
+
logger.critical(self.server_config)
|
|
77
85
|
super().start()
|
|
78
86
|
|
|
79
|
-
logger.critical(self.
|
|
87
|
+
logger.critical(self.server_config)
|
|
80
88
|
# If a registry address is provided, register the module
|
|
81
|
-
if self.
|
|
89
|
+
if self.server_config.registry_address:
|
|
82
90
|
try:
|
|
83
91
|
self._register_with_registry()
|
|
84
92
|
except Exception:
|
|
85
93
|
logger.exception("Failed to register with registry")
|
|
86
94
|
|
|
95
|
+
if self.module_servicer is not None:
|
|
96
|
+
logger.critical(
|
|
97
|
+
"Setup post init started with config: %s", self.client_config
|
|
98
|
+
)
|
|
99
|
+
self.module_servicer.setup.__post_init__(self.client_config)
|
|
100
|
+
|
|
87
101
|
async def start_async(self) -> None:
|
|
88
102
|
"""Start the module server and register with the registry if configured."""
|
|
89
|
-
logger.critical(self.
|
|
103
|
+
logger.critical(self.server_config)
|
|
90
104
|
await super().start_async()
|
|
91
105
|
|
|
92
|
-
logger.critical(self.
|
|
106
|
+
logger.critical(self.server_config)
|
|
93
107
|
# If a registry address is provided, register the module
|
|
94
|
-
if self.
|
|
108
|
+
if self.server_config.registry_address:
|
|
95
109
|
try:
|
|
96
110
|
self._register_with_registry()
|
|
97
111
|
except Exception:
|
|
98
112
|
logger.exception("Failed to register with registry")
|
|
99
113
|
|
|
114
|
+
if self.module_servicer is not None:
|
|
115
|
+
logger.critical(
|
|
116
|
+
"Setup post init started with config: %s", self.client_config
|
|
117
|
+
)
|
|
118
|
+
self.module_servicer.setup.__post_init__(self.client_config)
|
|
119
|
+
|
|
100
120
|
def stop(self, grace: float | None = None) -> None:
|
|
101
121
|
"""Stop the module server and deregister from the registry if needed."""
|
|
102
122
|
# If registered with a registry, deregister
|
|
103
|
-
if self.
|
|
123
|
+
if self.server_config.registry_address:
|
|
104
124
|
try:
|
|
105
125
|
self._deregister_from_registry()
|
|
106
126
|
except ServerError:
|
|
@@ -115,7 +135,8 @@ class ModuleServer(BaseServer):
|
|
|
115
135
|
ServerError: If communication with the registry server fails.
|
|
116
136
|
"""
|
|
117
137
|
logger.info(
|
|
118
|
-
"Registering module with registry at %s",
|
|
138
|
+
"Registering module with registry at %s",
|
|
139
|
+
self.server_config.registry_address,
|
|
119
140
|
)
|
|
120
141
|
|
|
121
142
|
# Create appropriate channel based on security mode
|
|
@@ -145,7 +166,7 @@ class ModuleServer(BaseServer):
|
|
|
145
166
|
module_id=self.module_class.metadata["module_id"],
|
|
146
167
|
version=self.module_class.metadata["version"],
|
|
147
168
|
module_type=module_type,
|
|
148
|
-
address=self.
|
|
169
|
+
address=self.server_config.address,
|
|
149
170
|
metadata=metadata,
|
|
150
171
|
)
|
|
151
172
|
|
|
@@ -173,7 +194,8 @@ class ModuleServer(BaseServer):
|
|
|
173
194
|
ServerError: If communication with the registry server fails.
|
|
174
195
|
"""
|
|
175
196
|
logger.info(
|
|
176
|
-
"Deregistering module from registry at %s",
|
|
197
|
+
"Deregistering module from registry at %s",
|
|
198
|
+
self.server_config.registry_address,
|
|
177
199
|
)
|
|
178
200
|
|
|
179
201
|
# Create appropriate channel based on security mode
|
|
@@ -208,29 +230,42 @@ class ModuleServer(BaseServer):
|
|
|
208
230
|
Raises:
|
|
209
231
|
ValueError: If credentials are required but not provided.
|
|
210
232
|
"""
|
|
211
|
-
if
|
|
233
|
+
if (
|
|
234
|
+
self.client_config is not None
|
|
235
|
+
and self.client_config.security == SecurityMode.SECURE
|
|
236
|
+
and self.client_config.credentials
|
|
237
|
+
):
|
|
212
238
|
# Secure channel
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
239
|
+
# Secure channel
|
|
240
|
+
root_certificates = Path(
|
|
241
|
+
self.client_config.credentials.root_cert_path
|
|
242
|
+
).read_bytes()
|
|
243
|
+
|
|
244
|
+
# mTLS channel
|
|
245
|
+
private_key = None
|
|
246
|
+
certificate_chain = None
|
|
247
|
+
if (
|
|
248
|
+
self.client_config.credentials.client_cert_path is not None
|
|
249
|
+
and self.client_config.credentials.client_key_path is not None
|
|
250
|
+
):
|
|
251
|
+
private_key = Path(
|
|
252
|
+
self.client_config.credentials.client_key_path
|
|
253
|
+
).read_bytes()
|
|
254
|
+
certificate_chain = Path(
|
|
255
|
+
self.client_config.credentials.client_cert_path
|
|
256
|
+
).read_bytes()
|
|
223
257
|
|
|
224
258
|
# Create channel credentials
|
|
225
259
|
channel_credentials = grpc.ssl_channel_credentials(
|
|
226
|
-
root_certificates=root_certificates
|
|
260
|
+
root_certificates=root_certificates,
|
|
261
|
+
certificate_chain=certificate_chain,
|
|
262
|
+
private_key=private_key,
|
|
227
263
|
)
|
|
228
|
-
|
|
229
264
|
return grpc.secure_channel(
|
|
230
|
-
self.
|
|
265
|
+
self.server_config.registry_address, channel_credentials
|
|
231
266
|
)
|
|
232
267
|
# Insecure channel
|
|
233
|
-
return grpc.insecure_channel(self.
|
|
268
|
+
return grpc.insecure_channel(self.server_config.registry_address)
|
|
234
269
|
|
|
235
270
|
def _determine_module_type(self) -> str:
|
|
236
271
|
"""Determine the module type based on its class.
|
|
@@ -102,7 +102,8 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
102
102
|
|
|
103
103
|
while module.status == ModuleStatus.RUNNING or not self.queue.empty():
|
|
104
104
|
output_data: dict = await self.queue.get()
|
|
105
|
-
|
|
105
|
+
|
|
106
|
+
if job_id not in output_data or job_id not in self.job_manager.modules:
|
|
106
107
|
message = f"Job {job_id} not found"
|
|
107
108
|
logger.warning(message)
|
|
108
109
|
context.set_code(grpc.StatusCode.NOT_FOUND)
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"""Client wrapper to ease channel creation with specific ServerConfig."""
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
|
+
from pathlib import Path
|
|
4
5
|
from typing import Any
|
|
5
6
|
|
|
6
7
|
import grpc
|
|
7
8
|
|
|
8
9
|
from digitalkin.grpc_servers.utils.exceptions import ServerError
|
|
9
|
-
from digitalkin.grpc_servers.utils.models import
|
|
10
|
+
from digitalkin.grpc_servers.utils.models import ClientConfig, SecurityMode
|
|
10
11
|
|
|
11
12
|
logger = logging.getLogger(__name__)
|
|
12
13
|
|
|
@@ -17,7 +18,7 @@ class GrpcClientWrapper:
|
|
|
17
18
|
stub: Any
|
|
18
19
|
|
|
19
20
|
@staticmethod
|
|
20
|
-
def _init_channel(config:
|
|
21
|
+
def _init_channel(config: ClientConfig) -> grpc.Channel:
|
|
21
22
|
"""Create an appropriate channel to the registry server.
|
|
22
23
|
|
|
23
24
|
Returns:
|
|
@@ -26,22 +27,27 @@ class GrpcClientWrapper:
|
|
|
26
27
|
Raises:
|
|
27
28
|
ValueError: If credentials are required but not provided.
|
|
28
29
|
"""
|
|
29
|
-
if config.security == SecurityMode.SECURE and config.credentials:
|
|
30
|
+
if config.security == SecurityMode.SECURE and config.credentials is not None:
|
|
30
31
|
# Secure channel
|
|
31
|
-
|
|
32
|
-
certificate_chain = cert_file.read()
|
|
32
|
+
root_certificates = Path(config.credentials.root_cert_path).read_bytes()
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
# mTLS channel
|
|
35
|
+
private_key = None
|
|
36
|
+
certificate_chain = None
|
|
37
|
+
if config.credentials.client_cert_path is not None and config.credentials.client_key_path is not None:
|
|
38
|
+
private_key = Path(config.credentials.client_key_path).read_bytes()
|
|
39
|
+
certificate_chain = Path(config.credentials.client_cert_path).read_bytes()
|
|
38
40
|
|
|
39
41
|
# Create channel credentials
|
|
40
|
-
channel_credentials = grpc.ssl_channel_credentials(
|
|
42
|
+
channel_credentials = grpc.ssl_channel_credentials(
|
|
43
|
+
root_certificates=root_certificates,
|
|
44
|
+
certificate_chain=certificate_chain,
|
|
45
|
+
private_key=private_key,
|
|
46
|
+
)
|
|
41
47
|
|
|
42
|
-
return grpc.secure_channel(
|
|
48
|
+
return grpc.secure_channel(config.address, channel_credentials)
|
|
43
49
|
# Insecure channel
|
|
44
|
-
return grpc.insecure_channel(
|
|
50
|
+
return grpc.insecure_channel(config.address)
|
|
45
51
|
|
|
46
52
|
def exec_grpc_query(self, query_endpoint: str, request: Any) -> Any: # noqa: ANN401
|
|
47
53
|
"""Execute a gRPC query with from the query's rpc endpoint name.
|
|
@@ -65,29 +65,18 @@ class ServerCredentials(BaseModel):
|
|
|
65
65
|
return v
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
class
|
|
69
|
-
"""
|
|
68
|
+
class ClientCredentials(BaseModel):
|
|
69
|
+
"""Model for client credentials in secure mode.
|
|
70
70
|
|
|
71
71
|
Attributes:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
mode: Server operation mode (sync/async)
|
|
76
|
-
security: Security mode (secure/insecure)
|
|
77
|
-
credentials: Server credentials for secure mode
|
|
78
|
-
server_options: Additional server options
|
|
79
|
-
enable_reflection: Enable reflection for the server
|
|
72
|
+
root_cert_path: path to the root certificate
|
|
73
|
+
client_key_path: Path to the client private key
|
|
74
|
+
client_cert_path: Path to the client certificate
|
|
80
75
|
"""
|
|
81
76
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
mode: ServerMode = Field(ServerMode.SYNC, description="Server operation mode (sync/async)")
|
|
86
|
-
security: SecurityMode = Field(SecurityMode.INSECURE, description="Security mode (secure/insecure)")
|
|
87
|
-
credentials: ServerCredentials | None = Field(None, description="Server credentials for secure mode")
|
|
88
|
-
server_options: list[tuple[str, Any]] = Field(default_factory=list, description="Additional server options")
|
|
89
|
-
enable_reflection: bool = Field(default=True, description="Enable reflection for the server")
|
|
90
|
-
enable_health_check: bool = Field(default=True, description="Enable health check service")
|
|
77
|
+
root_cert_path: Path = Field(..., description="Path to the root certificate")
|
|
78
|
+
client_key_path: Path | None = Field(None, description="Path to the client private key | mTLS enable")
|
|
79
|
+
client_cert_path: Path | None = Field(None, description="Path to the client certificate | mTLS enable")
|
|
91
80
|
|
|
92
81
|
# Enable __slots__ for memory efficiency
|
|
93
82
|
model_config = {
|
|
@@ -95,31 +84,53 @@ class ServerConfig(BaseModel):
|
|
|
95
84
|
"arbitrary_types_allowed": True,
|
|
96
85
|
"validate_assignment": True,
|
|
97
86
|
"use_enum_values": True,
|
|
87
|
+
"frozen": True, # Make immutable
|
|
98
88
|
}
|
|
99
89
|
|
|
100
|
-
@field_validator("
|
|
90
|
+
@field_validator("client_key_path", "client_cert_path", "root_cert_path")
|
|
101
91
|
@classmethod
|
|
102
|
-
def
|
|
103
|
-
"""Validate that
|
|
92
|
+
def check_path_exists(cls, v: Path | None) -> Path | None:
|
|
93
|
+
"""Validate that the file path exists.
|
|
104
94
|
|
|
105
95
|
Args:
|
|
106
|
-
v:
|
|
107
|
-
info: ValidationInfo containing other field values
|
|
96
|
+
v: Path to validate
|
|
108
97
|
|
|
109
98
|
Returns:
|
|
110
|
-
The validated
|
|
99
|
+
The validated path
|
|
111
100
|
|
|
112
101
|
Raises:
|
|
113
|
-
|
|
102
|
+
SecurityError: If the path does not exist
|
|
114
103
|
"""
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if security == SecurityMode.SECURE and v is None:
|
|
119
|
-
msg = "Credentials must be provided when using secure mode"
|
|
120
|
-
raise ConfigurationError(msg)
|
|
104
|
+
if v is not None and not v.exists():
|
|
105
|
+
msg = f"File not found: {v}"
|
|
106
|
+
raise SecurityError(msg)
|
|
121
107
|
return v
|
|
122
108
|
|
|
109
|
+
|
|
110
|
+
class ChannelConfig(BaseModel):
|
|
111
|
+
"""Base configuration for gRPC channels.
|
|
112
|
+
|
|
113
|
+
Attributes:
|
|
114
|
+
host: Host address
|
|
115
|
+
port: Port to listen on
|
|
116
|
+
mode: communication operation mode (sync/async)
|
|
117
|
+
security: Security mode (secure/insecure)
|
|
118
|
+
credentials: Client credentials for secure mode
|
|
119
|
+
"""
|
|
120
|
+
|
|
121
|
+
host: str = Field("0.0.0.0", description="Host address to bind the client to") # noqa: S104
|
|
122
|
+
port: int = Field(50051, description="Port to listen on")
|
|
123
|
+
mode: ServerMode = Field(ServerMode.SYNC, description="Client operation mode (sync/async)")
|
|
124
|
+
security: SecurityMode = Field(SecurityMode.INSECURE, description="Security mode (secure/insecure)")
|
|
125
|
+
|
|
126
|
+
# Enable __slots__ for memory efficiency
|
|
127
|
+
model_config = {
|
|
128
|
+
"extra": "forbid",
|
|
129
|
+
"arbitrary_types_allowed": True,
|
|
130
|
+
"validate_assignment": True,
|
|
131
|
+
"use_enum_values": True,
|
|
132
|
+
}
|
|
133
|
+
|
|
123
134
|
@field_validator("port")
|
|
124
135
|
@classmethod
|
|
125
136
|
def validate_port(cls, v: int) -> int:
|
|
@@ -149,6 +160,87 @@ class ServerConfig(BaseModel):
|
|
|
149
160
|
return f"{self.host}:{self.port}"
|
|
150
161
|
|
|
151
162
|
|
|
163
|
+
class ClientConfig(ChannelConfig):
|
|
164
|
+
"""Base configuration for gRPC clients.
|
|
165
|
+
|
|
166
|
+
Attributes:
|
|
167
|
+
host: Host address to bind the client to
|
|
168
|
+
port: Port to listen on
|
|
169
|
+
mode: Client operation mode (sync/async)
|
|
170
|
+
security: Security mode (secure/insecure)
|
|
171
|
+
credentials: Client credentials for secure mode
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
credentials: ClientCredentials | None = Field(None, description="Client credentials for secure mode")
|
|
175
|
+
|
|
176
|
+
@field_validator("credentials")
|
|
177
|
+
@classmethod
|
|
178
|
+
def validate_credentials(cls, v: ClientCredentials | None, info: ValidationInfo) -> ClientCredentials | None:
|
|
179
|
+
"""Validate that credentials are provided when in secure mode.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
v: The credentials value
|
|
183
|
+
info: ValidationInfo containing other field values
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
The validated credentials
|
|
187
|
+
|
|
188
|
+
Raises:
|
|
189
|
+
ConfigurationError: If credentials are missing in secure mode
|
|
190
|
+
"""
|
|
191
|
+
# Access security mode from the info.data dictionary
|
|
192
|
+
security = info.data.get("security")
|
|
193
|
+
|
|
194
|
+
if security == SecurityMode.SECURE and v is None:
|
|
195
|
+
msg = "Credentials must be provided when using secure mode"
|
|
196
|
+
raise ConfigurationError(msg)
|
|
197
|
+
return v
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class ServerConfig(ChannelConfig):
|
|
201
|
+
"""Base configuration for gRPC servers.
|
|
202
|
+
|
|
203
|
+
Attributes:
|
|
204
|
+
host: Host address to bind the server to
|
|
205
|
+
port: Port to listen on
|
|
206
|
+
max_workers: Maximum number of workers for sync mode
|
|
207
|
+
mode: Server operation mode (sync/async)
|
|
208
|
+
security: Security mode (secure/insecure)
|
|
209
|
+
credentials: Server credentials for secure mode
|
|
210
|
+
server_options: Additional server options
|
|
211
|
+
enable_reflection: Enable reflection for the server
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
max_workers: int = Field(10, description="Maximum number of workers for sync mode")
|
|
215
|
+
credentials: ServerCredentials | None = Field(None, description="Server credentials for secure mode")
|
|
216
|
+
server_options: list[tuple[str, Any]] = Field(default_factory=list, description="Additional server options")
|
|
217
|
+
enable_reflection: bool = Field(default=True, description="Enable reflection for the server")
|
|
218
|
+
enable_health_check: bool = Field(default=True, description="Enable health check service")
|
|
219
|
+
|
|
220
|
+
@field_validator("credentials")
|
|
221
|
+
@classmethod
|
|
222
|
+
def validate_credentials(cls, v: ServerCredentials | None, info: ValidationInfo) -> ServerCredentials | None:
|
|
223
|
+
"""Validate that credentials are provided when in secure mode.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
v: The credentials value
|
|
227
|
+
info: ValidationInfo containing other field values
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
The validated credentials
|
|
231
|
+
|
|
232
|
+
Raises:
|
|
233
|
+
ConfigurationError: If credentials are missing in secure mode
|
|
234
|
+
"""
|
|
235
|
+
# Access security mode from the info.data dictionary
|
|
236
|
+
security = info.data.get("security")
|
|
237
|
+
|
|
238
|
+
if security == SecurityMode.SECURE and v is None:
|
|
239
|
+
msg = "Credentials must be provided when using secure mode"
|
|
240
|
+
raise ConfigurationError(msg)
|
|
241
|
+
return v
|
|
242
|
+
|
|
243
|
+
|
|
152
244
|
class ModuleServerConfig(ServerConfig):
|
|
153
245
|
"""Configuration for Module gRPC server.
|
|
154
246
|
|
|
@@ -16,7 +16,7 @@ from pydantic import ValidationError
|
|
|
16
16
|
|
|
17
17
|
from digitalkin.grpc_servers.utils.exceptions import ServerError
|
|
18
18
|
from digitalkin.grpc_servers.utils.grpc_client_wrapper import GrpcClientWrapper
|
|
19
|
-
from digitalkin.grpc_servers.utils.models import
|
|
19
|
+
from digitalkin.grpc_servers.utils.models import ClientConfig
|
|
20
20
|
from digitalkin.services.setup.setup_strategy import SetupData, SetupServiceError, SetupStrategy, SetupVersionData
|
|
21
21
|
|
|
22
22
|
logger = logging.getLogger(__name__)
|
|
@@ -25,7 +25,7 @@ logger = logging.getLogger(__name__)
|
|
|
25
25
|
class GrpcSetup(SetupStrategy, GrpcClientWrapper):
|
|
26
26
|
"""This class implements the gRPC setup service."""
|
|
27
27
|
|
|
28
|
-
def __post_init__(self, config:
|
|
28
|
+
def __post_init__(self, config: ClientConfig) -> None:
|
|
29
29
|
"""Init the channel from a config file.
|
|
30
30
|
|
|
31
31
|
Need to be call if the user register a gRPC channel.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: digitalkin
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: SDK to build kin used in DigitalKin
|
|
5
5
|
Author-email: "DigitalKin.ai" <contact@digitalkin.ai>
|
|
6
6
|
License: Attribution-NonCommercial-ShareAlike 4.0 International
|
|
@@ -456,6 +456,7 @@ Requires-Dist: digitalkin-proto>=0.1.7
|
|
|
456
456
|
Requires-Dist: grpcio-health-checking>=1.71.0
|
|
457
457
|
Requires-Dist: grpcio-reflection>=1.71.0
|
|
458
458
|
Requires-Dist: grpcio-status>=1.71.0
|
|
459
|
+
Requires-Dist: openai>=1.70.0
|
|
459
460
|
Requires-Dist: pydantic>=2.11.3
|
|
460
461
|
Provides-Extra: dev
|
|
461
462
|
Requires-Dist: pytest>=8.3.4; extra == "dev"
|
|
@@ -7,19 +7,19 @@ base_server/mock/__init__.py,sha256=YZFT-F1l_TpvJYuIPX-7kTeE1CfOjhx9YmNRXVoi-jQ,
|
|
|
7
7
|
base_server/mock/mock_pb2.py,sha256=sETakcS3PAAm4E-hTCV1jIVaQTPEAIoVVHupB8Z_k7Y,1843
|
|
8
8
|
base_server/mock/mock_pb2_grpc.py,sha256=BbOT70H6q3laKgkHfOx1QdfmCS_HxCY4wCOX84YAdG4,3180
|
|
9
9
|
digitalkin/__init__.py,sha256=7LLBAba0th-3SGqcpqFO-lopWdUkVLKzLZiMtB-mW3M,162
|
|
10
|
-
digitalkin/__version__.py,sha256=
|
|
10
|
+
digitalkin/__version__.py,sha256=rNDXhMY4crjuy0nWOXRh9ypmALKFI7DzYaHCTDZkRl8,190
|
|
11
11
|
digitalkin/logger.py,sha256=9cDgyJV2QXXT8F--xRODFlZyDgjuTTXNdpCU3GdqCsk,382
|
|
12
12
|
digitalkin/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
digitalkin/grpc_servers/__init__.py,sha256=0cJBlwipSmFdXkyH3T0i6OJ1WpAtNsZgYX7JaSnkbtg,804
|
|
14
14
|
digitalkin/grpc_servers/_base_server.py,sha256=ec4xmgAuOMVg45a63O_PEa2T7mI4tJ6boxcXauFyZ5g,18649
|
|
15
|
-
digitalkin/grpc_servers/module_server.py,sha256=
|
|
16
|
-
digitalkin/grpc_servers/module_servicer.py,sha256=
|
|
15
|
+
digitalkin/grpc_servers/module_server.py,sha256=0jC5MN-H4MGA9O9J87gnlM8EHcbrkb0chuCm8yZh7gI,10232
|
|
16
|
+
digitalkin/grpc_servers/module_servicer.py,sha256=byqRpp9m8HS3NUUtKBWFXOncpUWGDW_xsyddA2qwaW4,12294
|
|
17
17
|
digitalkin/grpc_servers/registry_server.py,sha256=PmWaH4Xmg5Sj7NtFVLBNTOzkOfqo7dw_qyVBnaW4jy4,2238
|
|
18
18
|
digitalkin/grpc_servers/registry_servicer.py,sha256=mCAjNhdMq5DozZMEPsJK__DIxePEYxSWV-gAq-Xctk4,16469
|
|
19
19
|
digitalkin/grpc_servers/utils/exceptions.py,sha256=I00OM8p8up20He4dU1fiHsvdLj1DymjR_UmoeUm2MSA,785
|
|
20
20
|
digitalkin/grpc_servers/utils/factory.py,sha256=jm6rFjiqmtSv7BIHNAOxsG9xXtSvWpx9TfzSQiX97MQ,5899
|
|
21
|
-
digitalkin/grpc_servers/utils/grpc_client_wrapper.py,sha256=
|
|
22
|
-
digitalkin/grpc_servers/utils/models.py,sha256=
|
|
21
|
+
digitalkin/grpc_servers/utils/grpc_client_wrapper.py,sha256=6gj98T2_siZNlsamfz2Qkg89ebv4rS8Gm_X2FpE6Iow,2613
|
|
22
|
+
digitalkin/grpc_servers/utils/models.py,sha256=80F5oHiv8MOqMoDZJBXmJSRoVYJRyhaVcijQ2LinAig,8428
|
|
23
23
|
digitalkin/grpc_servers/utils/types.py,sha256=rQ78s4nAet2jy-NIDj_PUWriT0kuGHr_w6ELjmjgBao,539
|
|
24
24
|
digitalkin/models/__init__.py,sha256=hDHtUfswaNh8wo4NZaBItg9JqC0uNSRqXArNWSrGynY,163
|
|
25
25
|
digitalkin/models/module/__init__.py,sha256=ihvRlemJuFvU4armZIL-Vq-zaJx9UrjDoJAVPbEG8jw,345
|
|
@@ -56,7 +56,7 @@ digitalkin/services/registry/__init__.py,sha256=Zl4QAkCe9tOmmKGBWVuLQVFepdZiL0ec
|
|
|
56
56
|
digitalkin/services/registry/default_registry.py,sha256=VnWkF6nHpFxUKuUbZLPqzXqdA6oXmyV_ySpeuOCf_ko,277
|
|
57
57
|
digitalkin/services/registry/registry_strategy.py,sha256=uBXgZIv25jeXbeVO8vWvlNPxxNYu7_KiCw2PoE6AWr8,423
|
|
58
58
|
digitalkin/services/setup/default_setup.py,sha256=x1J6trXhyLC7V2OTe5pRY5mIFkQ4oyi3-aG50a1G1U4,8253
|
|
59
|
-
digitalkin/services/setup/grpc_setup.py,sha256=
|
|
59
|
+
digitalkin/services/setup/grpc_setup.py,sha256=4rLra3Ao0cwVX1L380VYwmGactoIk8gmcNHGlkrpEo8,12449
|
|
60
60
|
digitalkin/services/setup/setup_strategy.py,sha256=ZnJ_HwWCkHCPrqKekSD5L9y3p8wMwfjQ8sj2hLZq6go,4004
|
|
61
61
|
digitalkin/services/snapshot/__init__.py,sha256=Uzlnzo0CYlSpVsdiI37hW7xQk8hu3YA1fOI6O6MSzB0,270
|
|
62
62
|
digitalkin/services/snapshot/default_snapshot.py,sha256=Mb8QwWRsHh9I_tN0ln_ZiFa1QCZxOVWmuVLemQOTWpc,1058
|
|
@@ -67,12 +67,12 @@ digitalkin/services/storage/grpc_storage.py,sha256=BqWLK9w_03BEjlJCVbdrlbMvh2szG
|
|
|
67
67
|
digitalkin/services/storage/storage_strategy.py,sha256=vGo4aYkEp_GZV11m7vd-xY_Z3gVa5K0gMTzbj2Au_3o,6600
|
|
68
68
|
digitalkin/utils/__init__.py,sha256=sJnY-ZUgsjMfojAjONC1VN14mhgIDnzyOlGkw21rRnM,28
|
|
69
69
|
digitalkin/utils/arg_parser.py,sha256=3YyI6oZhhrlTmPTrzlwpQzbCNWDFAT3pggcLxNtJoc0,4388
|
|
70
|
-
digitalkin-0.2.
|
|
70
|
+
digitalkin-0.2.5.dist-info/licenses/LICENSE,sha256=Ies4HFv2r2hzDRakJYxk3Y60uDFLiG-orIgeTpstnIo,20327
|
|
71
71
|
modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
72
72
|
modules/minimal_llm_module.py,sha256=i9KTbv8w1ekzRYWDiRsxD6xLCoZ3uDjD_hWgfY2PRys,5637
|
|
73
73
|
modules/storage_module.py,sha256=bu52lW4RFcWB8VFDhrpBFfCaTSkVL6so3zrkfW4LO9E,6270
|
|
74
74
|
modules/text_transform_module.py,sha256=fAC6r_Ujca1Tz1qdWL4hTPZFn3gFWIVNj5-rytQMObE,7191
|
|
75
|
-
digitalkin-0.2.
|
|
76
|
-
digitalkin-0.2.
|
|
77
|
-
digitalkin-0.2.
|
|
78
|
-
digitalkin-0.2.
|
|
75
|
+
digitalkin-0.2.5.dist-info/METADATA,sha256=GLLOO0md8f6VLKykUxBJwZ2wTh3NEpBcKdi-V5wKvx8,29125
|
|
76
|
+
digitalkin-0.2.5.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
77
|
+
digitalkin-0.2.5.dist-info/top_level.txt,sha256=5_5e35inSM5YfWNZE21p5wGBojiVtQQML_WzbEk4BRU,31
|
|
78
|
+
digitalkin-0.2.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|