Repository: microsoftgraph/msgraph-sdk-python-core

Issue:
Batch requests don't have `method` property in payload.
Along with other issues:

- The array of requests should be in a `requests` property
- The `url` property of each item should be relative (so the `https://graph.microsoft.com/v1.0` should be trimmed off)

@shemogumbe 
To reproduce:

```python
# Use the request builder to generate a regular
# request to /me
user_request = graph_client.me.to_get_request_information()

today = datetime.today()
tomorrow = today + timedelta(days=1)

# Use the request builder to generate a regular
# request to /me/calendarview?startDateTime="start"&endDateTime="end"
query_params = CalendarViewRequestBuilder.CalendarViewRequestBuilderGetQueryParameters(
    start_date_time=today.isoformat(timespec='seconds'),
    end_date_time=tomorrow.isoformat(timespec='seconds')
)

config = CalendarViewRequestBuilder.CalendarViewRequestBuilderGetRequestConfiguration(
    query_parameters=query_params
)
events_request = graph_client.me.calendar_view.to_get_request_information(config)

# Build the batch
user_batch_item = BatchRequestItem(request_information=user_request)
events_batch_item = BatchRequestItem(request_information=events_request)
batch_request_content = BatchRequestContentCollection()
batch_request_content.add_batch_request_item(user_batch_item)
batch_request_content.add_batch_request_item(events_batch_item)

# Create batch request builder (temporary?)
batch_request_builder = BatchRequestBuilder(request_adapter=graph_client.request_adapter)

batch_response = await batch_request_builder.post(batch_request_content)
```

This results in the following payload going over the wire. Note the `users/me-token-to-replace` in the URLs - this should have been updated to `/me`.

```json
[
  {
    "id": "1c4593e4-b600-4945-85bf-d58f552ae414",
    "url": "https://graph.microsoft.com/v1.0/me",
    "depends_on": []
  },
  {
    "id": "e4bb3047-d4eb-4ed6-b051-7f21a13f3f5f",
    "url": "https://graph.microsoft.com/v1.0/me/calendarView?endDateTime=2024-09-26T14%3A12%3A59&startDateTime=2024-09-25T14%3A12%3A59",
    "depends_on": []
  }
]
```

This results in a 400 error. The `method` property is missing in the batch items, the URLs are wrong, and the payload should be in a `requests` property. It should look like:

```json
{
  "requests": [
    {
      "id": "1c4593e4-b600-4945-85bf-d58f552ae414",
      "method": "GET",
      "url": "/me",
      "depends_on": []
    },
    {
      "id": "e4bb3047-d4eb-4ed6-b051-7f21a13f3f5f",
      "method": "GET",
      "url": "/me/calendarView?endDateTime=2024-09-26T14%3A12%3A59&startDateTime=2024-09-25T14%3A12%3A59",
      "depends_on": []
    }
  ]
}
```

Hints from issue comments:
@shemogumbe: Hello @jasonjoh thanks for raising this.

On looking it out:
1. The method property actually exists in every batch_request_item.
```python
user_batch_item = BatchRequestItem(request_information=user_request)
events_batch_item = BatchRequestItem(request_information=events_request)

print(f"User batch item properties {dir(user_batch_item)}")
print(f"Events batch item properties {dir(events_batch_item)}")
# Build the batch content
batch_request_content = BatchRequestContent()
batch_request_content.add_request(request_id=user_batch_item.id, request=user_batch_item)
batch_request_content.add_request(request_id=events_batch_item.id, request=events_batch_item)
print(f"batch_request_content: {batch_request_content.requests}")
for request_id, batch_request_item in batch_request_content.requests.items():
    print(f"ID: {request_id}")
    print(f"URL: {batch_request_item.url}")
    print(f"Method: {batch_request_item.method}")
    print(f"Headers: {batch_request_item.headers}")
    print(f"Body: {batch_request_item.body}")
```
Gives:
```
User request <kiota_abstractions.request_information.RequestInformation object at 0x0000013B14A08EE0>
Events request <kiota_abstractions.request_information.RequestInformation object at 0x0000013B14A0B490>
User batch item properties ['API_VERSION_REGEX', 'ME_TOKEN_REGEX', '__abstractmethods__', '__annotations__', '__class__', '__dataclass_fields__', '__dataclass_params__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__match_args__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', '_body', '_depends_on', '_headers', '_id', '_method', 'body', 'create_from_discriminator_value', 'create_with_urllib_request', 'depends_on', 'get_field_deserializers', 'headers', 'id', 'method', 'serialize', 'set_depends_on', 'set_url', 'url']
Events batch item properties ['API_VERSION_REGEX', 'ME_TOKEN_REGEX', '__abstractmethods__', '__annotations__', '__class__', '__dataclass_fields__', '__dataclass_params__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__match_args__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_impl', '_body', '_depends_on', '_headers', '_id', '_method', 'body', 'create_from_discriminator_value', 'create_with_urllib_request', 'depends_on', 'get_field_deserializers', 'headers', 'id', 'method', 'serialize', 'set_depends_on', 'set_url', 'url']
batch_request_content: {'e349ebe0-80ac-4bdd-869a-82d299cbc6f5': BatchRequestItem(), 'e6b2c826-d997-4961-8d39-92319935590c': BatchRequestItem()}
ID: e349ebe0-80ac-4bdd-869a-82d299cbc6f5
URL: /me
Method: Method.GET
Headers: {'accept': 'application/json'}
Body: None
ID: e6b2c826-d997-4961-8d39-92319935590c
URL: /me/calendarView?endDateTime=2024-10-09T13%3A04%3A06&startDateTime=2024-10-08T13%3A04%3A06
Method: Method.GET
Headers: {'accept': 'application/json'}
Body: None
User batch item: /me

```

