digitalkin 0.3.1__py3-none-any.whl → 0.3.1.dev0__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.
@@ -175,8 +175,8 @@ class ClientConfig(ChannelConfig):
175
175
  credentials: ClientCredentials | None = Field(None, description="Client credentials for secure mode")
176
176
  channel_options: list[tuple[str, Any]] = Field(
177
177
  default_factory=lambda: [
178
- ("grpc.max_receive_message_length", 100 * 1024 * 1024), # 100MB
179
- ("grpc.max_send_message_length", 100 * 1024 * 1024), # 100MB
178
+ ("grpc.max_receive_message_length", 50 * 1024 * 1024), # 50MB
179
+ ("grpc.max_send_message_length", 50 * 1024 * 1024), # 50MB
180
180
  ],
181
181
  description="Additional channel options",
182
182
  )
@@ -223,8 +223,8 @@ class ServerConfig(ChannelConfig):
223
223
  credentials: ServerCredentials | None = Field(None, description="Server credentials for secure mode")
224
224
  server_options: list[tuple[str, Any]] = Field(
225
225
  default_factory=lambda: [
226
- ("grpc.max_receive_message_length", 100 * 1024 * 1024), # 100MB
227
- ("grpc.max_send_message_length", 100 * 1024 * 1024), # 100MB
226
+ ("grpc.max_receive_message_length", 50 * 1024 * 1024), # 50MB
227
+ ("grpc.max_send_message_length", 50 * 1024 * 1024), # 50MB
228
228
  ],
229
229
  description="Additional server options",
230
230
  )
@@ -10,7 +10,6 @@ from digitalkin.services.identity.identity_strategy import IdentityStrategy
10
10
  from digitalkin.services.registry.registry_strategy import RegistryStrategy
11
11
  from digitalkin.services.snapshot.snapshot_strategy import SnapshotStrategy
12
12
  from digitalkin.services.storage.storage_strategy import StorageStrategy
13
- from digitalkin.services.user_profile.user_profile_strategy import UserProfileStrategy
14
13
 
15
14
 
16
15
  class Session(SimpleNamespace):
@@ -90,7 +89,6 @@ class ModuleContext:
90
89
  registry: RegistryStrategy
91
90
  snapshot: SnapshotStrategy
92
91
  storage: StorageStrategy
93
- user_profile: UserProfileStrategy
94
92
 
95
93
  session: Session
96
94
  callbacks: SimpleNamespace
@@ -107,7 +105,6 @@ class ModuleContext:
107
105
  registry: RegistryStrategy,
108
106
  snapshot: SnapshotStrategy,
109
107
  storage: StorageStrategy,
110
- user_profile: UserProfileStrategy,
111
108
  session: dict[str, Any],
112
109
  metadata: dict[str, Any] = {},
113
110
  helpers: dict[str, Any] = {},
@@ -123,7 +120,6 @@ class ModuleContext:
123
120
  registry: RegistryStrategy.
124
121
  snapshot: SnapshotStrategy.
125
122
  storage: StorageStrategy.
126
- user_profile: UserProfileStrategy.
127
123
  metadata: dict defining differents Module metadata.
128
124
  helpers: dict different user defined helpers.
129
125
  session: dict referring the session IDs or informations.
@@ -137,7 +133,6 @@ class ModuleContext:
137
133
  self.registry = registry
138
134
  self.snapshot = snapshot
139
135
  self.storage = storage
140
- self.user_profile = user_profile
141
136
 
142
137
  self.metadata = SimpleNamespace(**metadata)
143
138
  self.session = Session(**session)
@@ -1,25 +1,11 @@
1
1
  """Types for module models."""
2
2
 
3
- from __future__ import annotations
4
-
5
- import copy
6
- import types
7
- import typing
8
3
  from datetime import datetime, timezone
9
- from typing import TYPE_CHECKING, Any, ClassVar, Generic, TypeVar, cast, get_args, get_origin
4
+ from typing import Any, ClassVar, Generic, TypeVar, cast
10
5
 
11
6
  from pydantic import BaseModel, ConfigDict, Field, create_model
12
7
 
13
8
  from digitalkin.logger import logger
