0

I am writing a python script to create a user in azure devops using the python client library for azure-devops-rest-api.

I am using the add_user_entitlement() function of MemberEntitlementManagementClient.

Link to the code of that client:

https://github.com/microsoft/azure-devops-python-api/blob/dev/azure-devops/azure/devops/v5_0/member_entitlement_management/member_entitlement_management_client.py

Corresponding REST API documentation:

https://learn.microsoft.com/en-us/rest/api/azure/devops/memberentitlementmanagement/user%20entitlements/add?view=azure-devops-rest-4.1

I wrote the code:

from azure.devops.connection import Connection
from azure.devops.v5_0.member_entitlement_management.models import *
import pprint

personal_access_token = <my token>

credentials = BasicAuthentication('', personal_access_token)
connection = Connection(base_url=organization_url, creds=credentials)

member_ent_mngmnt_client = connection.clients_v5_0.get_member_entitlement_management_client()

# List member entitlements
resp = member_ent_mngmnt_client.get_user_entitlements()
print(resp)

# ------ Add user entitlement -----------------

access_level = AccessLevel("express", None, None, None, None, None, None)
print(access_level)

graph_user = GraphUser(None, None, None, None, None, None, None, "user", None, None, "[email protected]", None, None, None)
 print(graph_user)

user_entitlement = UserEntitlement(None, None, None, None, None, None, graph_user)
print(user_entitlement)

# This is to check what is sent as the request body of REST API POST request
content = member_ent_mngmnt_client._serialize.body(user_entitlement, 'UserEntitlement')
print("\n Content : \n")
print(content)    

# Add user entitlement
resp = member_ent_mngmnt_client.add_user_entitlement(user_entitlement)  

print("\n Result: \n")  
print(resp)  

But I got the output with an error msrest.exceptions.DeserializationError::

{'additional_properties': {}, 'account_license_type': 'express', 'assignment_source': None, 'license_display_name': None, 'licensing_source': None, 'msdn_license_type': None, 'status': None, 'status_message': None}

{'additional_properties': {}, '_links': None, 'descriptor': None, 'display_name': None, 'url': None, 'legacy_descriptor': None, 'origin': None, 'origin_id': None, 'subject_kind': 'user', 'domain': None, 'mail_address': None, 'principal_name': '[email protected]', 'is_deleted_in_origin': None, 'metadata_update_date': None, 'meta_type': None}

{'additional_properties': {}, 'access_level': None, 'extensions': None, 'group_assignments': None, 'id': None, 'last_accessed_date': None, 'project_entitlements': None, 'user': <azure.devops.v5_0.member_entitlement_management.models.GraphUser object at 0x000002147F444FD0>}

Content :

{'user': {'subjectKind': 'user', 'principalName': '[email protected]'}}

Traceback (most recent call last):
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1294, in _deserialize
    value = self.deserialize_data(raw_value, attr_desc['type'])
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1447, in deserialize_data
    return self.deserialize_type[iter_type](data, data_type[1:-1])
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1478, in deserialize_iter
    return [self.deserialize_data(a, iter_type) for a in attr]
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1478, in <listcomp>
    return [self.deserialize_data(a, iter_type) for a in attr]
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1447, in deserialize_data
    return self.deserialize_type[iter_type](data, data_type[1:-1])
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1494, in deserialize_dict
    return {k: self.deserialize_data(v, dict_type) for k, v in attr.items()}
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1494, in <dictcomp>
    return {k: self.deserialize_data(v, dict_type) for k, v in attr.items()}
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1449, in deserialize_data
    obj_type = self.dependencies[data_type]
KeyError: ' key: int; value: str '

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:/Users/Anjana/Desktop/scripts_O365/az_devops_clientAPI_PAT.py", line 152, in <module>
    resp = member_ent_mngmnt_client.add_user_entitlement(user_entitlement)
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\azure\devops\v5_0\member_entitlement_management\member_entitlement_management_client.py", line 184, in add_user_entitlement
    return self._deserialize('UserEntitlementsPostResponse', response)
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1228, in __call__
    return self._deserialize(target_obj, data)
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1294, in _deserialize
    value = self.deserialize_data(raw_value, attr_desc['type'])
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1460, in deserialize_data
    return self._deserialize(obj_type, data)
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1298, in _deserialize
    raise_with_traceback(DeserializationError, msg, err)
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\exceptions.py", line 51, in raise_with_traceback
    raise error.with_traceback(exc_traceback)
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1294, in _deserialize
    value = self.deserialize_data(raw_value, attr_desc['type'])
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1447, in deserialize_data
    return self.deserialize_type[iter_type](data, data_type[1:-1])
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1478, in deserialize_iter
    return [self.deserialize_data(a, iter_type) for a in attr]
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1478, in <listcomp>
    return [self.deserialize_data(a, iter_type) for a in attr]
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1447, in deserialize_data
    return self.deserialize_type[iter_type](data, data_type[1:-1])
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1494, in deserialize_dict
    return {k: self.deserialize_data(v, dict_type) for k, v in attr.items()}
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1494, in <dictcomp>
    return {k: self.deserialize_data(v, dict_type) for k, v in attr.items()}
  File "C:\Users\Anjana\AppData\Local\Programs\Python\Python37\lib\site-packages\msrest\serialization.py", line 1449, in deserialize_data
    obj_type = self.dependencies[data_type]
msrest.exceptions.DeserializationError: Unable to deserialize to object: type, KeyError: ' key: int; value: str '

Can anyone help me to solve this error?

1 Answer 1

1

The deserialization error says that python cannot deserialize the response got to an object of type UserEntitlementsPostResponse. This happens when the response is not the expected one.

I edited the add_user_entitlement() function of MemberEntitlementManagementClient class of the python client by adding a line to print the response of the POST request. The response was:

{'operationResult': {'isSuccess': False, 'errors': [{'key': 5032, 'value': 'Access Denied: This user needs the following permission(s) on the resource Users to perform this action: Add Users'}], 'userId': '261d25ad091b', 'result': None}, 'isSuccess': False, 'userEntitlement': None}

Obviously, this was not the expected result. And this cannot be converted to a UserEntitlementsPostResponse type object. Hence, the error occurred.

As the error suggests, after adding the user (who runs the script) to a group 'project collection administrators' in our azure devops organization, the script worked correctly.

This step was important as the microsoft documentation for azure devops REST API ( https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/add-organization-users?view=azure-devops#prerequisites ) says:

To access and manage users, you must have Azure DevOps project collection administrator or organization owner permissions.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.