The base URL is also not included in the URL as shown in the traceback above.

Also, this particular request has a 400, probably due to formating when sending the batch request, Investigating
@shemogumbe: Note that the me-token-to replace is also done and we have me, this was done last week, you might need to update to latest version for testing.@shemogumbe: When using `to_get_request_information` the value for method comes in as an Enum of [Method ](https://github.com/microsoft/kiota-abstractions-python/blob/main/kiota_abstractions/method.py) type, since the API expects a string, we get a 400, to fix this we would get the value of the Enum is Enum is passed or the tsring of string is passed, fixed in https://github.com/microsoftgraph/msgraph-sdk-python-core/pull/701

Solution patch:
diff --git a/src/msgraph_core/requests/batch_request_item.py b/src/msgraph_core/requests/batch_request_item.py
index 61fa480..3bab345 100644
--- a/src/msgraph_core/requests/batch_request_item.py
+++ b/src/msgraph_core/requests/batch_request_item.py
@@ -1,4 +1,5 @@
 import re
+import enum
 import json
 from uuid import uuid4
 from typing import List, Optional, Dict, Union, Any
@@ -39,7 +40,10 @@ class BatchRequestItem(Parsable):
         if request_information is None or not request_information.http_method:
             raise ValueError("HTTP method cannot be Null/Empty")
         self._id = id or str(uuid4())
-        self.method = request_information.http_method
+        if isinstance(request_information.http_method, enum.Enum):
+            self._method = request_information.http_method.name
+        else:
+            self._method = request_information.http_method
         self._headers = request_information.request_headers
         self._body = request_information.content
         self.url = request_information.url.replace('/users/me-token-to-replace', '/me', 1)
@@ -183,7 +187,9 @@ class BatchRequestItem(Parsable):
         Sets the HTTP method of the request item.
         Args:
             value (str): The HTTP method of the request item.
+
         """
+
         self._method = value
 
     @property


Test patch:
diff --git a/tests/requests/test_batch_request_item.py b/tests/requests/test_batch_request_item.py
index 4b14b48..2dd3d86 100644
--- a/tests/requests/test_batch_request_item.py
+++ b/tests/requests/test_batch_request_item.py
@@ -2,6 +2,7 @@ import pytest
 from unittest.mock import Mock
 from urllib.request import Request
 from kiota_abstractions.request_information import RequestInformation
+from kiota_abstractions.method import Method
 from kiota_abstractions.headers_collection import HeadersCollection as RequestHeaders
 from msgraph_core.requests.batch_request_item import BatchRequestItem, StreamInterface
 from kiota_abstractions.serialization import SerializationWriter
@@ -109,6 +110,17 @@ def test_method_property(batch_request_item):
     assert batch_request_item.method == "POST"
 
 
+def test_batch_request_item_method_enum():
+    # Create a RequestInformation instance with an enum value for http_method
+    request_info = RequestInformation()
+    request_info.http_method = Method.GET
+    request_info.url = "https://graph.microsoft.com/v1.0/me"
+    request_info.headers = RequestHeaders()
+    request_info.content = None
+    batch_request_item = BatchRequestItem(request_information=request_info)
+    assert batch_request_item.method == "GET"
+
+
 def test_depends_on_property(batch_request_item):
     batch_request_item.set_depends_on(["request1", "request2"])
     assert batch_request_item.depends_on == ["request1", "request2"]