codemie-sdk-python 0.1.678__tar.gz → 0.1.680rc0__tar.gz

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.
Files changed (74) hide show
  1. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/PKG-INFO +14 -7
  2. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/README.md +3 -3
  3. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/pyproject.toml +8 -5
  4. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/__init__.py +6 -1
  5. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/conversation.py +3 -3
  6. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/user.py +7 -15
  7. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/conversation.py +2 -2
  8. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/customer_config_service.py +1 -1
  9. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/skill.py +0 -30
  10. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/user.py +0 -29
  11. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/auth/__init__.py +0 -0
  12. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/auth/credentials.py +0 -0
  13. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/client/__init__.py +0 -0
  14. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/client/client.py +0 -0
  15. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/exceptions.py +0 -0
  16. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/__init__.py +0 -0
  17. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/a2a.py +0 -0
  18. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/activity_event.py +0 -0
  19. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/admin.py +0 -0
  20. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/analytics.py +0 -0
  21. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/assistant.py +0 -0
  22. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/categories.py +0 -0
  23. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/common.py +0 -0
  24. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/cost_center.py +0 -0
  25. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/datasource.py +0 -0
  26. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/errors.py +0 -0
  27. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/file_operation.py +0 -0
  28. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/guardrails.py +0 -0
  29. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/integration.py +0 -0
  30. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/llm.py +0 -0
  31. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/mcp_config.py +0 -0
  32. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/mermaid.py +0 -0
  33. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/project.py +0 -0
  34. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/skill.py +0 -0
  35. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/task.py +0 -0
  36. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/vendor_assistant.py +0 -0
  37. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/vendor_guardrail.py +0 -0
  38. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/vendor_knowledgebase.py +0 -0
  39. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/vendor_runtime.py +0 -0
  40. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/vendor_workflow.py +0 -0
  41. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/workflow.py +0 -0
  42. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/workflow_execution_payload.py +0 -0
  43. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/workflow_state.py +0 -0
  44. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/workflow_thoughts.py +0 -0
  45. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/models/workflow_transition.py +0 -0
  46. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/a2a.py +0 -0
  47. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/activity_event.py +0 -0
  48. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/admin.py +0 -0
  49. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/analytics.py +0 -0
  50. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/assistant.py +0 -0
  51. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/categories.py +0 -0
  52. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/codemie_guardrails.py +0 -0
  53. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/cost_center.py +0 -0
  54. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/datasource.py +0 -0
  55. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/dynamic_config.py +0 -0
  56. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/files.py +0 -0
  57. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/integration.py +0 -0
  58. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/llm.py +0 -0
  59. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/mcp_configs.py +0 -0
  60. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/mermaid.py +0 -0
  61. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/project.py +0 -0
  62. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/project_budget_groups.py +0 -0
  63. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/task.py +0 -0
  64. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/vendor_assistant.py +0 -0
  65. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/vendor_guardrail.py +0 -0
  66. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/vendor_knowledgebase.py +0 -0
  67. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/vendor_runtime.py +0 -0
  68. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/vendor_workflow.py +0 -0
  69. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/webhook.py +0 -0
  70. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/workflow.py +0 -0
  71. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/workflow_execution.py +0 -0
  72. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/services/workflow_execution_state.py +0 -0
  73. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/utils/__init__.py +0 -0
  74. {codemie_sdk_python-0.1.678 → codemie_sdk_python-0.1.680rc0}/src/codemie_sdk/utils/http.py +0 -0
@@ -1,14 +1,21 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: codemie-sdk-python
3
- Version: 0.1.678
3
+ Version: 0.1.680rc0
4
4
  Summary: CodeMie SDK for Python
5
- Author: Vadym Vlasenko
6
- Author-email: vadym_vlasenko@epam.com
5
+ License: Apache-2.0
6
+ Author: CodeMie
7
7
  Requires-Python: >=3.12,<4.0
8
+ Classifier: License :: OSI Approved :: Apache Software License
8
9
  Classifier: Programming Language :: Python :: 3
9
10
  Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Programming Language :: Python :: 3.14
13
+ Classifier: Programming Language :: Python :: 3.15
10
14
  Requires-Dist: pydantic (>=2.12.2,<3.0.0)
11
15
  Requires-Dist: requests (>=2.31.0,<3.0.0)
16
+ Project-URL: Homepage, https://github.com/codemie-ai/codemie-sdk
17
+ Project-URL: Issues, https://github.com/codemie-ai/codemie-sdk/issues
18
+ Project-URL: Repository, https://github.com/codemie-ai/codemie-sdk
12
19
  Description-Content-Type: text/markdown
13
20
 
14
21
  # CodeMie Python SDK
@@ -84,11 +91,11 @@ from codemie_sdk import CodeMieClient
84
91
 
85
92
  # Initialize client with authentication parameters
86
93
  client = CodeMieClient(
87
- auth_server_url="https://keycloak.eks-core.aws.main.edp.projects.epam.com/auth",
94
+ auth_server_url="https://your-keycloak-host.example.com/auth",
88
95
  auth_client_id="your-client-id",
89
96
  auth_client_secret="your-client-secret",
90
97
  auth_realm_name="your-realm",
91
- codemie_api_domain="https://codemie.lab.epam.com/code-assistant-api"
98
+ codemie_api_domain="https://your-codemie-host.example.com/code-assistant-api"
92
99
  )
93
100
  ```
94
101
 
@@ -1367,7 +1374,7 @@ client = CodeMieClient(
1367
1374
 
1368
1375
  ## Support
1369
1376
 
1370
- For providing credentials please contact AI/Run CodeMie Team: Vadym_Vlasenko@epam.com or Nikita_Levyankov@epam.com
1377
+ For questions and bug reports, open an issue via GitHub Issues. To report a security vulnerability, follow the policy in [SECURITY.md](../../SECURITY.md).
1371
1378
 
1372
1379
  ## Development
1373
1380
 
@@ -71,11 +71,11 @@ from codemie_sdk import CodeMieClient
71
71
 
72
72
  # Initialize client with authentication parameters
73
73
  client = CodeMieClient(
74
- auth_server_url="https://keycloak.eks-core.aws.main.edp.projects.epam.com/auth",
74
+ auth_server_url="https://your-keycloak-host.example.com/auth",
75
75
  auth_client_id="your-client-id",
76
76
  auth_client_secret="your-client-secret",
77
77
  auth_realm_name="your-realm",
78
- codemie_api_domain="https://codemie.lab.epam.com/code-assistant-api"
78
+ codemie_api_domain="https://your-codemie-host.example.com/code-assistant-api"
79
79
  )
80
80
  ```
81
81
 
