import os import streamlit as st import requests import msal # 🤓 Load environment variables (Ensure these are set!) APPLICATION_ID_KEY = os.getenv('APPLICATION_ID_KEY') CLIENT_SECRET_KEY = os.getenv('CLIENT_SECRET_KEY') AUTHORITY_URL = 'https://login.microsoftonline.com/common' # Use 'common' for multi-tenant apps REDIRECT_URI = 'http://localhost:8501' # 👈 Make sure this matches your app's redirect URI # 🎯 Define the scopes your app will need SCOPES = ['User.Read', 'Calendars.ReadWrite'] # 🛠️ Initialize the MSAL client def get_msal_app(): return msal.ConfidentialClientApplication( client_id=APPLICATION_ID_KEY, client_credential=CLIENT_SECRET_KEY, authority=AUTHORITY_URL ) # 🔐 Acquire access token using authorization code def get_access_token(code): client_instance = get_msal_app() result = client_instance.acquire_token_by_authorization_code( code=code, scopes=SCOPES, redirect_uri=REDIRECT_URI ) if 'access_token' in result: return result['access_token'] else: st.error('Error acquiring token: ' + str(result.get('error_description'))) st.stop() # 🏃‍♂️ Main application function def main(): st.title("🦄 Simple Streamlit App with MS Graph API") # 🚀 Sidebar navigation st.sidebar.title("Navigation") menu = st.sidebar.radio("Go to", [ "1️⃣ Dashboard with Widgets", "🏠 Landing Page", "📅 Upcoming Events", "📆 Schedule", "📝 Agenda", "🔍 Event Details", "➕ Add Event", "🔎 Filter By" ]) # 🔑 Authentication if 'access_token' not in st.session_state: # 🕵️‍♂️ Check for authorization code in query parameters query_params = st.get_query_params() if 'code' in query_params: code = query_params['code'][0] st.write('🔑 Acquiring access token...') access_token = get_access_token(code) st.session_state['access_token'] = access_token st.rerun() # Reload the app to clear the code from URL else: # 📢 Prompt user to log in client_instance = get_msal_app() authorization_url = client_instance.get_authorization_request_url( scopes=SCOPES, redirect_uri=REDIRECT_URI ) st.write('👋 Please [click here]({}) to log in and authorize the app.'.format(authorization_url)) st.stop() else: # 🥳 User is authenticated, proceed with the app access_token = st.session_state['access_token'] headers = {'Authorization': 'Bearer ' + access_token} # 🤗 Greet the user response = requests.get('https://graph.microsoft.com/v1.0/me', headers=headers) if response.status_code == 200: user_info = response.json() st.sidebar.write(f"👋 Hello, {user_info['displayName']}!") else: st.error('Failed to fetch user info.') st.write(response.text) # 🎛️ Handle menu options if menu == "1️⃣ Dashboard with Widgets": st.header("1️⃣ Dashboard with Widgets") st.write("Widgets will be displayed here. 🎛️") # Add your widgets here elif menu == "🏠 Landing Page": st.header("🏠 Landing Page") st.write("Welcome to the app! 🥳") # Add landing page content here elif menu == "📅 Upcoming Events": st.header("📅 Upcoming Events") events = get_upcoming_events(access_token) for event in events: st.write(f"📆 {event['subject']} on {event['start']['dateTime']}") # Display upcoming events elif menu == "📆 Schedule": st.header("📆 Schedule") schedule = get_schedule(access_token) st.write(schedule) # Display schedule elif menu == "📝 Agenda": st.header("📝 Agenda") st.write("Your agenda for today. 📋") # Display agenda elif menu == "🔍 Event Details": st.header("🔍 Event Details") event_id = st.text_input("Enter Event ID") if event_id: event_details = get_event_details(access_token, event_id) st.write(event_details) # Display event details based on ID elif menu == "➕ Add Event": st.header("➕ Add Event") event_subject = st.text_input("Event Subject") event_start = st.date_input("Event Start Date") event_start_time = st.time_input("Event Start Time") event_end = st.date_input("Event End Date") event_end_time = st.time_input("Event End Time") if st.button("Add Event"): event_details = { "subject": event_subject, "start": { "dateTime": f"{event_start}T{event_start_time}", "timeZone": "UTC" }, "end": { "dateTime": f"{event_end}T{event_end_time}", "timeZone": "UTC" } } add_event(access_token, event_details) st.success("Event added successfully! 🎉") # Form to add new event elif menu == "🔎 Filter By": st.header("🔎 Filter Events") filter_criteria = st.text_input("Enter filter criteria") if filter_criteria: filtered_events = filter_events(access_token, filter_criteria) for event in filtered_events: st.write(f"📅 {event['subject']} on {event['start']['dateTime']}") # Filter events based on criteria else: st.write("Please select a menu option.") # 📅 Function to get upcoming events def get_upcoming_events(access_token): headers = {'Authorization': 'Bearer ' + access_token} response = requests.get('https://graph.microsoft.com/v1.0/me/events?$orderby=start/dateTime&$top=10', headers=headers) if response.status_code == 200: events = response.json().get('value', []) return events else: st.error('Failed to fetch upcoming events.') st.write(response.text) return [] # 📆 Function to get schedule (Placeholder) def get_schedule(access_token): # Implement API call to get schedule return "📆 Your schedule goes here." # ➕ Function to add a new event def add_event(access_token, event_details): headers = { 'Authorization': 'Bearer ' + access_token, 'Content-Type': 'application/json' } response = requests.post('https://graph.microsoft.com/v1.0/me/events', headers=headers, json=event_details) if response.status_code == 201: st.success('Event created successfully! 🎉') else: st.error('Failed to create event.') st.write(response.text) # 🔍 Function to get event details def get_event_details(access_token, event_id): headers = {'Authorization': 'Bearer ' + access_token} response = requests.get(f'https://graph.microsoft.com/v1.0/me/events/{event_id}', headers=headers) if response.status_code == 200: event = response.json() return event else: st.error('Failed to fetch event details.') st.write(response.text) return {} # 🔎 Function to filter events def filter_events(access_token, filter_criteria): headers = {'Authorization': 'Bearer ' + access_token} # Implement filtering logic based on criteria response = requests.get(f"https://graph.microsoft.com/v1.0/me/events?$filter=startswith(subject,'{filter_criteria}')", headers=headers) if response.status_code == 200: events = response.json().get('value', []) return events else: st.error('Failed to filter events.') st.write(response.text) return [] # 🚀 Run the main function if __name__ == "__main__": main()