File size: 6,936 Bytes
58d2388
 
 
 
 
5b1e4ca
 
 
 
 
58d2388
 
 
5b1e4ca
 
 
 
 
 
1597a23
5b1e4ca
1597a23
 
 
5b1e4ca
 
1597a23
5b1e4ca
 
 
 
 
 
 
 
 
1597a23
5b1e4ca
1597a23
 
 
e8313ed
1597a23
 
 
5b1e4ca
 
 
 
 
1597a23
 
 
5b1e4ca
1597a23
5b1e4ca
 
 
 
 
 
 
 
 
1597a23
 
 
 
 
 
 
 
 
5b1e4ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58d2388
5b1e4ca
 
 
1597a23
 
 
 
 
 
 
5b1e4ca
 
1597a23
 
5b1e4ca
 
 
 
 
 
 
1597a23
5b1e4ca
 
 
 
 
 
 
1597a23
 
 
 
5b1e4ca
1597a23
 
 
5b1e4ca
 
 
1597a23
a5267f3
5b1e4ca
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58d2388
5b1e4ca
 
1597a23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
from composio_llamaindex import ComposioToolSet, App, Action
from llama_index.core.agent import FunctionCallingAgentWorker
from llama_index.core.llms import ChatMessage
from llama_index.llms.openai import OpenAI
from dotenv import load_dotenv
import gradio as gr
import os
import time
import random

# Load environment variables
load_dotenv()

class CalendarWrappedAPI:
    def __init__(self):
        self.toolset = ComposioToolSet(api_key=os.getenv('COMPOSIO_API_KEY'))
        self.llm = OpenAI(model="gpt-4", api_key=os.getenv('OPENAI_API_KEY'))
        self.connections = {}
        
    def initiate_connection(self, entity_id, redirect_url=None):
        """Initialize connection using entity_id (username)"""
        if redirect_url is None:
            redirect_url = "https://yourwebsite.com/connection/success"
            
        try:
            connection_request = self.toolset.initiate_connection(
                redirect_url=redirect_url,
                entity_id=entity_id,
                app=App.GOOGLECALENDAR
            )
            
            # Store connection info
            self.connections[entity_id] = {
                'status': connection_request.connectionStatus,
                'redirect_url': connection_request.redirectUrl
            }
            
            
            # Return redirect URL and wait time immediately
            initial_response = {
                'status': 'initiated',
                'redirect_url': '<a>'+connection_request.redirectUrl+'</a>',
                'wait_time': wait_time,
                'message': f'Please click the link below to authenticate. Waiting {wait_time} seconds for completion...'
            }            
            # Check final status after waiting
            final_status = 'active'  # You would typically check the actual status here
            self.connections[entity_id]['status'] = final_status
            
            return {
                'status': final_status,
                'redirect_url': connection_request.redirectUrl,
                'message': f'Authentication process completed after {wait_time} seconds. Status: {final_status}'
            }
            
        except Exception as e:
            return {
                'status': 'error',
                'message': str(e)
            }
    
    def check_connection_status(self, entity_id):
        """Check the connection status using entity_id"""
        if entity_id in self.connections:
            return {
                'status': self.connections[entity_id]['status'],
                'wait_time': wait_time,
                'message': f'Status checked after {wait_time} seconds'
            }
        return {
            'status': 'not_found',
            'message': 'No connection found for this entity ID'
        }
    
    def generate_wrapped(self, entity_id):
        """Generate Calendar Wrapped summary using entity_id"""
        if entity_id not in self.connections:
            return "Please authenticate first by initiating a connection."
        
        if self.connections[entity_id]['status'] != 'active':
            return "Connection not active. Please complete the authentication process."
        
        tools = self.toolset.get_tools(apps=[App.GOOGLECALENDAR])
        
        prefix_messages = [
            ChatMessage(
                role="system",
                content="""
                You are a GOOGLE CALENDAR wrapped generator. Based on the user's calendar data,
                analyze the events and create a personalized "Calendar Wrapped" summary.
                Be extremely creative and funny about it. Include interesting statistics and patterns.
                """
            )
        ]
        
        agent = FunctionCallingAgentWorker(
            tools=tools,
            llm=self.llm,
            prefix_messages=prefix_messages,
            max_function_calls=10,
            allow_parallel_tool_calls=False,
            verbose=True
        ).as_agent()
        
        try:
            response = agent.chat(f"Create a Calendar Wrapped summary for user with entity_id: {entity_id}")
            return response
        except Exception as e:
            return f"Error generating wrapped: {str(e)}"

def create_gradio_api():
    api = CalendarWrappedAPI()
    
    def handle_connection(entity_id, redirect_url):
        result = api.initiate_connection(entity_id, redirect_url)
        return (
            result['message'],
            result['redirect_url'],
            result.get('status', 'unknown')
        )
    
    def check_status(entity_id):
        result = api.check_connection_status(entity_id)
        return f"Status: {result['status']}\n{result['message']}"
    
    def generate(entity_id):
        return api.generate_wrapped(entity_id)
    
    with gr.Blocks() as demo:
        gr.Markdown("""
        # Google Calendar Wrapped Generator
        Connect your Google Calendar and generate your personalized wrapped summary.
        """)
        
        with gr.Tab("Connection"):
            entity_id_input = gr.Textbox(
                label="Entity ID (Username)",
                placeholder="Enter your username as entity ID"
            )
            redirect_url_input = gr.Textbox(
                label="Redirect URL",
                placeholder="https://yourwebsite.com/connection/success"
            )
            connect_btn = gr.Button("Initialize Connection")
            
            # New outputs for better visibility
            redirect_link = gr.HTML(label="Authentication Link")
            
            connect_btn.click(
                fn=handle_connection,
                inputs=[entity_id_input, redirect_url_input],
                outputs=[redirect_link]
            )
            
        with gr.Tab("Status Check"):
            status_entity_id = gr.Textbox(
                label="Entity ID (Username)",
                placeholder="Enter your username as entity ID"
            )
            check_btn = gr.Button("Check Status")
            status_output = gr.Textbox(label="Connection Status")
            
            check_btn.click(
                fn=check_status,
                inputs=status_entity_id,
                outputs=status_output
            )
            
        with gr.Tab("Generate Wrapped"):
            wrapped_entity_id = gr.Textbox(
                label="Entity ID (Username)",
                placeholder="Enter your username as entity ID"
            )
            generate_btn = gr.Button("Generate Wrapped")
            wrapped_output = gr.Textbox(label="Wrapped Summary", lines=10)
            
            generate_btn.click(
                fn=generate,
                inputs=wrapped_entity_id,
                outputs=wrapped_output
            )
    
    return demo

if __name__ == "__main__":
    demo = create_gradio_api()
    demo.launch(share=True)  # Set share=False in production