|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
3 | 3 | from abc import ABC
|
4 |
| -from typing import TYPE_CHECKING, Any |
| 4 | +from typing import TYPE_CHECKING, Any, Generic, Literal, Sequence |
5 | 5 |
|
6 | 6 | from cognite.client.data_classes._base import (
|
7 | 7 | CogniteObject,
|
8 |
| - CogniteObjectUpdate, |
9 | 8 | CognitePrimitiveUpdate,
|
10 | 9 | CogniteResource,
|
11 | 10 | CogniteResourceList,
|
12 | 11 | CogniteUpdate,
|
13 | 12 | PropertySpec,
|
| 13 | + T_CogniteUpdate, |
14 | 14 | WriteableCogniteResource,
|
15 | 15 | )
|
16 | 16 | from cognite.client.data_classes.user_profiles import UserProfilesConfiguration
|
@@ -283,48 +283,202 @@ def dump(self, camel_case: bool = True) -> dict[str, Any]:
|
283 | 283 | return output
|
284 | 284 |
|
285 | 285 |
|
| 286 | +# Move into _base? |
| 287 | +class _CogniteNestedUpdate(Generic[T_CogniteUpdate]): |
| 288 | + def __init__(self, parent_object: T_CogniteUpdate, name: str) -> None: |
| 289 | + self._parent_object = parent_object |
| 290 | + self._name = name |
| 291 | + |
| 292 | + def _set(self, value: CogniteObject | None) -> T_CogniteUpdate: |
| 293 | + if self._name not in self._parent_object._update_object: |
| 294 | + self._parent_object._update_object[self._name] = {} |
| 295 | + update_object = self._parent_object._update_object[self._name] |
| 296 | + if "modify" in update_object: |
| 297 | + raise RuntimeError("Cannot set and modify the same property") |
| 298 | + if value is None: |
| 299 | + update_object["setNull"] = True |
| 300 | + else: |
| 301 | + update_object["set"] = value.dump(camel_case=True) |
| 302 | + return self._parent_object |
| 303 | + |
| 304 | + |
| 305 | +class _CogniteNestedUpdateProperty(Generic[T_CogniteUpdate]): |
| 306 | + def __init__(self, parent_object: T_CogniteUpdate, parent_name: str, name: str) -> None: |
| 307 | + self._parent_object = parent_object |
| 308 | + self._parent_name = parent_name |
| 309 | + self._name = name |
| 310 | + |
| 311 | + @property |
| 312 | + def _update_object(self) -> dict[str, Any]: |
| 313 | + if self._parent_name not in self._parent_object._update_object: |
| 314 | + self._parent_object._update_object[self._parent_name] = {} |
| 315 | + update_object = self._parent_object._update_object[self._parent_name] |
| 316 | + if "set" in update_object: |
| 317 | + raise RuntimeError("Cannot set and modify the same property") |
| 318 | + if "modify" not in update_object: |
| 319 | + update_object["modify"] = {} |
| 320 | + if self._name in update_object["modify"]: |
| 321 | + raise RuntimeError(f"Cannot modify {self._name} twice") |
| 322 | + return update_object |
| 323 | + |
| 324 | + |
| 325 | +class _CogniteNestedPrimitiveUpdate(_CogniteNestedUpdateProperty[T_CogniteUpdate]): |
| 326 | + def _set(self, value: None | str | int | bool) -> T_CogniteUpdate: |
| 327 | + update_object = self._update_object |
| 328 | + if self._parent_name == "userProfilesConfiguration" and self._name == "enabled": |
| 329 | + # Bug in Spec? |
| 330 | + update_object["modify"][self._name] = value |
| 331 | + elif value is None: |
| 332 | + update_object["modify"][self._name] = {"setNull": True} |
| 333 | + else: |
| 334 | + update_object["modify"][self._name] = {"set": value} |
| 335 | + return self._parent_object |
| 336 | + |
| 337 | + |
| 338 | +class _CogniteNestedListUpdate(_CogniteNestedUpdateProperty[T_CogniteUpdate]): |
| 339 | + def _update_modify_object( |
| 340 | + self, values: CogniteObject | Sequence[CogniteObject], word: Literal["set", "add", "remove"] |
| 341 | + ) -> T_CogniteUpdate: |
| 342 | + update_object = self._update_object |
| 343 | + value_list = [values] if isinstance(values, CogniteObject) else values |
| 344 | + if update_object["modify"].get(self._name) is not None: |
| 345 | + raise RuntimeError(f"Cannot {word} and modify the same property twice") |
| 346 | + update_object["modify"][self._name] = {word: [value.dump(camel_case=True) for value in value_list]} |
| 347 | + return self._parent_object |
| 348 | + |
| 349 | + def _set(self, values: CogniteObject | Sequence[CogniteObject]) -> T_CogniteUpdate: |
| 350 | + return self._update_modify_object(values, "set") |
| 351 | + |
| 352 | + def _add(self, values: CogniteObject | Sequence[CogniteObject]) -> T_CogniteUpdate: |
| 353 | + return self._update_modify_object(values, "add") |
| 354 | + |
| 355 | + def _remove(self, values: CogniteObject | Sequence[CogniteObject]) -> T_CogniteUpdate: |
| 356 | + return self._update_modify_object(values, "remove") |
| 357 | + |
| 358 | + |
286 | 359 | class ProjectUpdate(CogniteUpdate):
|
287 | 360 | """Changes applied to a Project.
|
288 | 361 |
|
289 | 362 | Args:
|
290 |
| - project: The Project to be updated. |
| 363 | + project (str): The Project to be updated. |
291 | 364 | """
|
292 | 365 |
|
293 |
| - class _PrimitiveProjectUpdate(CognitePrimitiveUpdate): |
| 366 | + def __init__(self, project: str) -> None: |
| 367 | + super().__init__(None, None) |
| 368 | + self._project = project |
| 369 | + |
| 370 | + class _PrimitiveProjectUpdate(CognitePrimitiveUpdate["ProjectUpdate"]): |
294 | 371 | def set(self, value: str) -> ProjectUpdate:
|
295 | 372 | return self._set(value)
|
296 | 373 |
|
297 |
| - class _OIDCProjectUpdate(CogniteObjectUpdate): |
| 374 | + class _NestedPrimitiveUpdateNullable(_CogniteNestedPrimitiveUpdate["ProjectUpdate"]): |
| 375 | + def set(self, value: str | bool | int | None) -> ProjectUpdate: |
| 376 | + return self._set(value) |
| 377 | + |
| 378 | + class _NestedPrimitiveUpdate(_CogniteNestedPrimitiveUpdate["ProjectUpdate"]): |
| 379 | + def set(self, value: str | bool | int) -> ProjectUpdate: |
| 380 | + return self._set(value) |
| 381 | + |
| 382 | + class _NestedListUpdate(_CogniteNestedListUpdate["ProjectUpdate"]): |
| 383 | + def set(self, values: Claim | Sequence[Claim]) -> ProjectUpdate: |
| 384 | + return self._set(values) |
| 385 | + |
| 386 | + def add(self, values: Claim | Sequence[Claim]) -> ProjectUpdate: |
| 387 | + return self._add(values) |
| 388 | + |
| 389 | + def remove(self, values: Claim | Sequence[Claim]) -> ProjectUpdate: |
| 390 | + return self._remove(values) |
| 391 | + |
| 392 | + class _NestedOIDCConfiguration(_CogniteNestedUpdate["ProjectUpdate"]): |
| 393 | + class _OIDCConfigurationUpdate: |
| 394 | + def __init__(self, parent_object: ProjectUpdate, name: str) -> None: |
| 395 | + self._parent_object = parent_object |
| 396 | + self._name = name |
| 397 | + |
| 398 | + @property |
| 399 | + def jwks_url(self) -> ProjectUpdate._NestedPrimitiveUpdate: |
| 400 | + return ProjectUpdate._NestedPrimitiveUpdate(self._parent_object, self._name, "jwksUrl") |
| 401 | + |
| 402 | + @property |
| 403 | + def token_url(self) -> ProjectUpdate._NestedPrimitiveUpdateNullable: |
| 404 | + return ProjectUpdate._NestedPrimitiveUpdateNullable(self._parent_object, self._name, "tokenUrl") |
| 405 | + |
| 406 | + @property |
| 407 | + def issuer(self) -> ProjectUpdate._NestedPrimitiveUpdate: |
| 408 | + return ProjectUpdate._NestedPrimitiveUpdate(self._parent_object, self._name, "issuer") |
| 409 | + |
| 410 | + @property |
| 411 | + def audience(self) -> ProjectUpdate._NestedPrimitiveUpdate: |
| 412 | + return ProjectUpdate._NestedPrimitiveUpdate(self._parent_object, self._name, "audience") |
| 413 | + |
| 414 | + @property |
| 415 | + def skew_ms(self) -> ProjectUpdate._NestedPrimitiveUpdateNullable: |
| 416 | + return ProjectUpdate._NestedPrimitiveUpdateNullable(self._parent_object, self._name, "skewMs") |
| 417 | + |
| 418 | + @property |
| 419 | + def access_claims(self) -> ProjectUpdate._NestedListUpdate: |
| 420 | + return ProjectUpdate._NestedListUpdate(self._parent_object, self._name, "accessClaims") |
| 421 | + |
| 422 | + @property |
| 423 | + def scope_claims(self) -> ProjectUpdate._NestedListUpdate: |
| 424 | + return ProjectUpdate._NestedListUpdate(self._parent_object, self._name, "scopeClaims") |
| 425 | + |
| 426 | + @property |
| 427 | + def log_claims(self) -> ProjectUpdate._NestedListUpdate: |
| 428 | + return ProjectUpdate._NestedListUpdate(self._parent_object, self._name, "logClaims") |
| 429 | + |
| 430 | + @property |
| 431 | + def is_group_callback_enabled(self) -> ProjectUpdate._NestedPrimitiveUpdateNullable: |
| 432 | + return ProjectUpdate._NestedPrimitiveUpdateNullable( |
| 433 | + self._parent_object, self._name, "isGroupCallbackEnabled" |
| 434 | + ) |
| 435 | + |
| 436 | + @property |
| 437 | + def identity_provider_scope(self) -> ProjectUpdate._NestedPrimitiveUpdateNullable: |
| 438 | + return ProjectUpdate._NestedPrimitiveUpdateNullable( |
| 439 | + self._parent_object, self._name, "identityProviderScope" |
| 440 | + ) |
| 441 | + |
298 | 442 | def set(self, value: OIDCConfiguration | None) -> ProjectUpdate:
|
299 |
| - return self._set((value and value.dump()) or {}) |
| 443 | + return self._set(value) |
300 | 444 |
|
301 |
| - def modify(self) -> ProjectUpdate: |
302 |
| - raise NotImplementedError |
| 445 | + @property |
| 446 | + def modify(self) -> _OIDCConfigurationUpdate: |
| 447 | + return self._OIDCConfigurationUpdate(self._parent_object, self._name) |
| 448 | + |
| 449 | + class _NestedUserProfilesConfiguration(_CogniteNestedUpdate["ProjectUpdate"]): |
| 450 | + class _UserProfilesConfigurationUpdate: |
| 451 | + def __init__(self, parent_object: ProjectUpdate, name: str) -> None: |
| 452 | + self._parent_object = parent_object |
| 453 | + self._name = name |
| 454 | + |
| 455 | + @property |
| 456 | + def enabled(self) -> ProjectUpdate._NestedPrimitiveUpdateNullable: |
| 457 | + return ProjectUpdate._NestedPrimitiveUpdateNullable(self._parent_object, self._name, "enabled") |
303 | 458 |
|
304 |
| - class _UserProfileProjectUpdate(CogniteObjectUpdate): |
305 | 459 | def set(self, value: UserProfilesConfiguration) -> ProjectUpdate:
|
306 |
| - return self._set(value.dump()) |
| 460 | + return self._set(value) |
307 | 461 |
|
308 |
| - def modify(self) -> ProjectUpdate: |
309 |
| - raise NotImplementedError |
| 462 | + @property |
| 463 | + def modify(self) -> _UserProfilesConfigurationUpdate: |
| 464 | + return self._UserProfilesConfigurationUpdate(self._parent_object, self._name) |
310 | 465 |
|
311 | 466 | @property
|
312 |
| - def project(self) -> ProjectUpdate._PrimitiveProjectUpdate: |
313 |
| - return ProjectUpdate._PrimitiveProjectUpdate(self, "project") |
| 467 | + def name(self) -> _PrimitiveProjectUpdate: |
| 468 | + return ProjectUpdate._PrimitiveProjectUpdate(self, "name") |
314 | 469 |
|
315 | 470 | @property
|
316 |
| - def oidc_configuration(self) -> ProjectUpdate._OIDCProjectUpdate: |
317 |
| - return ProjectUpdate._OIDCProjectUpdate(self, "oidcConfiguration") |
| 471 | + def oidc_configuration(self) -> _NestedOIDCConfiguration: |
| 472 | + return ProjectUpdate._NestedOIDCConfiguration(self, "oidcConfiguration") |
318 | 473 |
|
319 | 474 | @property
|
320 |
| - def user_profiles_configuration(self) -> ProjectUpdate._UserProfileProjectUpdate: |
321 |
| - return ProjectUpdate._UserProfileProjectUpdate(self, "userProfilesConfiguration") |
| 475 | + def user_profiles_configuration(self) -> _NestedUserProfilesConfiguration: |
| 476 | + return ProjectUpdate._NestedUserProfilesConfiguration(self, "userProfilesConfiguration") |
322 | 477 |
|
323 | 478 | @classmethod
|
324 | 479 | def _get_update_properties(cls) -> list[PropertySpec]:
|
325 | 480 | return [
|
326 |
| - # External ID is nullable, but is used in the upsert logic and thus cannot be nulled out. |
327 |
| - PropertySpec("project", is_nullable=False), |
| 481 | + PropertySpec("name", is_nullable=False), |
328 | 482 | PropertySpec("oidc_configuration", is_nullable=True),
|
329 | 483 | PropertySpec("user_profiles_configuration", is_nullable=False),
|
330 | 484 | ]
|
|
0 commit comments