14
- from digitalkin.utils.dynamic_schema import (
15
- DynamicField,
16
- get_fetchers,
17
- has_dynamic,
18
- resolve_safe,
19
- )
20
-
21
- if TYPE_CHECKING:
22
- from pydantic.fields import FieldInfo
23
9
 
24
10
 
25
11
  class DataTrigger(BaseModel):
@@ -75,50 +61,27 @@ SetupModelT = TypeVar("SetupModelT", bound="SetupModel")
75
61
  class SetupModel(BaseModel):
76
62
  """Base definition of setup model showing mandatory root fields.
77
63
 
78
- Optionally, the setup model can define a config option in json_schema_extra
79
- to be used to initialize the Kin. Supports dynamic schema providers for
80
- runtime value generation.
81
-
82
- Attributes:
83
- model_fields: Inherited from Pydantic BaseModel, contains field definitions.
64
+ Optionally, the setup model can define a config option in json_schema_extra to be used to initialize the Kin.
84
65
 
85
- See Also:
86
- - Documentation: docs/api/dynamic_schema.md
87
- - Tests: tests/modules/test_setup_model.py
66
+ Example:
67
+ class MySetup(SetupModel):
68
+ name: str = Field()
69
+ number: int = Field(..., json_schema_extra={"config": True})
88
70
  """
89
71
 
90
72
  @classmethod
91
- async def get_clean_model(
92
- cls,
93
- *,
94
- config_fields: bool,
95
- hidden_fields: bool,
96
- force: bool = False,
97
- ) -> type[SetupModelT]:
98
- """Dynamically builds and returns a new BaseModel subclass with filtered fields.
99
-
100
- This method filters fields based on their `json_schema_extra` metadata:
101
- - Fields with `{"config": True}` are included only when `config_fields=True`
102
- - Fields with `{"hidden": True}` are included only when `hidden_fields=True`
103
-
104
- When `force=True`, fields with dynamic schema providers will have their
105
- providers called to fetch fresh values for schema metadata like enums.
106
- This includes recursively processing nested BaseModel fields.
73
+ def get_clean_model(cls, *, config_fields: bool, hidden_fields: bool) -> type[SetupModelT]: # type: ignore
74
+ """Dynamically builds and returns a new BaseModel subclass.
107
75
 
108
- Args:
109
- config_fields: If True, include fields marked with `{"config": True}`.
110
- These are typically initial configuration fields.
111
- hidden_fields: If True, include fields marked with `{"hidden": True}`.
112
- These are typically runtime-only fields not shown in initial config.
113
- force: If True, refresh dynamic schema fields by calling their providers.
114
- Use this when you need up-to-date values from external sources like
115
- databases or APIs. Default is False for performance.
76
+ containing only those fields where json_schema_extra["config"] == True.
116
77
 
117
78
  Returns:
