import os import streamlit as st import requests import msal import secrets # Configuration APPLICATION_ID = os.getenv('APPLICATION_ID_KEY') CLIENT_SECRET = os.getenv('CLIENT_SECRET_KEY') AUTHORITY = 'https://login.microsoftonline.com/common' REDIRECT_URI = 'https://huggingface.co/spaces/awacke1/MSGraphAPI' SCOPES = ['User.Read', 'Calendars.ReadWrite', 'Mail.ReadWrite'] # MSAL setup def get_msal_app(): return msal.ConfidentialClientApplication( client_id=APPLICATION_ID, client_credential=CLIENT_SECRET, authority=AUTHORITY ) # Authentication functions def generate_auth_url(): msal_app = get_msal_app() state = secrets.token_urlsafe(32) st.session_state['auth_state'] = state return msal_app.get_authorization_request_url( scopes=SCOPES, redirect_uri=REDIRECT_URI, state=state ) def get_token_from_code(code): msal_app = get_msal_app() result = msal_app.acquire_token_by_authorization_code( code=code, scopes=SCOPES, redirect_uri=REDIRECT_URI ) if 'access_token' in result: return result else: raise Exception(f"Error acquiring token: {result.get('error_description')}") def get_token_from_cache(): if 'token_cache' in st.session_state: msal_app = get_msal_app() accounts = msal_app.get_accounts() if accounts: result = msal_app.acquire_token_silent(SCOPES, account=accounts[0]) if result: return result return None # API call function def make_api_call(endpoint, token): headers = {'Authorization': f'Bearer {token}'} response = requests.get(f'https://graph.microsoft.com/v1.0/{endpoint}', headers=headers) if response.status_code == 200: return response.json() else: st.error(f"API call failed: {response.status_code} - {response.text}") return None # Main application def main(): st.title("🦄 MS Graph API Integration") # Check for authentication token = get_token_from_cache() if 'code' in st.query_params: state = st.query_params.get('state') if state != st.session_state.get('auth_state'): st.error("Invalid state parameter. Please try logging in again.") st.session_state.clear() st.rerun() try: token = get_token_from_code(st.query_params['code']) st.session_state['token_cache'] = token st.success("Successfully authenticated!") st.rerun() except Exception as e: st.error(f"Authentication failed: {str(e)}") st.session_state.clear() if not token: auth_url = generate_auth_url() st.write("Please log in to continue:") st.markdown(f"[Login with Microsoft]({auth_url})") return # User is authenticated, show the main app st.sidebar.success("Authenticated successfully!") # Display user info user_info = make_api_call('me', token['access_token']) if user_info: st.sidebar.write(f"Welcome, {user_info.get('displayName', 'User')}!") # App functionality option = st.sidebar.selectbox( "Choose a function", ["View Emails", "View Calendar", "View OneDrive Files"] ) if option == "View Emails": emails = make_api_call('me/messages?$top=10', token['access_token']) if emails: for email in emails['value']: st.write(f"Subject: {email['subject']}") st.write(f"From: {email['from']['emailAddress']['name']}") st.write("---") elif option == "View Calendar": events = make_api_call('me/events?$top=10', token['access_token']) if events: for event in events['value']: st.write(f"Event: {event['subject']}") st.write(f"Start: {event['start']['dateTime']}") st.write("---") elif option == "View OneDrive Files": files = make_api_call('me/drive/root/children', token['access_token']) if files: for file in files['value']: st.write(f"File: {file['name']}") st.write(f"Type: {file['file']['mimeType'] if 'file' in file else 'Folder'}") st.write("---") if __name__ == "__main__": main()