diff --git a/ayon_api/_api.py b/ayon_api/_api.py index e7af02f25..acdd838d9 100644 --- a/ayon_api/_api.py +++ b/ayon_api/_api.py @@ -868,6 +868,7 @@ def get_user_by_name( def get_user( username: str | None = None, own_attributes: bool = False, + fill_attrib: bool = True, ) -> dict[str, Any] | None: """Get user info using REST endpoint. @@ -878,6 +879,9 @@ def get_user( own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on user, other attributes have 'None' value. + fill_attrib (bool): Fill missing attributes in 'attrib' with their + default values. Requires an additional request for user + attributes. Use 'False' when attributes are not needed. Returns: dict[str, Any] | None: User info or None if user is not @@ -888,6 +892,7 @@ def get_user( return con.get_user( username=username, own_attributes=own_attributes, + fill_attrib=fill_attrib, ) diff --git a/ayon_api/_api_helpers/base.py b/ayon_api/_api_helpers/base.py index 6110b5e0d..28b9798c0 100644 --- a/ayon_api/_api_helpers/base.py +++ b/ayon_api/_api_helpers/base.py @@ -132,6 +132,7 @@ def get_user( self, username: Optional[str] = None, own_attributes: bool = False, + fill_attrib: bool = True, ) -> Optional[dict[str, Any]]: raise NotImplementedError() diff --git a/ayon_api/_api_helpers/workfiles.py b/ayon_api/_api_helpers/workfiles.py index 67991da54..0278c60f7 100644 --- a/ayon_api/_api_helpers/workfiles.py +++ b/ayon_api/_api_helpers/workfiles.py @@ -224,7 +224,7 @@ def create_workfile_entity( major, minor, patch, _, _ = self.get_server_version_tuple() if (major, minor, patch) < (1, 1, 3): - user = self.get_user() + user = self.get_user(fill_attrib=False) username = user["name"] create_data["createdBy"] = username create_data["updatedBy"] = username diff --git a/ayon_api/server_api.py b/ayon_api/server_api.py index 41ac0eaf9..999a2f55b 100644 --- a/ayon_api/server_api.py +++ b/ayon_api/server_api.py @@ -1259,6 +1259,7 @@ def get_user( self, username: str | None = None, own_attributes: bool = False, + fill_attrib: bool = True, ) -> dict[str, Any] | None: """Get user info using REST endpoint. @@ -1269,6 +1270,9 @@ def get_user( own_attributes (bool): Fill 'own_attributes' with attribute values that are explicitly set on user, other attributes have 'None' value. + fill_attrib (bool): Fill missing attributes in 'attrib' with their + default values. Requires an additional request for user + attributes. Use 'False' when attributes are not needed. Returns: dict[str, Any] | None: User info or None if user is not @@ -1284,9 +1288,10 @@ def get_user( response.raise_for_status() user = response.data - attributes = self.get_attributes_for_type("user") - for attr_name, attr_data in attributes.items(): - user["attrib"].setdefault(attr_name, attr_data["default"]) + if fill_attrib: + attributes = self.get_attributes_for_type("user") + for attr_name, attr_data in attributes.items(): + user["attrib"].setdefault(attr_name, attr_data["default"]) # NOTE 'ownAttrib' is always filled for backwards compatibility fill_own_attribs(user) @@ -1372,7 +1377,7 @@ def login( """ if self.has_valid_token: try: - user_info = self.get_user() + user_info = self.get_user(fill_attrib=False) except UnauthorizedError: user_info = {} diff --git a/tests/test_get_user_attrib.py b/tests/test_get_user_attrib.py new file mode 100644 index 000000000..dee572a69 --- /dev/null +++ b/tests/test_get_user_attrib.py @@ -0,0 +1,66 @@ +"""'get_user' fills default attribute values only if 'fill_attrib' is 'True'. + +Does not require running AYON server. +""" +import pytest + +from ayon_api.server_api import ServerAPI +from ayon_api.utils import RestApiResponse + + +class FakeResponse: + status_code = 200 + + def raise_for_status(self): + pass + + +@pytest.fixture +def con(monkeypatch): + con = ServerAPI("http://localhost:0", create_session=False) + requested = [] + + def get(entrypoint, **kwargs): + requested.append(entrypoint) + return RestApiResponse(FakeResponse(), { + "name": "artist", + "attrib": {"email": "artist@example.com"}, + "ownAttrib": ["email"], + }) + + def get_attributes_for_type(entity_type): + requested.append(f"attributes/{entity_type}") + return { + "email": {"default": None}, + "fullName": {"default": ""}, + } + + monkeypatch.setattr(con, "get", get) + monkeypatch.setattr( + con, "get_attributes_for_type", get_attributes_for_type + ) + con.requested = requested + return con + + +def test_get_user_fills_default_attributes(con): + user = con.get_user("artist") + assert con.requested == ["users/artist", "attributes/user"] + assert user["attrib"] == { + "email": "artist@example.com", + "fullName": "", + } + + +def test_get_user_without_attributes(con): + user = con.get_user("artist", fill_attrib=False) + assert con.requested == ["users/artist"] + assert user["name"] == "artist" + assert user["attrib"] == {"email": "artist@example.com"} + assert "own_attributes" not in user + + +def test_get_user_without_attributes_own_attributes(con): + user = con.get_user("artist", own_attributes=True, fill_attrib=False) + assert con.requested == ["users/artist"] + assert user["own_attributes"] == {"email": "artist@example.com"}