scim2-client 0.6.0__py3-none-any.whl → 0.7.0__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.
scim2_client/client.py CHANGED
@@ -2,7 +2,6 @@ import asyncio
2
2
  import sys
3
3
  from collections.abc import Collection
4
4
  from dataclasses import dataclass
5
- from typing import Optional
6
5
  from typing import TypeVar
7
6
  from typing import Union
8
7
 
@@ -40,10 +39,10 @@ CONFIG_RESOURCES = (ResourceType, Schema, ServiceProviderConfig)
40
39
  @dataclass
41
40
  class RequestPayload:
42
41
  request_kwargs: dict
43
- url: Optional[str] = None
44
- payload: Optional[dict] = None
45
- expected_types: Optional[list[type[Resource]]] = None
46
- expected_status_codes: Optional[list[int]] = None
42
+ url: str | None = None
43
+ payload: dict | None = None
44
+ expected_types: list[type[Resource]] | None = None
45
+ expected_status_codes: list[int] | None = None
47
46
 
48
47
 
49
48
  class SCIMClient:
@@ -176,9 +175,9 @@ class SCIMClient:
176
175
 
177
176
  def __init__(
178
177
  self,
179
- resource_models: Optional[Collection[type[Resource]]] = None,
180
- resource_types: Optional[Collection[ResourceType]] = None,
181
- service_provider_config: Optional[ServiceProviderConfig] = None,
178
+ resource_models: Collection[type[Resource]] | None = None,
179
+ resource_types: Collection[ResourceType] | None = None,
180
+ service_provider_config: ServiceProviderConfig | None = None,
182
181
  check_request_payload: bool = True,
183
182
  check_response_payload: bool = True,
184
183
  check_response_content_type: bool = True,
@@ -194,10 +193,10 @@ class SCIMClient:
194
193
  self.check_response_status_codes = check_response_status_codes
195
194
  self.raise_scim_errors = raise_scim_errors
196
195
 
197
- def get_resource_model(self, name: str) -> Optional[type[Resource]]:
196
+ def get_resource_model(self, name: str) -> type[Resource] | None:
198
197
  """Get a registered model by its name or its schema."""
199
198
  for resource_model in self.resource_models:
200
- schema = resource_model.model_fields["schemas"].default[0]
199
+ schema = resource_model.__schema__
201
200
  if schema == name or schema.split(":")[-1] == name:
202
201
  return resource_model
203
202
  return None
@@ -205,15 +204,18 @@ class SCIMClient:
205
204
  def _check_resource_model(
206
205
  self, resource_model: type[Resource], payload=None
207
206
  ) -> None:
208
- if (
209
- resource_model not in self.resource_models
210
- and resource_model not in CONFIG_RESOURCES
211
- ):
207
+ schema_to_check = resource_model.__schema__
208
+ for element in self.resource_models:
209
+ schema = element.__schema__
210
+ if schema_to_check == schema:
211
+ return
212
+
213
+ if resource_model not in CONFIG_RESOURCES:
212
214
  raise SCIMRequestError(
213
215
  f"Unknown resource type: '{resource_model}'", source=payload
214
216
  )
215
217
 
216
- def resource_endpoint(self, resource_model: Optional[type[Resource]]) -> str:
218
+ def resource_endpoint(self, resource_model: type[Resource] | None) -> str:
217
219
  """Find the :attr:`~scim2_models.ResourceType.endpoint` associated with a given :class:`~scim2_models.Resource`.
218
220
 
219
221
  Internally, it looks if any :paramref:`resource_type <scim2_client.SCIMClient.resource_models>`
@@ -229,7 +231,7 @@ class SCIMClient:
229
231
  if resource_model is ServiceProviderConfig:
230
232
  return "/ServiceProviderConfig"
231
233
 
232
- schema = resource_model.model_fields["schemas"].default[0]
234
+ schema = resource_model.__schema__
233
235
  for resource_type in self.resource_types or []:
234
236
  if schema == resource_type.schema_:
235
237
  return resource_type.endpoint
@@ -250,7 +252,7 @@ class SCIMClient:
250
252
  ]
251
253
 
252
254
  def _check_status_codes(
253
- self, status_code: int, expected_status_codes: Optional[list[int]]
255
+ self, status_code: int, expected_status_codes: list[int] | None
254
256
  ):
255
257
  if (
256
258
  self.check_response_status_codes
@@ -276,15 +278,15 @@ class SCIMClient:
276
278
 
277
279
  def check_response(
278
280
  self,
279
- payload: Optional[dict],
281
+ payload: dict | None,
280
282
  status_code: int,
281
283
  headers: dict,
282
- expected_status_codes: Optional[list[int]] = None,
283
- expected_types: Optional[list[type[Resource]]] = None,
284
- check_response_payload: Optional[bool] = None,
285
- raise_scim_errors: Optional[bool] = None,
286
- scim_ctx: Optional[Context] = None,
287
- ) -> Union[Error, None, dict, type[Resource]]:
284
+ expected_status_codes: list[int] | None = None,
285
+ expected_types: list[type[Resource]] | None = None,
286
+ check_response_payload: bool | None = None,
287
+ raise_scim_errors: bool | None = None,
288
+ scim_ctx: Context | None = None,
289
+ ) -> Error | None | dict | type[Resource]:
288
290
  if raise_scim_errors is None:
289
291
  raise_scim_errors = self.raise_scim_errors
290
292
 
@@ -308,10 +310,7 @@ class SCIMClient:
308
310
  self._check_status_codes(status_code, expected_status_codes)
309
311
  return response_payload
310
312
 
311
- if (
312
- response_payload
313
- and response_payload.get("schemas") == Error.model_fields["schemas"].default
314
- ):
313
+ if response_payload and response_payload.get("schemas") == [Error.__schema__]:
315
314
  error = Error.model_validate(response_payload)
316
315
  if raise_scim_errors:
317
316
  raise SCIMResponseErrorObject(obj=error.detail, source=error)
@@ -352,9 +351,9 @@ class SCIMClient:
352
351
 
353
352
  def _prepare_create_request(
354
353
  self,
355
- resource: Union[AnyResource, dict],
356
- check_request_payload: Optional[bool] = None,
357
- expected_status_codes: Optional[list[int]] = None,
354
+ resource: AnyResource | dict,
355
+ check_request_payload: bool | None = None,
356
+ expected_status_codes: list[int] | None = None,
358
357
  **kwargs,
359
358
  ) -> RequestPayload:
360
359
  req = RequestPayload(
@@ -400,11 +399,11 @@ class SCIMClient:
400
399
 
401
400
  def _prepare_query_request(
402
401
  self,
403
- resource_model: Optional[type[Resource]] = None,
404
- id: Optional[str] = None,
405
- search_request: Optional[Union[SearchRequest, dict]] = None,
406
- check_request_payload: Optional[bool] = None,
407
- expected_status_codes: Optional[list[int]] = None,
402
+ resource_model: type[Resource] | None = None,
403
+ id: str | None = None,
404
+ search_request: SearchRequest | dict | None = None,
405
+ check_request_payload: bool | None = None,
406
+ expected_status_codes: list[int] | None = None,
408
407
  **kwargs,
409
408
  ) -> RequestPayload:
410
409
  req = RequestPayload(
@@ -418,7 +417,7 @@ class SCIMClient:
418
417
  if resource_model and check_request_payload:
419
418
  self._check_resource_model(resource_model)
420
419
 
421
- payload: Optional[SearchRequest]
420
+ payload: SearchRequest | None
422
421
  if not check_request_payload:
423
422
  payload = search_request
424
423
 
@@ -437,7 +436,7 @@ class SCIMClient:
437
436
  if resource_model is None:
438
437
  req.expected_types = [
439
438
  *self.resource_models,
440
- ListResponse[Union[self.resource_models]],
439
+ ListResponse[Union[self.resource_models]], # noqa: UP007
441
440
  ]
442
441
 
443
442
  elif resource_model == ServiceProviderConfig:
@@ -456,9 +455,9 @@ class SCIMClient:
456
455
 
457
456
  def _prepare_search_request(
458
457
  self,
459
- search_request: Optional[SearchRequest] = None,
460
- check_request_payload: Optional[bool] = None,
461
- expected_status_codes: Optional[list[int]] = None,
458
+ search_request: SearchRequest | None = None,
459
+ check_request_payload: bool | None = None,
460
+ expected_status_codes: list[int] | None = None,
462
461
  **kwargs,
463
462
  ) -> RequestPayload:
464
463
  req = RequestPayload(
@@ -482,14 +481,14 @@ class SCIMClient:
482
481
  )
483
482
 
484
483
  req.url = req.request_kwargs.pop("url", "/.search")
485
- req.expected_types = [ListResponse[Union[self.resource_models]]]
484
+ req.expected_types = [ListResponse[Union[self.resource_models]]] # noqa: UP007
486
485
  return req
487
486
 
488
487
  def _prepare_delete_request(
489
488
  self,
490
489
  resource_model: type,
491
490
  id: str,
492
- expected_status_codes: Optional[list[int]] = None,
491
+ expected_status_codes: list[int] | None = None,
493
492
  **kwargs,
494
493
  ) -> RequestPayload:
495
494
  req = RequestPayload(
@@ -504,9 +503,9 @@ class SCIMClient:
504
503
 
505
504
  def _prepare_replace_request(
506
505
  self,
507
- resource: Union[AnyResource, dict],
508
- check_request_payload: Optional[bool] = None,
509
- expected_status_codes: Optional[list[int]] = None,
506
+ resource: AnyResource | dict,
507
+ check_request_payload: bool | None = None,
508
+ expected_status_codes: list[int] | None = None,
510
509
  **kwargs,
511
510
  ) -> RequestPayload:
512
511
  req = RequestPayload(
@@ -560,9 +559,9 @@ class SCIMClient:
560
559
  self,
561
560
  resource_model: type[ResourceT],
562
561
  id: str,
563
- patch_op: Union[PatchOp[ResourceT], dict],
564
- check_request_payload: Optional[bool] = None,
565
- expected_status_codes: Optional[list[int]] = None,
562
+ patch_op: PatchOp[ResourceT] | dict,
563
+ check_request_payload: bool | None = None,
564
+ expected_status_codes: list[int] | None = None,
566
565
  **kwargs,
567
566
  ) -> RequestPayload:
568
567
  """Prepare a PATCH request payload.
@@ -622,9 +621,9 @@ class SCIMClient:
622
621
  self,
623
622
  resource_model: type[ResourceT],
624
623
  id: str,
625
- patch_op: Union[PatchOp[ResourceT], dict],
624
+ patch_op: PatchOp[ResourceT] | dict,
626
625
  **kwargs,
627
- ) -> Optional[Union[ResourceT, Error, dict]]:
626
+ ) -> ResourceT | Error | dict | None:
628
627
  raise NotImplementedError()
