Skip to content

Commit 2c8162e

Browse files
committed
refactor: move attribute inclusion/exclusion logic in ScimObject
1 parent 2a9d7a7 commit 2c8162e

File tree

3 files changed

+79
-61
lines changed

3 files changed

+79
-61
lines changed

scim2_models/base.py

Lines changed: 7 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -371,18 +371,18 @@ def set_complex_attribute_urns(self) -> None:
371371
from .attributes import ComplexAttribute
372372
from .attributes import is_complex_attribute
373373

374+
if isinstance(self, ComplexAttribute):
375+
main_schema = self.attribute_urn
376+
separator = "."
377+
else:
378+
main_schema = self.__class__.model_fields["schemas"].default[0]
379+
separator = ":"
380+
374381
for field_name in self.__class__.model_fields:
375382
attr_type = self.get_field_root_type(field_name)
376383
if not attr_type or not is_complex_attribute(attr_type):
377384
continue
378385

379-
if isinstance(self, ComplexAttribute):
380-
main_schema = self.attribute_urn
381-
separator = "."
382-
else:
383-
main_schema = self.__class__.model_fields["schemas"].default[0]
384-
separator = ":"
385-
386386
schema = f"{main_schema}{separator}{field_name}"
387387

388388
if attr_value := getattr(self, field_name):
@@ -505,66 +505,16 @@ def model_validate(
505505
def _prepare_model_dump(
506506
self,
507507
scim_ctx: Optional[Context] = Context.DEFAULT,
508-
attributes: Optional[list[str]] = None,
509-
excluded_attributes: Optional[list[str]] = None,
510508
**kwargs: Any,
511509
) -> dict[str, Any]:
512510
kwargs.setdefault("context", {}).setdefault("scim", scim_ctx)
513-
kwargs["context"]["scim_attributes"] = [
514-
validate_attribute_urn(attribute, self.__class__)
515-
for attribute in (attributes or [])
516-
]
517-
kwargs["context"]["scim_excluded_attributes"] = [
518-
validate_attribute_urn(attribute, self.__class__)
519-
for attribute in (excluded_attributes or [])
520-
]
521511

522512
if scim_ctx:
523513
kwargs.setdefault("exclude_none", True)
524514
kwargs.setdefault("by_alias", True)
525515

526516
return kwargs
527517

528-
def model_dump(
529-
self,
530-
*args: Any,
531-
scim_ctx: Optional[Context] = Context.DEFAULT,
532-
attributes: Optional[list[str]] = None,
533-
excluded_attributes: Optional[list[str]] = None,
534-
**kwargs: Any,
535-
) -> dict:
536-
"""Create a model representation that can be included in SCIM messages by using Pydantic :code:`BaseModel.model_dump`.
537-
538-
:param scim_ctx: If a SCIM context is passed, some default values of
539-
Pydantic :code:`BaseModel.model_dump` are tuned to generate valid SCIM
540-
messages. Pass :data:`None` to get the default Pydantic behavior.
541-
"""
542-
dump_kwargs = self._prepare_model_dump(
543-
scim_ctx, attributes, excluded_attributes, **kwargs
544-
)
545-
if scim_ctx:
546-
dump_kwargs.setdefault("mode", "json")
547-
return super().model_dump(*args, **dump_kwargs)
548-
549-
def model_dump_json(
550-
self,
551-
*args: Any,
552-
scim_ctx: Optional[Context] = Context.DEFAULT,
553-
attributes: Optional[list[str]] = None,
554-
excluded_attributes: Optional[list[str]] = None,
555-
**kwargs: Any,
556-
) -> str:
557-
"""Create a JSON model representation that can be included in SCIM messages by using Pydantic :code:`BaseModel.model_dump_json`.
558-
559-
:param scim_ctx: If a SCIM context is passed, some default values of
560-
Pydantic :code:`BaseModel.model_dump` are tuned to generate valid SCIM
561-
messages. Pass :data:`None` to get the default Pydantic behavior.
562-
"""
563-
dump_kwargs = self._prepare_model_dump(
564-
scim_ctx, attributes, excluded_attributes, **kwargs
565-
)
566-
return super().model_dump_json(*args, **dump_kwargs)
567-
568518
def get_attribute_urn(self, field_name: str) -> str:
569519
"""Build the full URN of the attribute.
570520

scim2_models/rfc7643/resource.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
from ..base import BaseModel
2727
from ..base import BaseModelType
2828
from ..reference import Reference
29-
from ..scim_object import SchemaObject
3029
from ..scim_object import ScimObject
3130
from ..utils import UNION_TYPES
3231
from ..utils import normalize_attribute_name
@@ -87,7 +86,7 @@ class Meta(ComplexAttribute):
8786
"""
8887

8988

90-
class Extension(SchemaObject):
89+
class Extension(ScimObject):
9190
@classmethod
9291
def to_schema(cls) -> "Schema":
9392
"""Build a :class:`~scim2_models.Schema` from the current extension class."""

scim2_models/scim_object.py

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,86 @@
11
"""Base SCIM object classes with schema identification."""
22

33
from typing import Annotated
4+
from typing import Any
5+
from typing import Optional
46

57
from .annotations import Required
68
from .base import BaseModel
9+
from .base import validate_attribute_urn
10+
from .context import Context
711

812

9-
class SchemaObject(BaseModel):
13+
class ScimObject(BaseModel):
1014
schemas: Annotated[list[str], Required.true]
1115
"""The "schemas" attribute is a REQUIRED attribute and is an array of
1216
Strings containing URIs that are used to indicate the namespaces of the
1317
SCIM schemas that define the attributes present in the current JSON
1418
structure."""
1519

20+
def _prepare_model_dump(
21+
self,
22+
scim_ctx: Optional[Context] = Context.DEFAULT,
23+
attributes: Optional[list[str]] = None,
24+
excluded_attributes: Optional[list[str]] = None,
25+
**kwargs: Any,
26+
) -> dict[str, Any]:
27+
kwargs = super()._prepare_model_dump(scim_ctx, **kwargs)
28+
kwargs["context"]["scim_attributes"] = [
29+
validate_attribute_urn(attribute, self.__class__)
30+
for attribute in (attributes or [])
31+
]
32+
kwargs["context"]["scim_excluded_attributes"] = [
33+
validate_attribute_urn(attribute, self.__class__)
34+
for attribute in (excluded_attributes or [])
35+
]
36+
return kwargs
1637

17-
class ScimObject(SchemaObject): ...
38+
def model_dump(
39+
self,
40+
*args: Any,
41+
scim_ctx: Optional[Context] = Context.DEFAULT,
42+
attributes: Optional[list[str]] = None,
43+
excluded_attributes: Optional[list[str]] = None,
44+
**kwargs: Any,
45+
) -> dict:
46+
"""Create a model representation that can be included in SCIM messages by using Pydantic :code:`BaseModel.model_dump`.
47+
48+
:param scim_ctx: If a SCIM context is passed, some default values of
49+
Pydantic :code:`BaseModel.model_dump` are tuned to generate valid SCIM
50+
messages. Pass :data:`None` to get the default Pydantic behavior.
51+
:param attributes: A multi-valued list of strings indicating the names of resource
52+
attributes to return in the response, overriding the set of attributes that
53+
would be returned by default.
54+
:param excluded_attributes: A multi-valued list of strings indicating the names of resource
55+
attributes to be removed from the default set of attributes to return.
56+
"""
57+
dump_kwargs = self._prepare_model_dump(
58+
scim_ctx, attributes, excluded_attributes, **kwargs
59+
)
60+
if scim_ctx:
61+
dump_kwargs.setdefault("mode", "json")
62+
return super(BaseModel, self).model_dump(*args, **dump_kwargs)
63+
64+
def model_dump_json(
65+
self,
66+
*args: Any,
67+
scim_ctx: Optional[Context] = Context.DEFAULT,
68+
attributes: Optional[list[str]] = None,
69+
excluded_attributes: Optional[list[str]] = None,
70+
**kwargs: Any,
71+
) -> str:
72+
"""Create a JSON model representation that can be included in SCIM messages by using Pydantic :code:`BaseModel.model_dump_json`.
73+
74+
:param scim_ctx: If a SCIM context is passed, some default values of
75+
Pydantic :code:`BaseModel.model_dump` are tuned to generate valid SCIM
76+
messages. Pass :data:`None` to get the default Pydantic behavior.
77+
:param attributes: A multi-valued list of strings indicating the names of resource
78+
attributes to return in the response, overriding the set of attributes that
79+
would be returned by default.
80+
:param excluded_attributes: A multi-valued list of strings indicating the names of resource
81+
attributes to be removed from the default set of attributes to return.
82+
"""
83+
dump_kwargs = self._prepare_model_dump(
84+
scim_ctx, attributes, excluded_attributes, **kwargs
85+
)
86+
return super(BaseModel, self).model_dump_json(*args, **dump_kwargs)

0 commit comments

Comments
 (0)