skip to Main Content

Context: I need some help understanding how can I manage the storage library of my SharePoint site.

Given I have the URL of my site as "https://mycompanyname.sharepoint.com/sites/mysitename"

I first want to "access" the site in order to get its id, in order later to get the drives under the site and manages the storage library.

Question: The problem I want to solve here is to get the Site in order to access its metadata and its id.

Permissions: I believe I have the Sites.Selected permission at Application level. I can try to ask for Sites.Read.All but it will take time. Is there a way with this least permission to get the job done somehow?

So far I tried, without success:

import os
import jwt
from typing import Optional, Literal
from azure.identity.aio import ClientSecretCredential
from msgraph import GraphServiceClient
from msgraph.generated.models.drive_item import DriveItem
from msgraph.generated.models.folder import Folder
from msgraph.generated.drives.item.items.item.content.content_request_builder import ContentRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
from msgraph.generated.models.o_data_errors.o_data_error import ODataError
from src.config.loader import CONFIG
import aiofiles
from src.utils.logger import get_logger

logger = get_logger(CONFIG.logging.name, CONFIG.logging.level)

class GraphClientSingleton():
    _client = None
    _credentials = None

    @classmethod
    def get_client(cls):
        if cls._client is None:
            # cls._authority = 'login.microsoftonline.com'
            cls._credentials = ClientSecretCredential(
                tenant_id = CONFIG.msgraph.tenant_id_sharepoint,
                client_id = CONFIG.msgraph.client_id_sharepoint,
                client_secret = CONFIG.msgraph.client_secret_sharepoint,
            )
            cls._scopes = ['https://graph.microsoft.com/.default']

            cls._client = GraphServiceClient(credentials=cls._credentials, scopes=cls._scopes)
        return cls._client

    @classmethod
    async def decode_token(cls):
        token = await cls.get_access_token()
        decoded_token = jwt.decode(token, options={"verify_signature": False})
        return decoded_token

    @classmethod
    async def get_access_token(cls):
        if cls._credentials is None:
            cls.get_client()
        
        token = await cls._credentials.get_token(*cls._scopes)
        return token.token
    
class SharePointDAO:
    def __init__(self):
        self.client = GraphClientSingleton.get_client()
        
if __name__ == "__main__":
    async def test_api():
        token = await GraphClientSingleton.decode_token()
        sp_dao = SharePointDAO()
        # Example 1
        from msgraph.generated.sites.sites_request_builder import SitesRequestBuilder
        from kiota_abstractions.base_request_configuration import RequestConfiguration
        # To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
        query_params = SitesRequestBuilder.SitesRequestBuilderGetQueryParameters(
            select = ["siteCollection", "webUrl"],
            filter = "siteCollection/root ne null",
        )
        request_configuration = RequestConfiguration(
            query_parameters = query_params,
        )
        sites = await sp_dao.client.sites.get(request_configuration = request_configuration)
        # Example 2 (not sure how to map the "real" URL with the needed url here)
        site_request_builder = sp_dao.client.sites.with_url(
            "https://graph.microsoft.com/v1.0/sites/mycompanyname.sharepoint.com:/mysitename"
        )
        site = await site_request_builder.get()
        # Example 3 (return empty list under "value")
        sites = await sp_dao.client.sites.get()
        # Example 4 (return 403 error "Access Denied")
        sites = await sp_dao.client.sites.get_all_sites.get()
        logger.info(sites)
    import asyncio
    asyncio.run(test_api())

2

Answers


  1. If you are using application permissions like Sites.Read.All, you can call getAllSites endpoint and filter the sites by webUrl.

    from msgraph import GraphServiceClient
    from msgraph.generated.sites.get_all_sites.get_all_sites_request_builder import GetAllSitesRequestBuilder
    from kiota_abstractions.base_request_configuration import RequestConfiguration
    
    graph_client = GraphServiceClient(credentials, scopes)
    
    query_params = GetAllSitesRequestBuilder.GetAllSitesRequestBuilderGetQueryParameters(
            filter = "webUrl eq 'https://mycompanyname.sharepoint.com/sites/mysitename'",
    )
    
    request_configuration = RequestConfiguration(
    query_parameters = query_params,
    )
    
    result = await graph_client.sites.get_all_sites.get(request_configuration = request_configuration)
    

    Or use $search query parameter:

    from msgraph import GraphServiceClient
    from msgraph.generated.sites.sites_request_builder import SitesRequestBuilder
    from kiota_abstractions.base_request_configuration import RequestConfiguration
    
    graph_client = GraphServiceClient(credentials, scopes)
    
    query_params = SitesRequestBuilder.SitesRequestBuilderGetQueryParameters(
            search = ""https://mycompanyname.sharepoint.com/sites/mysitename"",
    )
    
    request_configuration = RequestConfiguration(
    query_parameters = query_params,
    )
    
    result = await graph_client.sites.get(request_configuration = request_configuration)
    
    Login or Signup to reply.
  2. I agree with @user2250152, you can either filter the sites by webUrl or use $search query parameter to get specific SharePoint site ID.

    I have one SharePoint site named TestSite with below drives in it:

    GET https://graph.microsoft.com/v1.0/sites/siteId/drives
    

    Response:

    enter image description here

    To get this data using Python SDK via client credentials flow, make use of below sample code that fetches site Id first with $search and list drives data.

    import asyncio
    from azure.identity import ClientSecretCredential
    from msgraph import GraphServiceClient
    from msgraph.generated.sites.sites_request_builder import SitesRequestBuilder
    from kiota_abstractions.base_request_configuration import RequestConfiguration
    
    tenant_id = "tenantId"
    client_id = "appId"
    client_secret = "secret"
    
    site_url = "https://mytenant.sharepoint.com/sites/TestSite"
    
    credential = ClientSecretCredential(
        tenant_id=tenant_id,
        client_id=client_id,
        client_secret=client_secret
    )
    
    client = GraphServiceClient(credential)
    
    async def main():
        try:
            query_params = SitesRequestBuilder.SitesRequestBuilderGetQueryParameters(
                search=f""{site_url}""
            )
            request_configuration = RequestConfiguration(
                query_parameters=query_params
            )
            
            result = await client.sites.get(request_configuration=request_configuration)
            sites = result.value
            
            if sites:
                for site in sites:
                    print("Site ID:", site.id)
                    print("Site Name:", site.display_name)
                    print("Site Web URL:", site.web_url)
                    print("-" * 50)
    
                    site_id = site.id.split(",")[1]
                    print("Actual Site ID:", site_id)
    
                    drives = await client.sites.by_site_id(site_id).drives.get()
                    for drive in drives.value:
                        print("Drive ID:", drive.id)
                        print("Drive Name:", drive.name)
                        print("-" * 50)
            else:
                print("No site found with the specified URL.")
        except Exception as e:
            print(f"Error fetching site or drives: {e}")
    
    asyncio.run(main())
    

    Response:

    enter image description here

    Make sure to grant Sites.Read.All Microsoft Graph permission of Application type in app registration before running the code:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search