118
- A new BaseModel subclass with filtered fields.
79
+ Type[BaseModel]: A new BaseModel subclass with the filtered fields.
80
+
81
+ Raises:
82
+ ValueError: If both config_fields and hidden_fields are set to True.
119
83
  """
120
84
  clean_fields: dict[str, Any] = {}
121
-
122
85
  for name, field_info in cls.model_fields.items():
123
86
  extra = getattr(field_info, "json_schema_extra", {}) or {}
124
87
  is_config = bool(extra.get("config", False))
@@ -134,27 +97,7 @@ class SetupModel(BaseModel):
134
97
  logger.debug("Skipping '%s' (hidden-only)", name)
135
98
  continue
136
99
 
137
- # Refresh dynamic schema fields when force=True
138
- current_field_info = field_info
139
- current_annotation = field_info.annotation
140
-
141
- if force:
142
- # Check if this field has DynamicField metadata
143
- if has_dynamic(field_info):
144
- current_field_info = await cls._refresh_field_schema(name, field_info)
145
-
146
- # Check if the annotation is a nested BaseModel that might have dynamic fields
147
- nested_model = cls._get_base_model_type(current_annotation)
148
- if nested_model is not None:
149
- refreshed_nested = await cls._refresh_nested_model(nested_model)
150
- if refreshed_nested is not nested_model:
151
- # Update annotation to use refreshed nested model
152
- current_annotation = refreshed_nested
153
- # Create new field_info with updated annotation (deep copy for safety)
154
- current_field_info = copy.deepcopy(current_field_info)
155
- setattr(current_field_info, "annotation", current_annotation)
156
-
157
- clean_fields[name] = (current_annotation, current_field_info)
100
+ clean_fields[name] = (field_info.annotation, field_info)
158
101
 
159
102
  # Dynamically create a model e.g. "SetupModel"
160
103
  m = create_model(
@@ -163,231 +106,4 @@ class SetupModel(BaseModel):
163
106
  __config__=ConfigDict(arbitrary_types_allowed=True),
164
107
  **clean_fields,
165
108
  )
166
- return cast("type[SetupModelT]", m)
167
-
168
- @classmethod
169
- def _get_base_model_type(cls, annotation: type | None) -> type[BaseModel] | None:
170
- """Extract BaseModel type from an annotation.
171
-
172
- Handles direct types, Optional, Union, list, dict, set, tuple, and other generics.
173
-
174
- Args:
175
- annotation: The type annotation to inspect.
176
-
177
- Returns:
178
- The BaseModel subclass if found, None otherwise.
179
- """
180
- if annotation is None:
181
- return None
182
-
183
- # Direct BaseModel subclass check
184
- if isinstance(annotation, type) and issubclass(annotation, BaseModel):
185
- return annotation
186
-
187
- origin = get_origin(annotation)
188
- if origin is None:
189
- return None
190
-
191
- args = get_args(annotation)
192
- return cls._extract_base_model_from_args(origin, args)
193
-
194
- @classmethod
195
- def _extract_base_model_from_args(
196
- cls,
197
- origin: type,
198
- args: tuple[type, ...],
199
- ) -> type[BaseModel] | None:
200
- """Extract BaseModel from generic type arguments.
201
-
202
- Args:
203
- origin: The generic origin type (list, dict, Union, etc.).
204
- args: The type arguments.
205
-
206
- Returns:
207
- The BaseModel subclass if found, None otherwise.
208
- """
209
- # Union/Optional: check each arg (supports both typing.Union and types.UnionType)
210
- # Python 3.10+ uses types.UnionType for X | Y syntax
211
- if origin is typing.Union or origin is types.UnionType:
212
- return cls._find_base_model_in_args(args)
213
-
214
- # list, set, frozenset: check first arg
215
- if origin in {list, set, frozenset} and args:
216
- return cls._check_base_model(args[0])
217
-
218
- # dict: check value type (second arg)
219
- dict_value_index = 1
220
- if origin is dict and len(args) > dict_value_index:
221
- return cls._check_base_model(args[dict_value_index])
222
-
223
- # tuple: check first non-ellipsis arg
224
- if origin is tuple:
225
- return cls._find_base_model_in_args(args, skip_ellipsis=True)
226
-
227
- return None
228
-
229
- @classmethod
230
- def _check_base_model(cls, arg: type) -> type[BaseModel] | None:
231
- """Check if arg is a BaseModel subclass.
232
-
233
- Returns:
234
- The BaseModel subclass if arg is one, None otherwise.
235
- """
236
- if isinstance(arg, type) and issubclass(arg, BaseModel):
237
- return arg
238
- return None
239
-
240
- @classmethod
241
- def _find_base_model_in_args(
242
- cls,
243
- args: tuple[type, ...],
244
- *,
245
- skip_ellipsis: bool = False,
246
- ) -> type[BaseModel] | None:
247
- """Find first BaseModel in args.
248
-
249
- Returns:
250
- The first BaseModel subclass found, None otherwise.
251
- """
252
- for arg in args:
253
- if arg is type(None):
254
- continue
255
- if skip_ellipsis and arg is ...:
256
- continue
257
- result = cls._check_base_model(arg)
258
- if result is not None:
259
- return result
260
- return None
261
-
262
- @classmethod
263
- async def _refresh_nested_model(cls, model_cls: type[BaseModel]) -> type[BaseModel]:
264
- """Refresh dynamic fields in a nested BaseModel.
265
-
266
- Creates a new model class with all DynamicField metadata resolved.
267
-
268
- Args:
269
- model_cls: The nested model class to refresh.
270
-
271
- Returns:
272
- A new model class with refreshed fields, or the original if no changes.
273
- """
274
- has_changes = False
275
- clean_fields: dict[str, Any] = {}
276
-
277
- for name, field_info in model_cls.model_fields.items():
278
- current_field_info = field_info
279
- current_annotation = field_info.annotation
280
-
281
- # Check if field has DynamicField metadata
282
- if has_dynamic(field_info):
283
- current_field_info = await cls._refresh_field_schema(name, field_info)
284
- has_changes = True
285
-
286
- # Recursively check nested models
287
- nested_model = cls._get_base_model_type(current_annotation)
288
- if nested_model is not None:
289
- refreshed_nested = await cls._refresh_nested_model(nested_model)
290
- if refreshed_nested is not nested_model:
291
- current_annotation = refreshed_nested
292
- current_field_info = copy.deepcopy(current_field_info)
293
- setattr(current_field_info, "annotation", current_annotation)
294
- has_changes = True
295
-
296
- clean_fields[name] = (current_annotation, current_field_info)
297
-
298
- if not has_changes:
299
- return model_cls
300
-
301
- # Create new model with refreshed fields
302
- logger.debug("Creating refreshed nested model for '%s'", model_cls.__name__)
303
- return create_model(
304
- model_cls.__name__,
305
- __base__=BaseModel,
306
- __config__=ConfigDict(arbitrary_types_allowed=True),
307
- **clean_fields,
308
- )
309
-
310
- @classmethod
311
- async def _refresh_field_schema(cls, field_name: str, field_info: FieldInfo) -> FieldInfo:
312
- """Refresh a field's json_schema_extra with fresh values from dynamic providers.
313
-
314
- This method calls all dynamic providers registered for a field (via Annotated
315
- metadata) and creates a new FieldInfo with the resolved values. The original
316
- field_info is not modified.
317
-
318
- Uses `resolve_safe()` for structured error handling, allowing partial success
319
- when some fetchers fail. Successfully resolved values are still applied.
320
-
321
- Args:
322
- field_name: The name of the field being refreshed (used for logging).
323
- field_info: The original FieldInfo object containing the dynamic providers.
324
-
325
- Returns:
326
- A new FieldInfo object with the same attributes as the original, but with
327
- `json_schema_extra` containing resolved values and Dynamic metadata removed.
328
-
329
- Note:
330
- If all fetchers fail, the original field_info is returned unchanged.
331
- If some fetchers fail, successfully resolved values are still applied.
332
- """
333
- fetchers = get_fetchers(field_info)
334
-
335
- if not fetchers:
336
- return field_info
337
-
338
- fetcher_keys = list(fetchers.keys())
339
- logger.debug(
340
- "Refreshing dynamic schema for field '%s' with fetchers: %s",
341
- field_name,
342
- fetcher_keys,
343
- extra={"field_name": field_name, "fetcher_keys": fetcher_keys},
344
- )
345
-
346
- # Resolve all fetchers with structured error handling
347
- result = await resolve_safe(fetchers)
348
-
349
- # Log any errors that occurred with full details
350
- if result.errors:
351
- for key, error in result.errors.items():
352
- logger.warning(
353
- "Failed to resolve '%s' for field '%s': %s: %s",
354
- key,
355
- field_name,
356
- type(error).__name__,
357
- str(error) or "(no message)",
358
- extra={
359
- "field_name": field_name,
360
- "fetcher_key": key,
361
- "error_type": type(error).__name__,
362
- "error_message": str(error),
363
- "error_repr": repr(error),
364
- },
365
- )
366
-
367
- # If no values were resolved, return original field_info
368
- if not result.values:
369
- logger.warning(
370
- "All fetchers failed for field '%s', keeping original",
371
- field_name,
372
- )
373
- return field_info
374
-
375
- # Build new json_schema_extra with resolved values merged
376
- extra = getattr(field_info, "json_schema_extra", {}) or {}
377
- new_extra = {**extra, **result.values}
378
-
379
- # Create a deep copy of the FieldInfo to avoid shared mutable state
380
- new_field_info = copy.deepcopy(field_info)
381
- setattr(new_field_info, "json_schema_extra", new_extra)
382
-
383
- # Remove Dynamic from metadata (it's been resolved)
384
- new_metadata = [m for m in new_field_info.metadata if not isinstance(m, DynamicField)]
385
- setattr(new_field_info, "metadata", new_metadata)
386
-
387
- logger.debug(
388
- "Refreshed '%s' with dynamic values: %s",
389
- field_name,
390
- list(result.values.keys()),
391
- )
392
-
393
- return new_field_info
109
+ return cast("type[SetupModelT]", m) # type: ignore
@@ -107,18 +107,14 @@ class BaseModule( # noqa: PLR0904
107
107
  return self._status
108
108
 
109
109
  @classmethod
110
- async def get_secret_format(cls, *, llm_format: bool) -> str:
110
+ def get_secret_format(cls, *, llm_format: bool) -> str:
111
111
  """Get the JSON schema of the secret format model.
112
112
 
113
- Args:
114
- llm_format: If True, return LLM-optimized schema format with inlined
115
- references and simplified structure.
113
+ Raises:
114
+ NotImplementedError: If the `secret_format` is not defined.
116
115
 
117
116
  Returns:
118
- The JSON schema of the secret format as a JSON string.
119
-
120
- Raises:
121
- NotImplementedError: If the `secret_format` class attribute is not defined.
117
+ The JSON schema of the secret format as a string.
122
118
  """
123
119
  if cls.secret_format is not None:
124
120
  if llm_format:
@@ -128,18 +124,14 @@ class BaseModule( # noqa: PLR0904
128
124
  raise NotImplementedError(msg)
129
125
 
130
126
  @classmethod
131
- async def get_input_format(cls, *, llm_format: bool) -> str:
127
+ def get_input_format(cls, *, llm_format: bool) -> str:
132
128
  """Get the JSON schema of the input format model.
133
129
 
134
- Args:
135
- llm_format: If True, return LLM-optimized schema format with inlined
136
- references and simplified structure.
130
+ Raises:
131
+ NotImplementedError: If the `input_format` is not defined.
137
132
 
138
133
  Returns:
139
- The JSON schema of the input format as a JSON string.
140
-
141
- Raises:
142
- NotImplementedError: If the `input_format` class attribute is not defined.
134
+ The JSON schema of the input format as a string.
143
135
  """
144
136
  if cls.input_format is not None:
145
137
  if llm_format:
@@ -149,18 +141,14 @@ class BaseModule( # noqa: PLR0904
149
141
  raise NotImplementedError(msg)
150
142
 
151
143
  @classmethod
152
- async def get_output_format(cls, *, llm_format: bool) -> str:
144
+ def get_output_format(cls, *, llm_format: bool) -> str:
153
145
  """Get the JSON schema of the output format model.
154
146
 
155
- Args:
156
- llm_format: If True, return LLM-optimized schema format with inlined
157
- references and simplified structure.
147
+ Raises:
148
+ NotImplementedError: If the `output_format` is not defined.
158
149
 
159
150
  Returns:
160
- The JSON schema of the output format as a JSON string.
161
-
162
- Raises:
163
- NotImplementedError: If the `output_format` class attribute is not defined.
151
+ The JSON schema of the output format as a string.
164
152
  """
165
153
  if cls.output_format is not None:
166
154
  if llm_format:
@@ -170,29 +158,20 @@ class BaseModule( # noqa: PLR0904
170
158
  raise NotImplementedError(msg)
171
159
 
172
160
  @classmethod
173
- async def get_config_setup_format(cls, *, llm_format: bool) -> str:
161
+ def get_config_setup_format(cls, *, llm_format: bool) -> str:
174
162
  """Gets the JSON schema of the config setup format model.
175
163
 
176
- The config setup format is used only to initialize the module with configuration
177
- data. It includes fields marked with `json_schema_extra={"config": True}` and
178
- excludes hidden runtime fields.
179
-
180
- Dynamic schema fields are always resolved when generating the schema, as this
181
- method is typically called during module discovery or schema generation where
182
- fresh values are needed.
164
+ The config setup format is used only to initialize the module with configuration data.
165
+ The setup format is used to initialize an run the module with setup data.
183
166
 
184
- Args:
185
- llm_format: If True, return LLM-optimized schema format with inlined
186
- references and simplified structure.
167
+ Raises:
168
+ NotImplementedError: If the `setup_format` is not defined.
187
169
 