629
628
 
630
629
  def build_resource_models(
@@ -640,13 +639,13 @@ class SCIMClient:
640
639
  for schema, resource_type in resource_types_by_schema.items():
641
640
  schema_obj = schema_objs_by_schema[schema]
642
641
  model = Resource.from_schema(schema_obj)
643
- extensions = []
642
+ extensions: tuple[type[Extension], ...] = ()
644
643
  for ext_schema in resource_type.schema_extensions or []:
645
644
  schema_obj = schema_objs_by_schema[ext_schema.schema_]
646
645
  extension = Extension.from_schema(schema_obj)
647
- extensions.append(extension)
646
+ extensions = extensions + (extension,)
648
647
  if extensions:
649
- model = model[Union[tuple(extensions)]]
648
+ model = model[Union[extensions]] # noqa: UP007
650
649
  resource_models.append(model)
651
650
 
652
651
  return tuple(resource_models)
@@ -657,15 +656,14 @@ class BaseSyncSCIMClient(SCIMClient):
657
656
 
658
657
  def create(
659
658
  self,
660
- resource: Union[AnyResource, dict],
661
- check_request_payload: Optional[bool] = None,
662
- check_response_payload: Optional[bool] = None,
663
- expected_status_codes: Optional[
664
- list[int]
665
- ] = SCIMClient.CREATION_RESPONSE_STATUS_CODES,
666
- raise_scim_errors: Optional[bool] = None,
659
+ resource: AnyResource | dict,
660
+ check_request_payload: bool | None = None,
661
+ check_response_payload: bool | None = None,
662
+ expected_status_codes: list[int]
663
+ | None = SCIMClient.CREATION_RESPONSE_STATUS_CODES,
664
+ raise_scim_errors: bool | None = None,
667
665
  **kwargs,
668
- ) -> Union[AnyResource, Error, dict]:
666
+ ) -> AnyResource | Error | dict:
669
667
  """Perform a POST request to create, as defined in :rfc:`RFC7644 §3.3 <7644#section-3.3>`.
670
668
 
671
669
  :param resource: The resource to create
@@ -703,17 +701,16 @@ class BaseSyncSCIMClient(SCIMClient):
703
701
 
704
702
  def query(
705
703
  self,
706
- resource_model: Optional[type[AnyResource]] = None,
707
- id: Optional[str] = None,
708
- search_request: Optional[Union[SearchRequest, dict]] = None,
709
- check_request_payload: Optional[bool] = None,
710
- check_response_payload: Optional[bool] = None,
711
- expected_status_codes: Optional[
712
- list[int]
713
- ] = SCIMClient.QUERY_RESPONSE_STATUS_CODES,
714
- raise_scim_errors: Optional[bool] = None,
704
+ resource_model: type[AnyResource] | None = None,
705
+ id: str | None = None,
706
+ search_request: SearchRequest | dict | None = None,
707
+ check_request_payload: bool | None = None,
708
+ check_response_payload: bool | None = None,
709
+ expected_status_codes: list[int]
710
+ | None = SCIMClient.QUERY_RESPONSE_STATUS_CODES,
711
+ raise_scim_errors: bool | None = None,
715
712
  **kwargs,
716
- ) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
713
+ ) -> AnyResource | ListResponse[AnyResource] | Error | dict:
717
714
  """Perform a GET request to read resources, as defined in :rfc:`RFC7644 §3.4.2 <7644#section-3.4.2>`.
