Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sailpoint.beta.IdentityHistoryApi.get_historical_identity fails to deserialize results #9

Open
rob-buskens-sp opened this issue Apr 30, 2024 · 1 comment

Comments

@rob-buskens-sp
Copy link

Problem:
using a valid account id (see postman output below) the following API call fails.

identity_snapshot = sailpoint.beta.IdentityHistoryApi(beta_client).get_historical_identity(id=deleted_account.id)
results in:
Traceback (most recent call last):
File "", line 1, in
File "/Users/rob.buskens/Documents/Code/isc-hidden-identities/venv/lib/python3.9/site-packages/pydantic/validate_call_decorator.py", line 59, in wrapper_function
return validate_call_wrapper(*args, **kwargs)
File "/Users/rob.buskens/Documents/Code/isc-hidden-identities/venv/lib/python3.9/site-packages/pydantic/_internal/_validate_call.py", line 81, in call
res = self.pydantic_validator.validate_python(pydantic_core.ArgsKwargs(args, kwargs))
File "/Users/rob.buskens/Documents/Code/isc-hidden-identities/venv/lib/python3.9/site-packages/sailpoint/beta/api/identity_history_api.py", line 893, in get_historical_identity
return self.api_client.response_deserialize(
File "/Users/rob.buskens/Documents/Code/isc-hidden-identities/venv/lib/python3.9/site-packages/sailpoint/beta/api_client.py", line 316, in response_deserialize
return_data = self.deserialize(response_text, response_type)
File "/Users/rob.buskens/Documents/Code/isc-hidden-identities/venv/lib/python3.9/site-packages/sailpoint/beta/api_client.py", line 392, in deserialize
return self.__deserialize(data, response_type)
File "/Users/rob.buskens/Documents/Code/isc-hidden-identities/venv/lib/python3.9/site-packages/sailpoint/beta/api_client.py", line 431, in __deserialize
return self.__deserialize_model(data, klass)
File "/Users/rob.buskens/Documents/Code/isc-hidden-identities/venv/lib/python3.9/site-packages/sailpoint/beta/api_client.py", line 733, in __deserialize_model
return klass.from_dict(data)
File "/Users/rob.buskens/Documents/Code/isc-hidden-identities/venv/lib/python3.9/site-packages/sailpoint/beta/models/identity_history_response.py", line 89, in from_dict
_obj = cls.model_validate({
File "/Users/rob.buskens/Documents/Code/isc-hidden-identities/venv/lib/python3.9/site-packages/pydantic/main.py", line 551, in model_validate
return cls.pydantic_validator.validate_python(
pydantic_core._pydantic_core.ValidationError: 5 validation errors for IdentityHistoryResponse
accessItemCount.app
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.7/v/string_type
accessItemCount.role
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.7/v/string_type
accessItemCount.entitlement
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.7/v/string_type
accessItemCount.accessProfile
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.7/v/string_type
accessItemCount.account
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.7/v/string_type

in postman for that API and id:
{
"snapshot": "2024-04-16T17:10:15.485Z",
"id": "a772b05d2d1d400a873985f4261a9323",
"displayName": "10 Black",
"attributes": {},
"deletedDate": "2024-04-16T17:10:15.485Z",
"latestEventSnapshotDate": null,
"accessItemCount": {
"app": 0,
"role": 0,
"entitlement": 0,
"accessProfile": 0,
"account": 0
}
}

doesn't like the counts coming back as numbers? may be other issues as the response object is doing validation for strings.

class IdentityHistoryResponse(BaseModel):
"""
IdentityHistoryResponse
""" # noqa: E501
id: Optional[StrictStr] = Field(default=None, description="the identity ID")
display_name: Optional[StrictStr] = Field(default=None, description="the display name of the identity", alias="displayName")
snapshot: Optional[StrictStr] = Field(default=None, description="the date when the identity record was created")
deleted_date: Optional[StrictStr] = Field(default=None, description="the date when the identity was deleted", alias="deletedDate")
access_item_count: Optional[Dict[str, StrictStr]] = Field(default=None, description="A map containing the count of each access item", alias="accessItemCount")
attributes: Optional[Dict[str, StrictStr]] = Field(default=None, description="A map containing the identity attributes")
__properties: ClassVar[List[str]] = ["id", "displayName", "snapshot", "deletedDate", "accessItemCount", "attributes"]

using 1.0.4 of the python-sdk
running under Python 3.9.6 in a venv
used the sail cli to create the project.

@rob-buskens-sp
Copy link
Author

code sample fails on deleted identities that have accounts.

  1. access item counts, are numbers, not strings.
  2. deleted identities don't have attributes
import sailpoint.v3
import sailpoint.beta
from sailpoint.configuration import Configuration
from sailpoint.paginator import Paginator
from sailpoint.v3.models.search import Search
from pprint import pprint

configuration = Configuration()

matches = 0
count = 0

with sailpoint.v3.ApiClient(configuration) as v3_client, \
     sailpoint.beta.ApiClient(configuration) as beta_client:

    deleted_accounts = Paginator.paginate(sailpoint.beta.IdentityHistoryApi(beta_client).list_historical_identities, result_limit=1000, is_deleted=True)

    for deleted_account in deleted_accounts:
        print(f'checking  account {deleted_account.display_name:<60}', end='\r')

        identity_snapshot = sailpoint.beta.IdentityHistoryApi(beta_client).get_historical_identity(id=deleted_account.id)

        if (identity_snapshot.access_item_count["account"] > 0):
            matches += 1
            print(identity_snapshot.id, identity_snapshot.display_name, "is deleted but has accounts")

        count += 1

print(f'{count} accounts were checked')

Changing two of the StrictStr to Any highlights what's off in the generated code as this allows the code to run:

class IdentityHistoryResponse(BaseModel):
IdentityHistoryResponse

access_item_count: Optional[Dict[str, ***Any***]] = Field(default=None, description="A map containing the count of each access item", alias="accessItemCount")
attributes: Optional[Dict[str, ***Any***]] = Field(default=None, description="A map containing the identity attributes")
__properties: ClassVar[List[str]] = ["id", "displayName", "snapshot", "deletedDate", "accessItemCount", "attributes"]

Seems something needs to be tweaked in the api spec, or the generator config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant