awacke1 commited on
Commit
6e1e01a
Β·
verified Β·
1 Parent(s): 84135e5

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +217 -0
app.py ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ import requests
4
+ import msal
5
+ from datetime import datetime, timedelta
6
+
7
+ # Configuration
8
+ APPLICATION_ID_KEY = os.getenv('APPLICATION_ID_KEY')
9
+ CLIENT_SECRET_KEY = os.getenv('CLIENT_SECRET_KEY')
10
+ AUTHORITY_URL = 'https://login.microsoftonline.com/common'
11
+ REDIRECT_URI = 'https://huggingface.co/spaces/awacke1/MSGraphAPI'
12
+
13
+ # Define product to scope mapping
14
+ PRODUCT_SCOPES = {
15
+ "πŸ“§ Outlook": ['Mail.Read', 'Mail.Send'],
16
+ "πŸ“… Calendar": ['Calendars.ReadWrite'],
17
+ "πŸ“‹ Tasks": ['Tasks.ReadWrite'],
18
+ "πŸ—‚οΈ OneDrive": ['Files.ReadWrite.All'],
19
+ # ... (other products)
20
+ }
21
+
22
+ BASE_SCOPES = ['User.Read']
23
+
24
+ def get_msal_app():
25
+ return msal.ConfidentialClientApplication(
26
+ client_id=APPLICATION_ID_KEY,
27
+ client_credential=CLIENT_SECRET_KEY,
28
+ authority=AUTHORITY_URL
29
+ )
30
+
31
+ def get_access_token(code):
32
+ client_instance = get_msal_app()
33
+ try:
34
+ result = client_instance.acquire_token_by_authorization_code(
35
+ code=code,
36
+ scopes=st.session_state.get('request_scopes', BASE_SCOPES),
37
+ redirect_uri=REDIRECT_URI
38
+ )
39
+ if 'access_token' in result:
40
+ return result['access_token']
41
+ else:
42
+ raise Exception(f"Error acquiring token: {result.get('error_description')}")
43
+ except Exception as e:
44
+ st.error(f"Exception in get_access_token: {str(e)}")
45
+ raise
46
+
47
+ def make_api_call(access_token, endpoint, method='GET', data=None):
48
+ headers = {'Authorization': f'Bearer {access_token}', 'Content-Type': 'application/json'}
49
+ url = f'https://graph.microsoft.com/v1.0/{endpoint}'
50
+
51
+ if method == 'GET':
52
+ response = requests.get(url, headers=headers)
53
+ elif method == 'POST':
54
+ response = requests.post(url, headers=headers, json=data)
55
+ else:
56
+ raise ValueError(f"Unsupported method: {method}")
57
+
58
+ if response.status_code in [200, 201]:
59
+ return response.json()
60
+ else:
61
+ st.error(f"API call failed: {response.status_code} - {response.text}")
62
+ return None
63
+
64
+ def handle_outlook_integration(access_token):
65
+ st.subheader("πŸ“§ Outlook Integration")
66
+ emails = make_api_call(access_token, 'me/messages?$top=5&$orderby=receivedDateTime desc')
67
+ if emails and 'value' in emails:
68
+ for email in emails['value']:
69
+ st.write(f"From: {email['from']['emailAddress']['name']}")
70
+ st.write(f"Subject: {email['subject']}")
71
+ st.write(f"Received: {email['receivedDateTime']}")
72
+ st.write("---")
73
+ else:
74
+ st.write("No emails found or unable to fetch emails.")
75
+
76
+ def handle_calendar_integration(access_token):
77
+ st.subheader("πŸ“… Calendar Integration")
78
+ events = make_api_call(access_token, 'me/events?$top=5&$orderby=start/dateTime')
79
+ if events and 'value' in events:
80
+ for event in events['value']:
81
+ st.write(f"Event: {event['subject']}")
82
+ st.write(f"Start: {event['start']['dateTime']}")
83
+ st.write(f"End: {event['end']['dateTime']}")
84
+ st.write("---")
85
+ else:
86
+ st.write("No events found or unable to fetch events.")
87
+
88
+ st.write("Add a new event:")
89
+ event_subject = st.text_input("Event Subject")
90
+ event_date = st.date_input("Event Date")
91
+ event_time = st.time_input("Event Time")
92
+ if st.button("Add Event"):
93
+ event_start = datetime.combine(event_date, event_time)
94
+ event_end = event_start + timedelta(hours=1)
95
+ new_event = {
96
+ "subject": event_subject,
97
+ "start": {
98
+ "dateTime": event_start.isoformat(),
99
+ "timeZone": "UTC"
100
+ },
101
+ "end": {
102
+ "dateTime": event_end.isoformat(),
103
+ "timeZone": "UTC"
104
+ }
105
+ }
106
+ result = make_api_call(access_token, 'me/events', method='POST', data=new_event)
107
+ if result:
108
+ st.success("Event added successfully!")
109
+ else:
110
+ st.error("Failed to add event.")
111
+
112
+ def handle_tasks_integration(access_token):
113
+ st.subheader("πŸ“‹ Tasks Integration")
114
+ tasks = make_api_call(access_token, 'me/todo/lists')
115
+ if tasks and 'value' in tasks:
116
+ default_list = next((list for list in tasks['value'] if list['wellknownListName'] == 'defaultList'), None)
117
+ if default_list:
118
+ tasks = make_api_call(access_token, f"me/todo/lists/{default_list['id']}/tasks")
119
+ if tasks and 'value' in tasks:
120
+ for task in tasks['value']:
121
+ st.write(f"Task: {task['title']}")
122
+ st.write(f"Status: {'Completed' if task['status'] == 'completed' else 'Not Completed'}")
123
+ st.write("---")
124
+ else:
125
+ st.write("No tasks found or unable to fetch tasks.")
126
+ else:
127
+ st.write("Default task list not found.")
128
+ else:
129
+ st.write("Unable to fetch task lists.")
130
+
131
+ st.write("Add a new task:")
132
+ task_title = st.text_input("Task Title")
133
+ if st.button("Add Task"):
134
+ new_task = {
135
+ "title": task_title
136
+ }
137
+ result = make_api_call(access_token, f"me/todo/lists/{default_list['id']}/tasks", method='POST', data=new_task)
138
+ if result:
139
+ st.success("Task added successfully!")
140
+ else:
141
+ st.error("Failed to add task.")
142
+
143
+ def handle_onedrive_integration(access_token):
144
+ st.subheader("πŸ—‚οΈ OneDrive Integration")
145
+ files = make_api_call(access_token, 'me/drive/root/children')
146
+ if files and 'value' in files:
147
+ for file in files['value']:
148
+ st.write(f"Name: {file['name']}")
149
+ st.write(f"Type: {'Folder' if 'folder' in file else 'File'}")
150
+ st.write(f"Last Modified: {file['lastModifiedDateTime']}")
151
+ st.write("---")
152
+ else:
153
+ st.write("No files found or unable to fetch files.")
154
+
155
+ def main():
156
+ st.title("πŸ¦„ MS Graph API with AI & Cloud Integration for M365")
157
+
158
+ st.sidebar.title("πŸ“ M365 Products")
159
+ st.sidebar.write("Select products to integrate:")
160
+
161
+ selected_products = {}
162
+ for product in PRODUCT_SCOPES.keys():
163
+ selected = st.sidebar.checkbox(product)
164
+ if selected:
165
+ selected_products[product] = True
166
+
167
+ request_scopes = BASE_SCOPES.copy()
168
+ for product in selected_products:
169
+ request_scopes.extend(PRODUCT_SCOPES[product])
170
+ request_scopes = list(set(request_scopes))
171
+
172
+ st.session_state['request_scopes'] = request_scopes
173
+
174
+ if 'access_token' not in st.session_state:
175
+ client_instance = get_msal_app()
176
+ auth_url = client_instance.get_authorization_request_url(
177
+ scopes=request_scopes,
178
+ redirect_uri=REDIRECT_URI
179
+ )
180
+ st.write('πŸ‘‹ Please [click here]({}) to log in and authorize the app.'.format(auth_url))
181
+
182
+ query_params = st.query_params
183
+ if 'code' in query_params:
184
+ code = query_params.get('code')
185
+ st.write('πŸ”‘ Authorization Code Obtained:', code[:10] + '...')
186
+
187
+ try:
188
+ access_token = get_access_token(code)
189
+ st.session_state['access_token'] = access_token
190
+ st.success("Access token acquired successfully!")
191
+ st.rerun()
192
+ except Exception as e:
193
+ st.error(f"Error acquiring access token: {str(e)}")
194
+ st.stop()
195
+ else:
196
+ access_token = st.session_state['access_token']
197
+
198
+ user_info = make_api_call(access_token, 'me')
199
+ if user_info:
200
+ st.sidebar.write(f"πŸ‘‹ Hello, {user_info.get('displayName', 'User')}!")
201
+
202
+ if selected_products:
203
+ for product in selected_products:
204
+ if product == "πŸ“§ Outlook":
205
+ handle_outlook_integration(access_token)
206
+ elif product == "πŸ“… Calendar":
207
+ handle_calendar_integration(access_token)
208
+ elif product == "πŸ“‹ Tasks":
209
+ handle_tasks_integration(access_token)
210
+ elif product == "πŸ—‚οΈ OneDrive":
211
+ handle_onedrive_integration(access_token)
212
+ # Add more product integrations here
213
+ else:
214
+ st.write("No products selected. Please select products from the sidebar.")
215
+
216
+ if __name__ == "__main__":
217
+ main()