718
715
 
719
716
  - If `id` is not :data:`None`, the resource with the exact id will be reached.
@@ -777,15 +774,14 @@ class BaseSyncSCIMClient(SCIMClient):
777
774
 
778
775
  def search(
779
776
  self,
780
- search_request: Optional[SearchRequest] = None,
781
- check_request_payload: Optional[bool] = None,
782
- check_response_payload: Optional[bool] = None,
783
- expected_status_codes: Optional[
784
- list[int]
785
- ] = SCIMClient.SEARCH_RESPONSE_STATUS_CODES,
786
- raise_scim_errors: Optional[bool] = None,
777
+ search_request: SearchRequest | None = None,
778
+ check_request_payload: bool | None = None,
779
+ check_response_payload: bool | None = None,
780
+ expected_status_codes: list[int]
781
+ | None = SCIMClient.SEARCH_RESPONSE_STATUS_CODES,
782
+ raise_scim_errors: bool | None = None,
787
783
  **kwargs,
788
- ) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
784
+ ) -> AnyResource | ListResponse[AnyResource] | Error | dict:
789
785
  """Perform a POST search request to read all available resources, as defined in :rfc:`RFC7644 §3.4.3 <7644#section-3.4.3>`.
790
786
 
791
787
  :param resource_models: Resource type or union of types expected
@@ -827,13 +823,12 @@ class BaseSyncSCIMClient(SCIMClient):
827
823
  self,
828
824
  resource_model: type,
829
825
  id: str,
830
- check_response_payload: Optional[bool] = None,
831
- expected_status_codes: Optional[
832
- list[int]
833
- ] = SCIMClient.DELETION_RESPONSE_STATUS_CODES,
834
- raise_scim_errors: Optional[bool] = None,
826
+ check_response_payload: bool | None = None,
827
+ expected_status_codes: list[int]
828
+ | None = SCIMClient.DELETION_RESPONSE_STATUS_CODES,
829
+ raise_scim_errors: bool | None = None,
835
830
  **kwargs,
836
- ) -> Optional[Union[Error, dict]]:
831
+ ) -> Error | dict | None:
837
832
  """Perform a DELETE request to create, as defined in :rfc:`RFC7644 §3.6 <7644#section-3.6>`.
