Spaces:
Running
Running
| import os | |
| import streamlit as st | |
| import requests | |
| import msal | |
| import secrets | |
| import time | |
| from urllib.parse import urlencode | |
| # 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) | |
| auth_url = msal_app.get_authorization_request_url( | |
| scopes=SCOPES, | |
| redirect_uri=REDIRECT_URI, | |
| state=state | |
| ) | |
| # Store the state in query params | |
| new_query_params = st.query_params.to_dict() | |
| new_query_params['auth_state'] = state | |
| return f"{auth_url}&{urlencode(new_query_params)}" | |
| 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')}") | |
| # 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") | |
| # Debug information | |
| st.sidebar.write("Debug Info:") | |
| st.sidebar.write(f"Query Params: {st.query_params.to_dict()}") | |
| if 'code' in st.query_params and 'state' in st.query_params: | |
| received_state = st.query_params['state'] | |
| expected_state = st.query_params.get('auth_state') | |
| if received_state != expected_state: | |
| st.error(f"Invalid state parameter. Expected {expected_state}, got {received_state}") | |
| st.error("Please try logging in again.") | |
| st.query_params.clear() | |
| st.rerun() | |
| try: | |
| token = get_token_from_code(st.query_params['code']) | |
| st.session_state['token'] = token | |
| st.query_params.clear() | |
| st.success("Successfully authenticated!") | |
| st.rerun() | |
| except Exception as e: | |
| st.error(f"Authentication failed: {str(e)}") | |
| st.query_params.clear() | |
| st.rerun() | |
| if 'token' not in st.session_state: | |
| 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 | |
| token = st.session_state['token'] | |
| 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() |