Search code examples
pythonrestapiphotoazure-ad-graph-api

How to display user's image in Microsoft Graph using python


I tried using GET https://graph.microsoft.com/v1.0/me/photo/$value to get the user's image/photo but it only returns an HTTP 200 status code. How can I get the binary data?

I've also tried using the content.property as suggested in a similar post but get a .format is not an attribute of the dict.

@app.route("/photo")
def get_photo():
    token = _get_token_from_cache(app_config.SCOPE)
    if not token:
        return redirect(url_for("login"))
    photo = requests.get(app_config.PHOTO_ENDPOINT,  
            headers={'Authorization': 'Bearer ' + token['access_token']})
    print(photo.status_code)
    return photo

Solution

  • Gets a profile photo, and optionally saves a local copy. Returns a tuple of the raw photo data, HTTP status code, content type, and saved filename. Refer to this sample.

    def profile_photo(session, *, user_id='me', save_as=None):
        """Get profile photo, and optionally save a local copy.
        session = requests.Session() instance with Graph access token
        user_id = Graph id value for the user, or 'me' (default) for current user
        save_as = optional filename to save the photo locally. Should not include an
                  extension - the extension is determined by photo's content type.
        Returns a tuple of the photo (raw data), HTTP status code, content type, saved filename.
        """
    
        endpoint = 'me/photo/$value' if user_id == 'me' else f'users/{user_id}/$value'
        photo_response = session.get(api_endpoint(endpoint),
                                     stream=True)
        photo_status_code = photo_response.status_code
        if photo_response.ok:
            photo = photo_response.raw.read()
            # note we remove /$value from endpoint to get metadata endpoint
            metadata_response = session.get(api_endpoint(endpoint[:-7]))
            content_type = metadata_response.json().get('@odata.mediaContentType', '')
        else:
            photo = ''
            content_type = ''
    
        if photo and save_as:
            extension = content_type.split('/')[1]
            filename = save_as + '.' + extension
            with open(filename, 'wb') as fhandle:
                fhandle.write(photo)
        else:
            filename = ''
    
        return (photo, photo_status_code, content_type, filename)