838
833
 
839
834
  :param resource_model: The type of the resource to delete.
@@ -863,15 +858,14 @@ class BaseSyncSCIMClient(SCIMClient):
863
858
 
864
859
  def replace(
865
860
  self,
866
- resource: Union[AnyResource, dict],
867
- check_request_payload: Optional[bool] = None,
868
- check_response_payload: Optional[bool] = None,
869
- expected_status_codes: Optional[
870
- list[int]
871
- ] = SCIMClient.REPLACEMENT_RESPONSE_STATUS_CODES,
872
- raise_scim_errors: Optional[bool] = None,
861
+ resource: AnyResource | dict,
862
+ check_request_payload: bool | None = None,
863
+ check_response_payload: bool | None = None,
864
+ expected_status_codes: list[int]
865
+ | None = SCIMClient.REPLACEMENT_RESPONSE_STATUS_CODES,
866
+ raise_scim_errors: bool | None = None,
873
867
  **kwargs,
874
- ) -> Union[AnyResource, Error, dict]:
868
+ ) -> AnyResource | Error | dict:
875
869
  """Perform a PUT request to replace a resource, as defined in :rfc:`RFC7644 §3.5.1 <7644#section-3.5.1>`.
876
870
 
877
871
  :param resource: The new resource to replace.
@@ -912,15 +906,14 @@ class BaseSyncSCIMClient(SCIMClient):
912
906
  self,
913
907
  resource_model: type[ResourceT],
914
908
  id: str,
915
- patch_op: Union[PatchOp[ResourceT], dict],
916
- check_request_payload: Optional[bool] = None,
917
- check_response_payload: Optional[bool] = None,
918
- expected_status_codes: Optional[
919
- list[int]
920
- ] = SCIMClient.PATCH_RESPONSE_STATUS_CODES,
921
- raise_scim_errors: Optional[bool] = None,
909
+ patch_op: PatchOp[ResourceT] | dict,
910
+ check_request_payload: bool | None = None,
911
+ check_response_payload: bool | None = None,
912
+ expected_status_codes: list[int]
913
+ | None = SCIMClient.PATCH_RESPONSE_STATUS_CODES,
914
+ raise_scim_errors: bool | None = None,
922
915
  **kwargs,
923
- ) -> Optional[Union[ResourceT, Error, dict]]:
916
+ ) -> ResourceT | Error | dict | None:
924
917
  """Perform a PATCH request to modify a resource, as defined in :rfc:`RFC7644 §3.5.2 <7644#section-3.5.2>`.
