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

Batch Requests #683

Merged
merged 72 commits into from
Sep 19, 2024
Merged

Batch Requests #683

merged 72 commits into from
Sep 19, 2024

Conversation

shemogumbe
Copy link
Contributor

@shemogumbe shemogumbe commented Sep 5, 2024

Closes #474

Overview

Allow running multiple requests in a batch and with a collection

Demo

graph_scopes = ['https://graph.microsoft.com/.default']
user_client = GraphServiceClient(credentials=token, scopes=graph_scopes)

print(f"Graph Scopes: {graph_scopes}")

# Create a mock request adapter
request_adapter = user_client.request_adapter
print(f"Request Adapter: {dir(user_client.request_adapter)}")
print(f"Request Adapter: {type(user_client.request_adapter)}")

# Create an instance of BatchRequestBuilder
batch_request_builder = BatchRequestBuilder(request_adapter)

# Create batch Items
request_info1 = RequestInformation()
request_info1.http_method = "GET"
request_info1.url = "https://graph.microsoft.com/v1.0/me"
request_info1.url = "/me"

request_info1.headers = RequestHeaders()
request_info1.headers.add("Content-Type", "application/json")

request_info2 = RequestInformation()
request_info2.http_method = "GET"
request_info2.url = "/users"
request_info2.headers = RequestHeaders()
request_info2.headers.add("Content-Type", "application/json")
# bacth request items to be added to content
batch_request_item1 = BatchRequestItem(request_information=request_info1)
batch_request_item2 = BatchRequestItem(request_information=request_info2)

# Create some mock BatchRequestItems
batch_request_content = [batch_request_item1, batch_request_item2]
batch_content = BatchRequestContent(batch_request_content)


# Function to demonstrate the usage of BatchRequestBuilder
async def main():
    # Use post_content method to send a batch request
    request_info = await batch_request_builder.to_post_request_information(batch_content)

    # Print the request information
    print("\nRequest Information:")
    print(f"HTTP Method: {request_info.http_method}")
    print(f"URL Template: {request_info.url_template}")
    print(f"Content: {request_info.content}")

    print(f"Content Type: {type(request_info.content)}")  # content is a list and not bytes
    print(f"Headers: {request_info.headers}")

    batch_response_content = await batch_request_builder.post_content(
        batch_request_content=batch_content
    )

    # Print the batch response content
    print(f"Batch Response Content: {batch_response_content.responses}")
    for response in batch_response_content.responses:
        print(f"Request ID: {response.id}, Status: {response.status}")
        print(f"Response body: {response.body}, headers: {response.headers}")
        print("-------------------------------------------------------------")

    # Use to_post_request_information method to get request information
    request_info = await batch_request_builder.to_post_request_information(batch_content)


# Run the main function
asyncio.run(main())

Output

Request Information:
HTTP Method: Method.POST
URL Template: https://graph.microsoft.com/v1.0/$batch
Content: b'{"requests": [{"id": "a4ec0d4e-5982-4e64-9e31-91644f96257a", "method": "GET", "url": "/me", "depends_on": []}, {"id": "3e81de7b-fb93-40d3-ad19-6becfaa9f573", "method": "GET", "url": "/users", "depends_on": []}]}'
Content Type: <class 'bytes'>
Headers: <kiota_abstractions.headers_collection.HeadersCollection object at 0x000002650721F2E0>
Batch Response Content: [BatchResponseItem(), BatchResponseItem()]
Request ID: 3e81de7b-fb93-40d3-ad19-6becfaa9f573, Status: 200
Response body: b"{'@odata.context': 'https://graph.microsoft.com/v1.0/$metadata#users', 'value': [{'businessPhones': ['+1 425 555 0109'], 'displayName': 'Adele Vance', 'givenName': 'Adele', 'jobTitle': 'Retail Manager', 'mail': 'AdeleV@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '18/2111', 'preferredLanguage': 'en-US', 'surname': 'Vance', 'userPrincipalName': 'AdeleV@yygbp.onmicrosoft.com', 'id': '6d57388a-534a-4347-a264-b1fa0c3d95f3'}, {'businessPhones': ['+1 858 555 0110'], 'displayName': 'Alex Wilber', 'givenName': 'Alex', 'jobTitle': 'Marketing Assistant', 'mail': 'AlexW@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '131/1104', 'preferredLanguage': 'en-US', 'surname': 'Wilber', 'userPrincipalName': 'AlexW@yygbp.onmicrosoft.com', 'id': '4c7c823e-9480-4bda-8a56-ee7bcb590653'}, {'businessPhones': ['+1 205 555 0108'], 'displayName': 'Diego Siciliani', 'givenName': 'Diego', 'jobTitle': 'HR Manager', 'mail': 'DiegoS@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '14/1108', 'preferredLanguage': 'en-US', 'surname': 'Siciliani', 'userPrincipalName': 'DiegoS@yygbp.onmicrosoft.com', 'id': '1c196809-2483-46e7-8f6f-0989a1dbe972'}, {'businessPhones': ['+1 309 555 0104'], 'displayName': 'Grady Archie', 'givenName': 'Grady', 'jobTitle': 'Designer', 'mail': 'GradyA@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '19/2109', 'preferredLanguage': 'en-US', 'surname': 'Archie', 'userPrincipalName': 'GradyA@yygbp.onmicrosoft.com', 'id': 'c046d74d-857a-445e-bec6-bd504fefd012'}, {'businessPhones': ['+1 954 555 0118'], 'displayName': 'Henrietta Mueller', 'givenName': 'Henrietta', 'jobTitle': 'Developer', 'mail': 'HenriettaM@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '18/1106', 'preferredLanguage': 'en-US', 'surname': 'Mueller', 'userPrincipalName': 'HenriettaM@yygbp.onmicrosoft.com', 'id': 'f7d237ff-b77a-4899-8d01-7de4e8aec38c'}, {'businessPhones': ['+1 918 555 0101'], 'displayName': 'Isaiah Langer', 'givenName': 'Isaiah', 'jobTitle': 'Sales Rep', 'mail': 'IsaiahL@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '20/1101', 'preferredLanguage': 'en-US', 'surname': 'Langer', 'userPrincipalName': 'IsaiahL@yygbp.onmicrosoft.com', 'id': '5bd51fd7-2952-4628-b779-df00eaf84dfe'}, {'businessPhones': ['+1 502 555 0102'], 'displayName': 'Johanna Lorenz', 'givenName': 'Johanna', 'jobTitle': 'Senior Engineer', 'mail': 'JohannaL@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '23/2102', 'preferredLanguage': 'en-US', 'surname': 'Lorenz', 'userPrincipalName': 'JohannaL@yygbp.onmicrosoft.com', 'id': 'e713fef7-85c1-46bf-b558-3a16d821fdcd'}, {'businessPhones': ['+1 980 555 0101'], 'displayName': 'Joni Sherman', 'givenName': 'Joni', 'jobTitle': 'Paralegal', 'mail': 'JoniS@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '20/1109', 'preferredLanguage': 'en-US', 'surname': 'Sherman', 'userPrincipalName': 'JoniS@yygbp.onmicrosoft.com', 'id': '81114af6-4ec3-47b2-9bf8-656be6f05789'}, {'businessPhones': ['+1 913 555 0101'], 'displayName': 'Lee Gu', 'givenName': 'Lee', 'jobTitle': 'Director', 'mail': 'LeeG@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '23/3101', 'preferredLanguage': 'en-US', 'surname': 'Gu', 'userPrincipalName': 'LeeG@yygbp.onmicrosoft.com', 'id': '465728a0-91b3-439b-8d93-20b000c89433'}, {'businessPhones': ['+1 918 555 0107'], 'displayName': 'Lidia Holloway', 'givenName': 'Lidia', 'jobTitle': 'Product Manager', 'mail': 'LidiaH@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '20/2107', 'preferredLanguage': 'en-US', 'surname': 'Holloway', 'userPrincipalName': 'LidiaH@yygbp.onmicrosoft.com', 'id': '45f92007-04bb-43c2-8729-53aa6c5cc786'}, {'businessPhones': ['+1 918 555 0104'], 'displayName': 'Lynne Robbins', 'givenName': 'Lynne', 'jobTitle': 'Planner', 'mail': 'LynneR@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '20/1104', 'preferredLanguage': 'en-US', 'surname': 'Robbins', 'userPrincipalName': 'LynneR@yygbp.onmicrosoft.com', 'id': '7da423cf-c5fe-48df-9340-7497172df0ef'}, {'businessPhones': ['+1 412 555 0109'], 'displayName': 'Megan Bowen', 'givenName': 'Megan', 'jobTitle': 'Marketing Manager', 'mail': 'MeganB@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '12/1110', 'preferredLanguage': 'en-US', 'surname': 'Bowen', 'userPrincipalName': 'MeganB@yygbp.onmicrosoft.com', 'id': 'd88e413e-2e36-4515-bddf-48d5c4b60f0d'}, {'businessPhones': ['+1 858 555 0109'], 'displayName': 'Miriam Graham', 'givenName': 'Miriam', 'jobTitle': 'Director', 'mail': 'MiriamG@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '131/2103', 'preferredLanguage': 'en-US', 'surname': 'Graham', 'userPrincipalName': 'MiriamG@yygbp.onmicrosoft.com', 'id': '03c8c919-8662-4bfa-b690-2472af79de42'}, {'businessPhones': ['+1 206 555 0105'], 'displayName': 'Nestor Wilke', 'givenName': 'Nestor', 'jobTitle': 'Director', 'mail': 'NestorW@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '36/2121', 'preferredLanguage': 'en-US', 'surname': 'Wilke', 'userPrincipalName': 'NestorW@yygbp.onmicrosoft.com', 'id': 'd5fcbdb1-4378-4e5a-b66a-8d6b750bf06e'}, {'businessPhones': ['+1 502 555 0144'], 'displayName': 'Patti Fernandez', 'givenName': 'Patti', 'jobTitle': 'President', 'mail': 'PattiF@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '15/1102', 'preferredLanguage': 'en-US', 'surname': 'Fernandez', 'userPrincipalName': 'PattiF@yygbp.onmicrosoft.com', 'id': '441ea33c-8d50-417f-b5c1-75c2fe9605fe'}, {'businessPhones': ['+20 255501070'], 'displayName': 'Pradeep Gupta', 'givenName': 'Pradeep', 'jobTitle': 'Accountant', 'mail': 'PradeepG@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': '98/2202', 'preferredLanguage': 'en-US', 'surname': 'Gupta', 'userPrincipalName': 'PradeepG@yygbp.onmicrosoft.com', 'id': '5c14e3c4-d817-471e-bf8c-05784172de03'}, {'businessPhones': [''], 'displayName': 'Shem Ogumbe', 'givenName': 'Shem', 'jobTitle': None, 'mail': 'SHEMTEE@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': None, 'preferredLanguage': 'en', 'surname': 'Ogumbe', 'userPrincipalName': 'rosoft.com', 'id': '76b4a63a-8dee-428d-b39d-404d14a7ee96'}]}", headers: {'Cache-Control': 'no-cache', 'x-ms-resource-unit': '2', 'OData-Version': '4.0', 'Content-Type': 'application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8'}
-------------------------------------------------------------
Request ID: a4ec0d4e-5982-4e64-9e31-91644f96257a, Status: 200
Response body: b"{'@odata.context': 'https://graph.microsoft.com/v1.0/$metadata#users/$entity', 'businessPhones': ['254727138748'], 'displayName': 'Shem Ogumbe', 'givenName': 'Shem', 'jobTitle': None, 'mail': 'SHEMTEE@yygbp.onmicrosoft.com', 'mobilePhone': None, 'officeLocation': None, 'preferredLanguage': 'en', 'surname': 'Ogumbe', 'userPrincipalName': 'SHEMTEE@yygbp.onmicrosoft.com', 'id': '76b4a63a-8dee-428d-b39d-404d14a7ee96'}", headers: {'Cache-Control': 'no-cache', 'x-ms-resource-unit': '1', 'OData-Version': '4.0', 'Content-Type': 'application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8'}
-------------------------------------------------------------

Optional. Ancillary topics, caveats, alternative strategies that didn't work out, anything else.

@shemogumbe
Copy link
Contributor Author

Still need to do further review.

Any chance you can update the usage to show example for

  • deserializing the batch response item into a parsable object(e.g user)
  • passing custom error mappings to handler errors

#685

Copy link

Copy link
Contributor

@Ndiritu Ndiritu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor SonarCloud issues like commented out code can be addressed.

@shemogumbe shemogumbe merged commit 99e88a0 into main Sep 19, 2024
13 checks passed
@shemogumbe shemogumbe deleted the shem/batch_requests branch September 19, 2024 12:44
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

Successfully merging this pull request may close these issues.

Batch support
3 participants