Skip to content

Commit 1d427f2

Browse files
committed
fix(requests): approvedBy/rejectedBy are lists for multi-approver requests (BLDX-1611)
Live kill-argo testing: listing a page containing already-actioned requests crashed with a pydantic ValidationError — the server returns rejectedBy/approvedBy as arrays (multi-approver), while the model (copied from atlan-java, which is stale here) typed them str. Now Union[str, List[str]] with a regression test parsing an actioned record.
1 parent 1ba7d9f commit 1d427f2

2 files changed

Lines changed: 28 additions & 5 deletions

File tree

pyatlan/model/atlan_request.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from __future__ import annotations
55

66
import json
7-
from typing import Any, Dict, Generator, List, Optional
7+
from typing import Any, Dict, Generator, List, Optional, Union
88

99
from pydantic.v1 import Field, PrivateAttr, ValidationError, parse_obj_as
1010

@@ -132,11 +132,19 @@ class AtlanRequest(AtlanObject):
132132
default=None,
133133
description="How the request must be approved: `single`, `unanimous` or `consesus`.",
134134
)
135-
approved_by: Optional[str] = Field(
136-
default=None, description="User who approved the request, if approved."
135+
approved_by: Optional[Union[str, List[str]]] = Field(
136+
default=None,
137+
description=(
138+
"User(s) who approved the request — a list when the request "
139+
"has multiple approvers."
140+
),
137141
)
138-
rejected_by: Optional[str] = Field(
139-
default=None, description="User who rejected the request, if rejected."
142+
rejected_by: Optional[Union[str, List[str]]] = Field(
143+
default=None,
144+
description=(
145+
"User(s) who rejected the request — a list when the request "
146+
"has multiple approvers."
147+
),
140148
)
141149
status: Optional[str] = Field(
142150
default=None,

tests/unit/test_requests_client.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,21 @@ def test_list_with_typed_filter(client, mock_api_caller):
8282
mock_api_caller.reset_mock()
8383

8484

85+
def test_actioned_records_with_list_approvers_parse():
86+
"""rejectedBy/approvedBy come back as LISTS for multi-approver requests —
87+
a page containing already-actioned records must parse (regression: the
88+
str-typed fields crashed list() on any tenant with actioned requests)."""
89+
actioned = {
90+
**RAW_REQUEST,
91+
"status": "rejected",
92+
"rejectedBy": ["admin-one", "admin-two"],
93+
"approvedBy": [],
94+
}
95+
parsed = AtlanRequest(**actioned)
96+
assert parsed.rejected_by == ["admin-one", "admin-two"]
97+
assert parsed.approved_by == []
98+
99+
85100
def test_filter_builder_combines_with_and():
86101
"""Multiple typed filters combine with AND; enums serialize to their
87102
wire values."""

0 commit comments

Comments
 (0)