925
918
 
926
919
  :param resource_model: The type of the resource to modify.
@@ -990,15 +983,14 @@ class BaseAsyncSCIMClient(SCIMClient):
990
983
 
991
984
  async def create(
992
985
  self,
993
- resource: Union[AnyResource, dict],
994
- check_request_payload: Optional[bool] = None,
995
- check_response_payload: Optional[bool] = None,
996
- expected_status_codes: Optional[
997
- list[int]
998
- ] = SCIMClient.CREATION_RESPONSE_STATUS_CODES,
999
- raise_scim_errors: Optional[bool] = None,
986
+ resource: AnyResource | dict,
987
+ check_request_payload: bool | None = None,
988
+ check_response_payload: bool | None = None,
989
+ expected_status_codes: list[int]
990
+ | None = SCIMClient.CREATION_RESPONSE_STATUS_CODES,
991
+ raise_scim_errors: bool | None = None,
1000
992
  **kwargs,
1001
- ) -> Union[AnyResource, Error, dict]:
993
+ ) -> AnyResource | Error | dict:
1002
994
  """Perform a POST request to create, as defined in :rfc:`RFC7644 §3.3 <7644#section-3.3>`.
1003
995
 
1004
996
  :param resource: The resource to create
@@ -1036,17 +1028,16 @@ class BaseAsyncSCIMClient(SCIMClient):
1036
1028
 
1037
1029
  async def query(
1038
1030
  self,
1039
- resource_model: Optional[type[Resource]] = None,
1040
- id: Optional[str] = None,
1041
- search_request: Optional[Union[SearchRequest, dict]] = None,
1042
- check_request_payload: Optional[bool] = None,
1043
- check_response_payload: Optional[bool] = None,
1044
- expected_status_codes: Optional[
1045
- list[int]
1046
- ] = SCIMClient.QUERY_RESPONSE_STATUS_CODES,
1047
- raise_scim_errors: Optional[bool] = None,
1031
+ resource_model: type[Resource] | None = None,
1032
+ id: str | None = None,
1033
+ search_request: SearchRequest | dict | None = None,
1034
+ check_request_payload: bool | None = None,
1035
+ check_response_payload: bool | None = None,
1036
+ expected_status_codes: list[int]
1037
+ | None = SCIMClient.QUERY_RESPONSE_STATUS_CODES,
1038
+ raise_scim_errors: bool | None = None,
1048
1039
  **kwargs,
1049
- ) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
1040
+ ) -> AnyResource | ListResponse[AnyResource] | Error | dict:
1050
1041
  """Perform a GET request to read resources, as defined in :rfc:`RFC7644 §3.4.2 <7644#section-3.4.2>`.
1051
1042
 
1052
1043
  - If `id` is not :data:`None`, the resource with the exact id will be reached.
@@ -1110,15 +1101,14 @@ class BaseAsyncSCIMClient(SCIMClient):
1110
1101
 
1111
1102
  async def search(
1112
1103
  self,
1113
- search_request: Optional[SearchRequest] = None,
1114
- check_request_payload: Optional[bool] = None,
1115
- check_response_payload: Optional[bool] = None,
1116
- expected_status_codes: Optional[
1117
- list[int]
1118
- ] = SCIMClient.SEARCH_RESPONSE_STATUS_CODES,
1119
- raise_scim_errors: Optional[bool] = None,
1104
+ search_request: SearchRequest | None = None,
1105
+ check_request_payload: bool | None = None,
1106
+ check_response_payload: bool | None = None,
1107
+ expected_status_codes: list[int]
1108
+ | None = SCIMClient.SEARCH_RESPONSE_STATUS_CODES,
1109
+ raise_scim_errors: bool | None = None,
1120
1110
  **kwargs,
1121
- ) -> Union[AnyResource, ListResponse[AnyResource], Error, dict]:
1111
+ ) -> AnyResource | ListResponse[AnyResource] | Error | dict:
1122
1112
  """Perform a POST search request to read all available resources, as defined in :rfc:`RFC7644 §3.4.3 <7644#section-3.4.3>`.
1123
1113
 
1124
1114
  :param resource_models: Resource type or union of types expected
@@ -1160,13 +1150,12 @@ class BaseAsyncSCIMClient(SCIMClient):
1160
1150
  self,
1161
1151
  resource_model: type,
1162
1152
  id: str,
1163
- check_response_payload: Optional[bool] = None,
1164
- expected_status_codes: Optional[
1165
- list[int]
1166
- ] = SCIMClient.DELETION_RESPONSE_STATUS_CODES,
1167
- raise_scim_errors: Optional[bool] = None,
1153
+ check_response_payload: bool | None = None,
1154
+ expected_status_codes: list[int]
1155
+ | None = SCIMClient.DELETION_RESPONSE_STATUS_CODES,
1156
+ raise_scim_errors: bool | None = None,
1168
1157
  **kwargs,
1169
- ) -> Optional[Union[Error, dict]]:
1158
+ ) -> Error | dict | None:
1170
1159
  """Perform a DELETE request to create, as defined in :rfc:`RFC7644 §3.6 <7644#section-3.6>`.
1171
1160
 
1172
1161
  :param resource_model: The type of the resource to delete.
@@ -1196,15 +1185,14 @@ class BaseAsyncSCIMClient(SCIMClient):
1196
1185
 
1197
1186
  async def replace(
1198
1187
  self,
1199
- resource: Union[AnyResource, dict],
1200
- check_request_payload: Optional[bool] = None,
1201
- check_response_payload: Optional[bool] = None,
1202
- expected_status_codes: Optional[
1203
- list[int]
1204
- ] = SCIMClient.REPLACEMENT_RESPONSE_STATUS_CODES,
1205
- raise_scim_errors: Optional[bool] = None,
1188
+ resource: AnyResource | dict,
1189
+ check_request_payload: bool | None = None,
1190
+ check_response_payload: bool | None = None,
1191
+ expected_status_codes: list[int]
1192
+ | None = SCIMClient.REPLACEMENT_RESPONSE_STATUS_CODES,
1193
+ raise_scim_errors: bool | None = None,
1206
1194
  **kwargs,
1207
- ) -> Union[AnyResource, Error, dict]:
1195
+ ) -> AnyResource | Error | dict:
1208
1196
  """Perform a PUT request to replace a resource, as defined in :rfc:`RFC7644 §3.5.1 <7644#section-3.5.1>`.
1209
1197
 
1210
1198
  :param resource: The new resource to replace.
@@ -1245,15 +1233,14 @@ class BaseAsyncSCIMClient(SCIMClient):
1245
1233
  self,
1246
1234
  resource_model: type[ResourceT],
1247
1235
  id: str,
1248
- patch_op: Union[PatchOp[ResourceT], dict],
1249
- check_request_payload: Optional[bool] = None,
1250
- check_response_payload: Optional[bool] = None,
1251
- expected_status_codes: Optional[
1252
- list[int]
1253
- ] = SCIMClient.PATCH_RESPONSE_STATUS_CODES,
1254
- raise_scim_errors: Optional[bool] = None,
1236
+ patch_op: PatchOp[ResourceT] | dict,
1237
+ check_request_payload: bool | None = None,
1238
+ check_response_payload: bool | None = None,
1239
+ expected_status_codes: list[int]
1240
+ | None = SCIMClient.PATCH_RESPONSE_STATUS_CODES,
1241
+ raise_scim_errors: bool | None = None,
1255
1242
  **kwargs,
1256
- ) -> Optional[Union[ResourceT, Error, dict]]:
1243
+ ) -> ResourceT | Error | dict | None:
1257
1244
  """Perform a PATCH request to modify a resource, as defined in :rfc:`RFC7644 §3.5.2 <7644#section-3.5.2>`.
1258
1245
 
1259
1246
  :param resource_model: The type of the resource to modify.