Spaces:
Running
Running
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() |