uipath 2.1.48__py3-none-any.whl → 2.1.50__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.
@@ -315,7 +315,7 @@ class UiPathRuntimeContext(BaseModel):
315
315
  chat_handler: Optional[UiPathConversationHandler] = None
316
316
  is_conversational: Optional[bool] = None
317
317
 
318
- model_config = {"arbitrary_types_allowed": True}
318
+ model_config = {"arbitrary_types_allowed": True, "extra": "allow"}
319
319
 
320
320
  @classmethod
321
321
  def with_defaults(cls: type[C], config_path: Optional[str] = None, **kwargs) -> C:
@@ -5,6 +5,7 @@ from .attachments_service import AttachmentsService
5
5
  from .buckets_service import BucketsService
6
6
  from .connections_service import ConnectionsService
7
7
  from .context_grounding_service import ContextGroundingService
8
+ from .entities_service import EntitiesService
8
9
  from .folder_service import FolderService
9
10
  from .jobs_service import JobsService
10
11
  from .llm_gateway_service import UiPathLlmChatService, UiPathOpenAIService
@@ -25,4 +26,5 @@ __all__ = [
25
26
  "UiPathOpenAIService",
26
27
  "UiPathLlmChatService",
27
28
  "FolderService",
29
+ "EntitiesService",
28
30
  ]
