MSGraphAPI / app.py
awacke1's picture
Update app.py
0676bbf verified
raw
history blame
4.56 kB
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()