@@ -1354,7 +1354,7 @@ client = CodeMieClient(
1354
1354
 
1355
1355
  ## Support
1356
1356
 
1357
- For providing credentials please contact AI/Run CodeMie Team: Vadym_Vlasenko@epam.com or Nikita_Levyankov@epam.com
1357
+ For questions and bug reports, open an issue via GitHub Issues. To report a security vulnerability, follow the policy in [SECURITY.md](../../SECURITY.md).
1358
1358
 
1359
1359
  ## Development
1360
1360
 
@@ -1,15 +1,19 @@
1
1
  [tool.poetry]
2
2
  name = "codemie-sdk-python"
3
- version = "0.1.678"
3
+ version = "0.1.680rc0"
4
4
  description = "CodeMie SDK for Python"
5
- authors = [
6
- "Vadym Vlasenko <vadym_vlasenko@epam.com>",
7
- ]
5
+ authors = ["CodeMie"]
6
+ license = "Apache-2.0"
7
+ homepage = "https://github.com/codemie-ai/codemie-sdk"
8
+ repository = "https://github.com/codemie-ai/codemie-sdk"
8
9
  readme = "README.md"
9
10
  packages = [
10
11
  { include = "codemie_sdk", from="src"}
11
12
  ]
12
13
 
14
+ [tool.poetry.urls]
15
+ Issues = "https://github.com/codemie-ai/codemie-sdk/issues"
16
+
13
17
  [tool.poetry.dependencies]
14
18
  python = "^3.12"
15
19
  requests = "^2.31.0"
@@ -29,7 +33,6 @@ boto3 = "^1.39.8"
29
33
  aws-assume-role-lib = "^2.10.0"
30
34
  pyyaml = "^6.0.2"
31
35
  codemie-plugins = "^0.1.123"
32
- pytest-reportportal = "^5.5.2"
33
36
  pytest-playwright = "^0.7.0"
34
37
  tzlocal = "^5.3.1"
35
38
 
@@ -17,6 +17,8 @@ Basic usage:
17
17
  >>> assistants = client.assistants.list()
18
18
  """
19
19
 
20
+ from importlib.metadata import PackageNotFoundError, version as _pkg_version
21
+
20
22
  from .client.client import CodeMieClient
21
23
  from .models.vendor_assistant import (
22
24
  VendorType,
@@ -167,7 +169,10 @@ from .models.a2a import (
167
169
  )
168
170
  from .services.a2a import A2AService
169
171
 
170
- __version__ = "0.2.12"
172
+ try:
173
+ __version__ = _pkg_version("codemie-sdk-python")
174
+ except PackageNotFoundError: # running from a source tree that is not installed
175
+ __version__ = "0+unknown"
171
176
  __all__ = [
172
177
  "CodeMieClient",
173
178
  "VendorType",
@@ -92,7 +92,7 @@ class HistoryItem(BaseModel):
92
92
  thoughts: list[Thought] | None = Field(default_factory=list)
93
93
  workflowExecutionRef: str | bool | None = None
94
94
  executionId: str | None = None
95
- # WorkflowExecutionStatusEnum value, e.g. "In Progress" (EPMCDME-14075)
95
+ # WorkflowExecutionStatusEnum value, e.g. "In Progress"
96
96
  executionStatus: str | None = None
97
97
 
98
98
 
@@ -322,7 +322,7 @@ class AdminConversationListResponse(BaseModel):
322
322
  pagination: ConversationPagination
323
323
 
324
324
 
325
- # Feedback on assistant messages (EPMCDME-14625)
325
+ # Feedback on assistant messages
326
326
 
327
327
 
328
328
  class FeedbackMark(str, Enum):
@@ -345,7 +345,7 @@ class FeedbackCreateRequest(BaseModel):
345
345
 
346
346
  ``response`` is required by the backend even though the client already has
347
347
  the text elsewhere: omitting it returns a 422 ``response: Field required``
348
- error. This was the root cause of EPMCDME-14625, where the frontend built
348
+ error. This was the root cause of an earlier bug, where the frontend built
349
349
  the payload without it and negative feedback could never be submitted.
350
350
  Callers must always populate ``response`` -- an empty string is a valid
351
351
  value for incomplete, failed, or technical-error assistant responses.
@@ -13,15 +13,6 @@ class PaginationInfo(BaseModel):
13
13
  per_page: int
14
14
 
15
15
 
16
- class AdminUserProjectInfo(BaseModel):
17
- model_config = ConfigDict(extra="ignore")
18
-
19
- name: str
20
- display_name: Optional[str] = None
21
- is_project_admin: bool = False
22
- is_default: bool = False
23
-
24
-
25
16
  class AdminUserListItem(BaseModel):
26
17
  model_config = ConfigDict(extra="ignore")
27
18
 
@@ -35,7 +26,6 @@ class AdminUserListItem(BaseModel):
35
26
  is_maintainer: bool = False
36
27
  auth_source: Optional[str] = None
37
28
  last_login_at: Optional[str] = None
38
- projects: List[AdminUserProjectInfo] = []
39
29
  date: Optional[str] = None
40
30
 
41
31
 
@@ -46,6 +36,13 @@ class PaginatedUserListResponse(BaseModel):
46
36
  pagination: PaginationInfo
47
37
 
48
38
 
39
+ class AdminUserProjectInfo(BaseModel):
40
+ model_config = ConfigDict(extra="ignore")
41
+
42
+ name: str
43
+ is_project_admin: bool = False
44
+
45
+
49
46
  class CodeMieUserDetail(BaseModel):
50
47
  model_config = ConfigDict(extra="ignore")
51
48
 
@@ -74,7 +71,6 @@ class AdminUserProject(BaseModel):
74
71
 
75
72
  project_name: str
76
73
  is_project_admin: bool = False
77
- is_default: bool = False
78
74
  date: Optional[str] = None
79
75
 
80
76
 
@@ -106,10 +102,6 @@ class User(BaseModel):
106
102
  description="List of applications where user has admin rights",
107
103
  validation_alias="applicationsAdmin",
108
104
  )
109
- projects: list[AdminUserProjectInfo] = Field(
110
- default_factory=list,
111
- description="Projects the user belongs to, including the default-project flag",
112
- )
113
105
  picture: str = Field(default="", description="URL to user's profile picture")
114
106
  knowledge_bases: list[str] = Field(
115
107
  default_factory=list,
@@ -352,7 +352,7 @@ class ConversationService:
352
352
  SharedConversationResponse,
353
353
  )
354
354
 
355
- # Feedback management methods (EPMCDME-14625)
355
+ # Feedback management methods
356
356
 
357
357
  def create_feedback(self, request: FeedbackCreateRequest) -> FeedbackCreateResponse:
358
358
  """Submit like/dislike feedback on an assistant message.
@@ -385,7 +385,7 @@ class ConversationService:
385
385
  json_data=request.model_dump(by_alias=True, exclude_none=True),
386
386
  )
387
387
 
388
- # Conversation finishing (EPMCDME-11067)
388
+ # Conversation finishing
389
389
 
390
390
  def finish(self, conversation_id: str) -> ConversationFinishResponse:
391
391
  """Mark a conversation as finished (owner-only).
@@ -1,6 +1,6 @@
1
1
  """Customer config service implementation.
2
2
 
3
- Wraps four endpoints introduced in EPMCDME-13983:
3
+ Wraps four customer-config endpoints:
4
4
  GET /v1/config/declarations — list dynamic-config declarations (admin/maintainer)
5
5
  PUT /v1/config/declarations/{id} — save override settings for a component
6
6
  DELETE /v1/config/declarations/{id} — reset component to YAML default (idempotent)
@@ -397,33 +397,3 @@ class SkillService:
397
397
  Skill config with max_content_length and min_content_length
398
398
  """
399
399
  return self._api.get("/v1/skills/config", SkillConfigResponse)
400
-
401
- def generate_instructions(
402
- self,
403
- description: str,
404
- existing_instructions: str | None = None,
405
- skill_name: str | None = None,
406
- llm_model: str | None = None,
407
- ) -> dict:
408
- """Generate skill instructions from a description with AI.
409
-
410
- Args:
411
- description: User description of what the skill should do
412
- existing_instructions: Existing instructions to refine (optional)
413
- skill_name: Skill name for context (optional)
414
- llm_model: LLM model to use; platform default when omitted
415
-
416
- Returns:
417
- Dict with generated `instructions` and generation `metadata`
418
- """
419
- return self._api.post(
420
- "/v1/skills/instructions/generate",
421
- dict,
422
- json_data={
423
- "description": description,
424
- "existing_instructions": existing_instructions,
425
- "skill_name": skill_name,
426
- "llm_model": llm_model,
427
- },
428
- wrap_response=False,
429
- )
@@ -159,35 +159,6 @@ class UserService:
159
159
  wrap_response=False,
160
160
  )
161
161
 
162
- def set_default_project(self, user_id: str, project_name: str) -> dict:
163
- """Mark a project as the user's default project (admin or maintainer).
164
-
165
- Replaces any previously set default. The user must be a member of the project.
166
-
167
- Args:
168
- user_id: The user's unique identifier
169
- project_name: Name of the project to mark as default
170
- """
171
- return self._api.put(
172
- f"/v1/admin/users/{user_id}/projects/{project_name}/default",
173
- dict,
174
- json_data={},
175
- wrap_response=False,
176
- )
177
-
178
- def clear_default_project(self, user_id: str, project_name: str) -> dict:
179
- """Unset a project as the user's default project (admin or maintainer).
180
-
181
- Args:
182
- user_id: The user's unique identifier
183
- project_name: Name of the project to unset as default
184
- """
185
- return self._api.delete(
186
- f"/v1/admin/users/{user_id}/projects/{project_name}/default",
187
- dict,
188
- wrap_response=False,
189
- )
190
-
191
162
  def deactivate_user(self, user_id: str) -> None:
192
163
  """Deactivate (soft-delete) a user (SuperAdmin only).
193
164