@@ -0,0 +1,383 @@
1
+ from typing import Any, List, Optional, Type
2
+
3
+ from httpx import Response
4
+
5
+ from .._config import Config
6
+ from .._execution_context import ExecutionContext
7
+ from .._utils import Endpoint, RequestSpec
8
+ from ..models.entities import (
9
+ Entity,
10
+ EntityRecord,
11
+ EntityRecordsBatchResponse,
12
+ )
13
+ from ..tracing import traced
14
+ from ._base_service import BaseService
15
+
16
+
17
+ class EntitiesService(BaseService):
18
+ """Service for managing UiPath Data Service entities.
19
+
20
+ Entities are database tables in UiPath Data Service that can store
21
+ structured data for automation processes.
22
+ """
23
+
24
+ def __init__(self, config: Config, execution_context: ExecutionContext) -> None:
25
+ super().__init__(config=config, execution_context=execution_context)
26
+
27
+ @traced(name="entity_retrieve", run_type="uipath")
28
+ def retrieve(self, entity_key: str) -> Entity:
29
+ """Retrieve an entity by its key.
30
+
31
+ Args:
32
+ entity_key (str): The unique key/identifier of the entity.
33
+
34
+ Returns:
35
+ Entity: The entity with all its metadata and field definitions.
36
+ """
37
+ spec = self._retrieve_spec(entity_key)
38
+ response = self.request(spec.method, spec.endpoint)
39
+
40
+ return Entity.model_validate(response.json())
41
+
42
+ @traced(name="entity_retrieve", run_type="uipath")
43
+ async def retrieve_async(self, entity_key: str) -> Entity:
44
+ """Asynchronously retrieve an entity by its key.
45
+
46
+ Args:
47
+ entity_key (str): The unique key/identifier of the entity.
48
+
49
+ Returns:
50
+ Entity: The entity with all its metadata and field definitions.
51
+ """
52
+ spec = self._retrieve_spec(entity_key)
53
+
54
+ response = await self.request_async(spec.method, spec.endpoint)
55
+
56
+ return Entity.model_validate(response.json())
57
+
58
+ @traced(name="list_entities", run_type="uipath")
59
+ def list_entities(self) -> List[Entity]:
60
+ """List all entities in the Data Service.
61
+
62
+ Returns:
63
+ List[Entity]: A list of all entities with their metadata and field definitions.
64
+ """
65
+ spec = self._list_entities_spec()
66
+ response = self.request(spec.method, spec.endpoint)
67
+
68
+ entities_data = response.json()
69
+ return [Entity.model_validate(entity) for entity in entities_data]
70
+
71
+ @traced(name="list_entities", run_type="uipath")
72
+ async def list_entities_async(self) -> List[Entity]:
73
+ """Asynchronously list all entities in the Data Service.
74
+
75
+ Returns:
76
+ List[Entity]: A list of all entities with their metadata and field definitions.
77
+ """
78
+ spec = self._list_entities_spec()
79
+ response = await self.request_async(spec.method, spec.endpoint)
80
+
81
+ entities_data = response.json()
82
+ return [Entity.model_validate(entity) for entity in entities_data]
83
+
84
+ @traced(name="entity_list_records", run_type="uipath")
85
+ def list_records(
86
+ self,
87
+ entity_key: str,
88
+ schema: Optional[Type[Any]] = None, # Optional schema
89
+ start: Optional[int] = None,
90
+ limit: Optional[int] = None,
91
+ ) -> List[EntityRecord]:
92
+ """List records from an entity with optional pagination and schema validation.
93
+
94
+ Args:
95
+ entity_key (str): The unique key/identifier of the entity.
96
+ schema (Optional[Type[Any]]): Optional schema class for additional validation of records.
97
+ start (Optional[int]): Starting index for pagination.
98
+ limit (Optional[int]): Maximum number of records to return.
99
+
100
+ Returns:
101
+ List[EntityRecord]: A list of entity records.
102
+ """
103
+ # Example method to generate the API request specification (mocked here)
104
+ spec = self._list_records_spec(entity_key, start, limit)
105
+
106
+ # Make the HTTP request (assumes self.request exists)
107
+ response = self.request(spec.method, spec.endpoint, params=spec.params)
108
+
109
+ # Parse the response JSON and extract the "value" field
110
+ records_data = response.json().get("value", [])
111
+
112
+ # Validate and wrap records
113
+ return [
114
+ EntityRecord.from_data(data=record, model=schema) for record in records_data
115
+ ]
116
+
117
+ @traced(name="entity_list_records", run_type="uipath")
118
+ async def list_records_async(
119
+ self,
120
+ entity_key: str,
121
+ schema: Optional[Type[Any]] = None, # Optional schema
122
+ start: Optional[int] = None,
123
+ limit: Optional[int] = None,
124
+ ) -> List[EntityRecord]:
125
+ """Asynchronously list records from an entity with optional pagination and schema validation.
126
+
127
+ Args:
128
+ entity_key (str): The unique key/identifier of the entity.
129
+ schema (Optional[Type[Any]]): Optional schema class for additional validation of records.
130
+ start (Optional[int]): Starting index for pagination.
131
+ limit (Optional[int]): Maximum number of records to return.
132
+
133
+ Returns:
134
+ List[EntityRecord]: A list of entity records.
135
+ """
136
+ spec = self._list_records_spec(entity_key, start, limit)
137
+
138
+ # Make the HTTP request (assumes self.request exists)
139
+ response = await self.request_async(
140
+ spec.method, spec.endpoint, params=spec.params
141
+ )
142
+
143
+ # Parse the response JSON and extract the "value" field
144
+ records_data = response.json().get("value", [])
145
+
146
+ # Validate and wrap records
147
+ return [
148
+ EntityRecord.from_data(data=record, model=schema) for record in records_data
149
+ ]
150
+
151
+ @traced(name="entity_record_insert_batch", run_type="uipath")
152
+ def insert_records(
153
+ self,
154
+ entity_key: str,
155
+ records: List[Any],
156
+ schema: Optional[Type[Any]] = None,
157
+ ) -> EntityRecordsBatchResponse:
158
+ """Insert multiple records into an entity in a single batch operation.
159
+
160
+ Args:
161
+ entity_key (str): The unique key/identifier of the entity.
162
+ records (List[Any]): List of records to insert.
163
+ schema (Optional[Type[Any]]): Optional schema class for validation of records.
164
+
165
+ Returns:
166
+ EntityRecordsBatchResponse: Response containing successful and failed record operations.
167
+ """
168
+ spec = self._insert_batch_spec(entity_key, records)
169
+ response = self.request(spec.method, spec.endpoint, json=spec.json)
170
+
171
+ return self.validate_entity_batch(response, schema)
172
+
173
+ @traced(name="entity_record_insert_batch", run_type="uipath")
174
+ async def insert_records_async(
175
+ self,
176
+ entity_key: str,
177
+ records: List[Any],
178
+ schema: Optional[Type[Any]] = None,
179
+ ) -> EntityRecordsBatchResponse:
180
+ """Asynchronously insert multiple records into an entity in a single batch operation.
181
+
182
+ Args:
183
+ entity_key (str): The unique key/identifier of the entity.
184
+ records (List[Any]): List of records to insert.
185
+ schema (Optional[Type[Any]]): Optional schema class for validation of records.
186
+
187
+ Returns:
188
+ EntityRecordsBatchResponse: Response containing successful and failed record operations.
189
+ """
190
+ spec = self._insert_batch_spec(entity_key, records)
191
+ response = await self.request_async(spec.method, spec.endpoint, json=spec.json)
192
+
193
+ return self.validate_entity_batch(response, schema)
194
+
195
+ @traced(name="entity_record_update_batch", run_type="uipath")
196
+ def update_records(
197
+ self,
198
+ entity_key: str,
199
+ records: List[Any],
200
+ schema: Optional[Type[Any]] = None,
201
+ ) -> EntityRecordsBatchResponse:
202
+ """Update multiple records in an entity in a single batch operation.
203
+
204
+ Args:
205
+ entity_key (str): The unique key/identifier of the entity.
206
+ records (List[Any]): List of records to update.
207
+ schema (Optional[Type[Any]]): Optional schema class for validation of records.
208
+
209
+ Returns:
210
+ EntityRecordsBatchResponse: Response containing successful and failed record operations.
211
+ """
212
+ valid_records = [
213
+ EntityRecord.from_data(data=record.model_dump(by_alias=True), model=schema)
214
+ for record in records
215
+ ]
216
+
217
+ spec = self._update_batch_spec(entity_key, valid_records)
218
+ response = self.request(spec.method, spec.endpoint, json=spec.json)
219
+
220
+ return self.validate_entity_batch(response, schema)
221
+
222
+ @traced(name="entity_record_update_batch", run_type="uipath")
223
+ async def update_records_async(
224
+ self,
225
+ entity_key: str,
226
+ records: List[Any],
227
+ schema: Optional[Type[Any]] = None,
228
+ ) -> EntityRecordsBatchResponse:
229
+ """Asynchronously update multiple records in an entity in a single batch operation.
230
+
231
+ Args:
232
+ entity_key (str): The unique key/identifier of the entity.
233
+ records (List[Any]): List of records to update.
234
+ schema (Optional[Type[Any]]): Optional schema class for validation of records.
235
+
236
+ Returns:
237
+ EntityRecordsBatchResponse: Response containing successful and failed record operations.
238
+ """
239
+ valid_records = [
240
+ EntityRecord.from_data(data=record.model_dump(by_alias=True), model=schema)
241
+ for record in records
242
+ ]
243
+
244
+ spec = self._update_batch_spec(entity_key, valid_records)
245
+ response = await self.request_async(spec.method, spec.endpoint, json=spec.json)
246
+
247
+ return self.validate_entity_batch(response, schema)
248
+
249
+ @traced(name="entity_record_delete_batch", run_type="uipath")
250
+ def delete_records(
251
+ self,
252
+ entity_key: str,
253
+ record_ids: List[str],
254
+ ) -> EntityRecordsBatchResponse:
255
+ """Delete multiple records from an entity in a single batch operation.
256
+
257
+ Args:
258
+ entity_key (str): The unique key/identifier of the entity.
259
+ record_ids (List[str]): List of record IDs to delete.
260
+
261
+ Returns:
262
+ EntityRecordsBatchResponse: Response containing successful and failed record operations.
263
+ """
264
+ spec = self._delete_batch_spec(entity_key, record_ids)
265
+ response = self.request(spec.method, spec.endpoint, json=spec.json)
266
+
267
+ delete_records_response = EntityRecordsBatchResponse.model_validate(
268
+ response.json()
269
+ )
270
+
271
+ return delete_records_response
272
+
273
+ @traced(name="entity_record_delete_batch", run_type="uipath")
274
+ async def delete_records_async(
275
+ self,
276
+ entity_key: str,
277
+ record_ids: List[str],
278
+ ) -> EntityRecordsBatchResponse:
279
+ """Asynchronously delete multiple records from an entity in a single batch operation.
280
+
281
+ Args:
282
+ entity_key (str): The unique key/identifier of the entity.
283
+ record_ids (List[str]): List of record IDs to delete.
284
+
285
+ Returns:
286
+ EntityRecordsBatchResponse: Response containing successful and failed record operations.
287
+ """
288
+ spec = self._delete_batch_spec(entity_key, record_ids)
289
+ response = await self.request_async(spec.method, spec.endpoint, json=spec.json)
290
+
291
+ delete_records_response = EntityRecordsBatchResponse.model_validate(
292
+ response.json()
293
+ )
294
+
295
+ return delete_records_response
296
+
297
+ def validate_entity_batch(
298
+ self,
299
+ batch_response: Response,
300
+ schema: Optional[Type[Any]] = None,
301
+ ) -> EntityRecordsBatchResponse:
302
+ # Validate the response format
303
+ insert_records_response = EntityRecordsBatchResponse.model_validate(
304
+ batch_response.json()
305
+ )
306
+
307
+ # Validate individual records
308
+ validated_successful_records = [
309
+ EntityRecord.from_data(
310
+ data=successful_record.model_dump(by_alias=True), model=schema
311
+ )
312
+ for successful_record in insert_records_response.success_records
313
+ ]
314
+
315
+ validated_failed_records = [
316
+ EntityRecord.from_data(
317
+ data=failed_record.model_dump(by_alias=True), model=schema
318
+ )
319
+ for failed_record in insert_records_response.failure_records
320
+ ]
321
+
322
+ return EntityRecordsBatchResponse(
323
+ success_records=validated_successful_records,
324
+ failure_records=validated_failed_records,
325
+ )
326
+
327
+ def _retrieve_spec(
328
+ self,
329
+ entity_key: str,
330
+ ) -> RequestSpec:
331
+ return RequestSpec(
332
+ method="GET",
333
+ endpoint=Endpoint(f"datafabric_/api/Entity/{entity_key}"),
334
+ )
335
+
336
+ def _list_entities_spec(self) -> RequestSpec:
337
+ return RequestSpec(
338
+ method="GET",
339
+ endpoint=Endpoint("datafabric_/api/Entity"),
340
+ )
341
+
342
+ def _list_records_spec(
343
+ self,
344
+ entity_key: str,
345
+ start: Optional[int] = None,
346
+ limit: Optional[int] = None,
347
+ ) -> RequestSpec:
348
+ return RequestSpec(
349
+ method="GET",
350
+ endpoint=Endpoint(
351
+ f"datafabric_/api/EntityService/entity/{entity_key}/read"
352
+ ),
353
+ params=({"start": start, "limit": limit}),
354
+ )
355
+
356
+ def _insert_batch_spec(self, entity_key: str, records: List[Any]) -> RequestSpec:
357
+ return RequestSpec(
358
+ method="POST",
359
+ endpoint=Endpoint(
360
+ f"datafabric_/api/EntityService/entity/{entity_key}/insert-batch"
361
+ ),
362
+ json=[record.__dict__ for record in records],
363
+ )
364
+
365
+ def _update_batch_spec(
366
+ self, entity_key: str, records: List[EntityRecord]
367
+ ) -> RequestSpec:
368
+ return RequestSpec(
369
+ method="POST",
370
+ endpoint=Endpoint(
371
+ f"datafabric_/api/EntityService/entity/{entity_key}/update-batch"
372
+ ),
373
+ json=[record.model_dump(by_alias=True) for record in records],
374
+ )
375
+
376
+ def _delete_batch_spec(self, entity_key: str, record_ids: List[str]) -> RequestSpec:
377
+ return RequestSpec(
378
+ method="POST",
379
+ endpoint=Endpoint(
380
+ f"datafabric_/api/EntityService/entity/{entity_key}/delete-batch"
381
+ ),
382
+ json=record_ids,
383
+ )
uipath/_uipath.py CHANGED
@@ -13,6 +13,7 @@ from ._services import (
13
13
  BucketsService,
14
14
  ConnectionsService,
15
15
  ContextGroundingService,
16
+ EntitiesService,
16
17
  FolderService,
17
18
  JobsService,
18
19
  ProcessesService,
@@ -134,3 +135,7 @@ class UiPath:
134
135
  @property
135
136
  def llm(self) -> UiPathLlmChatService:
136
137
  return UiPathLlmChatService(self._config, self._execution_context)
138
+
139
+ @property
140
+ def entities(self) -> EntitiesService:
141
+ return EntitiesService(self._config, self._execution_context)
@@ -0,0 +1,286 @@
1
+ from enum import Enum
2
+ from typing import Any, Dict, List, Optional, Type, Union, get_args, get_origin
3
+
4
+ from pydantic import BaseModel, ConfigDict, Field, create_model
5
+
6
+
7
+ class ReferenceType(Enum):
8
+ ManyToOne = "ManyToOne"
9
+
10
+
11
+ class FieldDisplayType(Enum):
12
+ Basic = "Basic"
13
+ Relationship = "Relationship"
14
+ File = "File"
15
+ ChoiceSetSingle = "ChoiceSetSingle"
16
+ ChoiceSetMultiple = "ChoiceSetMultiple"
17
+ AutoNumber = "AutoNumber"
18
+
19
+
20
+ class DataDirectionType(Enum):
21
+ ReadOnly = "ReadOnly"
22
+ ReadAndWrite = "ReadAndWrite"
23
+
24
+
25
+ class JoinType(Enum):
26
+ LeftJoin = "LeftJoin"
27
+
28
+
29
+ class EntityType(Enum):
30
+ Entity = "Entity"
31
+ ChoiceSet = "ChoiceSet"
32
+ InternalEntity = "InternalEntity"
33
+ SystemEntity = "SystemEntity"
34
+
35
+
36
+ class EntityFieldMetadata(BaseModel):
37
+ model_config = ConfigDict(
38
+ validate_by_name=True,
39
+ )
40
+ type: str
41
+ required: bool
42
+ name: str
43
+
44
+
45
+ class ExternalConnection(BaseModel):
46
+ model_config = ConfigDict(
47
+ validate_by_name=True,
48
+ validate_by_alias=True,
49
+ )
50
+ id: str
51
+ connection_id: str = Field(alias="connectionId")
52
+ element_instance_id: str = Field(alias="elementInstanceId")
53
+ folder_id: str = Field(alias="folderKey") # named folderKey in TS SDK
54
+ connector_id: str = Field(alias="connectorKey") # named connectorKey in TS SDK
55
+ connector_name: str = Field(alias="connectorName")
56
+ connection_name: str = Field(alias="connectionName")
57
+
58
+
59
+ class ExternalFieldMapping(BaseModel):
60
+ model_config = ConfigDict(
61
+ validate_by_name=True,
62
+ validate_by_alias=True,
63
+ )
64
+ id: str
65
+ external_field_name: str = Field(alias="externalFieldName")
66
+ external_field_display_name: str = Field(alias="externalFieldDisplayName")
67
+ external_object_id: str = Field(alias="externalObjectId")
68
+ external_field_type: str = Field(alias="externalFieldType")
69
+ internal_field_id: str = Field(alias="internalFieldId")
70
+ direction_type: DataDirectionType = Field(alias="directionType")
71
+
72
+
73
+ class FieldDataType(BaseModel):
74
+ model_config = ConfigDict(
75
+ validate_by_name=True,
76
+ validate_by_alias=True,
77
+ )
78
+ name: str
79
+ length_limit: Optional[int] = Field(default=None, alias="LengthLimit")
80
+ max_value: Optional[int] = Field(default=None, alias="MaxValue")
81
+ min_value: Optional[int] = Field(default=None, alias="MinValue")
82
+ decimal_precision: Optional[int] = Field(default=None, alias="DecimalPrecision")
83
+
84
+
85
+ class FieldMetadata(BaseModel):
86
+ model_config = ConfigDict(
87
+ validate_by_name=True,
88
+ validate_by_alias=True,
89
+ )
90
+ id: Optional[str] = Field(default=None, alias="id")
91
+ name: str
92
+ is_primary_key: bool = Field(alias="isPrimaryKey")
93
+ is_foreign_key: bool = Field(alias="isForeignKey")
94
+ is_external_field: bool = Field(alias="isExternalField")
95
+ is_hidden_field: bool = Field(alias="isHiddenField")
96
+ is_unique: bool = Field(alias="isUnique")
97
+ reference_name: Optional[str] = Field(default=None, alias="referenceName")
98
+ reference_entity: Optional["Entity"] = Field(default=None, alias="referenceEntity")
99
+ reference_choiceset: Optional["Entity"] = Field(
100
+ default=None, alias="referenceChoiceset"
101
+ )
102
+ reference_field: Optional["EntityField"] = Field(
103
+ default=None, alias="referenceField"
104
+ )
105
+ reference_type: ReferenceType = Field(alias="referenceType")
106
+ sql_type: "FieldDataType" = Field(alias="sqlType")
107
+ is_required: bool = Field(alias="isRequired")
108
+ display_name: str = Field(alias="displayName")
109
+ description: Optional[str] = Field(default=None, alias="description")
110
+ is_system_field: bool = Field(alias="isSystemField")
111
+ field_display_type: Optional[str] = Field(
112
+ default=None, alias="fieldDisplayType"
113
+ ) # Should be FieldDisplayType enum
114
+ choiceset_id: Optional[str] = Field(default=None, alias="choicesetId")
115
+ default_value: Optional[str] = Field(default=None, alias="defaultValue")
116
+ is_attachment: bool = Field(alias="isAttachment")
117
+ is_rbac_enabled: bool = Field(alias="isRbacEnabled")
118
+
119
+
120
+ class ExternalField(BaseModel):
121
+ model_config = ConfigDict(
122
+ validate_by_name=True,
123
+ validate_by_alias=True,
124
+ )
125
+ field_metadata: FieldMetadata = Field(alias="fieldMetadata")
126
+ external_field_mapping_detail: ExternalFieldMapping = Field(
127
+ alias="externalFieldMappingDetail"
128
+ )
129
+
130
+
131
+ class EntityField(BaseModel):
132
+ model_config = ConfigDict(
133
+ validate_by_name=True,
134
+ )
135
+ id: Optional[str] = Field(default=None, alias="id")
136
+ definition: Optional[FieldMetadata] = Field(default=None, alias="definition")
137
+
138
+
139
+ class ExternalObject(BaseModel):
140
+ model_config = ConfigDict(
141
+ validate_by_name=True,
142
+ validate_by_alias=True,
143
+ )
144
+ id: str
145
+ external_object_name: str = Field(alias="externalObjectName")
146
+ external_object_display_name: str = Field(alias="externalObjectDisplayName")
147
+ primary_key: str = Field(alias="primaryKey")
148
+ external_connection_id: str = Field(alias="externalConnectionId")
149
+ entity_id: str = Field(alias="entityId")
150
+ is_primary_source: bool = Field(alias="isPrimarySource")
151
+
152
+
153
+ class ExternalSourceFields(BaseModel):
154
+ model_config = ConfigDict(
155
+ validate_by_name=True,
156
+ validate_by_alias=True,
157
+ )
158
+ fields: List[ExternalField]
159
+ external_object_detail: ExternalObject = Field(alias="externalObject")
160
+ external_connection_detail: ExternalConnection = Field(alias="externalConnection")
161
+
162
+
163
+ class SourceJoinCriteria(BaseModel):
164
+ model_config = ConfigDict(
165
+ validate_by_name=True,
166
+ validate_by_alias=True,
167
+ )
168
+ id: str
169
+ entity_id: str = Field(alias="entityId")
170
+ join_field_name: str = Field(alias="joinFieldName")
171
+ join_type: str = Field(alias="joinType")
172
+ related_source_object_id: str = Field(alias="relatedSourceObjectId")
173
+ related_source_object_field_name: str = Field(alias="relatedSourceObjectFieldName")
174
+ related_source_field_name: str = Field(alias="relatedSourceFieldName")
175
+
176
+
177
+ class EntityRecord(BaseModel):
178
+ model_config = {
179
+ "validate_by_name": True,
180
+ "validate_by_alias": True,
181
+ "extra": "allow",
182
+ }
183
+
184
+ id: str = Field(alias="Id") # Mandatory field validated by Pydantic
185
+
186
+ @classmethod
187
+ def from_data(
188
+ cls, data: Dict[str, Any], model: Optional[Any] = None
189
+ ) -> "EntityRecord":
190
+ """Create an EntityRecord instance by validating raw data and optionally instantiating a custom model.
191
+
192
+ :param data: Raw data dictionary for the entity.
193
+ :param model: Optional user-defined class for validation.
194
+ :return: EntityRecord instance
195
+ """
196
+ # Validate the "Id" field is mandatory and must be a string
197
+ id_value = data.get("Id", None)
198
+ if id_value is None or not isinstance(id_value, str):
199
+ raise ValueError("Field 'Id' is mandatory and must be a string.")
200
+
201
+ if model:
202
+ # Check if the model is a plain Python class or Pydantic model
203
+ cls._validate_against_user_model(data, model)
204
+
205
+ return cls(**data)
206
+
207
+ @staticmethod
208
+ def _validate_against_user_model(
209
+ data: Dict[str, Any], user_class: Type[Any]
210
+ ) -> None:
211
+ user_class_annotations = getattr(user_class, "__annotations__", None)
212
+ if user_class_annotations is None:
213
+ raise ValueError(
214
+ f"User-provided class '{user_class.__name__}' is missing type annotations."
215
+ )
216
+
217
+ # Dynamically define a Pydantic model based on the user's class annotations
218
+ # Fields must be valid type annotations directly
219
+ pydantic_fields = {}
220
+
221
+ for name, annotation in user_class_annotations.items():
222
+ is_optional = False
223
+
224
+ origin = get_origin(annotation)
225
+ args = get_args(annotation)
226
+
227
+ # Handle Optional[...] or X | None
228
+ if origin is Union and type(None) in args:
229
+ is_optional = True
230
+
231
+ # Check for optional fields
232
+ if is_optional:
233
+ pydantic_fields[name] = (annotation, None) # Not required
234
+ else:
235
+ pydantic_fields[name] = (annotation, ...) # type: ignore
236
+
237
+ # Dynamically create the Pydantic model class
238
+ dynamic_model = create_model(
239
+ f"Dynamic_{user_class.__name__}",
240
+ **pydantic_fields, # type: ignore
241
+ )
242
+
243
+ # Validate input data
244
+ dynamic_model.model_validate(data)
245
+
246
+
247
+ class Entity(BaseModel):
248
+ model_config = ConfigDict(
249
+ validate_by_name=True,
250
+ validate_by_alias=True,
251
+ )
252
+
253
+ name: str
254
+ display_name: str = Field(alias="displayName")
255
+ entity_type: str = Field(alias="entityType")
256
+ description: Optional[str] = Field(default=None, alias="description")
257
+ fields: Optional[List[FieldMetadata]] = Field(default=None, alias="fields")
258
+ external_fields: Optional[List[ExternalSourceFields]] = Field(
259
+ default=None, alias="externalFields"
260
+ )
261
+ source_join_criteria: Optional[List[SourceJoinCriteria]] = Field(
262
+ default=None, alias="sourceJoinCriteria"
263
+ )
264
+ record_count: Optional[int] = Field(default=None, alias="recordCount")
265
+ storage_size_in_mb: Optional[float] = Field(default=None, alias="storageSizeInMB")
266
+ used_storage_size_in_mb: Optional[float] = Field(
267
+ default=None, alias="usedStorageSizeInMB"
268
+ )
269
+ attachment_size_in_byte: Optional[int] = Field(
270
+ default=None, alias="attachmentSizeInBytes"
271
+ )
272
+ is_rbac_enabled: bool = Field(alias="isRbacEnabled")
273
+ id: str
274
+
275
+
276
+ class EntityRecordsBatchResponse(BaseModel):
277
+ model_config = ConfigDict(
278
+ validate_by_name=True,
279
+ validate_by_alias=True,
280
+ )
281
+
282
+ success_records: List[EntityRecord] = Field(alias="successRecords")
283
+ failure_records: List[EntityRecord] = Field(alias="failureRecords")
284
+
285
+
286
+ Entity.model_rebuild()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uipath
3
- Version: 2.1.48
3
+ Version: 2.1.50
4
4
  Summary: Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools.
5
5
  Project-URL: Homepage, https://uipath.com
6
6
  Project-URL: Repository, https://github.com/UiPath/uipath-python
@@ -2,7 +2,7 @@ uipath/__init__.py,sha256=IaeKItOOQXMa95avueJ3dAq-XcRHyZVNjcCGwlSB000,634
2
2
  uipath/_config.py,sha256=pi3qxPzDTxMEstj_XkGOgKJqD6RTHHv7vYv8sS_-d5Q,92
3
3
  uipath/_execution_context.py,sha256=Qo8VMUFgtiL-40KsZrvul5bGv1CRERle_fCw1ORCggY,2374
4
4
  uipath/_folder_context.py,sha256=D-bgxdwpwJP4b_QdVKcPODYh15kMDrOar2xNonmMSm4,1861
5
- uipath/_uipath.py,sha256=lDsF2rBurqxm24DlRan25z9SU9t9b2RkAGvoI645QSw,4314
5
+ uipath/_uipath.py,sha256=p2ccvWpzBXAGFSSF_YaaSWdEqzMmRt786d0pFWrCEwU,4463
6
6
  uipath/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  uipath/_cli/README.md,sha256=GLtCfbeIKZKNnGTCsfSVqRQ27V1btT1i2bSAyW_xZl4,474
8
8
  uipath/_cli/__init__.py,sha256=kf4GINkunFGMZkTk2Z4f1Q3-OsxpNnV6u_9BsBt1i0E,2229
@@ -59,7 +59,7 @@ uipath/_cli/_evals/_models/_agent_execution_output.py,sha256=llvApU4JkTnNgQ5DvHP
59
59
  uipath/_cli/_evals/_models/_evaluation_set.py,sha256=tVHykSget-G3sOCs9bSchMYUTpFqzXVlYYbY8L9SI0c,1518
60
60
  uipath/_cli/_evals/_models/_evaluators.py,sha256=l57NEVyYmzSKuoIXuGkE94Br01hAMg35fiS2MlTkaQM,2115
61
61
  uipath/_cli/_push/sw_file_handler.py,sha256=AX4TKM-q6CNGw3JyBW02M8ktPZuFMcAU9LN3Ii0Q2QI,18202
62
- uipath/_cli/_runtime/_contracts.py,sha256=iAjrYaKS4y4unaNnwiCityfvWMg15f7quNn32f6LFkU,28406
62
+ uipath/_cli/_runtime/_contracts.py,sha256=Mwdb11OULGg9xGSu_A6KCl7A5jw-fKe5tBiv62MZNVM,28424
63
63
  uipath/_cli/_runtime/_escalation.py,sha256=x3vI98qsfRA-fL_tNkRVTFXioM5Gv2w0GFcXJJ5eQtg,7981
64
64
  uipath/_cli/_runtime/_hitl.py,sha256=VKbM021nVg1HEDnTfucSLJ0LsDn83CKyUtVzofS2qTU,11369
65
65
  uipath/_cli/_runtime/_logging.py,sha256=MGklGKPjYKjs7J5Jy9eplA9zCDsdtEbkZdCbTwgut_4,8311
@@ -83,7 +83,7 @@ uipath/_cli/_utils/_project_files.py,sha256=a_mhBN0CLp2h56DYswjE79BP3M_LpIMYteJc
83
83
  uipath/_cli/_utils/_studio_project.py,sha256=HvzcpIIIA4hUIvMbId1dsAhmFLMuhnS2ZtyNdcpXJ8c,15422
84
84
  uipath/_cli/_utils/_tracing.py,sha256=2igb03j3EHjF_A406UhtCKkPfudVfFPjUq5tXUEG4oo,1541
85
85
  uipath/_cli/_utils/_uv_helpers.py,sha256=6SvoLnZPoKIxW0sjMvD1-ENV_HOXDYzH34GjBqwT138,3450
86
- uipath/_services/__init__.py,sha256=10xtw3ENC30yR9CCq_b94RMZ3YrUeyfHV33yWYUd8tU,896
86
+ uipath/_services/__init__.py,sha256=W08UO7ZBQRD8LBHsC6gaM4YBSUl8az0S4d6iZSKsdPE,965
87
87
  uipath/_services/_base_service.py,sha256=x9-9jhPzn9Z16KRdFHhJNvV-FZHvTniMsDfxlS4Cutk,5782
88
88
  uipath/_services/actions_service.py,sha256=2RPMR-hFMsOlqEyjIf3aF7-lrf57jdrSD0pBjj0Kyko,16040
89
89
  uipath/_services/api_client.py,sha256=kGm04ijk9AOEQd2BMxvQg-2QoB8dmyoDwFFDPyutAGw,1966
@@ -92,6 +92,7 @@ uipath/_services/attachments_service.py,sha256=NPQYK7CGjfBaNT_1S5vEAfODmOChTbQZf
92
92
  uipath/_services/buckets_service.py,sha256=5s8tuivd7GUZYj774DDUYTa0axxlUuesc4EBY1V5sdk,18496
93
93
  uipath/_services/connections_service.py,sha256=Rf-DCm43tsDM6Cfp41iwGR4gUk_YCdobGcmbSoKvQ6E,7480
94
94
  uipath/_services/context_grounding_service.py,sha256=EBf7lIIYz_s1ubf_07OAZXQHjS8kpZ2vqxo4mI3VL-A,25009
95
+ uipath/_services/entities_service.py,sha256=QKCLE6wRgq3HZraF-M2mljy-8il4vsNHrQhUgkewVVk,14028
95
96
  uipath/_services/folder_service.py,sha256=9JqgjKhWD-G_KUnfUTP2BADxL6OK9QNZsBsWZHAULdE,2749
96
97
  uipath/_services/jobs_service.py,sha256=UwsY0Cir7Yd5_mTeH0uHLmcmQZpdbT8KNx3z3F0cHZA,32775
97
98
  uipath/_services/llm_gateway_service.py,sha256=oZR--75V8ULdLjVC7lo-lJ5786J_qfXUDe0R9iWNAKs,24306
@@ -129,6 +130,7 @@ uipath/models/buckets.py,sha256=N3Lj_dVCv709-ywhOOdyCSvsuLn41eGuAfSiik6Q6F8,1285
129
130
  uipath/models/connections.py,sha256=V6Ecx10HBDO2HGaIGG8NGx4q2sEhViAoPOUgPosPfvE,2418
130
131
  uipath/models/context_grounding.py,sha256=3MaF2Fv2QYle8UUWvKGkCN5XGpx2T4a34fdbBqJ2fCs,1137
131
132
  uipath/models/context_grounding_index.py,sha256=OhRyxZDHDSrEmBFK0-JLqMMMT64jir4XkHtQ54IKtc0,2683
133
+ uipath/models/entities.py,sha256=x6jbq4o_QhgL_pCgvHFsp9O8l333kQhn8e9ZCBs72UM,9823
132
134
  uipath/models/errors.py,sha256=WCxxHBlLzLF17YxjqsFkkyBLwEQM_dc6fFU5qmBjD4A,597
133
135
  uipath/models/exceptions.py,sha256=F0ITAhJsl6Agvmnv4nxvgY5oC_lrYIlxWTLs0yx859M,1636
134
136
  uipath/models/interrupt_models.py,sha256=UzuVTMVesI204YQ4qFQFaN-gN3kksddkrujofcaC7zQ,881
@@ -145,8 +147,8 @@ uipath/tracing/_traced.py,sha256=qeVDrds2OUnpdUIA0RhtF0kg2dlAZhyC1RRkI-qivTM,185
145
147
  uipath/tracing/_utils.py,sha256=wJRELaPu69iY0AhV432Dk5QYf_N_ViRU4kAUG1BI1ew,10384
146
148
  uipath/utils/__init__.py,sha256=VD-KXFpF_oWexFg6zyiWMkxl2HM4hYJMIUDZ1UEtGx0,105
147
149
  uipath/utils/_endpoints_manager.py,sha256=iRTl5Q0XAm_YgcnMcJOXtj-8052sr6jpWuPNz6CgT0Q,8408
148
- uipath-2.1.48.dist-info/METADATA,sha256=PYtAIE5tJUVOv7QMf82ym3nhNYhitzMO9K6d0yg_yKQ,6482
149
- uipath-2.1.48.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
150
- uipath-2.1.48.dist-info/entry_points.txt,sha256=9C2_29U6Oq1ExFu7usihR-dnfIVNSKc-0EFbh0rskB4,43
151
- uipath-2.1.48.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
152
- uipath-2.1.48.dist-info/RECORD,,
150
+ uipath-2.1.50.dist-info/METADATA,sha256=4B2v7QjV8SWARnJFUKuv90VmWABDavf8JxerIpwMLfM,6482
151
+ uipath-2.1.50.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
152
+ uipath-2.1.50.dist-info/entry_points.txt,sha256=9C2_29U6Oq1ExFu7usihR-dnfIVNSKc-0EFbh0rskB4,43
153
+ uipath-2.1.50.dist-info/licenses/LICENSE,sha256=-KBavWXepyDjimmzH5fVAsi-6jNVpIKFc2kZs0Ri4ng,1058
154
+ uipath-2.1.50.dist-info/RECORD,,