microsoftgraph / msgraph-sdk-python

MIT License
358 stars 49 forks source link

Inconsistent usage of 'select' OData system query option #661

Open baabel opened 5 months ago

baabel commented 5 months ago

Describe the bug

When I query the SharePoint API using 'expand' and 'select' query options, the API expects 'select' and not '$select'.

This is not a huge problem as I can easily change my query params to use 'select', however we cannot use the Python msgraph SDK as it always converts the special system query options with a $ prepended.

To Reproduce Steps to reproduce the behavior:

  1. Using the Developer Graph Explorer run a query similar to this:

/items$expand=fields&$select=fields/status,lastModifiedDateTime,id

  1. See error: { "error": { "code": "BadRequest", "message": "Parsing OData Select and Expand failed: Found a path with multiple navigation properties or a bad complex property path in a select clause. Please reword your query such that each level of select or expand only contains either TypeSegments or Properties.", "innerError": { "date": "2024-04-09T18:29:12", "request-id": "60cb4f4b-e5f4-48ee-8f1c-981e88440310", "client-request-id": "ed396593-a29f-0d6b-d2d7-d8dc632e4edc" } } }

Workaround 4.Change the '$select' query param to 'select' (without the dollar sign) and you get a valid response.

/items$expand=fields&select=fields/status,lastModifiedDateTime,id

Expected behavior A valid listitems response from the API using $select

Additional context This also happens on the items/{id}/versions endpoint

Documentation for OData query options indicates $select as the query param:

https://learn.microsoft.com/en-us/odata/concepts/queryoptions-overview

andrueastman commented 4 months ago

Thanks for raising this @baabel

We'll be transferring this to the python repo as this seems to be related to the python SDK.

Any chance you can provide more information on the SDK version you are using as well as a sample snippets that is producing the incorrect response?

baabel commented 4 months ago

I have python code snipped that produces the problem below.

However, a question I have is... is this an issue in the backend where it should be reading '$select' and not 'select'? This is reproducible in the graph developer portal.

   `query_params = ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters(
        expand=["fields"],
        select=["fields/TechnicalOwner/Title", "fields/TechnicalDelegate/Title", "fields/*", "*"]
    )`
    request_configuration = ItemsRequestBuilder.ItemsRequestBuilderGetRequestConfiguration(
        query_parameters=query_params,
    )
    site_id = "<your-site-id>"
    list_id = "<your-list-id>"
    request_configuration.headers.add("Prefer", "HonorNonIndexedQueriesWarningMayFailRandomly")
    items = await (self._client.sites
                   .by_site_id(site_id)
                   .lists
                   .by_list_id(list_id)
                   .items
                   .get(request_configuration))

Using version 1.1.0

python3 -m pip show msgraph-sdk Name: msgraph-sdk Version: 1.1.0 Summary: The Microsoft Graph Python SDK Home-page: Author: Author-email: Microsoft graphtooling+python@microsoft.com

The 'TechnicalDelegate' and 'TechnicalOwner' fields in the 'select' param are to get the user info for TechnicalDelegateLookupId and TechnicalOwnerLookupId fields

The fields in a valid response would look like this:

"fields": { "@odata.etag": "\"fe379188-dbbf-4618-b370-975a209fb3b8,53\"", "FileLeafRef": "S_DigitalBanking.xlsx", "Title": "Questionnaire", "Doc_x0020_Type": "ABC", "Parent_x002f_PrimaryAppID": "0009933", "TechnicalDelegate": "Brian Aabel", "TechnicalDelegateLookupId": "1100", "TechnicalOwner": "Manish Gupta", "TechnicalOwnerLookupId": "1454", ... }

My only workaround at this point is to implement my own ItemsRequestBuilder.ItemsRequestBuilderGetQueryParameters class to override the behavior of method 'get_query_parameter':

1. if original_name == "select": return "select" # Or remove this mapping

  1. change the url_template current: "{+baseurl}/sites/{site%2Did}/lists/{list%2Did}/items{?%24top,%24skip,%24search,%24filter,%24orderby,%24select,%24expand}"

workaound: "{+baseurl}/sites/{site%2Did}/lists/{list%2Did}/items{?%24top,%24skip,%24search,%24filter,%24orderby,select,%24expand}"

I got it to work, the library code generates a query param with select= instead of $select=

The workaround generates a url like this:

https://graph.microsoft.com/v1.0/sites/.sharepoint.com,,/lists//items/?$expand=fields&select=fields/TechnicalOwner/Title,fields/TechnicalDelegate/Title,fields/,

baabel commented 4 months ago

Feedback provided