188
170
  Returns:
189
- The JSON schema of the config setup format as a JSON string.
190
-
191
- Raises:
192
- NotImplementedError: If the `setup_format` class attribute is not defined.
171
+ The JSON schema of the config setup format as a string.
193
172
  """
194
173
  if cls.setup_format is not None:
195
- setup_format = await cls.setup_format.get_clean_model(config_fields=True, hidden_fields=False, force=True)
174
+ setup_format = cls.setup_format.get_clean_model(config_fields=True, hidden_fields=False)
196
175
  if llm_format:
197
176
  return json.dumps(llm_ready_schema(setup_format), indent=2)
198
177
  return json.dumps(setup_format.model_json_schema(), indent=2)
@@ -200,28 +179,17 @@ class BaseModule( # noqa: PLR0904
200
179
  raise NotImplementedError(msg)
201
180
 
202
181
  @classmethod
203
- async def get_setup_format(cls, *, llm_format: bool) -> str:
182
+ def get_setup_format(cls, *, llm_format: bool) -> str:
204
183
  """Gets the JSON schema of the setup format model.
205
184
 
206
- The setup format is used at runtime and includes hidden fields but excludes
207
- config-only fields. This is the schema used when running the module.
208
-
209
- Dynamic schema fields are always resolved when generating the schema, as this
210
- method is typically called during module discovery or schema generation where
211
- fresh values are needed.
212
-
213
- Args:
214
- llm_format: If True, return LLM-optimized schema format with inlined
215
- references and simplified structure.
185
+ Raises:
186
+ NotImplementedError: If the `setup_format` is not defined.
216
187
 
217
188
  Returns:
218
- The JSON schema of the setup format as a JSON string.
219
-
220
- Raises:
221
- NotImplementedError: If the `setup_format` class attribute is not defined.
189
+ The JSON schema of the setup format as a string.
222
190
  """
223
191
  if cls.setup_format is not None:
224
- setup_format = await cls.setup_format.get_clean_model(config_fields=False, hidden_fields=True, force=True)
192
+ setup_format = cls.setup_format.get_clean_model(config_fields=False, hidden_fields=True)
225
193
  if llm_format:
226
194
  return json.dumps(llm_ready_schema(setup_format), indent=2)
227
195
  return json.dumps(setup_format.model_json_schema(), indent=2)
@@ -253,22 +221,17 @@ class BaseModule( # noqa: PLR0904
253
221
  return cls.input_format(**input_data)
254
222
 
255
223
  @classmethod
256
- async def create_setup_model(cls, setup_data: dict[str, Any], *, config_fields: bool = False) -> SetupModelT:
224
+ def create_setup_model(cls, setup_data: dict[str, Any], *, config_fields: bool = False) -> SetupModelT:
257
225
  """Create the setup model from the setup data.
258
226
 
259
- Creates a filtered setup model instance based on the provided data.
260
- Uses `get_clean_model()` internally to get the appropriate model class
261
- with field filtering applied.
262
-
263
227
  Args:
264
228
  setup_data: The setup data to create the model from.
265
229
  config_fields: If True, include only fields with json_schema_extra["config"] == True.
266
230
 
267
231
  Returns:
268
- An instance of the setup model with the provided data.
232
+ The setup model.
269
233
  """
270
- model_cls = await cls.setup_format.get_clean_model(config_fields=config_fields, hidden_fields=True)
271
- return model_cls(**setup_data)
234
+ return cls.setup_format.get_clean_model(config_fields=config_fields, hidden_fields=True)(**setup_data)
272
235
 
273
236
  @classmethod
274
237
  def create_secret_model(cls, secret_data: dict[str, Any]) -> SecretModelT:
@@ -473,8 +436,7 @@ class BaseModule( # noqa: PLR0904
473
436
 
474
437
  wrapper = config_setup_data.model_dump()
475
438
  wrapper["content"] = content.model_dump()
476
- setup_model = await self.create_setup_model(wrapper)
477
- await callback(setup_model)
439
+ await callback(self.create_setup_model(wrapper))
478
440
  self._status = ModuleStatus.STOPPING
479
441
  except Exception:
480
442
  logger.error("Error during module lifecyle")
@@ -12,7 +12,6 @@ from digitalkin.services.registry import DefaultRegistry, RegistryStrategy
12
12
  from digitalkin.services.services_models import ServicesMode, ServicesStrategy
13
13
  from digitalkin.services.snapshot import DefaultSnapshot, SnapshotStrategy
14
14
  from digitalkin.services.storage import DefaultStorage, GrpcStorage, StorageStrategy
15
- from digitalkin.services.user_profile import DefaultUserProfile, GrpcUserProfile, UserProfileStrategy
16
15
 
17
16
 
18
17
  class ServicesConfig(BaseModel):
@@ -54,10 +53,6 @@ class ServicesConfig(BaseModel):
54
53
  default_factory=lambda: ServicesStrategy(local=DefaultIdentity, remote=DefaultIdentity)
55
54
  )
56
55
  _config_identity: dict[str, Any | None] = PrivateAttr(default_factory=dict)
57
- _user_profile: ServicesStrategy[UserProfileStrategy] = PrivateAttr(
58
- default_factory=lambda: ServicesStrategy(local=DefaultUserProfile, remote=GrpcUserProfile)
59
- )
60
- _config_user_profile: dict[str, Any | None] = PrivateAttr(default_factory=dict)
61
56
 
62
57
  # List of valid strategy names for validation
63
58
  _valid_strategy_names: ClassVar[set[str]] = {
@@ -68,7 +63,6 @@ class ServicesConfig(BaseModel):
68
63
  "filesystem",
69
64
  "agent",
70
65
  "identity",
71
- "user_profile",
72
66
  }
73
67
 
74
68
  def __init__(
@@ -175,11 +169,6 @@ class ServicesConfig(BaseModel):
175
169
  """Get the identity service strategy class based on the current mode."""
176
170
  return self._identity[self.mode.value]
177
171
 
178
- @property
179
- def user_profile(self) -> type[UserProfileStrategy]:
180
- """Get the user_profile service strategy class based on the current mode."""
181
- return self._user_profile[self.mode.value]
182
-
183
172
  def update_mode(self, mode: ServicesMode) -> None:
184
173
  """Update the strategy mode.
185
174
 
@@ -13,7 +13,6 @@ from digitalkin.services.identity import IdentityStrategy
13
13
  from digitalkin.services.registry import RegistryStrategy
14
14
  from digitalkin.services.snapshot import SnapshotStrategy
15
15
  from digitalkin.services.storage import StorageStrategy
16
- from digitalkin.services.user_profile import UserProfileStrategy
17
16
 
18
17
  # Define type variables
19
18
  T = TypeVar(
@@ -24,8 +23,7 @@ T = TypeVar(
24
23
  | IdentityStrategy
25
24
  | RegistryStrategy
26
25
  | SnapshotStrategy
27
- | StorageStrategy
28
- | UserProfileStrategy,
26
+ | StorageStrategy,
29
27
  )
30
28
 
31
29
 
@@ -1,12 +1 @@
1
1
  """UserProfile service package."""
2
-
3
- from digitalkin.services.user_profile.default_user_profile import DefaultUserProfile
4
- from digitalkin.services.user_profile.grpc_user_profile import GrpcUserProfile
5
- from digitalkin.services.user_profile.user_profile_strategy import UserProfileServiceError, UserProfileStrategy
6
-
7
- __all__ = [
8
- "DefaultUserProfile",
9
- "GrpcUserProfile",
10
- "UserProfileServiceError",
11
- "UserProfileStrategy",
12
- ]
@@ -49,8 +49,8 @@ class GrpcUserProfile(UserProfileStrategy, GrpcClientWrapper, GrpcErrorHandlerMi
49
49
  ServerError: If gRPC operation fails
50
50
  """
51
51
  with self.handle_grpc_errors("GetUserProfile", UserProfileServiceError):
52
- # mission_id maps to the user context in the proto request
53
- request = user_profile_pb2.GetUserProfileRequest(mission_id=self.mission_id)
52
+ # mission_id typically contains user context
53
+ request = user_profile_pb2.GetUserProfileRequest(user_id=self.mission_id)
54
54
  response = self.exec_grpc_query("GetUserProfile", request)
55
55
 
56
56
  if not response.success: